9.2 KiB
Portal
Admin page
Devices
Device details
Device ports
Sensors
- A customer-facing web portal for lease operators to view their devices, see live status, issue commands, run calibrations, and view historical and SIM-usage data.
- Proper multi-user authentication with per-customer data isolation enforced server-side.
- Real-time UI: device state changes reflected in under a second.
- Mobile-friendly — operators use this on boats.
- Calibration wizard delivered first; other dashboards migrate over time.
3. Non-Goals
- Not replacing Grafana for deep historical analysis (can embed panels where useful).
- Not replacing ThingsBoard for telemetry storage.
- Not replacing Node-RED — Node-RED remains the orchestration and protocol-bridging layer.
- Not building native mobile apps. Web only, mobile-responsive.
4. Required Integrations
These are fixed. Everything else is the implementer's choice.
4.1 PostgREST
All persistent state — devices, customers, calibration sessions, command logs, configuration — is read and written via the existing PostgREST API. Authorization is enforced through PostgreSQL row-level security, keyed off claims in the Authentik-issued JWT. The portal must not bypass PostgREST to talk to the database directly.
4.2 MQTT (over WebSockets)
The portal subscribes to live device data via MQTT, almost certainly over secure WebSockets (WSS) from the browser. The MQTT broker is the source of truth for ephemeral state — online/offline, awake/asleep, live calibration values, sensor readings during streaming. Retained messages provide last-known state on initial connection; non-retained messages drive live updates.
Topic ACLs on the broker must restrict each user to topics for devices they own. Authentication mechanism (JWT plugin, dynamic credentials, per-user passwords) is a decision for the implementer in consultation with the existing infrastructure.
4.3 Node-RED
Node-RED is the command orchestration and protocol-bridging layer. The portal does not call Node-RED HTTP endpoints for routine work. Instead, the portal writes intent (a command row, a session start) to PostgREST, and Node-RED picks it up via PostgreSQL LISTEN/NOTIFY, publishes the appropriate MQTT command, watches for device acknowledgement, and updates state.
A small number of synchronous operations may justify a direct Node-RED HTTP endpoint, but this should be the exception, not the rule.
5. Functional Requirements
5.1 Authentication and User Management
- Users authenticate via Authentik (existing SSO).
- JWT used for both PostgREST authorization (RLS) and MQTT broker authentication.
- Users see only devices and data belonging to their organisation.
- Role model (admin, operator, viewer, etc.) to be confirmed — see open questions.
5.2 Device Management
- List view of all devices accessible to the user, with current status indicators.
- Filter and search by name, location, status, type.
- Detail view per device: configuration, location on map, last-seen timestamp, current readings, recent commands, calibration history.
- Edit configurable fields (name, notes, alarm thresholds, calibration config) through PostgREST.
5.3 Real-Time Monitoring
- Live status indicators per device: online/offline, awake/asleep, battery, signal strength, last reading.
- Updates reflected in the UI within ~1s of the device publishing.
- Visual indication when data is stale (no heartbeat for N seconds).
- Driven by MQTT subscriptions; reconnection handled gracefully.
5.4 Commands
- Users can issue commands to devices (wake, sleep, restart, trigger reading, enter/exit calibration mode, etc.).
- Issuing a command writes a row to a command-log table via PostgREST. The UI does not publish MQTT directly for commands.
- Node-RED publishes the MQTT command, watches for ack, updates the row's status.
- The UI shows command lifecycle in real time: pending → sent → acknowledged → completed (or failed/timed out).
- Per-device audit trail of all commands issued, by whom, with timestamps and outcome.
5.5 Calibration Wizard (priority feature)
A multi-step flow that replaces the existing Node-RED calibration page.
- User selects a device and sensor type to calibrate.
- Wizard creates a
calibration_sessionrecord (or equivalent) via PostgREST. - Wizard issues a "enter calibration mode" command (via the command flow above).
- While in calibration mode, the device publishes higher-rate raw values on a dedicated calibration topic; the wizard subscribes and displays them live.
- User captures reference points one at a time. Each captured point persists immediately to the database (so the session is resumable if interrupted).
- On finish, calibration coefficients are computed and saved to the session record. The device is taken out of calibration mode and the new coefficients are applied (mechanism via Node-RED).
- Past calibrations are listed per device, with timestamps, operator, and resulting coefficients.
- Where the calibration math runs (browser, Node-RED, PostgreSQL function, dedicated service) is the implementer's call.
5.6 Maps
- Map view showing all accessible devices with status-coloured markers.
- Aquaculture lease boundaries displayed as polygons where data is available.
- Marker popups link to device detail page.
- Live status updates reflected on the map.
5.7 Historical Data and Charts
- Per-device time-series charts of sensor readings over selectable time ranges.
- Implementer chooses charting library.
- Data source: PostgREST views over PostgreSQL. Where ThingsBoard or Grafana already provide a better view, embedding is acceptable.
5.8 Hologram SIM Usage
- Per-device cellular data usage and SIM status.
- Hologram API must be proxied through a backend — the API key is never exposed to the browser.
- Proxy implementation is the implementer's choice (Node-RED flow, small dedicated service, or PostgREST RPC calling out — all viable).
- Display: current-period usage summary plus a usage-over-time chart.
6. Non-Functional Requirements
6.1 Performance
- Usable over 4G connections from boats.
- Real-time UI changes within ~1s of MQTT message receipt.
- Initial page load under 3s on broadband, under 6s on mobile.
6.2 Security
- All traffic over TLS (HTTPS, WSS).
- Hologram API key, and any other backend-only credentials, never reachable from the browser.
- Authorization enforced server-side via RLS and broker ACLs. The UI may hide controls a user cannot use, but the server is the authority.
- MQTT topic ACLs restrict each user to their own devices' topics.
6.3 Reliability
- Portal degrades gracefully when MQTT or PostgREST is temporarily unavailable.
- MQTT WebSocket reconnects automatically with backoff.
- Stale-state warnings when live data has not updated within an expected window.
6.4 Maintainability
- Clear separation of concerns:
- PostgREST for persistent CRUD state.
- MQTT for ephemeral live state.
- Command flows: write to DB, observe state changes — never bypass.
- Consistent component library and design system across the app.
- Reasonable test coverage of the calibration wizard logic in particular.
7. Architecture Overview
Two parallel data paths in the browser:
- Persistent state — PostgREST for reads and writes of devices, sessions, commands, configuration. Authorized via Authentik JWT and PostgreSQL RLS.
- Live state — MQTT over WSS for real-time device status, telemetry streams during calibration, command-result events. Authorized via broker ACLs tied to the same JWT identity.
Command flow:
Browser → PostgREST insert (command row)
→ PostgreSQL NOTIFY
→ Node-RED LISTEN
→ MQTT publish to device
→ Device acts, publishes status
→ Browser MQTT subscription updates UI
→ Node-RED updates command row status
The browser is the consumer; Node-RED is the orchestrator; PostgreSQL is the system of record; the MQTT broker is the live event bus.
9. Open Questions
- User provisioning: Who creates user accounts in Authentik? Self-service, admin-only, or invitation-based?
- Role model: What roles exist beyond a simple admin/user split? Is there a "field operator" role distinct from a "lease manager" role?
- Lease boundaries: Where does the polygon data come from? State government open data, customer-supplied KML, manually drawn?
- Offline tolerance: Does the portal need to function partially offline, or is "shows a connection error" acceptable?
- Branding: Is there an existing visual identity to honour, or is the implementer free to choose?
- Migration: What happens to existing Node-RED dashboard users during cutover? Run both in parallel?
- Historical data source: Should historical charts read from PostgreSQL, ThingsBoard, or both? Is there a single canonical place?
- Alarm and notification model: Out of scope for v1, or required from day one?
- Audit and compliance: Are there regulatory requirements (data retention, traceability) that affect the calibration audit trail?




