BMS/ACTION_PLAN.md
2026-03-19 11:32:17 +00:00

7.3 KiB
Raw Permalink Blame History

BMS Action Plan — Post-Audit Fixes

Generated: 2026-03-10 Based on cross-referencing live site (bmsdemo.rdx4.com) against IMPROVEMENTS.md and source audit. Excludes: Clerk auth (intentional public demo), scheduled PDF email (deferred).


Phase 1 — Trivial Fixes (< 30 min, no backend, no context changes)

These are single-file, low-risk changes.

# File Issue Fix
1.1 components/layout/sidebar.tsx Network is in the "Safety" group alongside Leak and Fire, which is semantically wrong Move /network into the "Infrastructure" group, below Generator
1.2 lib/api.ts Base path is /api/backend and all fetch paths start /api/..., resulting in /api/backend/api/... — looks like a double-prefix at first glance Add a one-line comment above const BASE explaining the proxy path convention
1.3 IMPROVEMENTS.md Settings page (/settings) is fully built but completely absent from the plan Add a new entry to Phase 6 or a new Phase 7 "Untracked Additions" section to document it
1.4 IMPROVEMENTS.md Item 6.11 "mini floor map thumbnail" is marked [x] but what was built is a RoomStatusGrid (tabular room stats), not a visual rack-grid thumbnail Update the description to clarify what was actually delivered, or un-tick and add to backlog

Phase 2 — Settings Page: Wire Up Persistence

Currently all Settings save buttons have no onClick handler and threshold edits are never written anywhere. All pages read from the static THRESHOLDS constant in lib/thresholds.ts, making the entire Settings page cosmetic.

This phase makes Settings functional without a backend API — using localStorage and a React context so changes persist across refreshes and propagate to all pages at runtime.

2.1 — Create a ThresholdContext

New file: lib/threshold-context.tsx

  • Wraps the static THRESHOLDS object as default values
  • On mount, reads overrides from localStorage key bms_thresholds and merges
  • Exposes thresholds (the merged values) and setThresholds(patch) (writes to localStorage and re-renders)
  • Re-export a useThresholds() hook

2.2 — Add the provider to the dashboard layout

File: app/(dashboard)/layout.tsx

  • Wrap children in <ThresholdProvider> so all dashboard pages share the same context

2.3 — Update pages to read from context

Pages that currently import and use THRESHOLDS directly need to call useThresholds() instead. A grep for THRESHOLDS in app/(dashboard)/ will give the full list. Likely candidates:

  • environmental/page.tsx (temp/humidity thresholds for heatmap + ASHRAE table)
  • cooling/page.tsx (filter ΔP, COP, compressor thresholds)
  • power/page.tsx (rack power warn/crit lines on bar chart)
  • capacity/page.tsx (radial gauge colour bands)
  • floor-map/page.tsx (rack tile colour scale)

lib/thresholds.ts stays as the canonical defaults — no change needed there.

2.4 — Wire the Save buttons in settings/page.tsx

File: app/(dashboard)/settings/page.tsx

  • ThresholdsTab: call setThresholds({ temp: { warn, critical }, humidity: { ... }, power: { ... } }) in the Save onClick
  • ProfileTab / NotificationsTab: these are cosmetic for a demo — write to localStorage under bms_profile / bms_notifications keys so at least the values survive a refresh, even if they don't affect anything functional

2.5 — Add a visible "saved" confirmation

Currently there is no feedback when Save is clicked. Add a brief sonner toast (the project already uses it) on successful save. The Toaster is already mounted in the dashboard layout.


Phase 3 — Dashboard: True Mini Floor Map Thumbnail

Item 6.11 was marked done but delivered a room status table rather than a visual map.

File: app/(dashboard)/dashboard/page.tsx + new component components/dashboard/mini-floor-map.tsx

  • Replace (or sit alongside) RoomStatusGrid in the bottom row with a compact rack-grid tile
  • Re-use the colour logic already written in floor-map/page.tsx (temp overlay colours by default)
  • Each rack tile is a small coloured square (~12×16px), labelled with rack ID on hover tooltip
  • CRAC units shown as labelled strips at room edge (same pattern as full floor map)
  • Click navigates to /floor-map
  • Room tabs (Hall A / Hall B) if both rooms are present
  • Read from the same /api/readings/rack-status data already fetched on dashboard

This requires no backend changes — just a new presentational component that reuses existing API data.


Phase 4 — Floor Map: Zoom/Pan + CRAC Coverage Shading

These are the two remaining open items from 6.12.

4.1 — Zoom / Pan

File: app/(dashboard)/floor-map/page.tsx

  • Add react-zoom-pan-pinch (or equivalent) as a dependency: pnpm add react-zoom-pan-pinch
  • Wrap the rack grid div in a <TransformWrapper> / <TransformComponent> block
  • Add zoom controls (+ / / reset buttons) in the map header, above the legend
  • Pinch-to-zoom should work on touch devices automatically via the library

4.2 — CRAC Coverage Shading

File: app/(dashboard)/floor-map/page.tsx

  • Add a 5th overlay option to the overlay selector: CRAC Coverage
  • When active, colour each rack tile according to which CRAC unit is its nearest thermal neighbour (assign by row proximity — CRACs at room ends serve the rows closest to them, split at the midpoint)
  • Use a per-CRAC colour palette (46 distinct hues, low-opacity background fill)
  • Show CRAC ID in the legend with its assigned colour
  • No backend required — assignment is purely spatial, computed client-side from rack row index and CRAC position

Phase 5 — Environmental: Particle Count (ISO 14644)

Item 6.10. This is the only remaining [ ] item that hasn't been deferred.

5.1 — Simulator

File: backend simulator (not in frontend repo — coordinate with backend)

  • Add a ParticleBot (or extend an existing env bot) that emits:
    • particles_0_5um — count/m³, particles ≥0.5 µm
    • particles_5um — count/m³, particles ≥5 µm
    • Derived ISO class (19) per room, changing slowly with occasional spikes

5.2 — Backend API

  • New endpoint: GET /api/environmental/particles?site_id=&room_id=
  • Returns current counts + derived ISO class per room

5.3 — Frontend

File: app/(dashboard)/environmental/page.tsx + lib/api.ts

  • Add fetchParticleStatus(siteId) to lib/api.ts
  • Add a new panel on the Environmental page: "Air Quality — ISO 14644"
    • Per-room ISO class badge (ISO 19, colour-coded: green ≤7, amber 8, red 9)
    • 0.5 µm and 5 µm count bars with threshold lines (ISO 8 limits: 3,520,000 and 29,300 /m³)
    • A small note that DC target is ISO 8 (≤100,000 particles ≥0.5 µm/m³)
    • Trend sparkline (last 24h)

Execution Order Summary

Phase Scope Backend needed? Effort estimate
1 — Trivial fixes IMPROVEMENTS.md + sidebar + api.ts comment No ~20 min
2 — Settings persistence New context + localStorage + toast feedback No ~23 h
3 — Mini floor map New dashboard component No ~23 h
4 — Floor map zoom/pan + CRAC shading react-zoom-pan-pinch + overlay logic No ~34 h
5 — Particle count New simulator bot + API endpoint + env panel Yes ~34 h total