# Phase 8 acceptance scenario mapping This matrix maps every requested scenario to its actual test owner. The [final report](FINAL_ACCEPTANCE.md) supplies executed whole-suite results and qualifications; a test reference alone is not an execution claim. Backend tests are `DashboardPreferencesTests.cs`; frontend tests are `dashboardLayout.test.ts`, `hooks/useDashboardLayout.test.tsx`, `dashboard-customisation.test.tsx` and retained Dashboard/Analytics tests. Native cases are `phase8-dashboard-customisation.spec.ts` plus retained Dashboard/Analytics presentation cases. | # | Required scenario | Evidence and boundary | |---|---|---| | 1 | Useful defaults for a new user | Catalogue defaults, unsaved GET revision0, actual new-account Dashboard guidance; no fabricated metrics | | 2 | Existing users retain settings | Legacy owner-local five flags migrate only before first Save; real browser case and migration defaults | | 3 | Correct existing statistics | Retained exact monthly/count/denominator/custom-stage/company/source tests and native readback | | 4 | Enter/exit customisation | Explicit editor region, Cancel/Save, Escape and focus restoration; component/native cases | | 5 | Hide a widget | Draft checkbox updates preview; acknowledged-save HTTP readback | | 6 | Restore hidden widget | All-hidden recovery native case restores pipeline without changing job data | | 7 | Change order | Native drag and keyboard/touch buttons, live position, DOM order, real readback | | 8 | Supported size | Native select, mixed grid and persisted pipeline full-width; separate populated diagnostics save/read back all eight resizable widgets at both sizes across320/768/1024/1440px, including actual salary text-line regression; cards full only | | 9 | Save configuration | Real PUT acknowledgement and revision increment; disabled controls while pending | | 10 | Reload saved layout | Browser refresh plus actual API GET equals acknowledged widgets | | 11 | Logout/login | Real sign-out/sign-in journey retains server configuration | | 12 | Another session/device | Fresh browser context/login reads the same account layout; no physical second-device claim | | 13 | Cancel draft | Confirmation/no PUT, saved preview restored; reset/cancel server readback unchanged | | 14 | Reset defaults | Confirmed draft replacement, user can cancel before Save; no unrelated account write | | 15 | API error | Controlled503 keeps draft and localized error; retry persists exactly once after acknowledgement | | 16 | Network failure | Controlled route abort simulates transport loss; draft retained and retry works; no physical outage claim | | 17 | Obsolete widget | Actual backend stored-JSON GET ignores unknown IDs; frontend normalisation, no invalid renderer | | 18 | Invalid size | Backend HTTP rejects invalid write, stored read normalises; frontend falls back to catalogue size | | 19 | All hidden | Real nine-hidden saved layout, intentional empty state and accessible edit/restore | | 20 | Two sessions edit | Real session conflict409, explicit reload, reapply and acknowledgement; atomic simultaneous first-save regression | | 21 | Malformed/large payload | Actual Kestrel malformed/duplicate/unknown/oversized/chunked HTTP tests;16KB byte cap and32-entry maximum | | 22 | Statistics failure | Retained independent summary/trends loading/503/retry native cases; no false zeros | | 23 | New widgets/old layouts | Known missing entries appended hidden in saved revisions; future schema is read-only, downgrade denied | | 24 | Historic save failure | WAL held-reader actual layout write plus simultaneous saves and stale Identity replay regression; no permanent contention claim | | 25 | Cross-user access | Principal-derived GET/PUT, attempted query account override ignored, A/B persistence isolated; actual HTTP and cookie cases | | 26 | Anonymous denied | Actual GET/PUT401 in backend and real app auth browser tests | | 27 | Configuration cannot expose restricted data | Strict stable-ID/type/size/version allowlist; owner field never accepted; arbitrary query/HTML not supported | | 28 | Admin data protected | Ordinary cookie-authenticated account receives403; admin source stays unchanged | | 29 | Keyboard-only order | Native Enter on named move controls; live region and focus assertions | | 30 | Predictable focus | Editor entry geometry, row stable keys, first-position alternate-button focus, Cancel return, route keep-editing | | 31 | Responsive | Actual viewport matrices and no root horizontal overflow; preserved readable values tables and fluid chart | | 32 | Touch/scroll | Emulated-touch tap alternative passes; dedicated drag handle avoids ordinary-content drag. Physical device/software keyboard outstanding | | 33 | Bokmål | Localized editor/error/reset/control names; native EN/NB layouts. Human linguistic review remains outstanding | | 34 | Themes | Native light/dark screenshots and computed scheme assertions | | 35 | Reduced motion/focus | No custom motion; retained reduced-motion journeys and3px focus ring checks. Complete true zoom/manual contrast outstanding | | 36 | Dashboard data contracts | Same report endpoints/DTO consumers; exact existing source assertions retained | | 37 | Admin unchanged | No admin source edits; existing admin unit/native regression plus non-admin403 | | 38 | Navigation/other pages | All33 route patterns unchanged; final ordinary browser/backend/frontend suites | | 39 | Preference compatibility | Additive full migration chain/startup defaults, unrelated fields preserved, legacy flags and stale-session protections | | 40 | No protected capability removed | Exact57-group reconciliation with56PARTIAL/C11DEFERRED retained; source/test inventory and final suites | Additional regressions cover future-schema overwrite races during a paused request body, exact JavaScript revision limits, delayed acknowledgement after account disposal, malformed stored JSON and Identity's unrelated whole-user save. No production, model, provider grant, migration against live data or destructive operation was performed.