93 lines
11 KiB
Markdown
93 lines
11 KiB
Markdown
# 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.
|