d6d3dd977d
Map 57 capability groups before restructuring. Add behavioral regression coverage and a standalone TypeScript gate; retain the native SQLite package failure as separate baseline debt.
108 lines
11 KiB
Markdown
108 lines
11 KiB
Markdown
# Phase 2 — Preservation regression checkpoint
|
||
|
||
**Completed 2026-09-10 from `2d0f131` on `codex/ui-redesign-phase2`.** This checkpoint adds regression protection and an explicit TypeScript CI gate. **No visual redesign, application behavior change, route/layout/component restructuring, schema change or B07 work.** The Phase 1 source/audit remains intact.
|
||
|
||
## Preservation coverage
|
||
|
||
- **57/57 protected capability groups mapped (100%)**, with stable `PRES-` aliases of the original E/J/W/C/M/S/A IDs.
|
||
- **44 high-risk groups**, all mapped to existing behavioral assertions. High risk includes private identity, data edits/history/relationships, irreversible actions and shared navigation likely to be restructured.
|
||
- **147 referenced existing/new automated test files** across frontend and backend. Each row records route/entry, component/service owners, protected behavior, missing proof and expected later redesign impact.
|
||
- This percentage means **at least one core automated behavioral assertion per capability group**. It is not exhaustive sub-workflow, code, provider, mobile/accessibility or visual coverage. The matrix explicitly retains partial coverage and one native package-capture blocker.
|
||
|
||
Read the [complete preservation matrix](PRESERVATION_MATRIX.md), [traceability contract and Phase 2 change ledger](TRACEABILITY.md), and [baseline defects/intentional gaps](BASELINE_DEFECTS.md).
|
||
|
||
## High-risk additions and preserved evidence
|
||
|
||
| Workflow | New meaningful regression |
|
||
|---|---|
|
||
| Command/navigation/capture | Three component cases: job/company destination, closing clears query, add opens review without creating; real browser Ctrl+K search, legacy match link, reviewed add |
|
||
| CV section AI | Four cases: Reject/Close clear proposal without applying, edited proposal applies only on acceptance, failure retry leaves content untouched |
|
||
| Whole-CV AI | Five cases: explicit Apply/Reject; invalid JSON, missing IDs and duplicate IDs cannot become edits; save targets only selected CV |
|
||
| Cover-letter AI | One case: Reject preserves saved draft, disabled Save/no dirty state/no PUT |
|
||
| Settings | Two component cases: retry failed notification save with retained draft; changing one rule keeps other scenarios |
|
||
| Canonical profile → derived CV | Browser mobile edit/preview → reload → desktop preview; stored headline changes only selected CV, complete canonical profile and sibling remain unchanged |
|
||
| Documents/submission | Native profile/job/CV/letter/file fixture + legacy entry and capture; **expected failure P2-D01**, with desired immutable HTML/letter/archive-byte checks retained but not reached |
|
||
| Responsive preferences | Browser mobile→desktop rule draft stays, native save persists; notification false survives reload; separate direct API rule save |
|
||
| Permissions | Non-admin admin-menu entries absent, direct users GET/POST forbidden, normal CV create allowed, Free AI actions disabled and API 403 |
|
||
|
||
Existing B01 connection-time outbound protections, B02 ownership/session/cache checks, B03 rendering admission, B04 trusted principal/IP limits, B05 CSV bytes, and B06 application/configuration tests are unchanged. Mail draft revisions/uncertain sends, profile extraction acceptance, CV history, long PDF, job dirty navigation and other existing tests were retained.
|
||
|
||
## Baseline and fresh verification
|
||
|
||
Fresh local execution uses installed .NET **9.0.317**, Node dependencies already locked in the checkout, Windows/Chromium and Playwright's disposable SQLite API. There were no production requests or provider credentials. Test fixtures use only synthetic accounts and local URLs.
|
||
|
||
| Gate | Recorded Phase 1 baseline | Fresh Phase 2 result |
|
||
|---|---|---|
|
||
| Backend Release suite | 916 passing | **916 passed, 0 failed, 0 skipped**; no exclusions, count unchanged |
|
||
| Frontend Jest | 298 tests / 67 suites | **313 passed / 68 suites**; +15 cases, +1 test file; no existing test removed |
|
||
| General browser | 18 passing | **23 actually passed + 1 expected failure**, 0 unexpected failures/skips/flaky; original 18 still pass, +6 cases |
|
||
| B04 real HTTP | 9 cases | **9 passed** |
|
||
| B06 production-mode API/forwarding HTTP | 6 cases | **6 passed**; not nginx/Traefik runtime proof |
|
||
| B03 PDF burst/admission | 1 case | **1 passed**, multi-route capacity/recovery oracle unchanged |
|
||
| Compose ingress/configuration | 3 tests/17 hostile mutations | **3 passed** |
|
||
| Backend build | Release | **Pass, 0 warnings/errors**, warnings-as-errors |
|
||
| Frontend build | Next production static export | **Pass** |
|
||
| Standalone type check | Historical TS2571 repaired before Phase 2 | **Pass**; new explicit CI command, unchanged strictness |
|
||
| New browser-spec TypeScript | Previously no whole-Playwright type gate | **Pass** with temporary Node-aware config for this new spec only |
|
||
| ESLint | Zero-warning gate | **Pass**, no suppressions added |
|
||
| Tracked secret scan; diff whitespace | Required | **Pass** |
|
||
|
||
Playwright's list reporter says “24 passed” because expected failures count as expected outcomes. Its JSON records **23 `expectedStatus=passed/actual=passed` and one `expectedStatus=failed/actual=failed`**. Do not present this as 24 successful workflows. The failed native package test is not a regression introduced by application changes: there are no such changes in this branch. See P2-D01.
|
||
|
||
Intermediate test-authoring corrections: one missing test-fixture brace, Testing Library's unsupported `exact` role options, a Playwright callback named `use` misidentified as a React hook, and package capture's actual CV-tab location. Corrected test code rather than weakening lint/types or changing UI. The temporary isolated TypeScript config initially lacked Node type roots; setting the existing installed Node declarations resolved Buffer. No new dependency installed.
|
||
|
||
One initial rules-save 500 did not reproduce in the direct or repeated browser path; retained as observation P2-O01, not asserted as a diagnosed defect. The reproducible SQLite package/tailoring failure is recorded separately. No blanket skipping or gate bypass was added.
|
||
|
||
## Exact commands
|
||
|
||
From the repository root (PowerShell):
|
||
|
||
```powershell
|
||
$env:DOTNET_ROOT='C:/Users/Connor/.dotnet'
|
||
& C:/Users/Connor/.dotnet/dotnet.exe test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --configuration Release --no-restore --logger 'trx;LogFileName=phase2.trx' --results-directory .artifacts/redesign-phase2 -- xUnit.parallelizeTestCollections=false xUnit.maxParallelThreads=1
|
||
& C:/Users/Connor/.dotnet/dotnet.exe build JobTrackerApi/JobTrackerApi.csproj --configuration Release --no-restore -warnaserror
|
||
python scripts/test-ingress.py
|
||
python scripts/supply-chain.py scan-secrets
|
||
git diff --check
|
||
```
|
||
|
||
From `job-tracker-ui`:
|
||
|
||
```powershell
|
||
npm test -- --watchAll=false --runInBand
|
||
npm run typecheck
|
||
npm run lint
|
||
$env:NEXT_PUBLIC_API_BASE_URL='http://localhost:5302/api'
|
||
$env:NEXT_TELEMETRY_DISABLED='1'
|
||
npm run build
|
||
$env:DOTNET_ROOT='C:/Users/Connor/.dotnet'
|
||
$env:DOTNET_HOST_PATH='C:/Users/Connor/.dotnet/dotnet.exe'
|
||
$env:PLAYWRIGHT_STATIC_EXPORT='true'
|
||
$env:PLAYWRIGHT_PREBUILT_EXPORT='true'
|
||
$env:PLAYWRIGHT_JSON_OUTPUT_FILE='../.artifacts/phase2-browser-results.json'
|
||
node node_modules/@playwright/test/cli.js test --reporter=list,json
|
||
node node_modules/@playwright/test/cli.js test --config=playwright.rate-limits.config.ts
|
||
node node_modules/@playwright/test/cli.js test --config=playwright.ingress.config.ts
|
||
node node_modules/@playwright/test/cli.js test --config=playwright.pdf.config.ts
|
||
```
|
||
|
||
Initial focused command: `npm test -- --watchAll=false --runInBand --runTestsByPath src/quick-command-preservation.test.tsx src/ai-section-assistant.test.tsx src/cv-builder-deep-link.test.tsx src/settings-view.test.tsx` → 31 passed. Final full Jest includes the additional cover-letter reject case.
|
||
|
||
Final browser rerun after narrowing the known-failure annotation: `node node_modules/@playwright/test/cli.js test e2e/redesign-preservation.spec.ts` → five actual passes and the same one expected HTTP-500 capture failure (23.8s); no unexpected failures. Final lint and isolated browser-spec typing also pass.
|
||
|
||
Additional isolated browser-spec typing used `node node_modules/typescript/bin/tsc --project ../.artifacts/phase2-browser-tsconfig.json --noEmit`. Temporary config extends the frontend tsconfig, includes only `../job-tracker-ui/e2e/redesign-preservation.spec.ts`, sets `incremental:false`, `typeRoots:["../job-tracker-ui/node_modules/@types"]`, `types:["node"]`. This is a local check, not a claim that every pre-existing Playwright/config source is covered by the new CI type gate.
|
||
|
||
Local logs: `.artifacts/phase2-{backend,jest,build,api-build,typecheck,browser-typecheck,lint,browser,rate-limits,ingress,pdf,compose,secrets}.log`; backend TRX under `.artifacts/redesign-phase2`; browser JSON and sanitized outcome summary under `.artifacts`. Durable conclusions and reproduction remain in these committed documents/tests; raw traces with synthetic session material are not published.
|
||
|
||
The matrix was checked against the original ledger: 57 rows, 57 unique IDs, no missing/extra IDs, and all 147 test-reference paths exist. No production source file changed. Full baseline execution was not repeated for documentation-only edits.
|
||
|
||
## Remaining gaps and next phase
|
||
|
||
**Phase 2 is complete as a regression/planning checkpoint, with its documented baseline failure.** Phase 3 may define UX architecture: grouped sidebar, page/route destination and backwards compatibility, one Jobs table/board entry, canonical Career Profile/derived-document workflows, contextual AI review, and explicit mobile task rules. Keep the existing MUI/Emotion/React Router/API stack while planning. Do not implement those layouts or components in this checkpoint.
|
||
|
||
Before a later code migration, close that surface's matrix gaps or establish a deliberately scoped additional fixture. W07 package/tailoring needs native-provider success first; shared shell needs drawer/focus and bulk/saved-view cases; career/mail/admin need their specified interactive and provider proof. Screen-reader/touch/reflow and the full EN/NB × light/dark × desktop/mobile matrix remain visual/UX gates.
|
||
|
||
**F04 remains open.** The B06 repository/application changes are complete, but actual deployed proxy peer/listeners, firewall/NAT/IPv6, client IP, DNS/TLS/redirect and restart behavior remain unverified; follow the existing [operator commands](../../audits/2026-09-07/validation/b06-completion.md). Prior main CI run 743 failed in the browser worker and did not deploy; this branch's local success does not repair or certify that runner. Pushing this feature branch is a preservation checkpoint, not a production deployment or a release-readiness claim.
|
||
|
||
No Phase 3 implementation, visual redesign, component-library migration, B07 or later security ticket has begun.
|