7.3 KiB
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
THRESHOLDSobject as default values - On mount, reads overrides from
localStoragekeybms_thresholdsand merges - Exposes
thresholds(the merged values) andsetThresholds(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: callsetThresholds({ temp: { warn, critical }, humidity: { ... }, power: { ... } })in the Save onClickProfileTab/NotificationsTab: these are cosmetic for a demo — write tolocalStorageunderbms_profile/bms_notificationskeys 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)
RoomStatusGridin 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-statusdata 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
divin 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 (4–6 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 µmparticles_5um— count/m³, particles ≥5 µm- Derived ISO class (1–9) 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)tolib/api.ts - Add a new panel on the Environmental page: "Air Quality — ISO 14644"
- Per-room ISO class badge (ISO 1–9, 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 | ~2–3 h |
| 3 — Mini floor map | New dashboard component | No | ~2–3 h |
| 4 — Floor map zoom/pan + CRAC shading | react-zoom-pan-pinch + overlay logic | No | ~3–4 h |
| 5 — Particle count | New simulator bot + API endpoint + env panel | Yes | ~3–4 h total |