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:
@@ -2,7 +2,7 @@ import { useRouter } from 'next/router';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import Layout from '../../components/Layout';
|
||||
import JobMap from '../../components/map/JobMap';
|
||||
import type { MapPoint } from '../../components/map/types';
|
||||
import { pointSummary, type MapPoint } from '../../components/map/types';
|
||||
import { api } from '../../lib/api';
|
||||
import { useRequireAuth } from '../../lib/auth-context';
|
||||
import { useJobStream } from '../../lib/use-job-stream';
|
||||
@@ -98,13 +98,16 @@ export default function JobDetailPage() {
|
||||
</p>
|
||||
{job.description && <p>{job.description}</p>}
|
||||
|
||||
<div style={{ margin: '1rem 0', display: 'flex', gap: '1rem', color: '#555' }}>
|
||||
<div style={{ margin: '1rem 0', display: 'flex', gap: '1rem', color: '#555', flexWrap: 'wrap' }}>
|
||||
<span>
|
||||
<strong>{points.length}</strong> points
|
||||
</span>
|
||||
<span style={{ color: live > 0 ? '#388e3c' : '#999' }}>
|
||||
● live{live > 0 ? ` (+${live} this session)` : ''}
|
||||
</span>
|
||||
{points.length > 0 && (
|
||||
<span style={{ color: '#777' }}>latest: {pointSummary(points[points.length - 1])}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<JobMap points={points} heightPx={520} />
|
||||
|
||||
Reference in New Issue
Block a user