docs: update documentation to OKF v0.1 format
This commit is contained in:
+2
-1
@@ -3,7 +3,7 @@ type: api
|
|||||||
title: Setup Endpoint
|
title: Setup Endpoint
|
||||||
description: Dedicated POST /api/v1/setup/create-admin endpoint used only while no administrator exists.
|
description: Dedicated POST /api/v1/setup/create-admin endpoint used only while no administrator exists.
|
||||||
tags: [api, setup, bootstrap, first-admin]
|
tags: [api, setup, bootstrap, first-admin]
|
||||||
timestamp: 2026-07-21T16:23:40Z
|
timestamp: 2026-07-21T16:48:20Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Endpoint
|
# Endpoint
|
||||||
@@ -76,5 +76,6 @@ non-retryable inline error and offer a Retry button for everything else.
|
|||||||
# See also
|
# See also
|
||||||
|
|
||||||
- [First-Run Bootstrap Guide](/guides/bootstrap.md)
|
- [First-Run Bootstrap Guide](/guides/bootstrap.md)
|
||||||
|
- [Setup Form Field Errors](/guides/setup-field-errors.md)
|
||||||
- [Backend Module Map](/architecture/backend-modules.md)
|
- [Backend Module Map](/architecture/backend-modules.md)
|
||||||
- [Bootstrap Service](/architecture/frontend-structure.md)
|
- [Bootstrap Service](/architecture/frontend-structure.md)
|
||||||
@@ -3,7 +3,7 @@ type: architecture
|
|||||||
title: Frontend Structure
|
title: Frontend Structure
|
||||||
description: Angular routes, components, services, guards, and interceptors.
|
description: Angular routes, components, services, guards, and interceptors.
|
||||||
tags: [architecture, frontend, angular]
|
tags: [architecture, frontend, angular]
|
||||||
timestamp: 2026-07-21T15:05:00Z
|
timestamp: 2026-07-21T16:48:20Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Routes
|
# Routes
|
||||||
@@ -29,7 +29,7 @@ All components are standalone (no NgModules). Each component imports
|
|||||||
| `HomeComponent` | `frontend/src/app/features/home/home.component.ts` | Authenticated shell with header, conditional admin nav, and `<router-outlet>` for children. |
|
| `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. |
|
| `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. |
|
| `LoginComponent` | `frontend/src/app/features/auth/login.component.ts` | Username/password form. |
|
||||||
| `SetupCreateAdminComponent` | `frontend/src/app/features/setup/setup-create-admin.component.ts` | First-admin bootstrap modal with typed reactive form, validation messages, retry handling, session initialization, and redirect to `/admin`. |
|
| `SetupCreateAdminComponent` | `frontend/src/app/features/setup/setup-create-admin.component.ts` | First-admin bootstrap modal with typed reactive form, inline validation messages (via [the field-error helpers](/guides/setup-field-errors.md)), retry handling, session initialization, and redirect to `/admin`. |
|
||||||
|
|
||||||
# Services
|
# Services
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ type: architecture
|
|||||||
title: Key Files Index
|
title: Key Files Index
|
||||||
description: One-line responsibility for every important source file in the repository.
|
description: One-line responsibility for every important source file in the repository.
|
||||||
tags: [architecture, index, key-files]
|
tags: [architecture, index, key-files]
|
||||||
timestamp: 2026-07-21T15:05:00Z
|
timestamp: 2026-07-21T16:48:20Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# Backend
|
# Backend
|
||||||
@@ -123,6 +123,7 @@ timestamp: 2026-07-21T15:05:00Z
|
|||||||
| `frontend/src/app/features/setup/setup-create-admin.component.ts` | First-admin modal overlay (non-dismissible; typed reactive form). |
|
| `frontend/src/app/features/setup/setup-create-admin.component.ts` | First-admin modal overlay (non-dismissible; typed reactive form). |
|
||||||
| `frontend/src/app/features/setup/setup-create-admin.service.ts` | POSTs to `/api/v1/setup/create-admin` and tags the result with the error code. |
|
| `frontend/src/app/features/setup/setup-create-admin.service.ts` | POSTs to `/api/v1/setup/create-admin` and tags the result with the error code. |
|
||||||
| `frontend/src/app/features/setup/setup-create-admin.validators.ts` | Standalone `passwordMatchValidator` group-level reactive form validator. |
|
| `frontend/src/app/features/setup/setup-create-admin.validators.ts` | Standalone `passwordMatchValidator` group-level reactive form validator. |
|
||||||
|
| `frontend/src/app/features/setup/setup-create-admin.field-errors.ts` | Pure `usernameError` / `passwordError` / `confirmError` helpers that turn reactive-form state into the inline validation messages rendered next to each input. |
|
||||||
| `frontend/src/app/features/home/home.component.ts` | Authenticated shell: header + conditional admin nav + `<router-outlet>`. |
|
| `frontend/src/app/features/home/home.component.ts` | Authenticated shell: header + conditional admin nav + `<router-outlet>`. |
|
||||||
| `frontend/src/app/features/home/home.shell.ts` | Pure `shouldShowAdminNav({isAuthenticated, role})` predicate (unit-tested). |
|
| `frontend/src/app/features/home/home.shell.ts` | Pure `shouldShowAdminNav({isAuthenticated, role})` predicate (unit-tested). |
|
||||||
|
|
||||||
@@ -135,6 +136,7 @@ timestamp: 2026-07-21T15:05:00Z
|
|||||||
| `tests/frontend/admin-shell.spec.ts` | Unit tests for `shouldShowAdminNav` predicate. |
|
| `tests/frontend/admin-shell.spec.ts` | Unit tests for `shouldShowAdminNav` predicate. |
|
||||||
| `tests/frontend/admin-navigation.spec.ts` | Tests for admin guard decision + nav-link rendering. |
|
| `tests/frontend/admin-navigation.spec.ts` | Tests for admin guard decision + nav-link rendering. |
|
||||||
| `tests/frontend/auth-restore.spec.ts` | Round-trips `auth.session-storage` helpers + refresh success/failure paths. |
|
| `tests/frontend/auth-restore.spec.ts` | Round-trips `auth.session-storage` helpers + refresh success/failure paths. |
|
||||||
|
| `tests/frontend/setup-create-admin.spec.ts` | Pure-Jest tests for `passwordMatchValidator` and the three field-error helpers (`usernameError`, `passwordError`, `confirmError`). |
|
||||||
| `tests/frontend/guard-bootstrap-race.spec.ts` | Pins `decideAuthRedirect` so a refresh on a deep link never flashes `/bootstrap` or `/login` while auth is hydrating. |
|
| `tests/frontend/guard-bootstrap-race.spec.ts` | Pins `decideAuthRedirect` so a refresh on a deep link never flashes `/bootstrap` or `/login` while auth is hydrating. |
|
||||||
| `tests/backend/csrf-client.ts` | Test helper for CSRF flow. |
|
| `tests/backend/csrf-client.ts` | Test helper for CSRF flow. |
|
||||||
| `tests/backend/db-helper.ts` | Test helper for spinning up an isolated DB. |
|
| `tests/backend/db-helper.ts` | Test helper for spinning up an isolated DB. |
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ type: guide
|
|||||||
title: First-Run Bootstrap
|
title: First-Run Bootstrap
|
||||||
description: How a fresh HIPCTF instance is initialized by the very first administrator.
|
description: How a fresh HIPCTF instance is initialized by the very first administrator.
|
||||||
tags: [guide, bootstrap, first-admin, onboarding, tester]
|
tags: [guide, bootstrap, first-admin, onboarding, tester]
|
||||||
timestamp: 2026-07-21T16:23:40Z
|
timestamp: 2026-07-21T16:48:20Z
|
||||||
---
|
---
|
||||||
|
|
||||||
# When this flow runs
|
# When this flow runs
|
||||||
@@ -70,7 +70,8 @@ The modal **cannot** be dismissed by the user:
|
|||||||
| Modal overlay | `.overlay` | Full-screen backdrop. |
|
| Modal overlay | `.overlay` | Full-screen backdrop. |
|
||||||
| Modal card | `.modal[role="dialog"]` | Contains the form; stops click propagation. |
|
| Modal card | `.modal[role="dialog"]` | Contains the form; stops click propagation. |
|
||||||
| Username input | `[data-testid="setup-username"]` | Reactive control with length/pattern rules. |
|
| Username input | `[data-testid="setup-username"]` | Reactive control with length/pattern rules. |
|
||||||
| Password input | `[data-testid="setup-password"]` | Reactive control. |
|
| Password input | `[data-testid="setup-password"]` | Reactive control; shows inline error on touch when empty. |
|
||||||
|
| Password error | `[data-testid="setup-password-error"]` | Renders `passwordError()` (currently `required`). |
|
||||||
| Confirm input | `[data-testid="setup-password-confirm"]` | Reactive control. |
|
| Confirm input | `[data-testid="setup-password-confirm"]` | Reactive control. |
|
||||||
| Submit button | `[data-testid="setup-submit"]` | Triggers validation even when invalid; disabled only while submitting. |
|
| Submit button | `[data-testid="setup-submit"]` | Triggers validation even when invalid; disabled only while submitting. |
|
||||||
| Server error alert | `[data-testid="setup-server-error"]` | Displays `serverError()`. |
|
| Server error alert | `[data-testid="setup-server-error"]` | Displays `serverError()`. |
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
---
|
||||||
|
type: guide
|
||||||
|
title: Setup Form Field Errors
|
||||||
|
description: Pure error-computation functions that drive the inline validation messages on the first-admin modal.
|
||||||
|
tags: [setup, validation, forms, frontend]
|
||||||
|
timestamp: 2026-07-21T16:48:20Z
|
||||||
|
---
|
||||||
|
|
||||||
|
# Purpose
|
||||||
|
|
||||||
|
The three pure helpers exported by
|
||||||
|
`frontend/src/app/features/setup/setup-create-admin.field-errors.ts`
|
||||||
|
turn the raw Angular reactive-form control state into the user-facing
|
||||||
|
strings shown beside each input on the first-admin modal. Keeping them
|
||||||
|
as standalone functions (instead of `computed()` signals inside the
|
||||||
|
component) makes them trivially unit-testable in isolation — see
|
||||||
|
`tests/frontend/setup-create-admin.spec.ts`.
|
||||||
|
|
||||||
|
# Helpers
|
||||||
|
|
||||||
|
| Function | Returns | Reads |
|
||||||
|
|-----------------|---------------------------------------------------------|------------------------------------------------------------------------|
|
||||||
|
| `usernameError` | `string \| null` | `value`, `touched`, plus `errors` keys `required`/`minlength`/`maxlength`/`pattern`. |
|
||||||
|
| `passwordError` | `string \| null` | `value`, `touched`, plus `errors.required`. |
|
||||||
|
| `confirmError` | `string \| null` | `value`, `touched`, `errors.required`, and the group-level `groupMismatch` flag from [the password-match validator](/architecture/key-files.md). |
|
||||||
|
|
||||||
|
All three return `null` when the field is not yet `touched` (or, for
|
||||||
|
`confirmError`, when no group-level mismatch has been raised), so the
|
||||||
|
UI stays clean until the user has interacted with the form.
|
||||||
|
|
||||||
|
# Inputs
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export interface FieldErrorContext {
|
||||||
|
value: string;
|
||||||
|
touched: boolean;
|
||||||
|
errors: Partial<Record<FieldErrorKey, true>> | null;
|
||||||
|
groupMismatch?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type FieldErrorKey =
|
||||||
|
| 'required'
|
||||||
|
| 'minlength'
|
||||||
|
| 'maxlength'
|
||||||
|
| 'pattern'
|
||||||
|
| 'passwordMismatch';
|
||||||
|
```
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
|
||||||
|
```ts
|
||||||
|
usernameError({
|
||||||
|
value: 'ab',
|
||||||
|
touched: true,
|
||||||
|
errors: { minlength: true },
|
||||||
|
});
|
||||||
|
// -> 'Username must be at least 3 characters'
|
||||||
|
|
||||||
|
confirmError({
|
||||||
|
value: 'hunter2',
|
||||||
|
touched: true,
|
||||||
|
errors: null,
|
||||||
|
groupMismatch: true,
|
||||||
|
});
|
||||||
|
// -> 'Passwords do not match'
|
||||||
|
|
||||||
|
passwordError({
|
||||||
|
value: '',
|
||||||
|
touched: true,
|
||||||
|
errors: { required: true },
|
||||||
|
});
|
||||||
|
// -> 'Password is required'
|
||||||
|
```
|
||||||
|
|
||||||
|
# Wiring
|
||||||
|
|
||||||
|
* `SetupCreateAdminComponent` (`frontend/src/app/features/setup/setup-create-admin.component.ts`)
|
||||||
|
binds the three helpers to template method calls (`usernameError()`,
|
||||||
|
`passwordError()`, `confirmError()`) that read the corresponding
|
||||||
|
`FormControl` and pass its current state.
|
||||||
|
* The template
|
||||||
|
(`frontend/src/app/features/setup/setup-create-admin.component.html`)
|
||||||
|
renders the returned string inside a `<small class="field-error">`
|
||||||
|
with `data-testid="setup-{username|password|confirm}-error"`, and
|
||||||
|
mirrors the result on the input via `[attr.aria-invalid]`.
|
||||||
|
* `tests/frontend/setup-create-admin.spec.ts` exercises every code path
|
||||||
|
of the three helpers directly — no Angular TestBed is required.
|
||||||
|
|
||||||
|
# See also
|
||||||
|
|
||||||
|
- [First-Run Bootstrap](/guides/bootstrap.md) — how the helpers surface
|
||||||
|
to the operator.
|
||||||
|
- [Setup Endpoint](/api/setup.md) — server-side validation that
|
||||||
|
mirrors these messages.
|
||||||
|
- [Key Files Index](/architecture/key-files.md)
|
||||||
+4
-1
@@ -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-21T16:23:40Z.
|
they need. Last regenerated 2026-07-21T16:48:20Z.
|
||||||
|
|
||||||
# Architecture
|
# Architecture
|
||||||
|
|
||||||
@@ -52,6 +52,9 @@ they need. Last regenerated 2026-07-21T16:23:40Z.
|
|||||||
|
|
||||||
* [First-Run Bootstrap](/guides/bootstrap.md) - How a fresh instance is
|
* [First-Run Bootstrap](/guides/bootstrap.md) - How a fresh instance is
|
||||||
initialized by the very first admin via the non-dismissible modal.
|
initialized by the very first admin via the non-dismissible modal.
|
||||||
|
* [Setup Form Field Errors](/guides/setup-field-errors.md) - Pure
|
||||||
|
helpers that translate reactive-form state into the inline validation
|
||||||
|
messages on the first-admin modal.
|
||||||
* [Admin Shell & User Management](/guides/admin-shell.md) - How admins
|
* [Admin Shell & User Management](/guides/admin-shell.md) - How admins
|
||||||
navigate the post-login shell and reach the user-management area.
|
navigate the post-login shell and reach the user-management area.
|
||||||
* [Session Restoration on Reload](/guides/session-restoration.md) - How
|
* [Session Restoration on Reload](/guides/session-restoration.md) - How
|
||||||
|
|||||||
Reference in New Issue
Block a user