Mock-data wireframes covering spec §5 / §9 surface area. All read from
src/mocks/fixtures.ts — no backend wiring yet. Each screen is built from
the design-system primitives (Panel, Pill, Button, label-system, status-dot)
and adheres to the instrumentation-grade visual grammar.
Screens:
- /login LoginPage — RT vs SOC mode switch (segmented), role-tinted.
RT form picks rt_operator / rt_lead at sign-in (mock only).
SOC form takes a session token (out-of-band, D-006).
Left rail carries mission brief + platform telemetry.
- /engagements EngagementsPage — mission roster table (codename, client,
status, c2_type, operators, SOC count, window).
- /runs LiveCockpitPage — the cornerstone screen. 3-column layout:
steps timeline | step detail (resolved command,
output, evidence, detection) | side rail
(DetectionPanel for SOC; EvidencePanel +
DetectionPanel readonly + CleanupPanel for RT).
Control bar (F6 pause/skip/retry/abort) is lead-RT-only.
Stats header: steps done, detected/partial/missed counts.
- /scenarios ScenarioComposerPage — 3-column composer:
filterable TTP library | ordered steps with delays
| inspector (params from params_schema_json, target
host list, jinja2 cleanup template preview).
c2_type locked at scenario level (D-F3 / H33).
- /library TtpLibraryPage — catalog table with stealth-variant
flagging, source provenance (custom/atr/mission),
payload_type chip, tags. Import journal / ATR buttons.
- /reports ReportPage — restricted MITRE matrix (techniques
played only, H29), narration timeline, integrity
hash footer (SHA-256, H19/H24/F9). PDF/JSON/MD
export buttons.
- /audit AuditPage — append-only journal viewer (lead RT only,
F13). Tabular timestamp/actor/role/action/resource.
UX guardrails baked in:
- SOC analysts never see RT-only controls (conditional rendering, not just
disabled state). UI layer mirrors backend RBAC but does not replace it.
- Layout density and dark-first palette tuned for long purple sessions
(sober contrast, no flash, status colors carry information without
being shouted).
- Live cockpit reserves a clear visual slot for cleanup-failed alerts
(R-T5) — currently a Pill, real alert UX lands when the WebSocket is
wired in sprint 1+.
Mimic frontend
React + TypeScript SPA for the Mimic BAS platform. Lives behind the existing RT reverse proxy (Caddy + TLS + IP allowlist) — see D-007.
Stack
- React 19, TypeScript strict
- Vite 8 (dev/build)
- Tailwind 4 (semantic tokens in
src/styles/theme.css) - TanStack Query 5 for server state
- react-router-dom v7 for routing
- Recharts for the report visualisations
- Vitest + Testing Library for unit tests
- Playwright for E2E (covered in sprint 1+)
Scripts
npm install
npm run dev # vite dev server on :5173
npm run build # tsc -b && vite build
npm run typecheck # tsc -b --noEmit
npm run lint # eslint . (strict TS + react-hooks + prettier)
npm run format # prettier --write .
npm test # vitest run
npm run e2e # playwright test (needs npm run e2e:install once)
Layout
src/
├── components/
│ ├── brand/ # Wordmark (provisional, awaits PR3 charter)
│ ├── shell/ # AppShell, Sidebar, StatusRail
│ └── ui/ # Panel, Pill, Button — instrument-grade primitives
├── mocks/ # sprint 0 fixtures (no backend yet)
├── router/ # RootLayout helper
├── screens/ # one folder per top-level route
├── session/ # mock auth context (D-003 v1 hook-in point)
├── styles/ # theme.css (tokens), fonts.css, globals.css
└── types/ # cross-cutting type aliases
Design system status (provisional)
The token layer in src/styles/theme.css is structured to receive the RT
graphic charter (PR3) without touching component code. Component CSS reads
exclusively from semantic tokens (--accent-rt, --status-detected, …);
swapping the underlying primitive palette is the only change required when
PR3 lands.
Auth status (sprint 0)
The session context reads/writes a mock user in sessionStorage. No real
auth yet. v1 will wire local username/password + bcrypt (D-003); v2 maps
Keycloak OIDC claims onto the same role enum.
Fonts
IBM Plex (Sans / Sans Condensed / Mono), self-hosted under public/fonts/.
Files are not yet vendored — see public/fonts/README.md. Until then the
UI falls back to ui-sans-serif / ui-monospace.