fix(career): preserve reviewed profile values
CI and Deploy / test (pull_request) Successful in 4m39s
CI and Deploy / deploy (pull_request) Has been skipped

Keep extraction heuristics out of manual save, version, and import paths so reviewed locations, URLs, dates, and languages round-trip unchanged.
This commit is contained in:
cesnimda
2026-08-15 16:56:31 +02:00
parent a6cffe0473
commit f0b9b222ff
15 changed files with 277 additions and 37 deletions
+11
View File
@@ -159,6 +159,17 @@ Existing read paths (CV rendering, tailoring, match-score, cover letters) read
4. The eventual removal of the blob (once every reader is migrated to read relational) is a later
phase and out of scope here.
### Reviewed-value persistence boundary (2026-08-15)
Extraction payloads continue through `StructuredCvProfileJson.Normalize`, which applies heuristics
to reject parser noise and infer locations, URLs, roles, dates and languages. Once a profile reaches
the editable Career surface, it is reviewed user data: `NormalizeForPersistence`,
`SerializePersisted` and `DeserializePersisted` only trim/dedupe structural values and must not
reinterpret them. This separation prevents a manual website path, free-form date or location such
as "Remote across Europe" from changing on save, version restore, import merge or a legacy
projection read. `CareerProfileValidator` rejects oversized reviewed values explicitly instead of
silently discarding them.
This mirrors the additive, non-destructive philosophy of Phase 0/ADR-002: introduce the new model,
keep the old surface working via a derived projection, flip readers later.
+1
View File
@@ -198,3 +198,4 @@ Output was reduced to filenames and commit counts. The token artifact appears un
| V-164 | Career/Profile focused Jest; CV extraction/diff backend tests; AI-sidecar pytest; production frontend build; ingestion execution-path review | Repository root / `job-tracker-ui` / `tools/summarizer` | Reproduce and fix career-field resets while assessing the proposed Ollama accuracy pipeline | PASS — Career 17/17 including active-poll preservation; backend 8/8; sidecar 22/22; build passes. Polling now fetches run status only. Existing pipeline is confirmed as local parser/OCR → Ollama-first normalize/classify → deterministic C# validation/diff/review | Synthetic/JSDOM/fake model only; no real private CV, live Ollama model comparison, provider or production call. Repository `.venv` lacked pytest; global Python passed | Repository correction verified; model benchmark remains external/runtime work |
| V-165 | CV renderer/resolver/template tests; Builder helper/editor/list Jest; optimized frontend build; real headless Chromium DOM/PDF probe; diff check | Repository root / `job-tracker-ui` | Verify professional multi-page CV rendering, physical preview metrics, custom-section ordering and stored-output safety under pathological content | PASS — backend 25/25; frontend 21/21; build passes. A 14-role/75-skill fixture with oversized name/email/URL produced zero horizontal offenders and a 9-page 173,196-byte PDF with extractable final-page text. Custom sections share persisted order; partial pages use ceiling count; stale preview/save/export races are gated | Synthetic data and local Chromium only; authenticated 375/768/1440 app journey, real private CV, production browser binary and DOCX remain unverified | Renderer/PDF repository scope verified; application-browser and production gates remain |
| V-166 | Focused/full backend and frontend tests; optimized frontend build/TypeScript; diff review | Repository root / `job-tracker-ui` | Verify an administrator can identify the deployed application version without exposing build metadata in the normal-user UI/API bootstrap | PASS — focused Auth/System 36/36 and AppShell 2/2; backend 640/640; frontend 53 suites/221 tests; production build passes. Configured version/commit reaches admin `/api/auth/me`, normal users receive no configured metadata, and the responsive header badge is absent unless the admin-owned prop is supplied | Local/JSDOM evidence only; remote CI and deployed version comparison remain. Jest retains the documented force-exit/open-handle notice | Priority repository increment verified; ship proof remains |
| V-167 | Failing Career round-trip reproduction; affected/full backend; focused Career/Profile Jest; persistence-consumer and diff review | Repository root / `job-tracker-ui` | Preserve every reviewed Career text value across save/get/version/projection/import use without weakening extraction cleanup or write bounds | PASS — pre-fix location became `Oslo, Norway and` and the test failed; post-fix affected backend 112/112, backend 642/642 and Career/Profile UI 17/17 pass. Website path/query, remote location, free-form date, custom language and incomplete WIP entry round-trip; oversized website is rejected explicitly | Local SQLite/JSDOM only; no real private CV/model/provider/production data. One initial Jest command used nonexistent paths and was corrected; the correct files passed | Reviewed/extracted normalization boundary verified locally |
+2 -2
View File
@@ -10,9 +10,9 @@ Updated: 2026-08-15
- **Production-verified work:** None.
- **Blocked work:** SEC-006 parser upgrades remain outside the scoped frontend advisory permission; PROD-001/003/004 and REL-001 require documented production access and unfinished dependencies. Real provider, SMTP/MariaDB and production environments are unavailable; DEP-001 awaits approved merge/live verification. The in-app browser is available for local UI checks.
- **Deferred work:** None. Conditional multi-replica coordination, model deletion, realtime operation delivery and unrelated production changes remain outside current packages.
- **Immediate order:** admin version indicator full gate/ship proof; Career lossless manual persistence; CV contact contrast; JOBS-002 parity/regression; cross-app contrast/accessibility; PRODUCT-001; VER-001. External-only work remains skipped, not allowed to stall this queue.
- **Immediate order:** CV contact contrast; JOBS-002 parity/regression; cross-app contrast/accessibility; PRODUCT-001; VER-001. The admin version indicator is pushed in `a6cffe0`; Career lossless manual persistence is locally complete. External-only work remains skipped, not allowed to stall this queue.
- **Status counts:** 7 `VERIFIED LOCALLY`; 22 `IMPLEMENTED — NOT VERIFIED`; 1 `IN PROGRESS`; 4 `NOT STARTED`; 5 `BLOCKED`; 0 `DONE`; 0 `DEFERRED`.
- **Test status:** backend 640/640; frontend 53/53 suites and 221/221 tests; optimized production build/TypeScript pass. The version indicator also has focused Auth/System 36/36 and AppShell 2/2 evidence. Prior AI sidecar 22/22, Playwright 6/6, pathological nine-page Chromium/PDF proof and npm audit 0 evidence remain current. Historical JT-019 and Jest force-exit/open-handle behavior remain recorded.
- **Test status:** backend 642/642; affected Career/import/profile/job paths 112/112; Career/Profile UI 17/17; prior frontend 53/53 suites and 221/221 tests plus optimized production build/TypeScript pass. The version indicator also has focused Auth/System 36/36 and AppShell 2/2 evidence. Prior AI sidecar 22/22, Playwright 6/6, pathological nine-page Chromium/PDF proof and npm audit 0 evidence remain current. Historical JT-019 and Jest force-exit/open-handle behavior remain recorded.
- **Deployment status:** Gitea pull-request run 609 passed the complete CI job in 4m20s. Deploy was intentionally skipped because the workflow deploys only a `push` to `main`; live remains unchanged. No merge/deployment was performed directly, no production migrations were run and the AI operation worker remains disabled by default.
- **Production status:** Unchanged and unverified. No provider/model call, model pull, external request or paid API occurred.
- **Known regressions:** None found by automated/local browser checks. Jest still needs `--forceExit` and reports its existing open-handle notice. Email-provider/send tests are fake/local only; real delivery is not claimed. Current MAIL browser evidence is 1280×720 only because the browser surface could not resize or perform native Tab traversal. Interrupted attempts are aged after 15 minutes and notified without retry; the five-minute scan is unmeasured on a large ledger. Direct clean EF-only SQLite migration still hits the pre-existing historical blank-chain defect before later migrations; normal startup owns reconciliation. Cross-feature monthly AI usage accounting remains a rollout gap.
+5 -5
View File
@@ -55,8 +55,8 @@ This queue records the highest-value work that can proceed without production cr
| Order | Immediate work | Owning package(s) | Current state and finish line |
|---:|---|---|---|
| 1 | Admin-only deployed-version indicator in the application header | DEP-001, VER-001 | Implemented with authenticated API and shell tests. The badge shows the CI deployment version and exposes the commit SHA in its accessible label/tooltip only for administrators; full regression, remote CI and deployment smoke remain. |
| 2 | Lossless Career field persistence | CAREER-001 | Next implementable correction. Manual website/location/contact edits must round-trip exactly enough for user intent; extraction cleanup must not silently rewrite already reviewed values. Add controller and UI regression tests. |
| 3 | CV contact/header/sidebar contrast correction | CAREER-002 | Queued. Apply renderer-scoped theme ownership for contact/headline text and rerun pathological HTML/PDF proof without shrinking typography. |
| 2 | Lossless Career field persistence | CAREER-001 | Implemented and locally verified. Manual website/location/contact/date/language values now use a reviewed-data persistence boundary; extraction heuristics remain isolated to extraction. Full remote/production smoke remains. |
| 3 | CV contact/header/sidebar contrast correction | CAREER-002 | Next implementable correction. Apply renderer-scoped theme ownership for contact/headline text and rerun pathological HTML/PDF proof without shrinking typography. |
| 4 | Dedicated Job Details parity and JOBS-002 closure | JOBS-002 | In progress. Finish any remaining legacy follow-up/application-package parity, dirty-edit behavior, tenant authorization and 375/768/1440 theme/keyboard/history/error/long-data verification. |
| 5 | Cross-application contrast/accessibility pass | UX-002, UX-003, VER-001 | Queued after the scoped Career/CV corrections. Audit semantic alerts, secondary text, focus, loading/empty/error states and remaining hardcoded colors before documenting larger redesigns. |
| 6 | Honest Free/Pro homepage and upgrade surfaces | PRODUCT-001 | Not started. Inventory existing claims first; do not invent pricing, limits or trial terms before billing configuration is real. |
@@ -630,9 +630,9 @@ This queue records the highest-value work that can proceed without production cr
- **Required production verification:** synthetic account smoke.
- **Status:** `IMPLEMENTED — NOT VERIFIED`.
- **Blocker:** browser session was already finalized; three-width/theme/keyboard/Norwegian checks and production synthetic-account smoke remain.
- **Evidence:** `docs/verification/career-001-career-workspace.md`; V-117V-119 and V-164; focused Career/Profile 17/17, extraction backend 8/8, sidecar 22/22 and production build. State-aware actions/recent CVs are implemented, extraction polling no longer overwrites unsaved form state, and the Apply/Discard gate is unchanged.
- **Commit:** `268b3a0` (`feat(career): clarify workspace actions`) plus the CAREER-002 polling checkpoint recorded in V-164.
- **Remaining work:** correct lossless persistence for manually reviewed website/location/contact values, then run the browser and production gates. Live model-quality benchmarking and deeper builder interaction belong to CAREER-002.
- **Evidence:** `docs/verification/career-001-career-workspace.md`; V-117V-119, V-164 and V-167; focused Career/Profile UI 17/17, affected backend 112/112, full backend 642/642, extraction backend 8/8, sidecar 22/22 and production build. State-aware actions/recent CVs are implemented, extraction polling no longer overwrites unsaved form state, reviewed values round-trip without extraction reinterpretation, and the Apply/Discard gate is unchanged.
- **Commit:** `268b3a0` (`feat(career): clarify workspace actions`) plus the V-164 polling and V-167 persistence checkpoints.
- **Remaining work:** browser and production gates. Live model-quality benchmarking and deeper builder interaction belong to CAREER-002.
### CAREER-002 — CV Builder interaction redesign and external research
+7 -7
View File
@@ -2,17 +2,17 @@
Updated: 2026-08-15
- **Exact current task:** finish and ship the prioritized admin-only deployed-version indicator, then correct lossless Career manual-field persistence and CV contact contrast before returning to JOBS-002 closure.
- **Last completed step:** exposed configured build version/commit metadata through `/api/auth/me` only for administrators and added a compact responsive header badge with accessible version/commit text.
- **Files currently modified:** auth bootstrap DTO/controller/test, application shell/App bootstrap/test, and master programme tracking/evidence.
- **Commands already run:** focused Auth/System 36/36; focused AppShell 2/2; full backend 640/640; full frontend 53 suites/221 tests; optimized frontend build/TypeScript; diff check.
- **Test results:** all listed local gates pass. Jest retains the documented force-exit/open-handle notice; prior CV pathological proof and recorded baselines remain valid.
- **Exact current task:** commit/push lossless Career manual-field persistence, then correct CV header/sidebar contact contrast before returning to JOBS-002 closure.
- **Last completed step:** separated strict extraction normalization from lossless reviewed-profile persistence and routed Career save/version/restore/import-merge/legacy consumers through the correct boundary.
- **Files currently modified:** structured profile persistence/validation, Career and CV/job projection consumers, Career/import regressions, architecture and work-programme evidence.
- **Commands already run:** failing Career round-trip reproduction; affected backend 112/112; full backend 642/642; Career/Profile UI 17/17; diff check.
- **Test results:** all corrected commands pass. One initial Jest invocation named two nonexistent test paths and returned “No tests found”; the correct Career/Profile files then passed 17/17. Jest retains the documented force-exit/open-handle notice.
- **Services currently running:** none on task-owned ports 3000/5202. Playwright stopped its disposable API/Next servers. Pre-existing Docker services were not changed.
- **Temporary files or processes:** no task-owned process is running and the failed disposable migration database was removed. Existing synthetic browser evidence/account and startup-created local backup remain documented. No provider account, real email, private content, paid service or production service was accessed.
- **Production changes currently active:** none. No deployment, migration, provider connection/sync/send or production payload occurred.
- **Rollback status:** downgrade `20260810080858_AddEmailDraftClientRequestId`, then `20260810075206_AddEmailDrafts`, before reverting draft commits; then follow the existing MAIL rollback order (`ee5ef7e`, `449faeb`, `123fc55`/`e9937ac`, ledger downgrade before `653f011`). No production migration/deploy/provider grant occurred.
- **Uncommitted changes:** V-166 admin version indicator and tracking update; no dependency/schema/config/migration change.
- **Uncommitted changes:** V-167 Career reviewed-value persistence and tracking update; no dependency/schema/config/migration change. V-166 is committed/pushed as `a6cffe0`.
- **Known failures:** live deployment is not verified because PR deploy is intentionally skipped and the active branch is not approved for merge. Draft export/API/UI, full thread/category actions and non-Gmail review remain; existing accounts need re-consent and IMAP stays read-only. A clean full-chain SQLite apply fails in the pre-existing JT-019 migration before the new draft migration. Browser/provider/MariaDB/production unavailable or unverified; recovery scan performance is unmeasured at large ledger scale; Jest open handles; SEC-006 parser dependency work is still separately gated; parser isolation remains SEC-007.
- **Exact next action:** review, commit and push V-166; then fix the Career manual-value normalization boundary and CV contact contrast with focused regressions.
- **Exact next action:** review, commit and push V-167; then fix CV contact/header/sidebar contrast with renderer and PDF regressions.
- **Work that can continue independently:** the immediate queue in the master plan: Career lossless persistence, CV contrast, JOBS-002 closure, cross-app contrast/accessibility, PRODUCT-001 and VER-001. UX/JOBS production, MAIL provider mutations, SEC-006/007 and PROD packages retain their recorded external gates.
- **Decisions still required from the user:** none for synthetic/code-inspected repository work. Any provider connection or send test, internet/package upgrades, private data, external/paid providers and production actions retain explicit approval/safety gates; SEC-009 retention/legal policy remains unresolved.