AI Implementation feature(865): Scoreboard: Ranking, Matrix, Event Log and Score Graph (#52)
This commit was merged in pull request #52.
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
type: architecture
|
||||
title: Frontend Structure
|
||||
description: Angular routes, components, services, guards, interceptors, and authenticated SSE transport.
|
||||
tags: [architecture, frontend, angular, shell, sse, challenges, notifications]
|
||||
timestamp: 2026-07-23T00:10:00Z
|
||||
tags: [architecture, frontend, angular, shell, sse, challenges, scoreboard, notifications]
|
||||
timestamp: 2026-07-23T05:10:00Z
|
||||
---
|
||||
|
||||
# Routes
|
||||
@@ -16,7 +16,7 @@ Routes live in `frontend/src/app/app.routes.ts`:
|
||||
| `/login` | `LandingComponent` | `landingGuard` | Public landing and authentication modal. |
|
||||
| `/` | `HomeComponent` | `authGuard` | Authenticated shell and child outlet. |
|
||||
| `/challenges` | `ChallengesPage` | inherited | Full challenges board (category columns, modal, flag submit, live SSE). |
|
||||
| `/scoreboard` | `ScoreboardPage` | inherited | Placeholder scoreboard page. |
|
||||
| `/scoreboard` | `ScoreboardPage` | inherited | Live scoreboard page with 4 tabs (Ranking / Matrix / Event Log / Score Graph), live SSE `solve` updates. |
|
||||
| `/blog` | `BlogPage` | inherited | Placeholder blog page. |
|
||||
| `/admin` | `AdminUsersComponent` | `adminGuard` | Admin-only child route. |
|
||||
| `/admin/challenges` | `AdminChallengesComponent` | inherited | Sortable/searchable admin Challenges list, Add/Edit modal, import/export. |
|
||||
@@ -37,6 +37,12 @@ Routes live in `frontend/src/app/app.routes.ts`:
|
||||
| `ChallengesApiService` | `frontend/src/app/features/challenges/challenges.service.ts` | HTTP wrapper around `/api/v1/challenges/{board,status,:id,:id/solves}` returning `Observable<...>` and translating `HttpErrorResponse` into a typed `ApiErrorEnvelope`. |
|
||||
| `challenges.pure.ts` | `frontend/src/app/features/challenges/challenges.pure.ts` | Pure types + helpers for the challenges feature (`BoardCard`, `SolverRow`, `SolveEventPayload`, sorting, parsers, friendly error mapping, `formatDdHhMm`). |
|
||||
| `ChallengeCardComponent` / `CategoryColumnComponent` / `ChallengeModalComponent` | `frontend/src/app/features/challenges/` | Presentational components for the board grid, column, and detail modal. |
|
||||
| `ScoreboardPage` | `frontend/src/app/features/scoreboard/scoreboard.page.ts` | Smart page for `/scoreboard`: holds a `ScoreboardStore`, calls `store.loadAll()` + `store.wireSse(...)` on init, tears them down on destroy, and switches between the 4 tab components via `*ngIf` on `store.activeTab()`. |
|
||||
| `ScoreboardStore` | `frontend/src/app/features/scoreboard/scoreboard.store.ts` | Root-provided signal store backing `/scoreboard`: holds the four projections, active tab, loading + error state, and the SSE lifecycle (`wireSse` / `stop` / exponential reconnect on transport error). Mutates all four tabs from each `solve` frame via pure helpers (`parseSolveEventIntoRanking`, `mutateMatrixFromSolve`, `applySolveToGraph`, `dedupEventLogBySolveId`). |
|
||||
| `ScoreboardApiService` | `frontend/src/app/features/scoreboard/scoreboard.service.ts` | HTTP wrapper around `/api/v1/scoreboard/{ranking,matrix,event-log,graph}` returning typed `ApiErrorEnvelope`s. |
|
||||
| `scoreboard.pure.ts` | `frontend/src/app/features/scoreboard/scoreboard.pure.ts` | Pure types + helpers shared between the store and the four tab components (`RankingRow`, `MatrixView`, `EventLogRow`, `GraphView`, `SolveLivePayload`, `PLAYER_COLOR_PALETTE`, `stablePlayerColorIndex`, `applyRankingSort`, `parseSolveEventIntoRanking`, `dedupEventLogBySolveId`, `applySolveToGraph`, `mutateMatrixFromSolve`, `formatSolveDateTime`). |
|
||||
| `ScoreboardTabsComponent` | `frontend/src/app/features/scoreboard/tabs.component.ts` | Horizontal tab strip bound to `store.activeTab()`; emits `(select)` to switch tabs. |
|
||||
| `RankingComponent` / `MatrixComponent` / `EventLogComponent` / `ScoreGraphComponent` | `frontend/src/app/features/scoreboard/` | Presentational components for the 4 tabs; each binds a single `@Input()` from `ScoreboardStore` and uses `PLAYER_COLOR_PALETTE` + `stablePlayerColorIndex` to color each player consistently. |
|
||||
| `NotificationService` | `frontend/src/app/core/services/notification.service.ts` | Root-provided signal-backed store of `{ id, kind, message, ts }` records; `error()` / `info()` push, `dismiss(id)` / `clear()` remove. |
|
||||
| `errorNotificationInterceptor` | `frontend/src/app/core/interceptors/error-notification.interceptor.ts` | Functional HTTP interceptor that pushes a friendly message into `NotificationService` for every `HttpErrorResponse`; suppresses duplicate toasts for endpoints with their own error UI (login form, `/challenges/status` snapshot). |
|
||||
|
||||
@@ -121,5 +127,6 @@ for the full contract and tester matrix.
|
||||
- [Authenticated Shell](/guides/authenticated-shell.md)
|
||||
- [Event Window](/guides/event-window.md)
|
||||
- [Challenges Board](/guides/challenges-board.md)
|
||||
- [Scoreboard Page](/guides/scoreboard-page.md)
|
||||
- [Notifications](/guides/notifications.md)
|
||||
- [System Overview](/architecture/overview.md)
|
||||
|
||||
Reference in New Issue
Block a user