From 4e463de65c005b7a55cbe6fec83efbe16430a3d0 Mon Sep 17 00:00:00 2001 From: OpenVelo Agent Date: Wed, 22 Jul 2026 09:37:07 +0000 Subject: [PATCH] docs: update documentation to OKF v0.1 format --- docs/architecture/frontend-structure.md | 29 ++++++++- docs/architecture/key-files.md | 6 +- docs/guides/authenticated-shell.md | 25 ++++--- docs/guides/event-led-colors.md | 86 +++++++++++++++++++++++++ docs/index.md | 4 +- 5 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 docs/guides/event-led-colors.md diff --git a/docs/architecture/frontend-structure.md b/docs/architecture/frontend-structure.md index 48f6a5c..fe086d4 100644 --- a/docs/architecture/frontend-structure.md +++ b/docs/architecture/frontend-structure.md @@ -3,7 +3,7 @@ type: architecture title: Frontend Structure description: Angular routes, components, services, guards, interceptors, and authenticated SSE transport. tags: [architecture, frontend, angular, shell, sse] -timestamp: 2026-07-22T09:22:34Z +timestamp: 2026-07-22T09:35:00Z --- # Routes @@ -27,7 +27,7 @@ Routes live in `frontend/src/app/app.routes.ts`: | `HomeComponent` | `frontend/src/app/features/home/home.component.ts` | Smart shell; owns navigation signals, user hydration, change-password flow, and event-stream lifecycle. | | `ShellHeaderComponent` | `frontend/src/app/features/shell/header/shell-header.component.ts` | Renders title, active section, event LED/countdown, and user menu; contains component-scoped LED styling. | | `QuickTabsComponent` | `frontend/src/app/features/shell/tabs/quick-tabs.component.ts` | Emits navigation events for Challenges, Scoreboard, and Blog. | -| `EventStatusStore` | `frontend/src/app/core/services/event-status.store.ts` | Applies event state frames and computes countdown text. | +| `EventStatusStore` | `frontend/src/app/core/services/event-status.store.ts` | Applies event state frames and computes countdown text; re-exports the pure LED color mapping. | | `AuthenticatedEventSourceService` | `frontend/src/app/core/services/authenticated-event-source.service.ts` | Opens authenticated SSE over `fetch`, parsing streamed frames into `EventSourceLike` events. | | `AuthService` | `frontend/src/app/core/services/auth.service.ts` | Stores the access token used by the authenticated SSE transport. | | `UserStore` | `frontend/src/app/core/services/user.store.ts` | Hydrates the signed-in user and rank data. | @@ -59,6 +59,31 @@ and runs a one-second local timer. `HomeComponent` stops the store on destructio | `frontend/src/app/core/services/event-status.pure.ts` | Defines the event payload and transport interface. | | `tests/frontend/authenticated-event-source.spec.ts` | Regression coverage for authenticated SSE transport behavior. | +# Event-status pure helpers + +`frontend/src/app/core/services/event-status.pure.ts` owns the small, +no-Angular types and pure functions consumed by the event status pipeline. +`EventStatusStore` re-exports them so application code can import from a +single path. + +| Export | Purpose | +|---|---| +| `EventState` | Union `'running' \| 'countdown' \| 'stopped' \| 'unconfigured'`. | +| `EventStatePayload` | Server-pushed event window payload shape. | +| `EventSourceLike` | Minimal interface for any SSE transport the store can drive. | +| `formatDdHhMm(seconds)` | Pure `DD:HH:mm` formatter. | +| `deriveCountdownText(state, start, end)` | Pure mapping from event window state to countdown label. | +| `LED_COLOR_BY_STATE` | `Readonly>` mapping each state to its theme CSS variable (`var(--color-success)`, `--color-warning`, `--color-danger`, `--color-secondary`). | +| `ledBackgroundColor(state)` | Pure accessor returning the `background-color` value for the LED element. | + +`ShellHeaderComponent` exposes a `computed` signal `ledColor()` that calls +`ledBackgroundColor(this.eventState())` and binds it to the LED via +`[style.background-color]`. The component's `.led` base rule is therefore +shape-only (size, radius, `inline-block`, vertical alignment); the visible +color always comes from `LED_COLOR_BY_STATE` and is guaranteed to be a +non-transparent theme token. The four `led-` classes remain on the +element as selectors/test hooks but no longer own the color. + # See also - [Authenticated Shell](/guides/authenticated-shell.md) diff --git a/docs/architecture/key-files.md b/docs/architecture/key-files.md index de069ab..33ab169 100644 --- a/docs/architecture/key-files.md +++ b/docs/architecture/key-files.md @@ -3,7 +3,7 @@ type: architecture title: Key Files Index description: One-line responsibility for important source files, including authenticated event streaming. tags: [architecture, index, key-files] -timestamp: 2026-07-21T23:25:00Z +timestamp: 2026-07-22T09:35:00Z --- # Backend @@ -34,8 +34,8 @@ timestamp: 2026-07-21T23:25:00Z | `frontend/src/app/core/services/auth.service.ts` | Signal-backed access token and current-user state. | | `frontend/src/app/core/services/authenticated-event-source.service.ts` | Fetch-based authenticated SSE transport with frame parsing and abort support. | | `frontend/src/app/core/services/event-status.store.ts` | Event state signal store and one-second countdown timer. | -| `frontend/src/app/core/services/event-status.pure.ts` | Event payload types and pure countdown helpers. | -| `frontend/src/app/features/shell/header/shell-header.component.ts` | Shell title, status LED, countdown, and user menu. | +| `frontend/src/app/core/services/event-status.pure.ts` | Event payload types, pure countdown helpers, and the `LED_COLOR_BY_STATE` map used by the shell LED. | +| `frontend/src/app/features/shell/header/shell-header.component.ts` | Shell title, status LED (size/shape only — color comes from the pure map via `[style.background-color]`), countdown, and user menu. | | `frontend/src/app/features/shell/tabs/quick-tabs.component.ts` | Main shell navigation tabs. | | `frontend/src/app/features/shell/change-password/change-password-modal.component.ts` | Change-password form modal. | | `tests/frontend/authenticated-event-source.spec.ts` | Tests SSE authorization and frame transport behavior. | diff --git a/docs/guides/authenticated-shell.md b/docs/guides/authenticated-shell.md index 81e4d8f..00f0bae 100644 --- a/docs/guides/authenticated-shell.md +++ b/docs/guides/authenticated-shell.md @@ -3,7 +3,7 @@ type: guide title: Authenticated Shell description: How a signed-in user experiences the post-login shell, including authenticated event streaming. tags: [guide, shell, header, sse, navigation, tester] -timestamp: 2026-07-22T09:22:34Z +timestamp: 2026-07-22T09:35:00Z --- # When this view is available @@ -35,20 +35,29 @@ before the shell mounts. # Event LED colors -The LED is rendered by `ShellHeaderComponent` as a `` with one of four state classes attached via `[class.led-]`. Its component-scoped styling is declared in `frontend/src/app/features/shell/header/shell-header.component.ts` and is driven entirely by the existing theme color tokens — there is no per-state color in TypeScript. +The LED is rendered by `ShellHeaderComponent` as a `` with one of four state classes attached via `[class.led-]` and a `[style.background-color]` bound directly from a pure TypeScript helper. -| Event state | CSS class | Color token | Approx. hex | Visual | -|-------------------|-----------------------|-----------------------|-------------|--------| -| `countdown` | `led led-countdown` | `--color-warning` | `#f59e0b` | Yellow filled dot | -| `running` | `led led-running` | `--color-success` | `#10b981` | Green filled dot | -| `stopped` | `led led-stopped` | `--color-danger` | `#ef4444` | Red filled dot | -| `unconfigured` | `led led-unconfigured`| `--color-secondary` | `#64748b` | Neutral gray filled dot | +| Event state | CSS class | Color token (`[style.background-color]` value) | Approx. hex | Visual | +|-------------------|-----------------------|------------------------------------------------|-------------|--------| +| `countdown` | `led led-countdown` | `var(--color-warning)` | `#f59e0b` | Yellow filled dot | +| `running` | `led led-running` | `var(--color-success)` | `#10b981` | Green filled dot | +| `stopped` | `led led-stopped` | `var(--color-danger)` | `#ef4444` | Red filled dot | +| `unconfigured` | `led led-unconfigured`| `var(--color-secondary)` | `#64748b` | Neutral gray filled dot | + +The mapping is defined in [`frontend/src/app/core/services/event-status.pure.ts`](/architecture/frontend-structure.md#event-status-pure-helpers) as the constant `LED_COLOR_BY_STATE` and exposed through the helper `ledBackgroundColor(state)`. `ShellHeaderComponent` exposes it on the DOM via a `computed` signal called `ledColor()`, so the active theme token resolves at runtime and the LED is never painted with `transparent`. The base `.led` rule paints a 10×10 circular `inline-block`, so the LED is always the same size and shape — only the background color changes between states. The element also carries `aria-label="Event status: "` for assistive tech. +# What the tester should see + +* The 10×10 LED is visible (not transparent, not invisible) in every state. +* The LED color matches the table above for the active `EventState`. +* Switching the event window (countdown → running → stopped → unconfigured) flips the dot color in real time. +* The `aria-label` updates to `Event status: ` and never relies on color alone. + ## Quick tabs The tab strip `[data-testid="quick-tabs"]` contains `Challenges`, `Scoreboard`, and diff --git a/docs/guides/event-led-colors.md b/docs/guides/event-led-colors.md new file mode 100644 index 0000000..ea1b477 --- /dev/null +++ b/docs/guides/event-led-colors.md @@ -0,0 +1,86 @@ +--- +type: guide +title: Event LED Color Mapping +description: Single source of truth mapping each event window state to the themed background color painted on the authenticated shell's status LED. +tags: [guide, shell, led, theming, event-window, tester] +timestamp: 2026-07-22T09:35:00Z +--- + +# Purpose + +The 10×10 status dot in the authenticated shell LED +(`[data-testid="shell-led"]` in +[`ShellHeaderComponent`](/architecture/frontend-structure.md)) reflects the +current event window state. Its background color is driven by a single pure +helper so the dot is **never transparent** and the active theme token always +resolves at runtime. + +# Mapping + +Defined in +`frontend/src/app/core/services/event-status.pure.ts` and re-exported via +`frontend/src/app/core/services/event-status.store.ts`: + +| `EventState` | `ledBackgroundColor(state)` | Theme CSS variable | +|--------------|------------------------------|------------------------| +| `countdown` | `var(--color-warning)` | `--color-warning` | +| `running` | `var(--color-success)` | `--color-success` | +| `stopped` | `var(--color-danger)` | `--color-danger` | +| `unconfigured` | `var(--color-secondary)` | `--color-secondary` | + +Backing constant: `LED_COLOR_BY_STATE: Readonly>`. +The accessor function `ledBackgroundColor(state)` returns the same string for +each state. + +# How it reaches the DOM + +1. `HomeComponent` forwards the `state` signal from + [`EventStatusStore`](/architecture/frontend-structure.md) to + `ShellHeaderComponent` via its `eventState` input. +2. `ShellHeaderComponent.ledColor` is a `computed` signal defined as + `computed(() => ledBackgroundColor(this.eventState()))`. +3. The template binds it directly: + `[style.background-color]="ledColor()"`. +4. The LED's base `.led` rule is shape-only (`inline-block`, 10×10, circular, + `vertical-align: middle`); no `transparent` fallback is applied, so the + author background color is always visible. +5. The legacy `.led-running`, `.led-countdown`, `.led-stopped`, + `.led-unconfigured` CSS selectors remain on the element and continue to be + useful hooks for selectors and tests, but they no longer declare the color. + +# Examples + +## Programmatic lookup + +```ts +import { ledBackgroundColor, LED_COLOR_BY_STATE } from + './frontend/src/app/core/services/event-status.pure'; + +ledBackgroundColor('running'); // 'var(--color-success)' +ledBackgroundColor('stopped'); // 'var(--color-danger)' +LED_COLOR_BY_STATE.unconfigured; // 'var(--color-secondary)' +``` + +## Verifying in the DOM + +```ts +const dot = document.querySelector('[data-testid="shell-led"]') as HTMLElement; +dot.style.backgroundColor; // resolves to the current theme token, never empty +dot.getAttribute('aria-label'); // 'Event status: running' +``` + +# Tester checklist + +* The LED is **visible** in every state (no transparent or missing dot). +* The LED color matches the mapping table when the event window is forced + into each state via the [event window settings](/guides/event-window.md). +* Switching states live updates both the dot color and the + `aria-label="Event status: "` attribute. +* The four `led-` classes are still applied to the element. + +# See also + +- [Authenticated Shell](/guides/authenticated-shell.md) +- [Event Window](/guides/event-window.md) +- [Frontend Structure](/architecture/frontend-structure.md) +- [Theming](/guides/theming.md) diff --git a/docs/index.md b/docs/index.md index b689d13..9efd50f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,7 +11,7 @@ scoreboard, an event window with a public countdown, theming, and admin controls. The docs below are organized by purpose so agents can pull just the slice -they need. Last regenerated 2026-07-22T09:22:34Z. +they need. Last regenerated 2026-07-22T09:35:00Z. # Architecture @@ -75,5 +75,7 @@ they need. Last regenerated 2026-07-22T09:22:34Z. * [Theming](/guides/theming.md) - How themes are loaded and applied. * [Event Window](/guides/event-window.md) - How the 4-state event window and live countdown work, including the authenticated SSE stream. +* [Event LED Color Mapping](/guides/event-led-colors.md) - Source of + truth for the shell status dot's color in each `EventState`. * [Scoreboard Stream](/guides/scoreboard-stream.md) - How live solves are broadcast to clients.