# Jobjakt source inventory and gap analysis ## Evidence boundary Repository inspected read-only at `b2a9fd68b081a8cc1701b1c58eaea7e1070274af` on `codex/ui-redesign-phase4`. Working tree was clean at the initial check. Statements marked **Verified — source** describe inspected code, not exercised application behavior. Jobjakt runtime usability, test results, production schema and output fidelity are **Not Tested in this investigation**. All paths below are relative to `E:/Storage/Projects/Active/Job tracker`. No code, database, dependencies, migrations or deployment files were changed. ## Existing architecture: preserve this foundation | Area | Verified — source | Evidence | |---|---|---| | Routing | CV library/editor `/career/builder` and `/career/builder/:id`; public CV `/cv/:slug` | `job-tracker-ui/src/App.tsx:436`, `:437`, `:523` | | Editor ownership | Variant, themes and master outline loaded by existing editor; Content/Template/Customize/AI Tools/History tabs | `job-tracker-ui/src/views/CvBuilderEditor.tsx:59`, `:110`, `:605` | | CV autosave | 800ms serialized optimistic save with expected version; blank names prevent save; revision conflict stops automatic writes | `CvBuilderEditor.tsx:187–235` | | Recovery | Retry/status, unsaved-settings JSON download, reload saved version, route and unload protection | `CvBuilderEditor.tsx:341–389`, `:709–723` | | Undo/redo | Settings snapshots, normal-update cap 60; new update clears redo; names outside settings history | `CvBuilderEditor.tsx:301–339` | | Content editing | Section visibility/name/order, source overrides, custom presets/entries, hide/reorder/reset to source | `CvBuilderEditor.tsx:965–1045`, `:1243–1368`; `job-tracker-ui/src/cvBuilder.ts:3–79` | | Reordering | Native drag/drop plus explicit up/down controls | `job-tracker-ui/src/hooks/useDragReorder.ts:3–51`; `CvBuilderEditor.tsx:1203`, `:1341` | | Preview | 300ms API preview, stale-request suppression, last-good output retained, retry, page count/overflow notices | `CvBuilderEditor.tsx:163–185`, `:650–676` | | Physical page contract | Font/image readiness and renderer print CSS drive browser fragmentation; fit-to-width on resize | `job-tracker-ui/src/cvPreview.ts:3–49`; `CvBuilderEditor.tsx:513–529` | | Responsive editor | Sticky split panes on desktop, Edit/Preview one-pane mode below 900px | `CvBuilderEditor.tsx:57`, `:590–597`, `:632–676` | | Template gallery | ATS-first filter, selected template retained, responsive cards, availability/Pro handling, keyboard selection | `job-tracker-ui/src/components/CvTemplateGallery.tsx:31–68` | | Thumbnail limitation | Gallery uses schematic CSS illustrations, not actual rendered template output; sample-preview API already exists | `CvTemplateThumbnail.tsx:6–30`; `cvBuilder.ts:272` | | Design controls | Capability-filtered visual settings, null-as-default semantics, confirm before resetting visual overrides | `components/cv/CvCustomizeTab.tsx:33–124`; `cvBuilder.ts:193–217` | | CV data models | CareerProfile relational core plus JSON projection; variant is a lens over current master with stable entry keys | `JobTrackerApi/Models/CareerProfile.cs:12–33`; `Services/CareerProfileService.cs:51–101`; `Models/CvVariantSettings.cs:8–97` | | Render/export | Unsaved preview and saved PDF share CV renderer; export saves first; safe inline text handling | `Controllers/CvVariantController.cs:210–239`; `Services/ThemedCvRenderer.cs:203–218`; `CvBuilderEditor.tsx:418–434` | | Concurrency/history | CV expected version missing→428, conflict→409; version token; restore creates a new revision | `CvVariantController.cs:129–154`, `:191–208`; `Services/CvVariantService.cs:111–176`; `Data/JobTrackerContext.cs:483–485` | | Variant-history meaning | Historic settings re-resolve current master facts; historical settings do not freeze historic career content | `CvVariantService.cs:179–197`, `:224–232` | | Sharing | Owned variants/history; public slug checked explicitly; unpublish/re-publish rotates link; public PDF rate-limited | `Data/JobTrackerContext.cs:476–506`; `Controllers/PublicCvController.cs:28–56` | | AI | Pro eligibility, consent/routing boundary, grounded proposals, revision/fingerprint-bound apply token | `Services/CvAiSuggestionService.cs:31–135`, `:218–245`; `Services/AiPrivacyPolicy.cs:23–79` | | Cover-letter workspace | Job-owned explicit Save/Discard, dirty protection, starter text, version restore, AI compare/Apply/Reject | `components/ApplicationAssets.tsx:484–678`, `:699–817`; `views/ApplicationWorkspacePage.tsx:91–125`, `:262` | | Current text control | Labelled MUI textarea with Markdown-marker toolbar and selection restoration; not WYSIWYG | `components/RichTextField.tsx:12–77` | | Letter API/storage | Text, CurrentVersion, history and AI count; GET/PUT/restore; identical trimmed save avoids a new version | `JobTrackerApi/Controllers/ApplicationAssetsController.cs:17–86`; `Services/ApplicationAssetsService.cs:38–54`, `:240–316`; `job-tracker-ui/src/applicationWorkspace.ts:245–301` | | Documents index | Letters link back to application subsection; index includes existing resources, not another editing owner | `views/DocumentsPage.tsx:39–41`; `JobTrackerApi.Tests/DocumentsControllerTests.cs:56`, `:308` | | Frozen application evidence | Submitted package copies rendered CV HTML, letter text and attachment evidence | `JobTrackerApi/Models/SubmittedApplicationPackage.cs:3–20`; `Services/SubmittedApplicationPackageService.cs:59–104` | | Localization/theme | English/Bokmål, legacy Norwegian normalization, fallback/interpolation, current Archivo/MUI palette and density | `src/i18n/I18nProvider.tsx:22–67`; `src/i18n/translations.ts:1`; `src/theme.ts:9`, `:113–183`, `:217–224` | Paths in shortened rows retain the prefix from their full path earlier in the table: editor/frontend paths are under `job-tracker-ui/src`; C# controllers/models/services/data are under `JobTrackerApi`. ## Capability comparison | FlowCV observation | Jobjakt position from source | Actual gap / recommendation | Priority | |---|---|---|---| | Document cards and creation | Library already lists/creates/renames/duplicates/deletes CVs | Runtime qualification, not a replacement dashboard | Preserve | | Content outline and typed sections | Existing source-linked and custom section editor | Clarify master-source vs document-only changes; do not duplicate career CRUD | P1 UX | | Autosave | Existing revision-aware autosave and visible states | Preserve; stronger evidence of failure handling in source than observed FlowCV feedback | Preserve | | Undo/redo | Existing bounded settings history | Explain names/history scope; do not assume body and settings histories are interchangeable | P1 copy | | Reordering | Existing native drag and explicit up/down | Qualify touch/keyboard; no new drag dependency justified | Preserve/verify | | Template selection | Existing capability-aware gallery + shared preview API | Add real candidate preview before apply; schematic thumbnails can remain fast discovery aids | P1 | | Typography/layout controls | Broad existing normalized settings | Preserve supported-setting filters and null defaults; avoid exposing unsupported knobs | Preserve | | Preview and pagination | Existing physical renderer/fragmentation/fit-to-width | Manual zoom not found in inspected editor; add only if zoom research supports it | P2 optional | | AI | Existing grounded proposal, Apply and consent boundary | Preserve; paid FlowCV outputs were inaccessible and are not a benchmark | Preserve | | PDF export | Existing save-before-export and error states | Qualify newest-draft parity and long document recovery | Preserve/verify | | Duplication/versions | Existing duplicate/history/restore, unlike inaccessible FlowCV duplication | Retain; clearly distinguish revision history from frozen application evidence | P1 copy | | Letter content | Existing job-linked draft/history/AI | Add document preview/export around this owner, not a separate unsynchronized letter system | P1–P2 | | Resume-data reuse for letters | Attached CV and application context exist, but no explicit sender-copy designer found | Optional core-contact snapshot with explicit copy scope; preserve master facts | P2 | | Matching letter design | No corresponding frontend designer or generated letter PDF endpoint found in bounded searches | New letter rendering/settings contract is required | P2–P3 | | Generic letter data export | CSV/JSON/account ZIP/backup already include letter data; attachment downloads exist | Do not describe letters as having no export at all | Preserve | ## Material implementation constraints and risks ### Letter revision coverage is incomplete **Verified — source:** three production paths directly write `CoverLetterText` without using versioned letter persistence: - Job create: `JobTrackerApi/Controllers/JobApplicationsController.cs:783`, saved at `:817`. - Generic job update: `:878`, saved at `:929`; DTO at `Controllers/JobApplicationDtos.cs:113–137`. - Application draft update: `:1558`, saved at `:1578`; DTO at `JobApplicationDtos.cs:221–226`. The dedicated letter endpoint uses `ApplicationAssetsService.SaveCoverLetterAsync`; restore calls that service too. Its save request has no expected revision, versions use `max+1`, and the history index is non-unique (`ApplicationAssetsController.cs:22`; `ApplicationAssetsService.cs:310–316`; `JobTrackerContext.cs:570–571`). **Inferred risk:** concurrent or legacy writes can overwrite letter text without corresponding history/version conflict protection. A race was not reproduced. Any letter autosave or persistent design phase must account for every writer and preserve their different null/clear semantics. Merely adding a revision check in a new UI would be incomplete. ### Preview, current documents and frozen records differ - CV PDF renders saved state; preserve the existing save-before-export behavior. - CV settings history is not a historic master-profile snapshot. - Frozen submitted packages already preserve CV HTML and letter text. If designed letter output becomes evidence, capture its rendered artifact too; old text-only snapshots must remain readable. - A submitted-package capture does not establish delivery to an employer. Copy must not imply it does. ### Existing exports and pipelines **Verified — source:** `ExportController.cs:57,106,128–136` includes letter text/jobs in CSV/JSON; `AccountDataExportService.cs:189,208,213` includes versions/snapshots; encrypted backups serialize jobs (`BackupController.cs:34–42`). Downloading existing letter attachments is already supported. **Bounded negative finding:** controller/service searches found no generated standalone cover-letter HTML/PDF/DOCX endpoint; current dedicated surface is GET/PUT/restore. DOCX references found import/attachment support, not generated CV DOCX export. This does not prove deployed functionality outside the checkout is absent. The separate structured tailored-CV pipeline (`Models/TailoredCvDraft.cs:3–21`; `Controllers/JobApplicationsController.cs:1389–1535`) must not be silently merged into variant ownership. ### Dependencies and platform The package declares React 19, MUI 7, Next 16, React Router 7, Axios, Jest/Testing Library, Playwright and axe (`job-tracker-ui/package.json:5–38`, `:59–72`). These are declared ranges, not a fresh dependency installation audit. No new dependency is required for the recommended initial work. Preserve current nullable C#/EF, owner scoping, safe HTML, AI policy and document rendering boundaries.