docs: update documentation to OKF v0.1 format

This commit is contained in:
OpenVelo Agent
2026-07-22 09:37:07 +00:00
parent d134a56abe
commit 4e463de65c
5 changed files with 136 additions and 14 deletions
+27 -2
View File
@@ -3,7 +3,7 @@ type: architecture
title: Frontend Structure title: Frontend Structure
description: Angular routes, components, services, guards, interceptors, and authenticated SSE transport. description: Angular routes, components, services, guards, interceptors, and authenticated SSE transport.
tags: [architecture, frontend, angular, shell, sse] tags: [architecture, frontend, angular, shell, sse]
timestamp: 2026-07-22T09:22:34Z timestamp: 2026-07-22T09:35:00Z
--- ---
# Routes # 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. | | `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. | | `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. | | `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. | | `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. | | `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. | | `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. | | `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. | | `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<Record<EventState, string>>` 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-<state>` classes remain on the
element as selectors/test hooks but no longer own the color.
# See also # See also
- [Authenticated Shell](/guides/authenticated-shell.md) - [Authenticated Shell](/guides/authenticated-shell.md)
+3 -3
View File
@@ -3,7 +3,7 @@ type: architecture
title: Key Files Index title: Key Files Index
description: One-line responsibility for important source files, including authenticated event streaming. description: One-line responsibility for important source files, including authenticated event streaming.
tags: [architecture, index, key-files] tags: [architecture, index, key-files]
timestamp: 2026-07-21T23:25:00Z timestamp: 2026-07-22T09:35:00Z
--- ---
# Backend # 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/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/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.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/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, countdown, and user menu. | | `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/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. | | `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. | | `tests/frontend/authenticated-event-source.spec.ts` | Tests SSE authorization and frame transport behavior. |
+17 -8
View File
@@ -3,7 +3,7 @@ type: guide
title: Authenticated Shell title: Authenticated Shell
description: How a signed-in user experiences the post-login shell, including authenticated event streaming. description: How a signed-in user experiences the post-login shell, including authenticated event streaming.
tags: [guide, shell, header, sse, navigation, tester] tags: [guide, shell, header, sse, navigation, tester]
timestamp: 2026-07-22T09:22:34Z timestamp: 2026-07-22T09:35:00Z
--- ---
# When this view is available # When this view is available
@@ -35,20 +35,29 @@ before the shell mounts.
# Event LED colors # Event LED colors
The LED is rendered by `ShellHeaderComponent` as a `<span class="led">` with one of four state classes attached via `[class.led-<state>]`. 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 `<span class="led">` with one of four state classes attached via `[class.led-<state>]` and a `[style.background-color]` bound directly from a pure TypeScript helper.
| Event state | CSS class | Color token | Approx. hex | Visual | | Event state | CSS class | Color token (`[style.background-color]` value) | Approx. hex | Visual |
|-------------------|-----------------------|-----------------------|-------------|--------| |-------------------|-----------------------|------------------------------------------------|-------------|--------|
| `countdown` | `led led-countdown` | `--color-warning` | `#f59e0b` | Yellow filled dot | | `countdown` | `led led-countdown` | `var(--color-warning)` | `#f59e0b` | Yellow filled dot |
| `running` | `led led-running` | `--color-success` | `#10b981` | Green filled dot | | `running` | `led led-running` | `var(--color-success)` | `#10b981` | Green filled dot |
| `stopped` | `led led-stopped` | `--color-danger` | `#ef4444` | Red filled dot | | `stopped` | `led led-stopped` | `var(--color-danger)` | `#ef4444` | Red filled dot |
| `unconfigured` | `led led-unconfigured`| `--color-secondary` | `#64748b` | Neutral gray 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 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 is always the same size and shape — only the background color changes
between states. The element also carries between states. The element also carries
`aria-label="Event status: <state>"` for assistive tech. `aria-label="Event status: <state>"` 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: <state>` and never relies on color alone.
## Quick tabs ## Quick tabs
The tab strip `[data-testid="quick-tabs"]` contains `Challenges`, `Scoreboard`, and The tab strip `[data-testid="quick-tabs"]` contains `Challenges`, `Scoreboard`, and
+86
View File
@@ -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<Record<EventState, string>>`.
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: <state>"` attribute.
* The four `led-<state>` 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)
+3 -1
View File
@@ -11,7 +11,7 @@ scoreboard, an event window with a public countdown, theming, and admin
controls. controls.
The docs below are organized by purpose so agents can pull just the slice 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 # Architecture
@@ -75,5 +75,7 @@ they need. Last regenerated 2026-07-22T09:22:34Z.
* [Theming](/guides/theming.md) - How themes are loaded and applied. * [Theming](/guides/theming.md) - How themes are loaded and applied.
* [Event Window](/guides/event-window.md) - How the 4-state event * [Event Window](/guides/event-window.md) - How the 4-state event
window and live countdown work, including the authenticated SSE stream. 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 * [Scoreboard Stream](/guides/scoreboard-stream.md) - How live solves are
broadcast to clients. broadcast to clients.