feat(ui): Operator Viewport Overhaul — Master HUD & Split-Screen Dual Operations Deck (Phase 3) #17
Labels
No labels
blocked
bug
enhancement
high-priority
low-priority
needs-info
needs-triage
ready-for-agent
ready-for-human
referenced
research
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gabogg/hikcentral#17
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Parent
PR #13: docs(ui): industrial brutalist frontend redesign and tactical telemetry guidelines
What to build
Replace the operator view carousel with the split-screen tactical terminal layout.
This establishes the fixed 52px Master Tactical HUD ribbon, the 60% Left Wing Tactical Portal Matrix (with hardware contact states, wiring classifications, and alarm hoisting), and the 40% Right Wing Live Occupancy Tachometer & Flux Log (with Little's Law dwell envelope and directional flux stream), bound directly to
TelemetryEngine.subscribe(snapshot).Acceptance criteria
\Delta t), active cycle phase, instantaneous headcount (t), adaptive multiplier, and active alarm counter.CLOSED/OPEN), sensor classifications (VERIFIED_SENSOR,SENSORLESS_OPEN,SENSORLESS_JUMPERED), and dynamic alarm hoisting to top.>>> IN,<<< OUT).TelemetryEngine.subscribe(snapshot).Blocked by
📋 Tech Debt Carried Forward from Issue #16 Code Review
The following items from the #16 code review must be addressed during this issue (or as prefactoring before mounting the Operator Split-Screen Deck):
1. Issue #15 Carried Debt (Still Unresolved)
TacticalStaticFiles: MoveTacticalStaticFilesout ofapp/main.pyintoapp/middleware/static.pyto fix Divergent Change.pytest.mark.xfailchecks intest_static_assets.pyfor remaining CDN links (cdn.tailwindcss.comandcdnjs.cloudflare.com).2.
TelemetryEngineDeep-Module Architectural RefinementsFixtureTransportConcrete Class: Removethis._transport instanceof FixtureTransportintelemetry_engine.js:326. Transports must be handled polymorphically without class-name inspection._calculateBusinessCycle, calculate hours/minutes using server-time reference rather than client browser OSgetHours(), preventing timezone drift in distributed operations desks.NOCTURNAL_QUIETcovers the full03:30–04:30window rather than abruptly terminating at04:00._notifySubscribers().Phase 3 Resolved: Operator Viewport Overhaul — Master HUD & Split-Screen Dual Operations Deck
Delivered in commits
286467fandcdb7b90as part of PR #13.1. Carried Technical Debt Resolved (from Issue #16)
TacticalStaticFilesExtraction: Moved out ofapp/main.pyinto dedicatedapp/middleware/static.pyandapp/middleware/__init__.py.@pytest.mark.xfail(strict=True)intests/test_static_assets.pyfor remaining external CDN links awaiting Phase 5 standalone compilation.FixtureTransportDecoupling: Replaced concrete class inspection with duck-typed polymorphic transport contracts (autoConnect,injectSnapshot).TelemetryEnginenow project facility local time (UTC-4) via UTC getters, preventing client browser OS timezone skew.NOCTURNAL_QUIETboundaries to cover03:30–04:30local time across the mid-night reset._notifySubscribers().2. Operator Viewport Architecture & Features Implemented
#master-hud-ribbonwith WebSocket status/latency, clock skew (\Delta t), active cycle phase, countdown to reset, instantaneous headcountN(t)with residual margin, adaptive multiplier\rho, and active alarm counter.<output>,<data value="...">).#operator-carousel-viewportand carousel scrolling logic (moveCarouselToSlide,initOperatorCarousel) in favor of a persistent, high-density split-screen blueprint deck.[ P-XX ], contact pin state ([ CLOSED ]/[ OPEN ]/[ ALARM ]/[ OFFLINE ]), sensor classifications (VERIFIED_SENSOR,SENSORLESS_OPEN,SENSORLESS_JUMPERED), and dynamic alarm priority hoisting to the top of the matrix.<dl>/<dt>/<dd>metadata and container event delegation (data-action).N(t), Little's Law dwell capacity envelope (W_{\max}), and real-time monospaced traversal feed (>>> IN,<<< OUT).CommandDeckAdapter):app/static/js/src/ui/command_deck_adapter.jssubscribing toTelemetryEngine.subscribe(snapshot).POST /api/doors/{door_index_code}/controlsupporting operator commands (unlock,close) broadcasting immediately to WebSocket clients with standardDOOR_NOT_FOUNDerror code.app.jsandTelemetryEngineshare a single live WebSocket connection without redundant socket duplication.3. Verification & Quality Gates
tests/frontend/*.test.js).N(t)and\rho, event delegation).🔍 Code Review: Issue #17 — Operator Viewport Overhaul (Master HUD & Split-Screen Deck)
Fixed point:
f4203d8→ HEAD (cdb7b90)Diff: 17 files changed, +1511 / −791
Commits reviewed:
286467ffeat(ui): implement Master Tactical HUD and Split-Screen Operator Deck (#17)cdb7b90 docs(ui): mark local ticket 03 as resolved (#17)Standards
Hard Violations
app/static/css/tactical-telemetry.css:531box-shadow: inset 0 0 10px rgba(255, 42, 42, 0.2);. The design system explicitly forbids soft ambient glows/shadows in favor of crisp 1px solid boundaries.app/static/js/src/ui/command_deck_adapter.js:162, 343&app/static/index.html:241tabular-numson Dynamic Numeric Field: Residual error margin elements (±${errorMargin}) lacktabular-nums, causing visual jitter during live WebSocket updates.app/static/js/src/ui/command_deck_adapter.js:410new Date(item.timestamp).toLocaleTimeString()formats timestamps according to the client browser's local OS timezone, violating the facility-synchronized clock invariant.app/controllers/door_controller.py:68-84control_doorlacks a typedresponse_model, passes rawdict[str, Any], and raisesHTTPExceptionwith literalstatus_code=404instead ofstatus.HTTP_404_NOT_FOUND.Judgement Calls (Fowler Smell Baseline)
app/static/js/app.js:372initWebSocket()directly accesses the private transportwindow.telemetryEngine._transportrather than using public engine APIs.command_deck_adapter.js:19, 36vsapp.js:29, 585escapeHtmland duration formatting functions are duplicated across files instead of shared from a utility module.app/services/door_service.py:1187, 1238from app.services.monitor_service import ws_managerinline import and broadcast invocation is duplicated across door mutation methods.Spec
(a) Missing or Partial Requirements
renderHud()displays WebSocket latency and clock skew, but omits Artemis OpenAPI heartbeat and Bumblebee session status indicators specified in §4.2.(b) Scope Creep (Unrequested Behaviour)
command_deck_adapter.js:263-271adds interactive door ranking exclusion buttons ([ + INCLUDE ] / [ - EXCLUDE ]) on every operator tile, pulling an administrative diagnostics feature into the operator surveillance view.(c) Implemented-but-Wrong Requirements
N(t)andρinstead of the canonical domain symbols $O(t)$ (Estimated Occupancy) and $k$ (Proportional Exit Multiplier).toLocaleTimeString()truncates flux traversal event timestamps to seconds (HH:MM:SS), discarding the millisecond timestamps required for high-frequency CCTV event reconciliation.door_controller.py:79-83passesX-Error-Code: DOOR_NOT_FOUNDas an HTTP header rather than embedding{"detail": str, "error_code": "DOOR_NOT_FOUND"}in the response JSON.Tech Debt Status from Issues #15 & #16
TacticalStaticFilesfrommain.pyapp/middleware/static.py.test_static_assets.pyair-gap assertionstest_index_html_strictly_air_gapped_no_external_cdnswithxfail(strict=True).FixtureTransportconcrete classautoConnectandinjectSnapshot.03:30–04:30._notifySubscribers().TelemetryEngine._calculateBusinessCycle, but regressed incommand_deck_adapter.js:410viatoLocaleTimeString().Summary
\rhovs canonical $O(t)$/k); W2: Milliseconds stripped from flux feed.📋 Tech Debt Carried Forward into Issue #18
box-shadow: inset 0 0 10px rgba(...)intactical-telemetry.css:531with a solid 1px or 2px#FF2A2Abrutalist border.N(t)andρto the canonical domain symbols $O(t)$ and $k$.toLocaleTimeString()incommand_deck_adapter.js:410with a millisecond formatter (HH:MM:SS.mmm) referencing facility time.tabular-numson Margin: Addtabular-numsto±${errorMargin}elements.control_doorEndpoint: Define a PydanticDoorControlResponseschema inapp/schemas/models.py, usestatus.HTTP_404_NOT_FOUND, and return a standard{"detail": str, "error_code": str}body.app.js:372to usewindow.telemetryEngine.ingestMessage(...)instead of inspecting_transport.