docs: update documentation to OKF v0.1 format

This commit is contained in:
OpenVelo Agent
2026-07-21 15:32:48 +00:00
parent 960516a7bc
commit 5499e30f95
5 changed files with 173 additions and 19 deletions
+21 -8
View File
@@ -25,7 +25,7 @@ All components are standalone (no NgModules). Each component imports
| Component | Path | Purpose |
|------------------------|-----------------------------------------------------------------|-------------------------------------------------|
| `AppComponent` | `frontend/src/app/app.component.ts` | Root; renders `<router-outlet>` and calls `BootstrapService.load()`. |
| `AppComponent` | `frontend/src/app/app.component.ts` | Root; renders `<router-outlet>`, calls `BootstrapService.load()` then `AuthService.restoreSession()`. |
| `HomeComponent` | `frontend/src/app/features/home/home.component.ts` | Authenticated shell with header, conditional admin nav, and `<router-outlet>` for children. |
| `AdminUsersComponent` | `frontend/src/app/features/admin/admin-users.component.ts` | Admin-only user list rendered inside the home shell. |
| `LoginComponent` | `frontend/src/app/features/auth/login.component.ts` | Username/password form. |
@@ -35,16 +35,18 @@ All components are standalone (no NgModules). Each component imports
| Service | Path | Purpose |
|---------------------|---------------------------------------------------------------|-----------------------------------------------------------|
| `AuthService` | `frontend/src/app/core/services/auth.service.ts` | Signal-backed access token + current user. |
| `BootstrapService` | `frontend/src/app/core/services/bootstrap.service.ts` | Fetches `/api/v1/bootstrap`, applies theme tokens to CSS. |
| `AuthService` | `frontend/src/app/core/services/auth.service.ts` | Signal-backed access token + current user; persists session to `sessionStorage` and exposes `restoreSession()` + `waitUntilHydrated()`. |
| `BootstrapService` | `frontend/src/app/core/services/bootstrap.service.ts` | Fetches `/api/v1/bootstrap`, applies theme tokens to CSS; exposes `ready()` that deduplicates the in-flight load. |
| `AuthSessionStorage` (helpers) | `frontend/src/app/core/services/auth.session-storage.ts` | Pure `readStoredSession` / `writeStoredSession` / `clearStoredSession` against `sessionStorage` (key `hipctf.auth.v1`). |
| `AdminService` | `frontend/src/app/core/services/admin.service.ts` | `GET /api/v1/admin/users` (typed `AdminUser[]`). |
# Guards and interceptors
| Symbol | Path | Purpose |
|---------------------|---------------------------------------------------------------|-----------------------------------------------------------|
| `authGuard` | `frontend/src/app/core/guards/auth.guard.ts` | Redirects to `/bootstrap` when uninitialized, `/login` when not authenticated. |
| `adminGuard` | `frontend/src/app/core/guards/admin.guard.ts` | Delegates to `decideAdminGuard` (pure). Redirects to `/bootstrap`, `/login`, or `/` based on state; allows only admins. |
| `authGuard` | `frontend/src/app/core/guards/auth.guard.ts` | Async `CanActivateFn`; awaits `BootstrapService.ready()` and `AuthService.waitUntilHydrated()`, then delegates to `decideAuthRedirect`. |
| `decideAuthRedirect`| `frontend/src/app/core/guards/auth.guard.decision.ts` | Pure decision function mirroring `decideAdminGuard`; redirects to `/bootstrap` or `/login`, returns `true` otherwise. |
| `adminGuard` | `frontend/src/app/core/guards/admin.guard.ts` | Async `CanActivateFn`; awaits bootstrap + auth hydration, then delegates to `decideAdminGuard` (pure). Redirects to `/bootstrap`, `/login`, or `/` based on state; allows only admins. |
| `decideAdminGuard` | `frontend/src/app/core/guards/admin.guard.decision.ts` | Pure decision function: returns `{kind:'allow'}` or `{kind:'redirect', path}`. |
| `authInterceptor` | `frontend/src/app/core/interceptors/auth.interceptor.ts` | Attaches `Authorization: Bearer <accessToken>` header. |
| `csrfInterceptor` | `frontend/src/app/core/interceptors/csrf.interceptor.ts` | Attaches `X-CSRF-Token` header on POST/PUT/PATCH/DELETE. |
@@ -55,7 +57,10 @@ Both interceptors are wired in `frontend/src/main.ts` via
# Bootstrap flow
1. `AppComponent.ngOnInit()``BootstrapService.load()`.
1. `AppComponent.ngOnInit()``BootstrapService.load()` then
`AuthService.restoreSession()`. Both are deduplicated so concurrent
callers share a single in-flight promise (`loadPromise` /
`hydrateWaiters`).
2. `BootstrapService` calls `GET /api/v1/bootstrap` (public, with
`credentials: 'include'`).
3. The payload sets `initialized` (true iff any admin user exists),
@@ -64,8 +69,16 @@ Both interceptors are wired in `frontend/src/main.ts` via
4. Theme tokens are written to CSS custom properties on
`document.documentElement` (`--color-primary`, `--font-family`,
`--radius-*`, etc.) consumed by `frontend/src/styles.css`.
5. The `authGuard` reads `BootstrapService.initialized()` and either
allows navigation or redirects to `/bootstrap`.
5. `AuthService.restoreSession()` rehydrates the in-memory signals from
`sessionStorage` (key `hipctf.auth.v1`) and POSTs
`/api/v1/auth/refresh` with `withCredentials: true` to mint a fresh
access token. On success it persists the new token; on failure it
clears storage. Either way it flips `hydrated()` so the guards can
unblock.
6. The `authGuard` (and `adminGuard`) `await` `BootstrapService.ready()`
and `AuthService.waitUntilHydrated()` before reading `initialized()`
/ `isAuthenticated()`, which prevents a flash of `/bootstrap` or
`/login` on a hard refresh of a deep link.
# Home shell flow