SCRUM-251 — AdminUI audit trail table and release diff¶
Plan ref: UI-6 (docs/11-admin-plane-plan.md). Stacked on SCRUM-250. Reads the
Dashboard's merged /audit (SCRUM-238) and Config's release list.
What exists¶
| Piece | Notes |
|---|---|
| Audit page | table of time, source, actor, action, target, expandable details JSON; filters (source, actor, from, to) in the URL; "Load older entries" via next_cursor; a notice naming a source the Dashboard could not read |
| "View changes" | on release.publish and release.rollback rows; opens /config/releases/:channel/:releaseId?base=… |
| Release diff page | release header (channel, id, message, author/time, min client version change, base); namespaces added / removed / changed (version a → b, linking to the namespace) with unchanged ones collapsed; packs added / removed / changed |
diffManifests |
pure, unit-tested; packs are identified by hash, and one removal plus one addition under the same name reads as "changed" (old hash → new hash) |
| Config client | getRelease(channel, id) over the release list (before=id+1&limit=1, id checked) |
Config has no release-diff endpoint (only per-namespace version diffs), so the diff is computed in the browser from the two releases' manifests.
How to verify¶
cd services/adminui
npm run typecheck && npm run lint && npm run format:check && npx vitest run && npm run build
npx playwright test
Results at time of writing¶
- typecheck, lint, prettier, vitest (310 tests), build: pass; Playwright 15/15 incl. "clicking a publish entry opens the matching diff" and back keeping the filters.
- Screenshots checked: audit table and the diff of a rollback.
How it was built¶
DeepSeek run scoped (Landlock) to services/adminui (479 s, ~55k output tokens,
reasoning effort low). Claude review (screenshots): a pack re-uploaded under the same
name showed as an unrelated "added" and "removed" pair; they are now one "changed" row
(hash identity kept), with tests for both cases.