Files
jobtrackingapp/docs/redesign/phase-5/p5-15/p5-15-01/diagnostics/README.md
T

29 lines
4.4 KiB
Markdown

# P5-15-01 deferred preference diagnostics
These native Playwright probes run separately from the ordinary `job-tracker-ui/e2e` suite. They assert the intended behavior and fail on a genuine HTTP 500, incorrect persisted readback, or lost unsaved rule draft. There are no success response mocks, expected failures, retries within the probes, real account credentials, or provider calls.
From `job-tracker-ui`, after the normal Release API build and frontend preparation:
```powershell
rtk proxy node node_modules/@playwright/test/cli.js test --config=../docs/redesign/phase-5/p5-15/p5-15-01/diagnostics/playwright.config.ts
```
The config imports the ordinary Playwright config: the same local ports, disposable API database, synthetic administrative bootstrap account, serial worker and retained failure trace apply. The working directory must remain `job-tracker-ui`. Use the ordinary static-export / prebuilt / server-reuse environment options only when the corresponding local servers or export have already been prepared. Do not run alongside the main suite on the shared ports.
The first probe edits a rule, switches to Notifications and returns without saving. Its attachment records the initial value, draft, displayed return value, API readback status/value and count of rule writes. The second probe uses two pages in one genuine session: language selection and notification Save run alongside four genuine report/notification reads, for three alternating language rounds. Each round records actual mutation/read statuses, persisted language/notification values, document language and alert DOM counts before the success assertions. The raw `errorsVisible` name is misleading: counts include the Next route announcer and do not establish visible errors. The portable summary labels them accordingly. Partial evidence is retained when a round fails. The final reload checks persisted UI state.
## Native results and source characterization
Fresh final execution on 2026-10-09: **one pass, one failure**, separate from the ordinary browser suite. [Portable browser evidence](../evidence/browser-summary.json) contains actual outcomes, commands, times and fingerprints. Rules started at 14, was edited to 5, then returned to 14 after the tab round trip; API readback remained 14, with zero rule writes. The desired draft-retention assertion fails. No application repair or expected-failure flag is included.
The three native overlap rounds passed: all language writes 204, notification writes 200, concurrent report/notification reads 200, persisted values correct, and final reload retained Bokmål plus disabled notification preference. This did **not** reproduce the recorded preference-save 500 and does **not** close it or establish concurrency/load safety. No exception/root cause for the historical 500 is inferred from this run.
- `SettingsView.tsx:43`: `TabPanel` returns `null` for an inactive tab, unmounting `RulesSettingsCard`.
- `RulesSettingsCard.tsx:23`: rule drafts live in component state; mounting reads `/rules` again. A tab round trip has no draft owner above the unmounted card. The native failed assertion confirms that draft-loss risk.
- `I18nProvider.tsx:33`: `setLanguage` applies local state/storage immediately and catches the language PUT rejection without displaying it. A visually translated page is not evidence of a persisted successful preference.
- `AuthController.cs:549`: the language endpoint loads the local Identity user, sets `UiLanguage` and calls `UserManager.UpdateAsync`. Identity-result failure becomes 400; an uncaught storage failure can become 500. This source alone does not establish the historical 500's cause.
- `NotificationSettingsController.cs:29`: notification PUT updates another property of the same Identity user through `UpdateAsync`; unsuccessful Identity results explicitly become 500. Concurrent full-user writes, optimistic concurrency and SQLite contention remain hypotheses until response/server evidence identifies the failure.
- `SettingsView.tsx:70`: language-dependent notification reads can overlap the writes. The diagnostic exercises that real caller behavior, rather than substituting successful responses.
No application fix is included. An all-success bounded run cannot establish that an intermittent concurrency defect is resolved; preserve the observed statuses and report that limit. A failed run remains failed, with a separately recorded defect for follow-up ownership.