feat(admin): migrate audit presentation and protect pending actions

This commit is contained in:
cesnimda
2026-10-20 15:26:49 +02:00
parent 4760fd102c
commit f9e1d06bf7
12 changed files with 636 additions and 48 deletions
+2
View File
@@ -2,6 +2,8 @@
## Continuation — 20 October 2026
P7-10 [Audit](p7-10/AUDIT.md) final bounded gate:9 frontend,18 existing backend and3 native cases PASS; app/browser TypeScript, lint/build PASS. Export vZuD4f-46FJekdIR5rhRk; seven scans0violations/110incomplete nodes, two final images inspected. Ordinary REDs and pre-layout candidate remain retained. Users hygiene follow-up **4760fd102c21c684bd139206a12194c6fc8f6104** passed staged/full-phase whitespace and was normally pushed/directly verified13:10:57UTC. Audit publication follows after staged checks; System tests remain separate WIP.
P7-10 Users **7ecc0d66054787b1e2b3da6da7226b9585c66e34** normally pushed/directly verified **13:10:07 UTC**, with Audit/System regression work preserved. Final staged whitespace returned1 for an extra EOF blank line; the root continued publication incorrectly. Immediate follow-up removes it and checks staged/full-phase whitespace without altering behavior or claiming a rerun of the existing runtime evidence. Implemented Users acceptance remains CONDITIONAL GO; Audit follows.
Remaining P7-09 data presentation **8af9168014631633e38e8ba7cd22899fdf1092e2** was normally pushed and directly verified **07:58:49 UTC**, with clean HEAD=origin=remote development. P7-09 implemented scope is CONDITIONAL GO; qualifications remain. [P7-10 Users](p7-10/USERS.md) now has18/5 affected frontend,25backend and finalnative3/type/lint/build PASS; final hygiene/publication follows. Six new frontend cases derive861/99, three native cases derive342 browser tests; these are inventories, not fresh whole-suite results. Audit/System remain pending.
+2
View File
@@ -1,5 +1,7 @@
# Phase 7 — Initial preservation matrix
P7-10 [Audit](p7-10/AUDIT.md) adds PRES-A02/E08/E09 proof: exact Undo allowlist, owned Restore versus administrator Undo, persisted event/readback and ordinary-user denials. GET-only recovery, synchronized writes, current-language errors and disposed-session guards pass. All57 groups retain56 PARTIAL/C11 DEFERRED,33 routes. No server authorization/data contract or PDF/AI safeguard change. System and shared/manual accessibility acceptance remain pending.
P7-10 [Users](p7-10/USERS.md) adds bounded PRES-A01/E09 proof without changing any group disposition: native administrator create/role persistence, target-session revocation, non-admin denial, last-admin conflict and deletion-disabled response, plus retained self-demotion/exact-email guards. Failed reads are distinct from empty; committed-write recovery does not replay writes; submitted form and immutable session disposal are tested. Desktop grid scrolling remains intentional and all action rows fit. Seven scans report zero violations with28incomplete nodes retained. Audit/System, shared accessibility qualification and all human/provider/production requirements remain open;57groups/33routes unchanged.
## Import continuation — 20 October 2026
+1 -1
View File
@@ -25,7 +25,7 @@ The entry commit is `b5319981ad3d1bd635daff861453d23c0de5320b` on `codex/ui-rede
| [P7-07](p7-07/README.md) | Documents owner-scoped index | Implemented CONDITIONAL GO; contract/UI published and directly verified through9dfea12 at21:01:11UTC. Final affected86/8, native8+CV4+ordinaryP2-D01/types/lint/build PASS;18 reviewed PNGs,15axe0/101 qualified. Original32+Documents=33routes; actual MariaDB/human/device/production qualifications remain |
| [P7-08](p7-08/README.md) | Existing notifications and operations | Implemented CONDITIONAL GO and published: UTC9dfea/recent40cfe04/Operationsc5176e3, clean direct refs verified02:03:53UTC. Ops77/7+native12/types/lint/build/14Ops+1P2image reviews PASS;12Opsaxe0/3+14notifaxe0/102 qualified.57groups33routes/F20 preserved |
| [P7-09](p7-09/README.md) | Remaining Settings, Connections and data lifecycle | Sender/Preferences published dac2927/e7dba9a; company/import prerequisites published5addcde/3028d81; release repairs merged/pushed36fc5d5 with all WIP preserved. Remaining data presentation implemented CONDITIONAL GO:47/6 affected frontend,22backendcontracts, nativeSettings9/import4/CSV1/P2-D01 +types/lint/build PASS;37axe0violations/141incomplete nodes qualified,six final PNGs inspected. Final consumer/hygiene/publication receipt follows. Inventory855/99frontend,339browser,1057backend; full integrated acceptance remainsP7-12 |
| P7-10 | Admin operational presentation | Existing distinct Users/Audit/System routes and server authorization; planned |
| [P7-10](p7-10/README.md) | Admin operational presentation | Users published7ecc0d6/4760fd1; Audit implemented CONDITIONAL GO with9 frontend/18backend/3native PASS and final hygiene/publication pending. System follows separately. Derived868/99frontend,345browser/56files; no fresh integrated pass |
| P7-11 | Remaining Analytics/error/empty/dialog integration | Inventory-confirmed residual presentation only; existing reports remain; planned |
| P7-12 | Integrated full-migration acceptance | Every executed slice pushed with finite evidence; fresh applicable full regression and all debt dispositions; planned |
+25
View File
@@ -0,0 +1,25 @@
# P7-10 Audit
**Implemented CONDITIONAL GO; publication pending.** Entry is the published Users follow-up `4760fd102c21c684bd139206a12194c6fc8f6104`, which passed staged/full-phase whitespace and normal remote verification at13:10:57UTC. Users' earlier staged-check failure remains recorded in its report.
## Bounded changes
The existing `/admin/audit` read owner and shared read-state component remain. Shared h2/h3 page/section presentation, localized Events heading and a named keyboard-scrollable table replace the one-off surface. Loading, failure and actual empty results remain distinct; Retry only performs GET. Existing supported Undo types and Deleted-only Restore visibility are unchanged.
Mutations now share synchronous admission, pending focus and session/lifetime guards. They retain current-language safe errors and cannot start a private refresh or toast after disposal. A successful write followed by failed refresh offers read recovery without replaying the write. No endpoint, authorization, tenant filter or stored event changes.
Visual review found a fixed-layout Job column only92.5px wide. An ordinary browser regression failed before removing the fixed table layout and giving Job/Details useful minimum widths. The named table retains intentional two-dimensional keyboard scrolling within the page; app-root overflow is checked separately. Exceptionally long identities still wrap and produce taller rows rather than losing data.
## Evidence
- Frontend **9/9 PASS**: seven added regressions, two existing cases. Initial candidate produced three passing/six failing cases against the old owner. Final rerun13:24:37–13:24:41UTC passes with no pending/todo cases.
- Existing backend **18/18 PASS**, zero skipped: lifecycle events, ordinary job authorization and API authorization posture, using the unchanged Release binary.
- Native **3/3 PASS**, no skips/flaky/retries,13:23:21–13:23:49UTC, export `vZuD4f-46FJekdIR5rhRk`. Actual isolated HTTP proves owned Restore204, foreign ordinary Restore404, authorized Audit Undo200, unsupported Created Undo400, non-admin GET/POST403 and persisted event/readback. Controlled503 recovery remains GET-only.
- Finite English/Bokmål light/dark samples at320,390,768,1024,1440,1920. Seven all-enabled axe scans have zero violations and110 incomplete nodes. Contrast incompletes include clipped/overlapping backgrounds and the invisible badge; the inherited shell version badge also has an unresolved role/ARIA incomplete. No rules are suppressed.
- App/browser TypeScript, lint and production build PASS. [Portable results](evidence/audit-results.json) retain command hashes, source hashes explicitly captured after execution, native counts and image identities.
Final320px Bokmål dark and1440px English light PNGs were actually inspected; five others remain automated evidence. Full-page captures place fixed shell chrome over scrolled content and expose a skip-link capture artifact; these images do not establish human screen-reader, real zoom or physical-device acceptance. Earlier candidate results/images and both ordinary layout failures remain retained locally.
## Preservation and remaining work
PRES-A02/E08/E09 gain bounded evidence; all57 groups remain56 PARTIAL/C11 DEFERRED and33 routes. Derived inventory becomes868 frontend cases/99 suites and345 browser cases/56 files, not a fresh whole-suite pass. No backend, CV renderer, revision, frozen association or AI safeguard changes. Separate administrator recent-auth enforcement is absent in the existing contract and is not claimed. System follows as its own boundary; shared-shell accessibility and full integrated review remain pending. P5-13 stays withheld, production readiness stays NO-GO, Phase8 has not started.
+1 -1
View File
@@ -7,7 +7,7 @@ Follow the [approved handoff](../../phase-6/p6-05/PHASE7_HANDOFF.md): exactly th
| Boundary | State |
|---|---|
| [Users](USERS.md) | Implemented CONDITIONAL GO; pushed7ecc0d6/direct remote verified13:10:07UTC. Staged end-of-file whitespace failure is corrected in the immediate follow-up; no behavior change |
| Audit | Pending; preserve the exact supported Undo allowlist and ordinary owner-filtered Restore distinction |
| [Audit](AUDIT.md) | Implemented CONDITIONAL GO; final hygiene/publication pending; exact Undo allowlist and owner-filtered Restore distinction verified |
| System | Pending; preserve independent SMTP/probe/test/maintenance scopes, write-only secret semantics and truthful diagnostic availability |
All 57 preservation groups retain **56 PARTIAL / C11 DEFERRED**, with 33 routes. P5-13 is withheld; followMode remains deferred. No Phase 8 implementation. Production readiness remains NO-GO; the independently owner-authorized main release is still unverified after run831 failed with browser crashes/malformed Playwright JavaScript. Do not infer admin recent-auth enforcement: the current Users/Audit/System actions do not implement that separate guard. Preserve actual account-lifecycle/export recent-auth checks and record this gap rather than inventing a security protocol during presentation migration.
@@ -0,0 +1,254 @@
{
"observedUtc": "2026-10-20T13:24:48.227216+00:00",
"sourceScope": "Post-run observations, not pre-run captures",
"sources": {
"src/views/AdminAuditPage.tsx": "1c7011fa935efe2e532f6ab8f917005e486aa6fb525ad3a28aa1f67f28e461c4",
"src/admin-audit-page.test.tsx": "45f2a6274f465aa0c2b805d1ef163cee920b806827b2f3199ef7f89d76b1de3f",
"src/i18n/translations.ts": "6d06a414ec4860e11dcddc15d9da9fdfac2fc4903e932660f48fe87f97fefa3d",
"e2e/phase7-admin-audit.spec.ts": "cb29e9f7fc346a0a94f7a260eb17565f729172d784d55689cd1677597d1d7b92"
},
"gates": {
"typecheck": {
"path": ".artifacts/phase7/current/ui/typecheck-command.json",
"sha256": "c1e4f4c5aae8756320a67c8f0ac041b0af2449b0b092eeeb6b7c5c196dc625c2",
"name": "typecheck",
"command": [
"rtk",
"proxy",
"npm.cmd",
"run",
"typecheck"
],
"startedUtc": "2026-10-20T13:23:37.025665+00:00",
"finishedUtc": "2026-10-20T13:23:51.807391+00:00",
"exitCode": 0
},
"lint": {
"path": ".artifacts/phase7/current/ui/lint-command.json",
"sha256": "69765e83fcfd7f3a9bf00f1c50b6b5534d29e1ec7496899b0285e428c02f2430",
"name": "lint",
"command": [
"rtk",
"proxy",
"npm.cmd",
"run",
"lint"
],
"startedUtc": "2026-10-20T13:23:58.717915+00:00",
"finishedUtc": "2026-10-20T13:24:26.797518+00:00",
"exitCode": 0
},
"browser-typecheck": {
"path": ".artifacts/phase7/current/ui/browser-typecheck-command.json",
"sha256": "6498790444342ace32d26a6b348a42c6a7d86351e63b630dcd844eb85de58984",
"name": "browser-typecheck",
"command": [
"rtk",
"proxy",
"npm.cmd",
"exec",
"tsc",
"--",
"--project",
"../.artifacts/phase7/e2e-tsconfig.json",
"--noEmit"
],
"startedUtc": "2026-10-20T13:23:58.727010+00:00",
"finishedUtc": "2026-10-20T13:24:06.141866+00:00",
"exitCode": 0
},
"build": {
"path": ".artifacts/phase7/current/ui/build-command.json",
"sha256": "702efce7d8e68fa1e4fe554db569496a96426ed126ff44fa00f7a8bd4928c7ca",
"name": "build",
"command": [
"rtk",
"proxy",
"npm.cmd",
"run",
"build"
],
"startedUtc": "2026-10-20T13:23:06.425913+00:00",
"finishedUtc": "2026-10-20T13:23:13.499797+00:00",
"exitCode": 0
},
"admin-audit": {
"path": ".artifacts/phase7/current/ui/admin-audit-command.json",
"sha256": "f365ec9e6375d2c9d841b16c369d1656641d0e104de88eec11a675e4cf424396",
"name": "admin-audit",
"command": [
"rtk",
"proxy",
"node",
"node_modules/@playwright/test/cli.js",
"test",
"e2e/phase7-admin-audit.spec.ts",
"--retries=0",
"--reporter=list,json",
"--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\ui\\admin-audit-results"
],
"startedUtc": "2026-10-20T13:23:20.787111+00:00",
"finishedUtc": "2026-10-20T13:23:49.160207+00:00",
"exitCode": 0
}
},
"images": [
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-actual-read-recovery-en-light-390.png",
"sha256": "e0e0bf2c39858d8e6dc3484ad258d99517a2d56a4edca6ed094af3f1826eba82"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-320-nb-dark.png",
"sha256": "a42776f1f9f969a04335bb1bebf29af803e2f2d932effca29a07cc7b1c6367c5"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-390-en-light.png",
"sha256": "cef8b12e281ff0941af9843b229e031a157c7c23a32fe5e31e4c697248cdcfac"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-768-nb-light.png",
"sha256": "862e138da313fe3b98c67333d9edffa856a90c725bb3018e16607c24eb0d27b7"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1024-en-dark.png",
"sha256": "ad83e6f81db626e22433b052129d68064320b50801547cc7aa9b2e7e9e858079"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1440-en-light.png",
"sha256": "2e318c01e8c34602095fb4916aa0af7b3350cde8d4200ce1f56814c3d16ac223"
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1920-nb-dark.png",
"sha256": "fddfee7b450800a5d92bd1c4470efafa6ee8f91586a4ddeb8f2d98da9209838e"
}
],
"scans": [
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-actual-read-recovery-en-light-390-axe.json",
"violations": 0,
"incompleteNodes": 17,
"incompleteRules": [
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-320-nb-dark-axe.json",
"violations": 0,
"incompleteNodes": 30,
"incompleteRules": [
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-390-en-light-axe.json",
"violations": 0,
"incompleteNodes": 30,
"incompleteRules": [
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-768-nb-light-axe.json",
"violations": 0,
"incompleteNodes": 14,
"incompleteRules": [
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1024-en-dark-axe.json",
"violations": 0,
"incompleteNodes": 15,
"incompleteRules": [
"aria-prohibited-attr",
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1440-en-light-axe.json",
"violations": 0,
"incompleteNodes": 2,
"incompleteRules": [
"aria-prohibited-attr",
"color-contrast"
]
},
{
"path": ".artifacts/phase7/p7-10/audit-corrected-visuals/audit-long-event-1920-nb-dark-axe.json",
"violations": 0,
"incompleteNodes": 2,
"incompleteRules": [
"aria-prohibited-attr",
"color-contrast"
]
}
],
"frontend": {
"path": ".artifacts/phase7/current/unit/admin-audit-final-20261020T132437Z-command.json",
"sha256": "68a102a137f0afdd3f28beb56b10080488a3731d888a810f622b0c9a2664e72c",
"command": [
"rtk",
"proxy",
"npm.cmd",
"test",
"--",
"--runInBand",
"--watchAll=false",
"--json",
"--outputFile=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\unit\\admin-audit-final-20261020T132437Z.json",
"src/admin-audit-page.test.tsx"
],
"startedUtc": "2026-10-20T13:24:37.036615+00:00",
"finishedUtc": "2026-10-20T13:24:41.662819+00:00",
"exitCode": 0,
"counts": {
"numPassedTests": 9,
"numFailedTests": 0,
"numPendingTests": 0,
"numTodoTests": 0,
"numPassedTestSuites": 1,
"numFailedTestSuites": 0
}
},
"backend": {
"path": ".artifacts/phase7/current/backend-career/p710-audit-contracts-20261020T131806Z/command.json",
"sha256": "414225a57ab39e08dd969f731783d02a8fedb18bbf909cf23cff8d00d2297063",
"command": [
"rtk",
"proxy",
"C:/Users/Connor/.dotnet/dotnet.exe",
"test",
"JobTrackerApi.Tests/JobTrackerApi.Tests.csproj",
"--configuration",
"Release",
"--no-build",
"--filter",
"FullyQualifiedName~JobLifecycleEventTests|FullyQualifiedName~JobApplicationsAuthorizationTests|FullyQualifiedName~ApiAuthorizationPostureTests",
"--logger",
"trx;LogFileName=career.trx",
"--results-directory",
"E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase7\\current\\backend-career\\p710-audit-contracts-20261020T131806Z"
],
"startedUtc": "2026-10-20T13:18:06.101978+00:00",
"finishedUtc": "2026-10-20T13:18:08.677765+00:00",
"exitCode": 0,
"logSha256": "c32da774fcaa0683a52253fa57169d2c4887c7847644bf304cadc2544a9e0ec9",
"counts": {
"total": 18,
"passed": 18,
"failed": 0,
"notExecuted": 0
},
"resultSha256": "0ed622b407eff7a8c78b862422cc0c5dcdc9fb6eb4ec5dfad16ba4cdcc49a566"
},
"buildId": "vZuD4f-46FJekdIR5rhRk",
"nativeStats": {
"startTime": "2026-10-20T13:23:21.336Z",
"duration": 27787.152000000002,
"expected": 3,
"skipped": 0,
"unexpected": 0,
"flaky": 0
},
"nativeResultSha256": "54b901ecf079d252716da2f57bad553a64b898c7f0f4b2acbd05459d8c8d21ea"
}
@@ -0,0 +1,104 @@
{
"schemaVersion": 1,
"checkpoint": "p7-10",
"status": "PASS",
"checkedUtc": "2026-10-20T13:26:37.561220+00:00",
"commands": [
{
"name": "secret-scan",
"command": [
"rtk",
"proxy",
"C:\\Users\\Connor\\AppData\\Local\\Programs\\Python\\Python312\\python.exe",
"-X",
"utf8",
"scripts/supply-chain.py",
"scan-secrets"
],
"startedUtc": "2026-10-20T13:26:33.986812+00:00",
"finishedUtc": "2026-10-20T13:26:36.708184+00:00",
"exitCode": 0,
"log": ".artifacts/phase7/current/static/20261020T132633Z/secret-scan.log",
"logSha256Raw": "be5119e6057287d397e87759f855c91e634e3bfac61c8be7584d05592ba2dfcd"
},
{
"name": "working-whitespace",
"command": [
"rtk",
"proxy",
"git",
"diff",
"--check"
],
"startedUtc": "2026-10-20T13:26:36.708184+00:00",
"finishedUtc": "2026-10-20T13:26:36.811807+00:00",
"exitCode": 0,
"log": ".artifacts/phase7/current/static/20261020T132633Z/working-whitespace.log",
"logSha256Raw": "3a1889bb3f9660d6e0f7bcf9d41ea52f9b3b845c85f2847257728d2388fc0290"
},
{
"name": "staged-whitespace",
"command": [
"rtk",
"proxy",
"git",
"diff",
"--cached",
"--check"
],
"startedUtc": "2026-10-20T13:26:36.811807+00:00",
"finishedUtc": "2026-10-20T13:26:36.906524+00:00",
"exitCode": 0,
"log": ".artifacts/phase7/current/static/20261020T132633Z/staged-whitespace.log",
"logSha256Raw": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"name": "phase7-whitespace",
"command": [
"rtk",
"proxy",
"git",
"diff",
"--check",
"b5319981ad3d1bd635daff861453d23c0de5320b"
],
"startedUtc": "2026-10-20T13:26:36.907534+00:00",
"finishedUtc": "2026-10-20T13:26:37.105504+00:00",
"exitCode": 0,
"log": ".artifacts/phase7/current/static/20261020T132633Z/phase7-whitespace.log",
"logSha256Raw": "3a1889bb3f9660d6e0f7bcf9d41ea52f9b3b845c85f2847257728d2388fc0290"
}
],
"untrackedSecretScan": {
"files": 0,
"findings": 0
},
"documentation": {
"files": 33,
"relativeLinks": 631,
"errors": []
},
"preservation": {
"groups": 57,
"statuses": {
"PARTIAL": 56,
"PASS": 0,
"FAIL": 0,
"DEFERRED": 1
},
"originalRoutesPreserved": true,
"currentConcreteRoutes": 33
},
"production": {
"main": "d1fcd2308755dfc112a2bd6a736dd763bbc895f9",
"originMain": "d1fcd2308755dfc112a2bd6a736dd763bbc895f9",
"status": "NO-GO",
"qualification": "Local fetched refs; direct push observation recorded separately."
},
"hashPolicy": "Portable JSON UTF8 LF; raw log hashes measure exact saved bytes.",
"limits": [
"Pattern scanner skips binary and files over2MiB; not historical Git/production secrets.",
"Local links check target existence, not URL/heading anchors.",
"Static evidence is not runtime/manual/device/provider/production acceptance."
]
}