Tie points to locator serial numbers and store receiver telemetry
Field setups often relay through a phone/gateway that owns the MQTT connection, so the publishing credential and the instrument are now separate concepts: - Points messages carry a "serial" identifying the locator receiver; unknown serials are auto-registered as devices in the publisher's org (name "Locator <serial>"). Device.mqttUsername is now optional and serialNumber is unique per org. - LocatePoint gains standard receiver telemetry: frequencyHz, currentMa, signalDb, gainDb, locateMode (PEAK/NULL/BROAD_PEAK/SONDE), phaseDeg, compassDeg, distortionPct, plus GPS quality columns vAccuracy, satellites, hdop. All optional; raw payload still kept. - Migration hand-edited to preserve the generated geom column and its GIST index (Prisma diff wanted to drop both). - REST create/point DTOs, map tooltips, job-detail latest-point readout, devices settings form, seed, and the sample publisher all carry the new fields. - Added .dockerignore for backend/web: COPY . . was clobbering the image's freshly generated Prisma client with the host's stale node_modules, breaking image builds after schema changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/// <reference types="google.maps" />
|
||||
import { APIProvider, Map as GoogleMap, useMap } from '@vis.gl/react-google-maps';
|
||||
import { useEffect, useRef } from 'react';
|
||||
import { JobMapProps, MapPoint, UTILITY_COLORS } from '../types';
|
||||
import { JobMapProps, MapPoint, pointSummary, UTILITY_COLORS } from '../types';
|
||||
|
||||
const API_KEY = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY || '';
|
||||
|
||||
@@ -67,7 +67,7 @@ function PointsLayer({ points, fitBounds }: { points: MapPoint[]; fitBounds: boo
|
||||
strokeColor: '#ffffff',
|
||||
strokeWeight: 1.5,
|
||||
},
|
||||
title: `${p.utilityType} · ${p.fixType}${p.depth != null ? ` · depth ${p.depth}m` : ''}\n${new Date(p.recordedAt).toLocaleString()}`,
|
||||
title: `${pointSummary(p)}\n${new Date(p.recordedAt).toLocaleString()}`,
|
||||
});
|
||||
overlaysRef.current.push(marker);
|
||||
}
|
||||
|
||||
@@ -8,9 +8,27 @@ export interface MapPoint {
|
||||
lng: number;
|
||||
utilityType: string;
|
||||
fixType: string;
|
||||
depth: number | null;
|
||||
sequence: number | null;
|
||||
recordedAt: string;
|
||||
// Locator receiver telemetry (all optional — depends on the instrument)
|
||||
depth: number | null;
|
||||
frequencyHz: number | null;
|
||||
currentMa: number | null;
|
||||
signalDb: number | null;
|
||||
gainDb: number | null;
|
||||
locateMode: string | null;
|
||||
compassDeg: number | null;
|
||||
distortionPct: number | null;
|
||||
}
|
||||
|
||||
export function pointSummary(p: MapPoint): string {
|
||||
const parts = [`${p.utilityType} · ${p.fixType}`];
|
||||
if (p.depth != null) parts.push(`depth ${p.depth}m`);
|
||||
if (p.frequencyHz != null)
|
||||
parts.push(p.frequencyHz >= 1000 ? `${p.frequencyHz / 1000}kHz` : `${p.frequencyHz}Hz`);
|
||||
if (p.currentMa != null) parts.push(`${p.currentMa}mA`);
|
||||
if (p.locateMode) parts.push(p.locateMode);
|
||||
return parts.join(' · ');
|
||||
}
|
||||
|
||||
export interface JobMapProps {
|
||||
|
||||
Reference in New Issue
Block a user