diff --git a/docs/cv-redesign/CAPABILITIES.md b/docs/cv-redesign/CAPABILITIES.md new file mode 100644 index 0000000..93b7cd0 --- /dev/null +++ b/docs/cv-redesign/CAPABILITIES.md @@ -0,0 +1,24 @@ +# Current capability and preservation matrix + +Source baseline: `28f83df`. Source inspection is not a runtime pass. All frontend paths below are under `job-tracker-ui/src/`; backend paths under `JobTrackerApi/`. + +| Existing capability | Current owner | Improvement / research trace | Data impact | Coverage and preservation | +|---|---|---|---|---| +| Library, duplicate, delete, publish/share | `views/CvBuilderPage.tsx`, `views/CvBuilderEditor.tsx`, `CvVariantController` | Preserve existing routes and actions; D1–D2, E19–21 | None | cv-builder-page, cv-editor-frame, PublicCv tests | +| Identity, linked job, save states | editor header, serialized save queue | More prominent document context; wireframe D-A, AC-01/04 | None | editor-frame and revision readiness | +| Canonical Career Profile | CareerProfileService, CvVariantService resolution | Explicit source/local wording; never duplicate career CRUD | None | CvBuilderTests, profile/override browser cases | +| Section outline/navigation/hide/order | editor ContentTab, SectionRow, EntryList, useDragReorder | Preserve stable keys, custom sections/presets; accurate reorder feedback and focus; E1–7/13, AC-03 | Existing settings only | cv-content-workflow, cv-responsive-workflow, cvBuilder unit | +| Personal/contact, summary, experience, education, skills, languages, certifications, projects, interests, awards, publications, organisations, references | actual outline and DEFAULT_SECTION_ORDER; master contact | Preserve actual inventory, custom courses/volunteer/additional experience/declaration and arbitrary text | Existing settings; no master deletion | renderer/outline and custom-section tests | +| Adjacent preview, physical pages, fit-to-width | editor, cvPreview.ts, ThemedCvRenderer | Preserve debounce, last-good result and error/retry; improve page navigation; E2/14, M1–4, AC-05 | None | cv-preview-presentation, pagination and PDF oracles | +| Template catalogue / availability / capability filtering | CvTemplateGallery, CvCustomizeTab, cvBuilder.ts | Real sample candidate before explicit Apply, cancel with no writes, stale-result exclusion; E8–12, AC-02 | Only confirmed visual patch; one undo step | gallery/controls and candidate dialog tests | +| Typography/colours/spacing/page/contact/section settings | CvCustomizeTab, renderer normalisation | Preserve safe ranges and null inheritance; app theme remains separate | No migration | cv-document-controls, CV settings/PDF corpus | +| Undo/redo and saved settings history | editor, CvVariantService | Explain that settings resolve today's master; frozen package is separate; AC-10 | None | editor/history and submitted-package tests | +| CV optimistic save, conflict/recovery/export | editor, CvVariantService, shared EF Version | Preserve RD21 queue/ack semantics, fail before stale export | No token change | CvRevisionReadinessTests, rd21 companions, MariaDB | +| Application CV attachment/tailoring/letter | ApplicationAssets, applicationWorkspace.ts, ApplicationAssetsService | Keep job ownership and explicit Save/Discard; clarify pair; L2–9, AC-06–09 | Versioned letter extensions only after all writers safe | assets, cross-writer, owner/concurrency tests | +| Dedicated letter save/restore | shared application Version + CoverLetterVersions | Reuse RD21 token; original new-counter proposal superseded | Preserve null/clear and atomic history | ApplicationAssetsTests and relational provider | +| Generic/create/draft letter writes | JobApplicationsController | Route intended mutations through shared history staging before presentation | Add missing history without independent save/commit | all callers/DTOs/imports must be inventoried before change | +| Frozen submitted packages, exports/backups | SubmittedApplicationPackageService, AccountDataExportService, Backup/Export controllers | Preserve bytes and old text-only snapshots; designed-letter capture requires additive compatible contract | Never rewrite old records | submitted-package, documents, backup/export tests | +| AI tools/proposals/eligibility | existing CV and application AI services | Preserve Apply/Reject and consent; paid FlowCV results unobserved | None | existing AI contracts; semantics remain deferred | +| EN/Bokmål, light/dark, compact mode | I18nProvider/translations, MUI tokens, editor media query | Use same owners, no duplicate active mobile editor; AC-11/12 | None | unit, axe, viewport/theme/locale browser matrix; human cards separate | + +The broader 57-group Phase 9 inventory retains 56 PARTIAL and C11 DEFERRED; this feature cannot promote unrelated groups. Research controls not supported by current Jobjakt are not silently added as new models. diff --git a/docs/cv-redesign/ENTRY.md b/docs/cv-redesign/ENTRY.md new file mode 100644 index 0000000..4dfa03a --- /dev/null +++ b/docs/cv-redesign/ENTRY.md @@ -0,0 +1,35 @@ +# CV-UX-01 scope and entry decision + +25 October 2026. Owner authorisation: the standalone CV-UX-01 Entry Approval and Implementation Authorisation supplied in this chat. This is the separately scoped feature entry artifact required by P9-SEC-02; it does not amend historical acceptance. + +## Baseline and decision + +Verified clean checkout at `28f83df` on `fix/p9-model-cache-and-ci-qualification`, matching the locally recorded origin branch. Read `docs/redesign/phase-9/p9-sec-02/ACCEPTANCE_ADDENDUM_2026-10-25.md` and the architecture overview. Created `feature/cv-editor-flowcv-redesign` directly from that checkpoint. Live remote identity is checked when publishing checkpoints. + +**Entry: CONDITIONAL GO for isolated CV development.** The missing standalone authorisation is supplied by the owner. RD21 is RESOLVED in its tested scope; Windows/Linux PDF fidelity PASS; Python security CONDITIONAL PASS and model/cache PASS within tested CPU scope. None of those historical passes is a new test execution for this feature. + +Hosted MariaDB remains BLOCKED and runner isolation UNVERIFIED. Production and Phase 10 remain NO-GO. Human screen-reader/device/keyboard/zoom/Bokmål/print and provider cards remain untested; they carry into final acceptance rather than being closed by automation. Python vendor-query coverage and CPU/GPU/semantic limitations remain unchanged. No production or hosted-runner changes are in scope. + +## Authoritative scope and architecture + +Extend the existing React/MUI editor, route, locale/theme providers, .NET/EF persistence, and renderer. Preserve Career Profile as canonical, CV overrides as document-specific, null-as-inherit design settings, settings revision history, immutable recorded application artifacts, owner filtering, sharing, AI review/consent and all supported sections. No replacement document engine, AI provider, font system or new UI dependency. + +Implement the approved original research concepts: coherent editing/preview workspace; deliberate sample template preview before applying; reversible visual-only changes; keyboard/touch alternatives for section ordering; accurate provenance/history; responsive EN/Bokmål controls; connected application/letter workflows. Preserve existing capabilities rather than rebuilding functionality already delivered in Phases 1–9. + +The historical research's proposed *new letter revision counter* conflicts with RD21's newer shared application `Version`. Reuse the repaired shared optimistic concurrency token. Do not replace it or change no-op acknowledgement semantics. Before persistent letter presentation or PDF, close generic/create/draft writer history gaps at the shared persistence owner and prove atomicity and tenant isolation. This dependency is implementation work inside CV-UX, not permission to weaken revision protection. If it cannot be qualified, withhold the dependent letter feature and identify the exact failed gate. + +## Research provenance + +Primary package: `C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/README.md`. + +Read the README, audit, component inventory, source gap analysis, original design, desktop/mobile wireframes, phased plan and acceptance criteria. All 37 PNG/DOM-AX pairs exist; all 83 manifest entries match SHA-256. Screenshot contact sheets were inspected locally; selected DOM/AX evidence is assessed against its stated snapshot limits. No FlowCV account or external endpoint is accessed. Import research prose and a hash/checkpoint inventory; keep third-party screenshots and raw selected DOM out of product assets and Git. Source references from the original `b2a9fd68` baseline are historical, not current line evidence. + +## Acceptance and stop conditions + +Original AC-01–15 remain the acceptance framework, reconciled in PLAN.md and CAPABILITIES.md. Test real current owners, not parallel mocks presented as integration proof. Separate focused, full, relational, browser, PDF, human and production results. Failure/superseded attempts remain identifiable; never add focused reruns to full totals. + +Stop dependent work on demonstrated loss of Career Profile/history/frozen content, unqualified revision behavior, missing immutable baseline, unsafe schema conversion, unsupported rendering contract or production dependency. Continue independent safe tasks. No Docling/CV-IMPORT-01, AI-P5-13 semantics, FINN/NAV, Phase 10 deletion, main merge or deployment. + +## Delivery + +Checkpoint sequence: CV-UX-00 research/architecture; CV-UX-01 workspace; CV-UX-02 sections; CV-UX-03 preview/design; CV-UX-04 document/letter integration; CV-UX-05 save/revision qualification; CV-UX-06 responsive/accessibility/localisation; CV-UX-07 regression/PDF/final decision. Track concrete changes/tests in TODO.md. Commit and normally push validated checkpoints individually, verify remote equality, and continue autonomously. Final report must retain missing human/provider/hosted evidence and a separate CV-IMPORT readiness decision. diff --git a/docs/cv-redesign/PLAN.md b/docs/cv-redesign/PLAN.md new file mode 100644 index 0000000..0a4a30d --- /dev/null +++ b/docs/cv-redesign/PLAN.md @@ -0,0 +1,20 @@ +# CV-UX-01 implementation plan + +**Goal:** modernise the existing CV/document workflow without replacing its persistence or rendering contracts. +**Architecture:** existing React/MUI editor plus existing .NET/EF owners; candidate preview is read-only until explicit visual-only application. Shared application Version remains the letter concurrency token. +**Spec:** ENTRY.md, owner mission, imported research design/wireframes and AC-01–15. +**Execution:** autonomous in the requested feature branch; use task-scoped implementation/review where useful, retain checkpoint evidence in TODO.md. No routine permission pauses. + +## Constraints and review focus + +No main merge/deployment, canonical-profile replacement, new AI providers, Docling, Phase 10 cleanup or unbounded customization. No new dependency initially. Check stale candidate responses, theme cancellation, unsaved export ordering, cross-writer atomicity and historical-source semantics. Retain exact null/clear contracts, tenant filtering, all existing supported controls and frozen bytes. + +## Tasks + +1. **CV-UX-00 entry/research:** verify baseline, hash all original files, inspect all 37 screenshot/DOM checkpoints, preserve portable research prose and map every recommendation against current owners. Commit/push entry and plan. +2. **CV-UX-01/02 workspace/sections:** extend `views/CvBuilderEditor.tsx` and both locale dictionaries. Preserve controls and layout owners; improve context, history wording, section reorder announcements/focus and section discovery. Add assertions to current editor browser tests before changing behavior; run focused suites and commit/push. +3. **CV-UX-03 candidates/preview:** add `components/cv/CvTemplatePreviewDialog.tsx`; integrate at `CvCustomizeTab` without changing library creation semantics. Reuse `cvBuilderApi.themePreview(themeId): Promise` and `applyCvTheme`. Test no update on open/cancel, retry, late response, lock enforcement, reset confirmation, preservation and one undo step. Physical pages use cvPreview readiness; no new PDF request for browsing. Add bounded page navigation to existing preview. Commit/push after unit/browser proof. +4. **CV-UX-04/05 letters:** inventory every current `CoverLetterText` writer and caller. Reuse RD21 Version instead of the historical proposal's second revision system. Add failing cross-writer/history/null/clear tests, then stage all intended mutations atomically at the shared service owner. Qualify on actual disposable MariaDB before persistent design/export. Preserve explicit local drafts, no-op acknowledgement, restore-as-new, imports/backups and owner isolation. Add only compatible letter rendering/settings after this gate; safe body-only preview can proceed independently and must say what it previews. Record precise blockers without pretending an incomplete subphase is accepted. +5. **CV-UX-06/07 acceptance:** run frontend/backend regression, browser preservation and failure workflows, theme/locale/width/accessibility checks and original Windows/Linux PDF oracles. Bind outputs to source. Review whole diff, fix material defects, publish evidence and exact limitations. Human/device/provider checks remain NOT TESTED unless actually performed. Commit/push final report and verify remote equality. Hand off CV-IMPORT requirements without starting it. + +Each implementation task starts with a failing behavior assertion, then the smallest implementation and matching focused verification. Existing passing functionality is retained as regression coverage, not rewritten merely to generate a new diff. Exact final commands/counts belong in acceptance evidence, not this prospective plan. diff --git a/docs/cv-redesign/research/01-flowcv-audit.md b/docs/cv-redesign/research/01-flowcv-audit.md new file mode 100644 index 0000000..cde1a3d --- /dev/null +++ b/docs/cv-redesign/research/01-flowcv-audit.md @@ -0,0 +1,676 @@ +# FlowCV UI/UX investigation + +Research completed 20–21 October 2026. Targets: [resume dashboard](https://app.flowcv.com/resumes) and [cover letters](https://app.flowcv.com/cover-letters). The user operated the browser manually; REA passively inspected the page, took screenshots and observed bounded network windows through the dedicated localhost CDP endpoint. No scripted clicks, typing, navigation, upgrades or privileged API calls were used. + +## Evidence standard and boundaries + +- **Verified**: visible screenshot/DOM/accessibility or network metadata within a stated checkpoint; explicitly attributed user observations are identified. Source findings for Jobjakt are separately labelled Verified — source. +- **Inferred**: a plausible interpretation of that evidence, not established implementation behaviour. +- **Not Tested**: no successful behavioural verification. It never means a feature is absent. + +There are **37 curated checkpoints**, each with a PNG and selected DOM/accessibility JSON. Every checkpoint records the user's manual action, findings, original REA evidence identifiers and observation limits. Findings within a checkpoint describe knowledge at that moment; later checkpoints can resolve an earlier Not Tested item. The coverage summary below is the final status. + +The endpoint was the user-authorised Chrome-family browser at http://127.0.0.1:9222; REA reported Edge 155.0.4283.62. Desktop captures are generally 1912×948; the cover-letter creation gallery was 1661×948. Mobile captures used a measured 390×840 emulated viewport, despite an approximately 390×844 requested setup. This is not real-device evidence. Capture timestamps are UTC in the JSON; research dates here use Europe/Paris. + +Screenshots and extracts use the newly created synthetic Resume 1 / Letter 1, or FlowCV's public sample templates. The initial pre-synthetic capture is excluded from this package. The raw REA session ledger is deliberately not exported. No passwords, cookies, credential headers, storage, request/response bodies or original personal CV content are included. Account and document identifiers are omitted from retained network metadata. Synthetic contact values are not reproduced in the narrative. Screenshots of proprietary sample designs are research evidence only and must not be reused as Jobjakt assets. + +DOM files are selected structures, not complete HTML archives. AX snapshots establish reported names/roles/states at a moment; they do not establish a complete keyboard or screen-reader experience. Bounded network observation cannot recover earlier activity or prove durability, causation, exact debounce or backend implementation. No product marketing claim is treated as a verified functional result. + +## Main UX findings + +1. **Verified — coherent desktop editing loop.** The editor keeps forms and a physical-page preview adjacent. Editing an experience title updates the document before Done; section ordering and typography changes also appear in the preview. On narrow screens, a dedicated preview replaces the side-by-side layout. Evidence E2–E3, E13–E14, M1–M3. +2. **Verified — deliberate, reversible design choice.** Gallery selection opens a larger sample/details view, then Use this template applies a bundle of design values. One undo restored the prior design; redo reapplied it. Observed synthetic content remained. This is evidence for one template operation, not unlimited history or full data equivalence. E8–E12. +3. **Verified metadata / Inferred automatic saving.** Successful resume entry PATCH and letter body POST requests occurred while forms remained open before Done. User saw no save feedback in sampled resume edits; final snapshots lacked saving/saved text. A transient indicator may have been missed. The network observations support autosave, but reload durability and failure handling remain Not Tested. E3–E4, L6. +4. **Verified — separate data and design reuse.** Letters start blank and offer explicit contact copying and separate resume design copying, each with source selection and replacement scope. Design copying retained the paragraph and sender. Copying is observed; ongoing synchronization is not established. L2–L9. +5. **Verified — access limits shape workflows.** Draft Cover Letter opens a Pro gate. Duplicate opens a one-resume plan-limit prompt. Successful AI generation and successful duplication are Not Tested; no upgrade was performed. E16–E17, E20–E21. +6. **Verified snapshot findings / Inferred accessibility risks.** Unnamed icon buttons, duplicate MM/YYYY date names and an unnamed letter body textbox were observed. Some modal snapshots retained underlying controls; focus trapping was not exercised. The drag announcement reported position 3→3 despite changed order. These warrant direct assistive-technology reproduction rather than a blanket compliance conclusion. E2, E5, E8–E9, E13–E14, L6, M2–M4. +7. **Verified form state / Inferred date validation gap.** Start 02/2026 and End 01/2026 coexist with no visible error, AX invalid=false and Done available. The user could not choose a prior year but could choose the prior month in the same year. Submission/backend acceptance was not tested; the dates were restored. M4. +8. **Verified — PDF export path completes.** Resume and letter downloads returned 200 application/pdf; user reported completed downloads. Resume success popup was captured. Files were not opened, so page fidelity, font embedding, accessibility and full text retention remain Not Tested. E18, L10. + +## Final coverage matrix + +| Requested area | Final finding / limit | Status | Evidence | +|---|---|---|---| +| Resume navigation/dashboard/cards | Sidebar, new tile, thumbnail/title/edited/A4/overflow and action list observed | Verified | D1–D2 | +| Resume creation | User created a fresh resume before capture; wizard/import/blank transition not observed | Not Tested | D1, E1 | +| Content editing/types | Fifteen existing headings; experience form; add-content chooser; project entry added and retained | Verified for sampled flows | E1–E7 | +| Drag/drop | Mouse section reorder changes outline/preview; rows move aside per user | Verified | E12–E13 | +| Keyboard/touch drag | Instructions present, actual success/cancel not exercised | Not Tested | E1, E13 | +| Templates | Gallery → details → Apply → Undo → Redo, observed content retained | Verified for one template | E8–E12 | +| Layout customisation | One/Two/Mix and numerous controls present; template changed layout; section order changed | Verified presence and sampled effects | E7, E10–E13 | +| Typography | 10.5→11pt and preview update; font groups/options; user reports hover preview | Verified increment/list; hover Inferred | E14–E16 | +| Page preview | Adjacent desktop pages and narrow stacked overlay observed | Verified | E14, M2 | +| Zoom | No dedicated zoom in sampled views; pinch/keyboard/manual zoom not exercised | Not Tested overall | E19, M2 | +| Save | Before-Done save requests, preview update, reopen retained title; exact persistence and error behaviour unknown | Verified observations; autosave Inferred | E3–E4, L6 | +| Undo/redo | Applied template undone/redone successfully | Verified limited scope | E11–E12 | +| AI | Hub/cards and Pro gate observed; no generation/result tested | Verified entry/gate; results Not Tested | E16–E17 | +| Export | Resume/letter PDF metadata and user completion; downloaded contents not checked | Verified completion metadata; fidelity Not Tested | E18, L10 | +| Duplication | Attempt blocked by one-resume gate | Verified gate; successful copy Not Tested | E20–E21 | +| Versions/history | No selector seen in sampled menus; cannot establish absence | Not Tested | D2, E19–E21 | +| Responsive/mobile | 390×840 content/form/preview states; real phone/keyboard/rotation unknown | Verified emulation; hardware Not Tested | M1–M4 | +| Letter creation/editor | New blank → letter content/preview; sender/body/customize exercised | Verified sampled workflow | L1–L7 | +| Shared resume data | Explicit source selection, replacement warning and copied sender fields | Verified copy; live sync Not Tested | L3–L5 | +| Matching designs | Separate copy-design review; compatible settings changed; content retained | Verified mapping; exact equivalence Not Tested | L7–L9 | + +## Observable network metadata + +Only traffic generated by the user's actions was observed; these paths are evidence, not an invitation to call undocumented endpoints. Queries/identifiers, credentials and bodies are excluded. + +| Action window | Observed metadata | Interpretation / limit | +|---|---|---| +| Resume title edit, 45 seconds | GET /api/resumes/:document-id 200; PATCH /api/resumes/save_entry 200 | Consistent with before-Done save; no payload/durability proof. See E3 and [selected metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E3-network-metadata.json) | +| Resume Download | GET /api/resumes/download 200, application/pdf | Successful export response; bytes not inspected | +| Letter body edit, 45 seconds | Two POST /api/letters/save_body 200, application/json | Before-Done requests observed; duplicate-request cause and debounce unknown | +| Letter Download and Overview, 45 seconds | GET /api/letters/download 200, application/pdf | User reported export complete; final dashboard captured | + +Client logging/helper traffic also appeared in some windows. It does not prove a user-facing state or explain backend implementation. Selected request metadata is retained in each applicable JSON file. + +## UX implications for Jobjakt + +**Inferred recommendations:** retain adjacent output feedback, separate design browsing from application, preserve content and make design changes reversible. Keep contact-copy and design-copy distinct. Improve the clarity of saving rather than copying sampled ambiguity. Treat focus/naming/date validation as explicit acceptance conditions. Jobjakt should organise these patterns around an application and its career-data provenance, not reproduce FlowCV's standalone-document appearance. + +Priorities are proposal judgments, not measured prevalence: high priority for reliable saving, accessible controls and safe export; medium priority for actual rendered candidate previews and clear compatible design reuse; lower priority for custom zoom or advanced layout controls until user need is established. + +## Manual walkthrough and checkpoint evidence + +The following actions are the actual requested manual sequence. No additional user action is needed now. For reproduction, use only synthetic data in a dedicated test account. Each screenshot captures the resulting state, not a continuous recording of every gesture. Per-checkpoint Not Tested findings are historical; use the final coverage matrix above for overall status. + +### D1 — D1-dashboard + +Manual action: User prepared synthetic Resume 1 before capture; creation actions not observed. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D1-dashboard-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D1-dashboard.png) + +Inspection: `ev_ad9b4a83d5f903f7a81ecdda728e90787e1acd96e043816e38bb16676ae5e15f` +Screenshot: `ev_36fa7c238b35367839ebafd99207b3e088840583b067d10addf34a7d0321179e` + +- **Verified** — Navigation links, New resume button, A4 document preview, relative edited time, card overflow. +- **Verified** — Focusable overflow button has empty accessible name. +- **Not Tested** — Creation, overflow actions, keyboard behavior and autosave. + +![Checkpoint D1](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D1-dashboard.png) + +### D2 — D2-card-menu + +Manual action: User clicked the Resume 1 card overflow control and left it open. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D2-card-menu-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D2-card-menu.png) + +Inspection: `ev_e6042f9f3781652d832a21236af57e30b2eb23f4b018b307feb912bfd62b518a` +Screenshot: `ev_25b9c8c43ab933e0a36c38a5901a28748f3fc902987cf85da908939b647cb9af` + +- **Verified** — Overflow opens a panel positioned upward over the card preview, with Edit title, Duplicate, AI translate Beta, Download and Delete. +- **Verified** — Panel actions are exposed as buttons; no menu or menuitem role appears in this accessibility snapshot. Trigger remains focused; expanded state is not reported. +- **Not Tested** — Successful duplication, translation, download, deletion, rename validation, keyboard navigation, focus trapping/restoration and versions. + +![Checkpoint D2](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/D2-card-menu.png) + +### E1 — E1-editor + +Manual action: User opened Resume 1 editor and reports adding one of every content type. Add operations happened before capture. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E1-editor-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E1-editor.png) + +Inspection: `ev_b0daa0caa9ac03b664b5c02b8d1bc02fb60cef98bb1ae80eef0665fc10203321` +Screenshot: `ev_06b7ffebb9dfea53dca237ac6c90914006a9b5f901e39ce1b41d1cc256aea484` + +- **Verified** — Content editor is at /resume/content. Header links: Overview, Content, Customize, AI Tools; document switcher, Download and overflow control. +- **Verified** — Desktop split view: section accordions left, document preview right. Current screenshot is scrolled near bottom of content list. +- **Verified** — 15 headings: Summary, Skills, Languages, Professional Experience, Education, Certificates, Awards, Courses, Projects, Interests, References, Declaration, Publications, Organisations, Custom. Add Content control present. +- **Verified** — Entry drag buttons expose instructions for Space to lift, arrow keys to move and Escape to cancel. Add Entry and Delete section controls exist. +- **Not Tested** — Keyboard reorder success, section reorder, add workflow, save state, preview update timing, undo/redo and zoom. No save indicator text observed in this snapshot; this does not prove absence. + +![Checkpoint E1](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E1-editor.png) + +### E2 — E2-experience-form + +Manual action: User expanded Professional Experience and opened the synthetic entry; no edits made during capture. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E2-experience-form-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E2-experience-form.png) + +Inspection: `ev_222a079e080b076e0bffc9f9d4dd7a3702e27d75d39b5e227d801a62611c40ec` +Screenshot: `ev_eee014d7499e9b230aa69e7f9ede1548f25e86d40e2e918852810c8420f358b2` + +- **Verified** — Experience editing replaces the left accordion pane with an Edit Entry form while the resume preview remains alongside. +- **Verified** — Employer autocomplete combobox plus Link button; Job Title and Location text inputs; Start Date/End Date inputs with Clear date controls; richtext Description. +- **Verified** — Richtext tools: Bold, Italic, Underline, Bulleted list, Insert link, left/center/right/justified alignment. AI shortcuts: Improve Writing, Suggest Content, Grammar Check, Shorter. +- **Verified** — Done button, Get Tips, eye and trash icons, section customization disclosure. Eye/trash buttons have empty names in this snapshot. +- **Verified** — Both date inputs expose accessible name MM/YYYY despite separate visible Start Date and End Date labels. +- **Not Tested** — Autocomplete suggestions, date validation, AI results, hide/delete effects, Done semantics and autosave. + +![Checkpoint E2](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E2-experience-form.png) + +### E3 — E3-title-edit + +Manual action: User replaced Job Title with UX Test Engineer, paused without clicking Done and reported no visible feedback. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E3-title-edit-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E3-title-edit.png) + +Inspection: `ev_0cd546540fc14303a49e09d45250c176b791539b72dcbc0f1d0f18ed8a3eca30` +Screenshot: `ev_dfff05a0439ed3fb98374ff00a1ad15ff546de1292246929f4e6a7e36fc7f07e` + +- **Verified** — UX Test Engineer appears in document preview while entry form remains open; user did not click Done. +- **Verified** — 45-second attach window observed GET /api/resumes/:document-id 200, PATCH /api/resumes/save_entry 200 and POST /clientlog 200. No payloads or raw headers captured. +- **Inferred** — Successful save_entry PATCH during the manual title edit is consistent with automatic saving before Done; no reload persistence or conflict behavior tested. +- **Verified** — User reported seeing no feedback; final AX snapshot has no saving/saved text. Transient visual indicators may have been missed. +- **Not Tested** — Reload persistence, exact debounce timing, error/retry, offline behavior, undo/redo, whether Done triggers additional saves. + +![Checkpoint E3](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E3-title-edit.png) + +### E4 — E4-section-customizations + +Manual action: User clicked Done, reopened experience, confirmed title retention and expanded section customizations. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E4-section-customizations-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E4-section-customizations.png) + +Inspection: `ev_94df1db000f48a368e9f348da0bd456417b8971eab9d2cc552d1cd36e4c2414f` +Screenshot: `ev_1a179ded7f695b3c7bcc55e803712e611faa589ad7e9f74d0ba3c032499a0376` + +- **Verified** — UX Test Engineer remains visible after user reports Done then reopening the same entry. This verifies in-app reopen retention, not browser reload persistence. +- **Verified** — Section disclosure expands and changes name to Hide customizations for this section with expanded=true. +- **Verified** — Work Experience customizations show two Title/Subtitle Order choices: Job Title - Employer and Employer - Job Title; latter visibly selected. Group promotions checkbox is unchecked. +- **Verified** — Hint links to Customize > Entry Layout for more options. +- **Not Tested** — Applying order choice, grouping multiple promotions, history/undo, reload persistence and date validation. + +![Checkpoint E4](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E4-section-customizations.png) + +### E5 — E5-add-content + +Manual action: User chose Job Title - Employer and reported preview order swapped; clicked Done and Add Content, leaving chooser open. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E5-add-content-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E5-add-content.png) + +Inspection: `ev_8585fc786af03622136cc7cc4fd137b7aef895552f954624634a07a9082f4825` +Screenshot: `ev_876d6db0f707207fc96777f24129617d82de323cacfd628a7e7d3bb7a51f0ef7` + +- **Verified** — Add Content opens a large modal with icon/title/help-text tiles in four columns at this desktop viewport. +- **Verified** — Current chooser lists Education, Professional Experience, Skills, Languages, Certificates, Interests, Projects, Courses, Awards, Organisations, Publications, References and two Custom tiles (existing custom section and add-custom tile). +- **Verified** — Summary and Declaration exist in this document but are not offered in this captured chooser state. Do not infer they are unsupported or why they are omitted. +- **Verified** — Dialog has modal=true but an empty accessible name. Close icon is an unnamed button. Background controls remain in the captured AX tree; focus is reported on Add Content. Keyboard containment was not tested. +- **Verified** — Experience entry name now reads UX Test Engineer, employer after presentation change; user reports preview swapped their order. +- **Not Tested** — Choosing a new section, duplicate section rules, custom schema editing, modal keyboard behavior and add cancellation. + +![Checkpoint E5](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E5-add-content.png) + +### E6 — E6-new-project + +Manual action: User selected Projects from Add Content and left the blank form untouched. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E6-new-project-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E6-new-project.png) + +Inspection: `ev_161f5f8f94f0203d86559fad55ffa1409b0057ccb9ea8e5293b46d32e85462f9` +Screenshot: `ev_faba34d15eed1a0996caa0be4b0e349f9318ae1f17371bd048eb9a5a6058ebe7` + +- **Verified** — Choosing Projects when a Projects section already exists opens a blank Edit Entry form at /resume/content/edit/project/:entry-id. The existing project remains visible in the preview. +- **Verified** — Project fields: Project title with Link, Sub title, Start Date, End Date and richtext Description. Project title is focused; exposed required states are false. Done, hide/delete icons, AI shortcuts and customization disclosure are present. +- **Inferred** — Chooser appears to add a new entry to the existing typed section; successful completion and section count still need corroboration. +- **Not Tested** — Empty-submit validation, date validation, new entry persistence, cancellation and reordering. + +![Checkpoint E6](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E6-new-project.png) + +### E7 — E7-customize-overview + +Manual action: User completed new synthetic Project B, clicked Done and opened Customize; reported no save feedback. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E7-customize-overview-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E7-customize-overview.png) + +Inspection: `ev_29122a19664a4b20938e5e993a7724630c2026735b53816bfb09f1927f7f17f5` +Screenshot: `ev_6c3f2921a298021bafd22d7a8549e202d238ff857b461848f5b9fa97aa6e010e` + +- **Verified** — Customize route /resume/customization retains preview and shows anchor navigation: Document, Templates, Layout, Font Size, Spacing, Entries, Headings, Font, Colors, Header, Photo, Links, Footer, Sections. +- **Verified** — Document defaults currently English (UK), DD/MM/YYYY, A4; Browse templates control present. Existing and new UX Test Project B appear together under Projects in preview. +- **Verified** — Layout controls include One/Two/Mix columns, Top/Left/Right header, section drag list with page breaks and 45%/55% column widths. Two and Left currently selected. +- **Verified** — AX exposes font size offsets, line height, spacing, margins, entry/date layout, heading styles, fonts, color area/modes, accent targets, header alignment/icon styling, photo options, link styling, footer fields and section customizations. Presence only; effects not tested. +- **Verified** — Current fonts: Zilla Slab body and Same as body font for name. Color modes Single/Multi/Image; current Multi. Photo controls explain options appear after photo added. +- **Inferred** — Floating curved-arrow pair resembles undo/redo; both are unnamed buttons in AX, so function and scope need testing. +- **Verified** — User reports no save feedback while adding project and moving to Customize. +- **Not Tested** — Template selection effects, typography changes, page format/language effects, undo/redo, drag/drop success, preview zoom and pagination behavior. + +![Checkpoint E7](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E7-customize-overview.png) + +### E8 — E8-template-gallery + +Manual action: User clicked Browse templates and left gallery open without selecting a design. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E8-template-gallery-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E8-template-gallery.png) + +Inspection: `ev_34a67434596debe1e00e2df269fd980805596a3e2672dbf85c58056984e45eff` +Screenshot: `ev_8d0f02f709a199c296cb157cd2c0b0f72c79aff3ef8f9f580381c5296c844f6b` + +- **Verified** — Browse templates opens Apply a design template modal at ?modal=resume-templates. Four preview cards per row at 1912px, labeled names beneath; gallery extends below viewport. +- **Verified** — Filter controls All Templates, Popular, Simple, Modern, Creative are exposed as checkboxes, All Templates checked. Their filtering behavior is not yet tested. +- **Verified** — Gallery previews show sample content rather than the current synthetic resume content. Original assets are retained only in audit screenshots; no template or asset extraction/reuse. +- **Verified** — Modal and close button have empty accessible names in this snapshot. Underlying Browse templates remains the reported focused control; keyboard behavior not tested. +- **Not Tested** — Template application/confirmation, content retention, filter combinations, paywalls, undo and persistence. + +![Checkpoint E8](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E8-template-gallery.png) + +### E9 — E9-template-detail + +Manual action: User selected CLASSIC CLEAR; observed larger preview/details and Use this template action. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E9-template-detail-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E9-template-detail.png) + +Inspection: `ev_f7a67166d2bd44bdd125f56b4898ca111f847d444b241602e9c7447a39abad91` +Screenshot: `ev_2e4070d424f8a2b08fe758d596abf332fbe7f81c48994cbe88a950da64d4f92c` + +- **Verified** — Selecting Classic Clear opens a larger sample preview and detail modal, preserving underlying editor design until Use this template is chosen. URL gains template=classic-clear. +- **Verified** — Use this template is a named button. Detail copy advertises A4/US-Letter, editable text, customization, print readiness and online sharing. Only copy presence is verified; exported output/sharing not tested. +- **Verified** — Selected design preview uses sample content, not the synthetic current document. No confirmation warning observed before this intermediate screen. +- **Not Tested** — Applying design, data retention, undo/redo, export format and online sharing. + +![Checkpoint E9](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E9-template-detail.png) + +### E10 — E10-template-applied + +Manual action: User clicked Use this template; returned to editor. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E10-template-applied-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E10-template-applied.png) + +Inspection: `ev_1c3e980e78819f5e18cb5699e73769df96cb4ab97eb9b72617507b962676be1e` +Screenshot: `ev_84ad8e6f58511776c9ef45c65919fdcc51acd611976e8013e0ffcf2c475659aa` + +- **Verified** — Use this template closes modal and returns to Customize. Layout changed from Two to One; preview changed to single column, centered header, uppercase ruled headings and Alegreya body font. +- **Verified** — Synthetic experience title, original section content and new Project B remain in AX/preview after application. No field-by-field export or backend comparison performed. +- **Verified** — Template changes a bundle of settings: section order, typography, spacing, margins, color/header choices and entry layout. Base font remains 10.5pt; line height is now 1.15 and margins 22mm/12mm. +- **Not Tested** — Undo/redo reversibility, template persistence after reload, full data equivalence, original design recovery and pagination/export fidelity. + +![Checkpoint E10](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E10-template-applied.png) + +### E11 — E11-template-undo + +Manual action: User clicked left curved arrow once and reported previous design returned. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E11-template-undo-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E11-template-undo.png) + +Inspection: `ev_f3fb5aaa4e6e000aa3e6bcc1f629f56d9605f2523453afeefbc2402cc9b0dddc` +Screenshot: `ev_a37daa85e4c405b317c43692cc8e4c51f9ebf558223c15c61f93c3060ca056d7` + +- **Verified** — One click on left curved-arrow control restores observed two-column layout, left header, Zilla Slab font, previous spacing/margins, color settings and section ordering after template application. +- **Verified** — New synthetic Project B remains present after undo; title and content edits predate template change. +- **Verified** — Right curved arrow changes from visually muted to active-looking. Both controls remain unnamed in AX; actual redo still needs testing. +- **Not Tested** — Redo, history depth, content-edit undo scope, cross-route history and persistence across reload. + +![Checkpoint E11](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E11-template-undo.png) + +### E12 — E12-redo-layout + +Manual action: User clicked right curved arrow and Layout anchor; reported single-column design returned. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E12-redo-layout-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E12-redo-layout.png) + +Inspection: `ev_e5a2e4f3d0b6b943afe0da9a498258f82531022a8ca5a08370e778350f985ab7` +Screenshot: `ev_7154704a4b67cc5f439ff95330a8f13c8ef9a6b3d199e26845e51c40cfd1d060` + +- **Verified** — Right curved-arrow restores applied single-column template: One selected, Alegreya font, template settings and reordered sections; synthetic content remains observed. +- **Verified** — Layout anchor scrolls controls into view while fixed top navigation remains. Section layout uses a vertical list of draggable labeled rows with grip icons and a fixed Personal Details block above. +- **Verified** — Current section order starts Summary, Professional Experience, Education, Skills, Certificates, Languages. Rows expose keyboard drag instructions. +- **Not Tested** — Actual section reorder, column reassignment, mixed columns, page-break placement, undo beyond this template change and layout save errors. + +![Checkpoint E12](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E12-redo-layout.png) + +### E13 — E13-sections-reordered + +Manual action: User dragged Skills grip above Education and reported rows moving aside with no confirmation. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E13-sections-reordered-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E13-sections-reordered.png) + +Inspection: `ev_71a3567de75d1f60c83413c74d0706df4d86354dffd7e03f5071ca9240461e27` +Screenshot: `ev_4aec11aea42785fe1f7ed11998db285538b84581e8327a97aab767286ff91b8b` + +- **Verified** — Mouse drag moves Skills above Education in both section layout list and document preview; neighboring rows shifted during dragging per user report; no visible confirmation reported. +- **Verified** — AX contains drop announcement: You have dropped the item. You have moved the item from position 3 to position 3. +- **Inferred** — Drop announcement may be misleading because before/after section order changed while reported source/destination positions are equal. Needs keyboard/screen-reader reproduction before treating as general defect. +- **Not Tested** — Keyboard drop success/cancel, drag across columns, entry reorder, persistence after reload and multi-page page-break behavior. + +![Checkpoint E13](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E13-sections-reordered.png) + +### E14 — E14-font-size-pagination + +Manual action: User clicked Font Size anchor and Base Font Size plus once; reported 11pt and preview update. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E14-font-size-pagination-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E14-font-size-pagination.png) + +Inspection: `ev_cc9fd5d81bc873d743bdab192ac6cab18686a982ebe40ad71f77056b177d44a7` +Screenshot: `ev_179245b5fdcbc71ead83b56b401a424dfdd155d051c0f69f4964408a50f74ef6` + +- **Verified** — One plus click increases Base Font Size from 10.5pt to 11pt. User observed preview update; final screenshot shows changed typography and two physical page surfaces separated by a gap. +- **Verified** — Font Size card offers base size and relative offsets for Full Name, Professional Title, Section Headings and Entry Header using segmented-looking tracks plus minus/plus controls. +- **Verified** — Spacing card begins with Line Height and Space Between Elements; line height remains 1.15. Increment/decrement buttons are unnamed in AX, and no slider role appears in this snapshot. +- **Not Tested** — Whether 11pt caused page count to increase, numeric ranges/limits, keyboard slider operation, zoom, typography persistence and export pagination parity. + +![Checkpoint E14](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E14-font-size-pagination.png) + +### E15 — E15-body-font-picker + +Manual action: User opened Font anchor and Body Font selector, leaving list open. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E15-body-font-picker-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E15-body-font-picker.png) + +Inspection: `ev_631e87802ee8aeef5fb4dab08e631c56c690f98f13e767c2f1c315f017b3191c` +Screenshot: `ev_13f9be64f32fe9a60ecbca6aaff96dcec9c063cced14cd3dcd5bb810ee44a2fa` + +- **Verified** — Body Font opens scrollable option list grouped SERIF, SANS and MONO, with each font name rendered as a sample. Current Alegreya has visible checkmark. +- **Verified** — AX exposes 35 font options in this capture, including Source Sans Pro, Roboto, Lora, EB Garamond and Courier Prime. Body Font trigger expanded=true with listbox popup semantics. +- **Verified** — No search field observed in this captured picker. Do not infer font upload is unsupported from this view. +- **Not Tested** — Changing body/name font, keyboard selection, multilingual glyph coverage, font embedding and export matching. + +![Checkpoint E15](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E15-body-font-picker.png) + +### E16 — E16-ai-tools + +Manual action: User selected Source Sans Pro, reported preview also changes on hover, then opened AI Tools without submitting. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E16-ai-tools-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E16-ai-tools.png) + +Inspection: `ev_fb3a4e206d2e43df4a1b54c29a9f449e73254d22854b8ba57fd39761a39248c9` +Screenshot: `ev_23a286d3242f4ac2a639436b01a80e198396d1af1d6a02ad201981747f78c677` + +- **Verified** — AI Tools route /resume/ai-tools shows Pro-plan notice and Upgrade to Pro action, plus Translate resume, Improve writing, Draft Cover Letter, Generate Summary, Check spelling & grammar cards. +- **Verified** — Draft Cover Letter copy says it uses resume and target job description. Grammar check copy distinguishes checking from rewriting. These are interface claims; resulting behavior not tested. +- **Verified** — Document preview remains alongside AI tool navigation. +- **Inferred** — User reports choosing Source Sans Pro changes preview, including temporary preview on font hover. Current screenshot is visibly sans serif; selected font value and hover cancellation not independently captured. +- **Not Tested** — AI input forms, gating enforcement, privacy disclosure, quota, generation latency/result quality, apply/reject/undo behavior and AI network requests. + +![Checkpoint E16](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E16-ai-tools.png) + +### E17 — E17-ai-plan-gate + +Manual action: User clicked Draft now and paused; resulting screen is a Pro-plan gate. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E17-ai-plan-gate-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E17-ai-plan-gate.png) + +Inspection: `ev_12a8c212379a827a672c5a843089b51cb3f17b1ac7d08d52c84aec99fbccf1fa` +Screenshot: `ev_b6747488e6683bb26410d9a10bcc4175267d81d21aad22448a97be6798baf5e8` + +- **Verified** — Draft now opens a plan gate stating AI features are available on Pro, with Stay on Free, Upgrade to Pro and close controls. No drafting form or generation result observed. +- **Verified** — Gate copy advertises unlimited PDF downloads, all resume templates and design options on free plan. This verifies messaging, not unlimited use or export behavior. +- **Not Tested** — Paid AI input fields, generation, resume/job data use, privacy options, quotas and apply/reject results. No upgrade or generation requested. + +![Checkpoint E17](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E17-ai-plan-gate.png) + +### E18 — E18-pdf-export-success + +Manual action: User dismissed Pro gate and clicked Download; observed spinner popup then download. Passive 45-second window captured export metadata and final success state. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E18-pdf-export-success-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E18-pdf-export-success.png) + +Inspection: `ev_118c18eba2941646b36112d2b6e12f437373ed07c68044e50c71e72356b31574` +Screenshot: `ev_5eef7462f875407f9108732f79bdfb3960fc3eddc647b8df0cfc7c4f94542b0f` + +- **Verified** — Manual Download observed successful GET /api/resumes/download with 200 application/pdf. No response body, query identifiers, cookies or raw headers retained. +- **Verified** — Final AX/screenshot shows Resume downloaded success popup with encouragement and return-to-editing action. User reports spinner popup then completed download; spinner pixels not captured. +- **Not Tested** — Actual local PDF contents, page size/count, font embedding, selectable text, output accessibility, retry/failure path and alternative export formats. + +![Checkpoint E18](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E18-pdf-export-success.png) + +### E19 — E19-editor-menu + +Manual action: User closed export success popup and opened top-right editor overflow. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E19-editor-menu-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E19-editor-menu.png) + +Inspection: `ev_66d2d5de5ab3f0312070cf2de2c422ba73ebef337a16e48d0c8efd0b4f313667` +Screenshot: `ev_9979db4473a8bfa16a324c3c64a5b99d6da90830af00532abe7ea717bdcb54ff` + +- **Verified** — Top-right editor overflow exposes two menuitems: Download via email and Get shareable link. No version/history/zoom control appears in this menu state. +- **Verified** — Unlike earlier custom dialogs, current AX snapshot is restricted to menu content with menuitem roles. No keyboard navigation test performed. +- **Not Tested** — Email delivery, publishing/sharing, link permissions, revocation and history/version availability elsewhere. Neither action was invoked. + +![Checkpoint E19](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E19-editor-menu.png) + +### E20 — E20-document-switcher + +Manual action: User opened Resume 1 dropdown beside Download. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E20-document-switcher-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E20-document-switcher.png) + +Inspection: `ev_6f7f6080bdc5fce13f013989611d56f4645dd0877b3a78325b6bb837d33aa291` +Screenshot: `ev_d15b868e07cbc9b34bc8f86ef42e381974c78011ee030ee52f3d9a05a04f020c` + +- **Verified** — Resume selector opens My Resumes popover listing Resume 1 with Switch to Resume 1, Duplicate, More actions and Add new resume controls. +- **Verified** — Duplicate and More actions controls are named in AX, unlike the editor top-level overflow. No revision or version selector appears in current popover. +- **Not Tested** — Switching between distinct documents, duplication result, per-document actions, creation limit and revision/history availability elsewhere. + +![Checkpoint E20](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E20-document-switcher.png) + +### E21 — E21-duplicate-limit + +Manual action: User clicked Duplicate beside Resume 1 and paused at the free-plan limit prompt. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E21-duplicate-limit-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E21-duplicate-limit.png) + +Inspection: `ev_7ed607de6ab1b76248336853400a6fcb6cff2d7cb00c118ff20307f5e000d225` +Screenshot: `ev_32ac3f25adddbadbf8c63df2c841bbd9df53d8e21d4f27c2db0bc98b0ce228bb` + +- **Verified** — Duplicate opens Need more than one resume? gate stating free plan includes one resume and upgrade is required to create another. No successful duplicate observed. +- **Verified** — Gate offers upgrade and close; no purchase or upgrade performed. +- **Not Tested** — Copy naming, independent editing, copied content/design ownership, version history and duplicate behavior on paid plan. + +![Checkpoint E21](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/E21-duplicate-limit.png) + +### M1 — M1-mobile-content + +Manual action: User opened Content and manually configured narrow responsive viewport, then scrolled top. REA observed 390x840. + +Viewport: 390×840. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M1-mobile-content-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M1-mobile-content.png) + +Inspection: `ev_40089fc5360494f28adfc53c69d0e8bf54aedffeeb1ded2c99915580a3fdb25d` +Screenshot: `ev_7fc958b068d40052e920a5dc355ebbca1b3348137237a0e0963db39d74297852` + +- **Verified** — At observed 390x840 viewport desktop split view becomes a single editing column. Top bar contains FlowCV logo and Menu; content cards remain full-width. +- **Verified** — Fixed bottom action bar exposes Preview and Add Content. Preview document text is absent from current AX snapshot; content editor remains available. +- **Verified** — Section order retains Skills above Education; synthetic new project remains in section inventory. Resume data survives the tested route and viewport transitions. +- **Not Tested** — Real phone input/touch, mobile keyboard, screen rotation, horizontal overflow measurements, focus containment, mobile form editing, preview zoom and responsive breakpoints between desktop/mobile. + +![Checkpoint M1](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M1-mobile-content.png) + +### M2 — M2-mobile-preview + +Manual action: User tapped Preview from mobile bottom action bar and left overlay open without zooming. + +Viewport: 390×840. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M2-mobile-preview-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M2-mobile-preview.png) + +Inspection: `ev_98bb54236c647e0a9f7d8c51857a81613aa8902cab2cfbb66fb4fe203b71ea4e` +Screenshot: `ev_4d506a3682f782dc59359f720672b16e58e134d7e6152e09664ba99155bae9e1` + +- **Verified** — Preview opens an overlay with document pages scaled to narrow viewport width and stacked vertically. Keep editing and Download remain fixed at bottom. +- **Verified** — Two page surfaces are visible, showing synthetic content and manual section order. No dedicated zoom or page-jump control is visible or named in current AX snapshot. +- **Verified** — Underlying content controls remain in AX with Preview reported focused; overlay has no dialog role in this capture. Keyboard/focus behavior needs direct testing. +- **Not Tested** — Pinch zoom, keyboard zoom, scroll-to-page behavior, background scroll lock, focus restoration, mobile export success and real-device viewport behavior. + +![Checkpoint M2](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M2-mobile-preview.png) + +### M3 — M3-mobile-experience-form + +Manual action: User returned from Preview and opened synthetic experience entry at mobile viewport. + +Viewport: 390×840. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M3-mobile-experience-form-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M3-mobile-experience-form.png) + +Inspection: `ev_7438eaa81dc1ab424351608a47c7a6c1a2c9ade0d32c48db170cc142e8c4b046` +Screenshot: `ev_3d6e4ffbab5ab9458fb2f81ce499a4703a3f208588f0f18f34b58c580ea68b80` + +- **Verified** — At 390x840, experience form stacks Job Title/Employer/Location/Description; Start Date and End Date remain side by side. Fixed bottom Preview and Done actions replace desktop Done card. +- **Verified** — Richtext alignment changes from four separate desktop alignment buttons to named Text alignment: left dropdown. Bold/Italic/Underline/Bullets/Link remain visible. +- **Verified** — Mobile top bar provides Content back navigation and Menu. Tips, hide and delete icons remain; date inputs still have identical MM/YYYY accessible names. +- **Not Tested** — On-screen keyboard occlusion, typing/autosave on real phone, date validation, touch target sizes, mobile richtext editing and focus behavior. + +![Checkpoint M3](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M3-mobile-experience-form.png) + +### M4 — M4-date-range-edge + +Manual action: User tried earlier end date via picker, reported earlier year unavailable, and selected Jan 2026 while start remained Feb 2026. No Done/submit performed. + +Viewport: 390×840. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M4-date-range-edge-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M4-date-range-edge.png) + +Inspection: `ev_c2d6c60adec181a44e436d3d4c0521c238accc04d5049ac960400a4c49ad742f` +Screenshot: `ev_8c9eaa781bb0f05893e036ef405584db4c7ffe9d99dea1e13cb417328682e978` + +- **Verified** — Captured form simultaneously displays Start Date 02/2026 and End Date 01/2026, with Done available, no visible error and both AX textbox invalid states false. +- **Verified** — Open end-date picker has Present (Current) unchecked, month selector including Jan-Dec/Remove month, and year option 2026/Remove year in captured AX. +- **Inferred** — Likely month-level date-range validation gap: picker appears to restrict year but permits end month before start in same year. User could not choose 2025; server-side validation and persistence of invalid range not tested. +- **Not Tested** — Done/submit behavior for invalid range, backend acceptance, direct typed values, current-date upper bound, year-only semantics, localization, validation after start-date change and exported invalid range. + +![Checkpoint M4](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/M4-date-range-edge.png) + +### L1 — L1-cover-letter-creation-gallery + +Manual action: User restored synthetic experience date per report, returned desktop width and opened cover-letters landing page. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L1-cover-letter-creation-gallery-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L1-cover-letter-creation-gallery.png) + +Inspection: `ev_c76aa58744f5010fa270ce4673894e5a7b2981fdd412b31b6ec87a100a99bb04` +Screenshot: `ev_07589c12580810ff1e5cbb99fa7b12f07afe655252b2846b501b626661d029df` + +- **Verified** — At /cover-letters with no user letters displayed, landing state is Create a cover letter with New blank tile and template gallery. Sidebar includes Resume, Cover Letter and Job Tracker. +- **Verified** — Filters All Templates/Simple/Modern/Creative appear as checkboxes; All Templates selected. At observed 1661x948, first row has New blank and two named template previews. +- **Verified** — Copy promises first cover letter free, all features and unlimited downloads. This verifies messaging, not paid-plan behavior or download limits. +- **Not Tested** — Blank/template creation, populated document card dashboard, letter limits, resume data reuse and matching design. + +![Checkpoint L1](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L1-cover-letter-creation-gallery.png) + +### L2 — L2-blank-cover-letter-editor + +Manual action: User clicked New blank in cover-letter gallery and left initial editor untouched. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L2-blank-cover-letter-editor-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L2-blank-cover-letter-editor.png) + +Inspection: `ev_7b253acb997286f8ba1a04264425b1d26c015e1070ee13ed3b757b464a7bddd8` +Screenshot: `ev_fffab0e75768770a9d081490745ff98b82f6e202096c12b0c132c0cc7837d1b3` + +- **Verified** — New blank creates Letter 1 and opens /cover-letter/write with desktop content/preview split and Overview, Content, Customize, letter selector and Download controls. +- **Verified** — Content cards: Sender details (Modern header), Date, Recipient details, Subject, Body, Signature. Cards have named Edit controls in AX. +- **Verified** — Initial date is 21st October 2026; sender/recipient/subject/body/signature show Not added. Preview includes date and default greeting/signoff placeholders. +- **Verified** — Existing resume contact data was not automatically populated into this initial blank letter state. No resume-data/design prompt observed after New blank. +- **Not Tested** — Explicit resume-data import, sender editing, body formatting, signature input, letter autosave, matching designs, export and mobile letter editing. + +![Checkpoint L2](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L2-blank-cover-letter-editor.png) + +### L3 — L3-letter-sender-form + +Manual action: User opened Sender details without entering personal information. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L3-letter-sender-form-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L3-letter-sender-form.png) + +Inspection: `ev_47716576389df49c1829c355fb0578cc38143c5a19d900adac3a3eb2f1d9cb84` +Screenshot: `ev_8748dbce582666081c7a1533ff34b839ab18f8dd56e284dd82bcb51c1467fdea` + +- **Verified** — Sender editor provides explicit Copy from resume button with accessible name Copy sender details from resume. +- **Verified** — Sender style radios Modern Header (selected) and Classic Sender; fields Full name, Professional title, Email, Phone, Location; photo affordance and reorder grips for contact details. +- **Verified** — Add details options include LinkedIn, Website, Nationality, Date of Birth, Visa, Passport or Id, Availability and Show More. Presence does not establish data validation or privacy defaults. +- **Not Tested** — Copy source selection, which fields copy, one-time copy versus live synchronization, sender style change, photo upload and reorder behavior. + +![Checkpoint L3](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L3-letter-sender-form.png) + +### L4 — L4-copy-sender-prompt + +Manual action: User clicked Copy from resume and paused at source-selection prompt. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L4-copy-sender-prompt-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L4-copy-sender-prompt.png) + +Inspection: `ev_3683e215fbaa8c2e81eb7a73a40b2bb8da64d31ca65ad7b83b0bc77b734dd947` +Screenshot: `ev_0bf571ddbe3214622a7ed8139bb29247aa08f96a880e03e5c9e1e038c576dc88` + +- **Verified** — Copy from resume opens source selector and explicit warning that current personal details and photo will be replaced. +- **Verified** — Resume dropdown initially Select resume; Copy sender details disabled until source chosen. Cancel action present. +- **Inferred** — Wording describes replacement/copy, suggesting snapshot semantics rather than live synchronization; actual cross-document update behavior remains untested. +- **Not Tested** — Source selection list, successful import, copied field completeness, overwrite behavior with populated sender and later resume edits. + +![Checkpoint L4](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L4-copy-sender-prompt.png) + +### L5 — L5-sender-copied + +Manual action: User selected synthetic Resume 1 and confirmed Copy sender details; populated sender form and preview observed. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L5-sender-copied-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L5-sender-copied.png) + +Inspection: `ev_4a2b3b2216ec89aec2fc4b216bd554f1610035b4b92d4ff8443ccc3dedeb15a9` +Screenshot: `ev_9d117446769749ec0ae92ae5d97638912d115f637770e4e4e60f0043f954bdd0` + +- **Verified** — Copying from synthetic Resume 1 populates name, professional title, email, phone, location and optional website/nationality/ID/LinkedIn/birth-date/visa/availability fields. Those details appear in letter preview. +- **Verified** — Modern Header remains selected and letter body stays blank with default greeting/signoff. Copy did not import experience or project paragraphs into body. +- **Inferred** — Copy imports optional personal fields broadly rather than only core contact fields; a design recommendation should make this scope clear before replacement. +- **Not Tested** — Photo copying, omitted-field removal, data synchronization after later edits, copy rollback, source provenance display and server persistence. + +![Checkpoint L5](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L5-sender-copied.png) + +### L6 — L6-letter-body-autosave + +Manual action: User clicked sender Done, opened Body, entered synthetic paragraph and paused without Done. + +Viewport: 1661×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L6-letter-body-autosave-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L6-letter-body-autosave.png) + +Inspection: `ev_2a9c8e18bcbd77d5eb97f207368c40c1b64038951afb273a43a09432df632c83` +Screenshot: `ev_062ceef0ba96b17ccccbf745be4c452387f75757569f0b345d8edcad43cdb7ff` + +- **Verified** — Body editor has Bold, Italic, Underline, Bulleted list, Insert link and four text alignment controls. Synthetic paragraph appears in editor and document preview before Done. +- **Verified** — 45-second window recorded two successful POST /api/letters/save_body requests, both 200 application/json. No content bodies, credential headers or query values retained. +- **Inferred** — Save requests while form remains open are consistent with automatic saving before Done. Exact debounce, duplicate-request cause, storage semantics and reload durability remain unknown. +- **Not Tested** — Richtext formatting effects, preview latency, request-error feedback, undo/redo for body content, grammar/AI assistance, signature image input and backend persistence after reload. +- **Verified** — Body richtext textbox has an empty accessible name. Screenshot and AX show paragraph in bold in editor and preview; direct toolbar action sequence was not observed. + +![Checkpoint L6](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L6-letter-body-autosave.png) + +### L7 — L7-letter-customize + +Manual action: User clicked body Done and opened letter Customize. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L7-letter-customize-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L7-letter-customize.png) + +Inspection: `ev_912473419851c3564a9414b838f5eb3d52241149470b321adc1342232ec2482c` +Screenshot: `ev_396b6686ad1e45a4d9741562fc459418785686be19a2bd12675ce5de6ffd2ddd` + +- **Verified** — Letter Customize at /cover-letter/design has Copy resume design and Browse templates, plus anchor navigation for document, templates, layout, header, photo, font size, spacing, font, colors, links and footer. +- **Verified** — Letter-specific controls include sender style, date/recipient drag reorder, position choices, declaration position/line and name emphasis; common typography/color/header/link/footer controls also appear. +- **Verified** — Current design shows Modern Header, Source Sans Pro body, name Same as body font, base 11pt, line height1.5 and 16mm margins. Letter remains alongside controls; synthetic body and copied sender retained. +- **Not Tested** — Copy resume design mapping/confirmation, letter template application, reordering letter blocks, photo/signature behavior, cover-letter undo/redo and matching export. + +![Checkpoint L7](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L7-letter-customize.png) + +### L8 — L8-copy-resume-design-prompt + +Manual action: User opened Copy resume design and selected Resume 1, pausing before Copy design. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L8-copy-resume-design-prompt-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L8-copy-resume-design-prompt.png) + +Inspection: `ev_0ba43afeea2f65bf7dcbaedb159283d7ff1f0cc893cfd4be2f0d5a4b5b4bfae6` +Screenshot: `ev_90aeda9eff89587946336fe0e96f7275c56c21ee94914b984fc15dcd858823c5` + +- **Verified** — Copy resume design opens source selector with explicit scope: matching colors, typography, spacing, layout, header and footer settings will be replaced. +- **Verified** — Selected synthetic Resume 1 is shown; Copy design enabled and Cancel available. Data import is separate from design import. +- **Not Tested** — Which settings map exactly, copied sender style, content preservation after apply, undo and continued synchronization. + +![Checkpoint L8](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L8-copy-resume-design-prompt.png) + +### L9 — L9-resume-design-copied + +Manual action: User confirmed Copy design from synthetic Resume 1 and left resulting letter Customize visible. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L9-resume-design-copied-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L9-resume-design-copied.png) + +Inspection: `ev_f5092d02be6d769ea918c76647452ad80345108afcfc11147a868cce1ad56861` +Screenshot: `ev_b416b97a00bfd64b5bbf0229c297c64f0ec1541e6a2d68cc471714c8c494e0e2` + +- **Verified** — Copy design closes dialog and updates letter preview/settings while retaining synthetic body and copied sender. +- **Verified** — Name/professional-title offsets change +8/+2 to +11/+5; margins change from16mm to22mm horizontal/12mm vertical. Link icon becomes checked. Base11pt, Source Sans Pro and centered Modern Header remain. +- **Verified** — Letter line-height now displays1.2, while captured resume line-height was1.15. This is a mapped compatible design, not demonstrated pixel-identical settings. +- **Inferred** — Line-height difference may be rounding, clamping or document-specific mapping; implementation unknown and not inferred from pixels alone. +- **Not Tested** — Live synchronization after resume changes, complete copied-setting equivalence, design-copy undo, export matching and letter-specific layout edge cases. + +![Checkpoint L9](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L9-resume-design-copied.png) + +### L10 — L10-letter-export-dashboard + +Manual action: User downloaded letter, dismissed any success popup and clicked Overview; 45-second passive window observed export and final dashboard. + +Viewport: 1912×948. [Selected DOM/AX and metadata](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L10-letter-export-dashboard-evidence.json) · [Screenshot](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L10-letter-export-dashboard.png) + +Inspection: `ev_6275d35f61b5ec2e8cde5c8672ef31ab14a27c4b0dff21c5836147cc5b83e2b1` +Screenshot: `ev_c9216ebbb5c6e39a5d2b9dba4407db97ac818d3bd00c2b1401e33e9482276d2c` + +- **Verified** — Letter Download returned200 application/pdf from GET /api/letters/download. User reports completed export; no PDF body or local file inspected. +- **Verified** — Overview opens populated My Cover Letters dashboard at /cover-letters with New letter tile, Letter1 thumbnail, relative edit time, A4 metadata and unnamed overflow button. +- **Verified** — Dashboard thumbnail and AX retain copied sender, edited synthetic paragraph and new design after returning from editor. +- **Not Tested** — Local PDF fidelity/accessibility, letter duplication/versions/overflow actions, letter mobile behavior, multiple-letter limit and live resume synchronization. + +![Checkpoint L10](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/L10-letter-export-dashboard.png) diff --git a/docs/cv-redesign/research/02-component-interaction-inventory.md b/docs/cv-redesign/research/02-component-interaction-inventory.md new file mode 100644 index 0000000..7553918 --- /dev/null +++ b/docs/cv-redesign/research/02-component-interaction-inventory.md @@ -0,0 +1,64 @@ +# Component and interaction inventory + +Research dates: 20–21 October 2026. FlowCV evidence is passive REA observation of the user-operated browser. Jobjakt evidence is source inspection at `b2a9fd68b081a8cc1701b1c58eaea7e1070274af`, branch `codex/ui-redesign-phase4`. No Jobjakt runtime checks were performed. + +**Verified** identifies observed UI or explicitly identified source behavior. **Inferred** identifies an interpretation. **Not Tested** is not a claim that a feature is missing. Screenshots and selected DOM/accessibility extracts are linked from [the audit](01-flowcv-audit.md). + +## FlowCV components + +| Component | Observed interaction and states | Evidence | Classification / limits | +|---|---|---|---| +| Dashboard navigation | Resume, Cover Letter, Job Tracker; active destination highlighted | D1, L1, L10 | Verified; destination behavior beyond research targets Not Tested | +| Document card | Page thumbnail, title, relative edited time, A4 metadata, overflow | D1, D2, L10 | Verified; thumbnail exposes document text through AX too | +| Resume card actions | Edit title, Duplicate, AI translate Beta, Download, Delete | D2 | Verified presence; only duplication was subsequently attempted | +| Creation surface | Large new-document tile; blank letter or gallery starting points | D1, L1–L2 | Letter blank creation Verified; resume creation occurred before capture | +| Editor navigation | Overview / Content / Customize / AI Tools; document switcher / Download / overflow | E1–E2, E19–E20 | Verified; letters use Content / Customize | +| Content outline | Collapsible typed sections, entry rows, Add Entry, Delete section, Add Content | E1, E5 | Verified presence; deletion not invoked | +| Section catalogue | Summary, Skills, Languages, Professional Experience, Education, Certificates, Awards, Courses, Projects, Interests, References, Declaration, Publications, Organisations, Custom | E1, E5 | Existing section headings Verified. Current chooser omitted Summary/Declaration; reason unknown | +| Add Content chooser | Icon/title/description tiles in modal; choosing Projects opens a new entry for existing section | E5–E7 | Verified transition; no general duplicate-section rule established | +| Experience form | Employer autocomplete, job title, location, month/year dates, link action, rich text, Tips, hide/delete icons | E2 | Verified presence; autocomplete and hide/delete effects Not Tested | +| Date picker | Present switch, month/year selectors, remove month/year choices | M4 | Verified; year restriction user-observed; same-year reversed month accepted into form | +| Rich text | Bold/italic/underline/bullets/link/alignment; AI shortcuts in resume form | E2, L6 | Controls Verified; bold letter paragraph appears in both editor and preview; not all formatting actions tested | +| Automatic saving | Entry PATCH and letter-body POST succeed while forms remain open before Done | E3, L6 | Network metadata Verified; autosave interpretation Inferred; no durability/race proof | +| Save feedback | User saw no feedback during sampled resume edits; final snapshots lack saving/saved text | E3, E7 | Verified bounded observation; transient indicators may have been missed | +| Section presentation | Job-title/employer order; group promotions | E4–E5 | Order change Verified; grouping effect Not Tested | +| Design navigation | Document, Templates, Layout, Font Size, Spacing, Entries, Headings, Font, Colors, Header, Photo, Links, Footer, Sections | E7 | Verified presence; most individual effects not tested | +| Gallery | Filter chips, named sample cards, large detail preview, separate Use this template action | E8–E10 | Verified; filter result behavior Not Tested | +| Template application | Changes bundle of layout, order, typography, spacing, margins and colors; observed content retained | E10 | Verified for one template and synthetic document | +| Undo/redo | Left arrow restores previous design; right arrow reapplies template; new project retained | E11–E12 | Verified for template operation; scope/depth/content history Not Tested | +| Layout ordering | Dotted grips, rows move aside, preview order follows drop | E12–E13 | Verified; keyboard instructions present, keyboard success Not Tested | +| Columns | One / Two / Mix; header position and column widths | E7, E12 | Verified controls; template application exercised one/two configurations, direct Mix behavior Not Tested | +| Typography | Base size and offsets; 10.5→11pt increment; font list with serif/sans/mono groups | E14–E16 | Increment Verified. Hover preview user-reported; temporary state not independently captured | +| Page preview | Desktop adjacent pages; narrow overlay stacks scaled pages; two page surfaces observed | E14, M2 | Verified; dedicated zoom not observed in inspected states; pinch/zoom Not Tested | +| AI tool hub | Translate, Improve, Draft Cover Letter, Generate Summary, grammar check | E16–E17 | Entry points and Pro gate Verified; input forms/results behind gate Not Tested | +| Export | Spinner reported; PDF response 200; resume success popup; letter PDF response 200 | E18, L10 | Verified metadata/user report; downloaded files not opened | +| Document switcher | My Resumes popover, Duplicate, More actions, Add Resume | E20–E21 | Verified; duplicate blocked by one-document plan limit | +| Versions | No revision selector seen in sampled menus | D2, E19–E21 | Not Tested overall; no absence claim | +| Mobile content | 390×840 single column; Menu header; fixed Preview/Add Content | M1 | Verified emulated viewport, not real-device acceptance | +| Mobile form | Paired dates, stacked fields, alignment dropdown, fixed Preview/Done | M3 | Verified; real keyboard/touch/rotation Not Tested | +| Letter anatomy | Sender, date, recipient, subject, body, signature cards | L2 | Verified; recipient/subject/signature forms not exercised | +| Sender reuse | Select resume, replacement warning, disabled-until-selected action, explicit copy | L3–L5 | Verified; live synchronization Not Tested | +| Design reuse | Separate resume source picker and replacement scope; compatible settings copied without losing letter text | L7–L9 | Verified; full setting identity and live linking not established | + +## Accessibility observations to retain in the proposal + +| Observation | Evidence | Status | +|---|---|---| +| Dashboard overflow and some editor/icon/increment buttons expose empty names | D1–D2, E2, E7, E14 | Verified snapshot finding | +| Both date inputs are named MM/YYYY despite different visible labels | E2, M3–M4 | Verified snapshot finding | +| Some custom modals expose an empty dialog name, and underlying controls remain in AX | E5, E8–E9 | Verified structure; focus containment Not Tested | +| Editor overflow exposes actual menuitem roles | E19 | Verified; avoid generalizing all menus as deficient | +| Drag instructions describe Space / arrows / Escape | E1, E7 | Verified affordance; keyboard behavior Not Tested | +| Drop announcement says position 3→3 despite observed changed order | E13 | Text Verified; misleading-announcement diagnosis Inferred | +| Letter body textbox has no accessible name | L6 | Verified snapshot finding | + +## Interaction rules worth considering for Jobjakt + +1. Keep editing and document output adjacent where space permits; offer a deliberate preview mode on narrow screens. +2. Separate browsing a design from committing it; preserve content and offer reversible application. +3. Keep content-copy and design-copy operations distinct, with clear replacement scope. +4. Reflect reorder results in both outline and document; provide a visible keyboard alternative and accurate announcements. +5. Make successful saves and failed saves legible. Successful HTTP responses alone are not sufficient user feedback. +6. Keep job, document and source-profile ownership explicit. Jobjakt already has stronger application context than the observed standalone FlowCV workflow. + +These are design recommendations, not findings that Jobjakt lacks the corresponding capability. diff --git a/docs/cv-redesign/research/03-jobjakt-gap-analysis.md b/docs/cv-redesign/research/03-jobjakt-gap-analysis.md new file mode 100644 index 0000000..b16b4b3 --- /dev/null +++ b/docs/cv-redesign/research/03-jobjakt-gap-analysis.md @@ -0,0 +1,92 @@ +# 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. diff --git a/docs/cv-redesign/research/04-jobjakt-design-proposal.md b/docs/cv-redesign/research/04-jobjakt-design-proposal.md new file mode 100644 index 0000000..f48e91e --- /dev/null +++ b/docs/cv-redesign/research/04-jobjakt-design-proposal.md @@ -0,0 +1,75 @@ +# Jobjakt design proposal: prepare an application with confidence + +**Status: proposed design — Not Tested.** This is an original proposal grounded in [observed interaction patterns](01-flowcv-audit.md) and [verified Jobjakt source](03-jobjakt-gap-analysis.md). It is not an implemented feature or an imitation of FlowCV's templates. + +## Product direction + +Make the document editor answer three questions throughout the task: “Which application is this for?”, “What have I changed?”, and “Is this the version I can safely export?” Jobjakt's advantage is the relationship between career facts, a tailored CV, the application letter and the application record. Build around that relationship rather than creating another isolated document studio. + +Preserve the existing CV editor, routes, MUI components, renderers, revision contracts and application workspace. Improve the journey in small increments. Existing CV autosave, undo/redo, preview recovery, AI review and history should remain the foundation, not be rebuilt. + +| Approach considered | Benefit | Cost / risk | Decision | +|---|---|---|---| +| Extend existing CV and application document surfaces | Reuses mature saving, rendering, ownership, localisation and tests; keeps application context | Requires a careful letter contract and some shared visual treatment | **Recommended** | +| Replace both with a new universal document engine | Uniform editor surface | Large migration, duplicate models, loss of working safeguards, no measured need | Defer | +| Only polish CV controls | Fast, low risk | Leaves cover letters without a complete designed-document workflow | Useful first phase, insufficient final scope | + +## Information architecture + +Keep the CV library at `/career/builder`, the editor at `/career/builder/:id`, and the application-scoped cover letter in the current application workspace. The Documents page remains the cross-application index. Avoid a new standalone letter library until users demonstrate a need for letters unrelated to applications. + +CV library cards should prioritise document name, linked application when available, theme label and saved status/date. A schematic thumbnail can remain the lightweight list representation; a clearly labelled “Preview design” opens an actual rendered candidate. Open, Duplicate, PDF and existing publication actions use the current handlers. Icon-only actions have document-specific accessible names. Do not introduce “version” as a synonym for a duplicated document. + +In the application workspace, present CV and Cover letter as a coordinated document pair. Show the attached CV name, a link to edit it, and the letter's own save state. Preserve existing attachment and submitted-package controls. A package captured in Jobjakt is labelled “Recorded application package”; it must not imply the application was actually sent. + +## CV editing + +Keep Content, Template, Customize, AI Tools and History. Separate frequent controls from advanced controls using the existing capability metadata. Content starts with the outline and a short explanation: “Uses your career profile. Changes here apply to this CV.” Each overridden entry shows “Edited for this CV” with the existing reset-to-source action. Editing master facts remains an explicit navigation action, protected by the existing unsaved-change guard. + +Section rows expose title, visibility, entry count, drag handle and named Move up/down actions. Dragging is an enhancement. Up/down controls remain usable with keyboard and touch, including at the first/last item. Announce the actual new position and restore focus to the moved row. Preserve stable source keys and custom entries; do not derive identity from display order or translated labels. + +Existing typed content and custom presets remain the catalogue. Add-content choices explain the resulting object: “Add a project entry” versus “Add a custom section”. Reuse existing presets rather than creating 15 new backend tables for FlowCV's observed headings. Validate dates according to Jobjakt's actual source model; month precision must be compared as year/month, with explicit semantics for year-only values and Current. + +The preview shows physical pages, page count, fit percentage and last render status. While a new preview is pending, keep the previous document and identify it as updating. On failure retain the last good output and provide Retry. Do not display “Saved” solely because a preview succeeded. A manual zoom control is a later usability decision: first verify that current fit-to-width plus browser zoom supports real users. No custom pinch handler in the initial scope. + +## Template selection and design + +Use Jobjakt's current themes and metadata. Selecting a gallery card opens a candidate preview with the actual template renderer; switching candidates does not persist a change. Initial implementation may use the existing synthetic sample-preview endpoint, explicitly labelled “Sample content”. Previewing the user's current unsaved CV is a separate extension only if the current endpoint contract cannot support it safely. + +The candidate view explains supported controls and which visual overrides will reset. “Apply design” performs the existing visual-only settings update and creates one undo step. Content ordering, hidden entries, custom content and overrides must remain intact according to the current apply-theme contract. Cancel closes without dirtying the CV. Locked designs use existing availability rules, not a new billing mechanism. + +Customize keeps the current options with their null/inherit semantics. Use existing font choices and renderer-safe values; avoid a new font catalogue or font upload. Show units next to numbers, errors next to invalid fields, and “Use theme default” where supported. Do not silently reset unsupported values that the existing editor deliberately retains. + +## Save, history and export + +Preserve the CV save state machine: dirty → saving → saved; recoverable failure → retry; revision conflict → stop automatic writes and offer recovery. Keep status text next to the document title. A conflict message explains that another edit was saved and offers existing download/reload recovery. Export waits for the current draft's successful save; a failure cannot fall back to exporting an older revision without an explicit, accurately labelled choice. + +History copy distinguishes **CV settings revision** from a frozen document. Historical settings currently resolve against the current career profile. Tell users this before restoring; do not market settings history as a full historical CV snapshot. The submitted application package is a separate recorded artifact. A full frozen-document history is outside this plan unless explicitly chosen later. + +Letter editing keeps the existing **Save / Discard** contract initially. FlowCV's sampled absence of visible saving feedback is a reason to retain Jobjakt's clear state, not to remove it. Any later autosave decision depends on resolving all letter writers and revision conflicts first. + +## Cover letter: complete the document workflow + +Use two clear modes within the existing letter area: Write and Preview. Write retains the labelled Markdown text field and existing toolbar. Show a small formatting hint and rendered preview so users understand the input. Avoid a rich-text dependency in the first release; visual preview is more valuable than replacing the underlying editing model. + +Add a compact document-details region only as part of the approved letter schema: sender, recipient/company, date and subject. Initial values are explicit local drafts. “Copy contact details” opens a field-selection review and copies only approved fields. Default selection is name, professional title, email and phone; location and links are optional. Birth date, nationality, passport/ID, visa and unrelated profile details are never copied by default. Each copy is a snapshot; later profile edits do not silently overwrite the letter. + +“Match attached CV” maps compatible typography, colours, page size, margins and header treatment to a letter design snapshot. It does not copy CV columns or skill layout into a prose letter. Show what will change, preserve all letter text and recipient data, and allow cancellation. Store effective compatible values so a later CV theme change does not silently restyle the letter. Retain an optional source CV identifier for explanation; rendering must not depend on that CV continuing to exist. + +Letter preview and PDF must use the same safe renderer and pagination contract, with an independently testable letter render model. Reuse the CV export infrastructure only where its contract fits; do not pass letter text through a CV variant or the separate tailored-CV draft model. Letter export saves the intended draft, then exports that revision. Existing CSV/JSON/backup exports remain data exports and continue to include letter content/history. + +## AI interaction + +Keep Jobjakt's existing consent, plan, metering and explicit review flow. A suggestion appears beside the current draft with Apply / Reject. Applying changes the draft; the current letter Save action still determines persistence. Cancel, failure, navigation and a changed application must not apply stale suggestions. Never describe AI-generated text as verified career facts. Avoid inventing FlowCV AI input/result behaviour: only its entry points and Pro gate were observed. + +## Visual direction + +Use the verified current `job-tracker-ui/src/theme.ts`: Archivo UI typography, existing MUI spacing and semantic tokens; primary accent `#5B5BD6`, existing indigo/cyan gradient, inverse navigation `#0F172A`. Dark surfaces currently use `#0B0B0E`, `#111116` and `#1C1C24`. Use theme roles so light/dark mode continue to work. Do not hard-code older homepage tokens into the editor. + +Create hierarchy through grouping, concise labels and stable controls. White physical document pages stay independent of application chrome. Use colour for selection/status with text and icons, never colour alone. Avoid FlowCV's branding, template geometry, proprietary assets, promotional copy and gallery illustrations. Existing Jobjakt themes are the design source; new templates require separate original design work and export checks. + +## Completion boundary + +The proposed outcome is a more understandable existing CV editor plus a safe application-scoped letter preview, matching design and PDF workflow. New standalone letter accounts, collaborative editing, unrestricted font upload, manual page-break designers, multi-format DOCX output, new AI providers and a universal document platform are deferred. None is required to deliver this scope. + +See [wireframe specifications](05-desktop-mobile-wireframes.md), [implementation sequence](06-phased-implementation-plan.md) and [acceptance tests](07-acceptance-and-test-plan.md). Every proposal here remains **Not Tested** until implementation and validation. diff --git a/docs/cv-redesign/research/05-desktop-mobile-wireframes.md b/docs/cv-redesign/research/05-desktop-mobile-wireframes.md new file mode 100644 index 0000000..ce6266b --- /dev/null +++ b/docs/cv-redesign/research/05-desktop-mobile-wireframes.md @@ -0,0 +1,142 @@ +# Desktop and mobile wireframe specifications + +**Status: proposed, Not Tested.** These are implementable layout and interaction specifications, not screenshots of Jobjakt. They preserve the existing routes and current 900px editor breakpoint. Measurements below are starting constraints for review, not claims about current rendered geometry. + +## D-A: desktop CV editor, 1440 × 900 + +```text +┌────────── existing application navigation ────────────────────────────────┐ +│ Career / CVs › Application CV Saved PDF More │ +│ For: [role · company] / General CV Uses current career profile │ +├──────────────────────────────────────┬───────────────────────────────────┤ +│ Content Template Customize AI History│ Preview 2 pages · Fit 72% │ +│ │ │ +│ SECTION OUTLINE │ ┌───────────────────┐ │ +│ Summary Visible │ │ │ │ +│ Experience · 3 entries ↑ ↓ ⋮ │ │ Physical page 1 │ │ +│ Test engineer │ │ │ │ +│ Edited for this CV Reset │ └───────────────────┘ │ +│ Skills ↑ ↓ ⋮ │ │ +│ + Add content │ ┌───────────────────┐ │ +│ │ │ Physical page 2 │ │ +└──────────────────────────────────────┴────────┴───────────────────┴──────┘ +``` + +Keep the current application shell. Within remaining editor width, target an edit pane of 420–520px where space permits, a 16–24px gutter and a flexible preview pane. At 900–1100px prioritise a usable form over a large page image; do not force the 1440px dimensions. Each pane scrolls as the existing editor allows; title/status/actions and preview heading remain findable. Page scale is fit-to-available-width, never a change to actual page dimensions. + +The context line uses existing linked-job data. A general variant says “General CV”; no fabricated company. Clicking the source profile link uses the existing navigation guard. Status reserves a stable width for Saved, Saving, Unsaved and Save failed. Conflict/recovery expands a message below the header without replacing the draft. PDF remains named and reachable when tabs scroll. + +Content rows have 44px minimum practical touch target areas, visible focus and named move controls. Only the row handle starts drag. Visibility and delete remain separate actions. Remove/hide wording follows actual data ownership. Section detail shows source entry versus local override; reset explains what content it replaces. + +## D-B: template candidate view + +```text +┌ Choose a design Close ┐ +│ [ATS filter] [All available] Selected: current design │ +├─────────────────┬───────────────────────────────────────────┤ +│ Theme cards │ Candidate name · category · availability │ +│ [existing A] │ ┌─────────────────────────────────────┐ │ +│ [existing B] │ │ Actual rendered sample / candidate │ │ +│ [existing C] │ └─────────────────────────────────────┘ │ +│ │ Sample content • visual overrides reset │ +│ │ Content edits are preserved │ +├─────────────────┴───────────────────────────────┬───────────┤ +│ Cancel │ Apply │ +└────────────────────────────────────────────────┴───────────┘ +``` + +Use an existing MUI Dialog with a labelled title, normal focus trap and return focus to the invoking card. Selection changes only candidate state. Loading uses a contained progress message; failure offers Retry and leaves Cancel reachable. Explicitly distinguish synthetic sample from the user's live content. Locked candidate exposes the existing plan explanation and cannot be applied. Apply is disabled during the single mutation. One successful application creates one undo step. + +## D-C: application cover letter + +```text +┌ Application: role · company ────────────────────────────────────────────┐ +│ Attached CV: [CV name] [Open] Cover letter v3 · Unsaved │ +│ Write Preview Save Discard PDF History │ +├─────────────────────────────────┬───────────────────────────────────────┤ +│ DOCUMENT DETAILS │ Preview · Updating / Current │ +│ [Copy contact details] │ ┌────────────────────────┐ │ +│ Sender / recipient / date │ │ Sender │ │ +│ Subject │ │ Date · Recipient │ │ +│ [Match attached CV] │ │ Subject │ │ +│ │ │ │ │ +│ LETTER │ │ Dear … │ │ +│ [Markdown toolbar] │ │ Paragraphs … │ │ +│ [labelled multiline field] │ │ Sign-off │ │ +│ AI: action/tone/language │ └────────────────────────┘ │ +│ [Review suggestion] │ │ +└─────────────────────────────────┴───────────────────────────────────────┘ +``` + +This remains inside the current application workspace. Do not introduce another top-level navigation system. The exact document-details fields are introduced only with their versioned persistence contract. Before that phase, provide body-only preview, explicit Save and current history using existing data. “Match” is disabled with an explanation if no CV is attached; offer the current attach action. + +AI review occupies an existing comparison region and does not obscure Save state. Source and proposed text are labelled. Apply changes the local draft; no success message claims persistence before Save. History names source/time/version and previews before restoration. Restore creates a new version, preserving history. + +Copy-contact dialog lists selectable fields, default core contact scope and overwrite warning. Design dialog lists compatible settings and source CV. Both provide Cancel and an explicit final action; neither changes data on opening. After success, focus returns to the invoking button and a concise status announces the draft change. + +## M-A: mobile CV content, 390 × 844; must also work at 320px + +```text +┌ Back CV name More ┐ +│ Saved / Saving / Save failed │ +│ Application context │ +│ Content Template Customize AI … │ +├────────────────────────────────────┤ +│ Summary Edit │ +│ Experience · 3 Edit │ +│ [grip] Skills ↑ ↓ Visible │ +│ Education │ +│ + Add content │ +│ │ +├────────────────────────────────────┤ +│ Edit Preview │ +└────────────── safe area ────────────┘ +``` + +Below 900px use the existing Edit/Preview mode rather than mounting an inaccessible duplicate editor behind a simulated modal. Preserve the selected tab, expanded section, scroll position and draft when switching modes. Expose the mode group with programmatic selection state. Inactive pane is hidden from focus and accessibility navigation. Announce current mode briefly, without reading the document on every change. + +Header title may truncate visually but has its full accessible name. The status line wraps rather than disappearing into overflow. Secondary actions move into a named More menu; history remains discoverable. Bottom controls include safe-area padding and do not cover the final form field. Browser text zoom to 200% can switch to a more compact arrangement without horizontal application overflow. + +## M-B: mobile entry form and preview + +Entry edit is a single column. Dates may share a row only while labels and month/year fields fit; stack at 320px or large text. Use distinct accessible labels “Start date” and “End date”, with format help described separately. Errors are adjacent, persistent and associated with the input. Focus the first invalid field only on attempted submit, not during ordinary typing. + +The keyboard must not cover active text or primary actions. Avoid relying solely on a fixed viewport height; test the existing scrolling layout with the real on-screen keyboard and safe areas. Reorder works with Move up/down on touch without dragging. A draft remains intact when entering preview and returning. + +Preview fills available width with scaled physical page surfaces, visible page count and render status. The standard Edit/Preview control returns to editing. PDF is available from a named action. Fit changes visual scale only. Preserve browser pinch/text-zoom functionality; do not claim custom gesture support. Long pages scroll vertically and last-good output remains available after a failed refresh. + +## M-C: mobile cover letter + +```text +┌ Back Letter · role/company More ┐ +│ Unsaved changes │ +│ Write Preview │ +│ CV: [attached CV] │ +├───────────────────────────────────┤ +│ Document details ▾ │ +│ Letter text │ +│ [format toolbar, wraps] │ +│ [multiline input] │ +│ AI suggestion / review │ +├───────────────────────────────────┤ +│ Discard Save │ +└───────────────────────────────────┘ +``` + +Keep explicit Save/Discard until concurrency prerequisites are met. PDF and History may be in More when space is constrained, but are available in both modes. Save failure remains visible after scrolling; tapping Retry cannot generate concurrent submissions. Dirty navigation invokes the existing guard. A valid retry preserves text, formatting and document details. + +## State, accessibility and localisation specification + +| State | Visual response | Accessibility / focus | Persistence rule | +|---|---|---|---| +| Loading | Skeleton plus descriptive progress | Busy region; no repeated announcements | No blank draft writes | +| Empty | Clear starter action, no fake content | Named CTA and heading | Starter inserts into local draft only | +| Dirty | Unsaved status; letter Save enabled | Polite status once, not per keystroke | Draft retained until save/discard | +| Saving | Progress with stable button layout | Busy/disabled duplicate submit | Serialize mutations | +| Save failed | Inline explanation, Retry/recovery | Alert on transition; draft stays focused | No automatic destructive reload | +| Conflict | Specific conflict and recovery actions | Focusable recovery; no forced loss | Stop auto writes, never blind retry | +| Preview updating/failed | Last-good page labelled accordingly | Status associated with preview | Preview failure never marks save failed or saved | +| Exporting | Named progress, prevent duplicate export | Keep current context | Export intended saved revision only | +| Restoring | Preview/warning then new revision | Confirm dialog focus lifecycle | Existing historical records retained | + +Use existing English/Bokmål locale provider and translation keys. New labels, errors, ARIA names and date examples require both locales. Respect document language independently of interface language where the current model supports it. Test long Norwegian words, æ/ø/å, long URLs, large contact blocks and empty sections. Every proposed state above is **Not Tested** until validated against the implementation. diff --git a/docs/cv-redesign/research/06-phased-implementation-plan.md b/docs/cv-redesign/research/06-phased-implementation-plan.md new file mode 100644 index 0000000..6f776fe --- /dev/null +++ b/docs/cv-redesign/research/06-phased-implementation-plan.md @@ -0,0 +1,180 @@ +# Jobjakt application documents Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. Execution method is subject to the user's later choice; this document authorises no implementation. + +**Goal:** Improve the existing CV workflow and complete an application-scoped cover-letter preview, design-matching and PDF workflow without weakening recovery or ownership. + +**Architecture:** Extend existing React/MUI editors and .NET services. Keep CV variants as lenses over career data; keep letters attached to applications. Share established rendering, pagination and export infrastructure where the contracts fit, while giving letters their own render model and complete revision coverage. + +**Tech Stack:** Existing React, TypeScript, MUI, React Router, Axios, C#/.NET 9, EF Core, Playwright/Chromium, Jest/Testing Library and existing i18n. No new package is proposed initially. + +**Spec:** [Design proposal](04-jobjakt-design-proposal.md), [wireframes](05-desktop-mobile-wireframes.md), [source constraints](03-jobjakt-gap-analysis.md), [acceptance criteria](07-acceptance-and-test-plan.md). + +## Global constraints + +- Research only until explicit user approval. No commands below have been run as implementation or verification. +- Preserve `/career/builder`, `/career/builder/:id`, current application routes, MUI/theme, Archivo and English/Bokmål localisation. +- Keep the existing 900px edit/preview breakpoint initially; verify 320, 390, 768, 899, 900, 1024 and 1440px layouts. +- Preserve current owner scoping, plan checks, AI consent/review, HTML escaping, link restrictions and PDF resource limits. +- Preserve CV save-before-export, expected-version conflicts, last-good preview and settings-only history semantics. +- Letter Save/Discard remains explicit. Do not add autosave as a side effect of adding preview. +- No FlowCV code, templates, graphics, branding or proprietary assets may be reused. +- All repository paths below are relative to `E:/Storage/Projects/Active/Job tracker`. Newly proposed files are identified explicitly. No existing migrations are rewritten. +- Approval of a future implementation does not authorise destructive or production migrations/deployment. + +## Review focus + +1. A late template response must not replace the currently selected candidate: Phase 1 task 2 stale-request test. +2. A stale writer on any letter endpoint must not overwrite a newer letter: Phase 2 task 3 cross-endpoint concurrency tests. +3. A new draft must not export an old saved document after save failure: Phase 3 task 5 held-save/export tests. +4. Removing or changing the attached CV must not alter an already saved letter design: Phase 3 task 4 snapshot test. +5. A restored CV settings revision must not be presented as a frozen historic profile: Phase 1 task 1 history-copy test and Phase 4 package checks. + +## File and dependency map + +| Responsibility | Existing files to extend | New files only when phase needs them | +|---|---|---| +| CV hierarchy, provenance, save/history wording | `job-tracker-ui/src/views/CvBuilderEditor.tsx`, `src/i18n/translations.ts` | None | +| Template candidate preview | `src/components/CvTemplateGallery.tsx`, `src/cvBuilder.ts`, editor | `src/components/cv/CvTemplatePreviewDialog.tsx` | +| Letter text/revision contract and all writers | `JobTrackerApi/Models/JobApplication.cs`, `Models/CoverLetterVersion.cs`, `Services/ApplicationAssetsService.cs`, `Controllers/ApplicationAssetsController.cs`, `Controllers/JobApplicationsController.cs`, `Controllers/JobApplicationDtos.cs`, `Data/JobTrackerContext.cs`; frontend `src/applicationWorkspace.ts`, `src/components/ApplicationAssets.tsx` and all actual create/update callers | Additive migration created only after schema design approval | +| Letter rendering and design snapshot | Existing CV safe-rendering/normalisation and export infrastructure; existing letter controller/service | `JobTrackerApi/Models/CoverLetterDocumentSettings.cs`, `Services/CoverLetterRenderer.cs`; frontend `src/components/CoverLetterPreview.tsx` | +| Saved letter PDF | `ApplicationAssetsController.cs`, `ApplicationAssetsService.cs`, existing PDF admission/export registration in `Program.cs` | Small letter export adapter only if existing exporter cannot accept rendered HTML cleanly | +| Frozen package and data exports | `Services/SubmittedApplicationPackageService.cs`, `Models/SubmittedApplicationPackage.cs`, `Services/AccountDataExportService.cs`, `Controllers/BackupController.cs`, `Controllers/ExportController.cs`, documents listing | Additive package artifact schema only when needed | +| Coverage | Existing CV and application-assets unit/E2E suites | Focused letter render/concurrency/PDF tests, not a parallel test framework | + +Paths abbreviated as `src/...` in this table belong to `job-tracker-ui`. No cross-cutting editor refactor is required before these phases. + +## Phase 1 — improve the CV workflow without a schema change + +### Task 1: clarify scope, history and mobile actions + +**Modify:** `job-tracker-ui/src/views/CvBuilderEditor.tsx`, `src/i18n/translations.ts`; library view only where card labelling needs adjustment. **Tests:** existing `src/cv-builder-page.test.tsx`, `e2e/cv-editor-frame.spec.ts`, `e2e/cv-responsive-workflow.spec.ts`. + +**Interfaces:** Consume current variant/job metadata and existing save/undo/history handlers. Produce labels and navigation only; do not change CV DTOs or persistence. + +- [ ] Add a failing assertion that restoring settings history is described as using the current career profile; assert new EN/NB labels and named overflow actions. +- [ ] Run the focused unit file and confirm the new assertion fails for the missing behaviour, not setup failure. +- [ ] Add context/provenance wording, keep existing retry/conflict controls and move controls reachable at mobile widths. Use existing handlers and semantic tokens. +- [ ] Run focused tests; extend responsive workflow for inactive-pane focus exclusion, move-up/down focus retention and dirty mode switching. Confirm source facts remain unchanged. +- [ ] Review and commit only the scoped change after the focused checks pass. + +**Exit:** clearer document ownership, correct history semantics and accessible actions; no new backend contract. Covers AC-01, 03, 04, 11, 12. + +### Task 2: render a candidate before applying a theme + +**Modify:** `job-tracker-ui/src/components/CvTemplateGallery.tsx`, `src/views/CvBuilderEditor.tsx`, `src/i18n/translations.ts`. **Create:** `src/components/cv/CvTemplatePreviewDialog.tsx` and a focused test. **Reuse:** `cvBuilderApi.themePreview(themeId: string): Promise` and `applyCvTheme(settings, themeId)` in `src/cvBuilder.ts`. + +**Proposed component interface:** `CvTemplatePreviewDialog({theme, open, onClose, onApply})`, where `theme: CvTheme | null`, `open: boolean`, `onClose: () => void`, `onApply: (themeId: string) => void`. Consume existing API/render DTO; do not invent a new template payload. + +- [ ] Add tests named `candidateSelectionDoesNotSave`, `cancelPreservesDraft`, `lateCandidateResponseIsIgnored`, `applyIsOneUndoStep` and `lockedCandidateCannotApply`; assert actual request/write counts. +- [ ] Run the focused tests and confirm the new behaviours fail before implementation. +- [ ] Implement the dialog using the existing sample-preview API, with a visible Sample content label, loading/error/retry, focus trap/return, and explicit Apply. Reuse established preview readiness logic where its sample contract fits. +- [ ] Preserve current visual-reset confirmation, capability filtering, availability rules and content metadata. Apply via the editor's normal settings update, not a second persistence path. +- [ ] Run template gallery, document controls and editor tests. Exercise EN/NB, desktop/mobile, preview failure and late response. Commit the independently usable candidate-preview feature. + +**Exit:** accurate sample preview before a reversible theme application. Covers AC-02, 05, 11. Depends on no schema or new dependency. + +## Phase 2 — make all letter writes revision-safe + +### Task 3: close the shared persistence gap before persistent design + +**Modify:** the letter model/service/controller/DTO files in the map; all frontend callers of generic job create/update and application draft updates. **Tests:** `JobTrackerApi.Tests/ApplicationAssetsTests.cs`, new `CoverLetterConcurrencyTests.cs`, frontend `src/application-assets.test.tsx`, current job update tests. **Schema:** additive current-letter revision plus per-version snapshot fields only as required; no changes are authorised now. + +**Proposed contract:** extend `CoverLetterDto` with `revision: number` (server `Revision: int`). Dedicated save and restore accept `expectedRevision: number`; successful content change returns the new revision and creates one history record. No-op content saves do not advance it. Use a dedicated EF concurrency token on the application letter revision so unrelated job edits are not needlessly conflicted. + +**All-writer policy:** + +| Writer | Required handling | +|---|---| +| Job create | Initial nonblank text gets initial revision/history in the same transaction as job creation; blank remains empty | +| Dedicated letter save and restore | Require expected revision; missing → 428, stale → 409; restore appends rather than rewinds | +| Generic job update | Preserve existing null-clears behaviour. Any request that changes the letter must carry expected letter revision | +| Application draft update | Preserve null-leaves-unchanged and whitespace-clears behaviour; require revision when a mutation is requested | +| AI generate/improve | Continue returning proposals; no direct letter mutation until explicit Apply and Save | + +Legacy clients that attempt letter mutations without the revision receive 428 with a stable error code. Generic updates that do not change letter content continue to work. Audit serialized full-job clients so stale copies do not unintentionally request changes; update them to carry the correct revision or omit letter mutation through an explicit DTO contract. Do not silently convert clear into unchanged. + +- [ ] Find every `CoverLetterText` assignment and every call to save/restore across controllers, services, fixtures, import/restore flows and clients. Capture the inventory in implementation review; include backup/import semantics explicitly. +- [ ] Write failing tests: dedicated-vs-generic concurrent writes; generic-vs-draft; save-vs-restore; unchanged job update; null/whitespace semantics; foreign owner; failed transaction; no-op save. Use two independent database contexts and the supported relational provider, not only EF InMemory. +- [ ] Confirm the new tests fail on the unprotected behaviour before implementation. +- [ ] Centralise revision validation and history staging in `ApplicationAssetsService` using the existing DbContext and a single transaction for job and letter changes. Existing controller calls must not save the letter independently before a later job update can fail. Map EF concurrency conflicts consistently to 409. +- [ ] Add an additive migration after inspecting existing schema and version duplicates read-only. Seed revision from existing history/current text deterministically. Preserve every historic row. A duplicate-history preflight blocks uniqueness changes; it never deletes records automatically. +- [ ] Update all mutation DTOs, frontend API callers, mock responses, fixtures and recovery UI in the same contract change. Hold migration execution and production rollout for their own approved step. Document old-client 428 compatibility and rollout order. +- [ ] Run the focused .NET and frontend tests. Prove lost-update prevention on the supported relational database. Commit the contract and its migration source together once review is complete. + +**Exit:** every normal letter writer participates in a consistent revision/history boundary. This phase is valuable without letter design. Covers AC-06, 07, 09. Phase 3 persistence depends on this gate; do not bypass it with UI-only version checking. + +## Phase 3 — letter presentation, matching and export + +### Task 4: persist explicit document details and a compatible design snapshot + +**Create:** `JobTrackerApi/Models/CoverLetterDocumentSettings.cs`, `Services/CoverLetterRenderer.cs`; frontend `src/components/CoverLetterPreview.tsx`. **Modify:** letter current/version models and DTOs, `ApplicationAssetsService`, controller, `src/applicationWorkspace.ts`, `src/components/ApplicationAssets.tsx`, translations. **Tests:** new `JobTrackerApi.Tests/CoverLetterRenderingTests.cs`, existing assets tests plus focused preview tests. + +**Proposed settings DTO:** versioned JSON with `schemaVersion: 1`; explicit sender/recipient/date/subject fields; design values for page size, permitted fonts, base font size, line height, margins, accent/text colours and compatible header style. Represent copied contact/design as snapshots with optional source CV id. Do not embed arbitrary CSS, raw HTML, remote font URLs or CV column definitions. Reuse current renderer allowlists and numeric clamps; define the compatible subset in this model and test every field. Do not invent broader numeric ranges than existing validated settings. + +**Proposed renderer contract:** `CoverLetterRenderer.Render(string? text, CoverLetterDocumentSettings settings, string language) -> string` safe complete document HTML. Preview consumes unsaved draft text/settings without persisting. The saved letter DTO and every history snapshot carry both text and settings. Text-only old versions resolve to documented defaults. A change to either text or settings advances the shared revision once. + +- [ ] Write failing tests for script/link/CSS injection, supported Markdown, long Norwegian prose, empty text, old text-only versions, settings normalisation and two-page output readiness. +- [ ] Add contact-copy tests asserting only approved core fields are selected by default; optional identity fields are excluded; copy cancellation leaves the draft unchanged. +- [ ] Add design-match tests asserting compatible values are snapshotted, body/recipient preserved, and later CV edits/deletion cannot change saved letter presentation. +- [ ] Implement safe letter HTML with existing escaping/Markdown semantics and established page metrics. Share only proven helpers; no universal document engine or new WYSIWYG library. +- [ ] Extend the explicit Save DTO from Phase 2 to atomically persist text/settings/revision. Update history restore and account/export/backup serializers so presentation is not lost on restore or recovery. Missing legacy settings produce defaults, not failure. +- [ ] Add the responsive preview and two copy-review dialogs inside the existing application letter component. Preserve Save/Discard, route protection, last-good preview and stale-request suppression. Do not mount duplicate active editors at mobile widths. +- [ ] Run focused tests and the mobile letter workflow with a held request, a failed preview and a changed application. Commit after both contract and interaction checks pass. + +**Exit:** safe local preview, explicit core-contact copy, compatible design matching and restorable letter presentation. Covers AC-07, 08, 10–13. Depends on Phase 2 for persistence. A body-only preview can be released earlier using existing data, but must not masquerade as saved document design. + +### Task 5: export the intended saved letter revision + +**Modify:** `ApplicationAssetsController.cs`, letter service/renderer, PDF exporter integration and `Program.cs` registration as needed; frontend `applicationWorkspace.ts` and `ApplicationAssets.tsx`. **Test:** focused letter export tests and new `job-tracker-ui/e2e/cover-letter-document.spec.ts`. + +**Proposed routes:** `POST /api/jobapplications/{jobId}/cover-letter/preview` for owner-scoped unsaved draft HTML; `GET /api/jobapplications/{jobId}/cover-letter/export-pdf?expectedRevision={revision}` for owner-scoped saved PDF. Stale revision is 409, unknown/foreign job follows current non-disclosure policy. Response is `application/pdf`; no document content in logs. Routes are proposals, not discovered endpoints. + +- [ ] Add failing tests that held/failed save prevents PDF export; expected-revision mismatch cannot export a different letter; foreign owner cannot preview/export; admission timeout and renderer failure preserve the draft. +- [ ] Reuse current Chromium admission, cancellation, bounded work and cleanup. Avoid adding a second unmanaged browser pool. Serve preview/PDF from the same letter HTML contract and font readiness rules. +- [ ] Implement Save-then-export for dirty letters with explicit Saving/Exporting/failure status. A failed save never silently downloads old text. Disable duplicate export submissions while work is pending. +- [ ] Run renderer/export integration and E2E tests, then manually inspect local synthetic PDFs for A4/Letter sizing, text selection, fonts, links, page breaks, omissions and desktop/mobile preview consistency. +- [ ] Commit the scoped workflow after evidence is recorded. Do not promise tagged PDF accessibility unless independently verified. + +**Exit:** letter PDF feature with revision fidelity and safe resource handling. Covers AC-08, 09, 13, 15. + +## Phase 4 — preserve records and qualify the release + +### Task 6: snapshot designed letters and run the failure matrix + +**Modify:** `JobTrackerApi/Services/SubmittedApplicationPackageService.cs`, `Models/SubmittedApplicationPackage.cs`, data/export/backup models and serializers only as required for the letter artifact; document metadata UI and translations. **Tests:** `SubmittedApplicationPackageTests.cs`, `DocumentsControllerTests.cs`, account export/backup tests and current document contracts. + +**Contract:** a new package records the exact letter text, effective presentation snapshot and rendered artifact/hash for that capture. Existing records remain readable as text-only captures. No historic record is silently rerendered from today's CV settings. UI uses “Recorded application package”; capture is not proof of submission/delivery. + +- [ ] Write failing tests for old package readability, snapshot immutability after source changes, owner-scoped artifact access, interrupted capture and exact-byte hash consistency. +- [ ] Implement the smallest additive artifact change; preserve existing retention/attachment rules and data portability. Document storage impact and cleanup policy rather than inventing an unbounded render archive. +- [ ] Run document, package, account export and backup round-trip tests. Ensure all ordinary read/list endpoints remain read-only. +- [ ] Run the [Break Jobjakt matrix](07-acceptance-and-test-plan.md) in a disposable local/test environment. Include real phone/keyboard, screen reader, EN/NB, light/dark, offline/reconnect, concurrency and long-document PDF checks. +- [ ] Record exact commit, commands, results, screenshots, limitations and outstanding human checks. Obtain implementation/release review before any production action. Commit the qualified changes without unrelated refactoring. + +**Exit:** document records and portable data remain faithful; a bounded release decision has reproducible evidence. Covers AC-10–15. No production deployment is part of this research plan. + +## Suggested verification commands for the future implementer + +Run from the appropriate project directory; commands are examples for the inspected scripts, not results. Prefix shell calls with RTK per repository instructions. Reconfirm the SDK/package state at execution time. Database-dependent suites require a disposable approved test database; never aim them at production. + +```powershell +# job-tracker-ui +rtk proxy npm test -- --runInBand src/cv-template-gallery.test.tsx src/cv-document-controls.test.tsx +rtk proxy npm test -- --runInBand src/application-assets.test.tsx +rtk proxy npm run typecheck +rtk proxy npm run lint +rtk proxy npm run test:e2e -- e2e/cv-editor-frame.spec.ts e2e/cv-responsive-workflow.spec.ts +# repository root; use configured SDK 9.0.317 +rtk proxy dotnet test JobTrackerApi.Tests/JobTrackerApi.Tests.csproj --filter "FullyQualifiedName~ApplicationAssetsTests|FullyQualifiedName~CvRevisionReadinessTests" +``` + +New files named in tasks must be included in the matching focused run; run the broad required repository gates once the final changes justify them. If system `dotnet` cannot resolve the pinned SDK, use `C:/Users/Connor/.dotnet/dotnet.exe` with the proper `DOTNET_ROOT`. Do not install/upgrade dependencies merely to start this plan. + +## Dependency order, rollback and stop conditions + +Phase 1 can ship independently. Phase 2 is a separate persistence project and can ship without presentation changes. Phase 3 depends on Phase 2; Phase 4 depends on the designed-letter output. Keep schema changes additive and old snapshots readable. Before any future schema deployment, document backup, forward/backward application compatibility and a tested rollback of application code that does not discard new data. Do not assume reverting a migration is safe. + +Stop a phase if it requires a second editor/state framework, a replacement CV renderer, an undocumented external endpoint, silent data conversion, or an unreviewed destructive schema step. Resolve the concrete scope issue in review. New AI providers, standalone letter documents, DOCX generation, touch-drag libraries, custom zoom and new font infrastructure remain deferred. + +**Plan self-review:** all design requirements map to the six tasks and acceptance IDs; the five review-focus risks have named tests; proposed contracts are marked as proposed; current runtime and production claims remain Not Tested. No implementation, test execution or schema operation has occurred during this investigation. diff --git a/docs/cv-redesign/research/07-acceptance-and-test-plan.md b/docs/cv-redesign/research/07-acceptance-and-test-plan.md new file mode 100644 index 0000000..bcb4de4 --- /dev/null +++ b/docs/cv-redesign/research/07-acceptance-and-test-plan.md @@ -0,0 +1,85 @@ +# Acceptance criteria and test plan + +**Status: proposed criteria — all implementation acceptance checks below are Not Tested in this investigation.** Existing tests were inspected, not executed. FlowCV evidence and Jobjakt source inspection establish design inputs, not production readiness. + +## Acceptance criteria + +| ID | Measurable acceptance | Evidence to collect after implementation | +|---|---|---| +| AC-01 Document ownership | General/linked-application context is accurate. Local CV overrides never mutate career facts; reset-to-source is explicit | Unit plus E2E before/after source assertions; EN/NB screenshots | +| AC-02 Candidate selection | Opening, selecting and cancelling a theme preview makes zero save requests. Late responses cannot replace the selected candidate. Apply changes only permitted visual values and is one undo step | Held-response tests; request counts; draft/content equivalence assertions | +| AC-03 Editing/reorder | Existing typed/custom content, hide/reset/order survive template changes and reload. Every reorder works with Move up/down and retains focus with accurate position feedback | Unit tests; keyboard E2E; manual touch check | +| AC-04 CV recovery | Saving, Saved, Retry and conflict states remain distinct. Stale save returns conflict and preserves recovery draft; blank name cannot silently persist | Existing readiness tests plus held/failure/conflict E2E | +| AC-05 Preview accuracy | Real renderer sample labelled as sample. Current preview waits for fonts/images and ignores stale responses; failed refresh keeps labelled last-good output | Render/fragmentation tests; failure screenshot; PDF comparison | +| AC-06 Complete letter revision boundary | Every letter mutation path records intended history atomically. Missing revision on mutation is 428; stale is 409. Existing null/clear semantics are preserved and no-op text save does not add history | Two-context relational concurrency tests covering every writer; DTO/client contract tests | +| AC-07 Letter draft integrity | Typing, formatting, copying and AI Apply alter local draft until explicit Save. Failed save/navigation recovery preserves it. Restore creates a new text-and-settings version | Assets unit tests, held-save and restore E2E, old-version fixture | +| AC-08 Letter copy/match | Core contact fields require reviewed copy; optional identity fields are not selected by default. Design mapping preserves body/recipient and is a snapshot independent of later CV edits/deletion | Field-selection tests, cancel tests, source-change test and screenshots | +| AC-09 Export fidelity | Dirty draft is saved before export; failed or stale save yields no old-document download. PDF matches requested saved revision; foreign owner receives no output | API integration; byte/text markers; request-order E2E; manual PDF review | +| AC-10 Historical integrity | Settings-history wording explains current-master resolution. Recorded application packages retain immutable content/artifacts; legacy text-only records still open | Source-mutation tests, exact-byte/hash package tests, copy review | +| AC-11 Accessibility | Named buttons/fields, modal focus/return, visible focus, accurate errors and status announcements. All primary workflows usable by keyboard; inactive mobile pane excluded from focus/AX | Testing Library, axe triage, keyboard and screen-reader human checks | +| AC-12 Responsive/localised | No application overflow or obscured primary action at 320/390/768/899/900/1024/1440px. EN/NB and light/dark remain usable at 200% text zoom; real keyboard does not cover active field | Width matrix; manual phone, browser zoom, long-label screenshots | +| AC-13 Safe rendering/resources | Untrusted text cannot execute HTML/script or unsafe URLs/CSS. PDF honours bounded admission, timeout and cancellation without leaked work | Renderer security tests; resource/failure integration checks | +| AC-14 Data portability | Current text, settings and history survive account export/backup round-trip; existing CSV/JSON data exports continue to work; owner filtering retained | Export/import fixtures, backward-compatible snapshot and owner tests | +| AC-15 Release evidence | Exact commit and reproducible commands/results recorded. No automated result is described as human, real-device or production acceptance | Signed-off checklist listing tests run, skips, defects and release limitations | + +## Existing tests to extend, not duplicate + +| Area | Inspected existing coverage | Future extension | +|---|---|---| +| CV editor/library | `job-tracker-ui/src/cv-builder-page.test.tsx` loading/retry/creation/locks/duplicate/conflict; `e2e/cv-editor-frame.spec.ts` editor save/undo/export/history/mobile | New context/history copy and named actions only where changed | +| Controls/themes | `src/cv-document-controls.test.tsx`, `src/cvBuilder.test.ts`, `src/cv-template-gallery.test.tsx`, `src/cv-template-thumbnail.test.tsx` | Candidate cancel/apply/stale response; preserve existing capability and visual reset rules | +| Preview/responsive | `e2e/cv-preview-presentation.spec.ts`, `cv-responsive-workflow.spec.ts`, `cv-pagination.spec.ts` | Inactive-pane focus; letter equivalent; shared readiness regression | +| CV backend | `JobTrackerApi.Tests/CvBuilderTests.cs`, `CvRevisionReadinessTests.cs`, `PublicCvControllerTests.cs`, `CvExportRetentionTests.cs` | Reuse as regression gates; do not rewrite working CV services merely to add letters | +| Letter editing | `job-tracker-ui/src/application-assets.test.tsx` explicit Apply/Save, reject, failed save, restore and ownership changes | Text/settings revision, cross-writer conflicts, preview and export ordering | +| Letter/backend | `JobTrackerApi.Tests/ApplicationAssetsTests.cs` version/no-op/restore/owner/AI behaviour | Relational concurrency and writer bypass regression tests | +| Document records | `SubmittedApplicationPackageTests.cs`, `DocumentsControllerTests.cs`; frontend document contracts | Designed-letter artifact snapshot, old record compatibility and portable data | + +Frontend paths abbreviated as `src`/`e2e` are under `job-tracker-ui`. Coverage listed is **Verified — test source exists**, not a pass result. Assertions must be checked against the final code and supported provider at execution time. + +## Functional scenarios and fixtures + +Use synthetic names, roles and text only. Fixtures: empty career profile; one short CV; custom/hidden/overridden entries; 15-section long CV; two unrelated applications; two owners; old text-only letter/history/package; a designed letter; a missing/deleted attached CV; slow font/image; invalid Markdown links; long æ/ø/å text; 10-page letter; two tabs at one revision. + +1. Create/open a CV with current supported themes; edit a local override; verify master unchanged; undo/redo; reload; export; restore settings with correct warning. +2. Open theme candidates, cancel, race two preview requests, retry failure, apply, undo/redo and verify content/metadata preservation. +3. Reorder first/middle/last sections and entries by keyboard controls, desktop drag and real touch alternatives. Check focus and actual announced positions. +4. Write letter, preview without saving, edit formatting, attempt navigation, cancel guard, save, reopen and restore. Repeat after failed save and application switch. +5. Copy reviewed contact details and compatible design separately; cancel both; change/delete source CV and verify no silent letter update. +6. Export a dirty letter while save is held, fails or conflicts. Download only the requested successful saved revision. Compare document markers in preview/PDF. +7. Capture an application package, change source data/design, reopen package and export account/backup data. Original record must remain immutable; capture must not imply delivery. + +## Deliberate “Break Jobjakt” failure, abuse and resilience phase + +Run only in an approved disposable local/test environment after implementation. No load, destructive data or abuse testing against FlowCV or production is authorised by this research plan. + +| Challenge | Required behaviour / evidence | +|---|---| +| Two tabs save same CV revision | One accepted, stale edit conflicts; recovery draft retained; no blind retry loop | +| Letter dedicated save races generic job update/draft update/restore | Exactly one intended revision wins; no silent overwrite or orphan history; other writer receives conflict | +| Slow request finishes after user changes application/theme | Stale result ignored; no cross-application draft or preview leak | +| Network drops during save/export | Unsaved text/settings retained; retry explicit; no false success or old-document export | +| Server commits but client loses response | Reload/reconciliation identifies saved revision; repeat save cannot duplicate history unnecessarily | +| Empty name, whitespace, reversed month/year, year-only date | Validated at actual trust boundary; precision semantics documented; error associated with field; no silent destructive normalisation | +| Unknown theme, hidden capability, extreme numeric/CSS input | Server allowlists/clamps or rejects consistently; unsupported values cannot execute CSS or corrupt layout | +| Script tags, unsafe URLs, Markdown nesting, huge links | Escaped/safe output, bounded work, no execution in preview/PDF | +| Foreign owner job/CV/history/artifact id | No content, metadata or existence leakage beyond established policy; no writes | +| Expired consent, exhausted plan, AI failure/cancel | Existing policy enforced; draft unchanged; stale proposal cannot apply after relevant data/revision changes | +| Long Nordic text, oversized entry, slow/missing font/image | Physical pagination remains stable; visible error/last-good output where needed; export bounded | +| Repeated PDF requests and cancelled clients | Admission and timeout enforced; browser/page resources cleaned; no unbounded new pool | +| Delete source CV / update career profile after match | Saved letter remains a snapshot; CV history copy stays truthful; frozen records remain identical | +| Legacy backup/versions missing settings; duplicate historic version rows | Defaults preserve readability; preflight blocks unsafe uniqueness migration; no automatic deletion | +| Mobile keyboard, orientation, 200% text zoom, keyboard-only dialog | No obscured action or trapped focus; input selection/draft preserved; safe areas honoured | + +## Verification levels and release gates + +**Gate A — source:** all writers/callers/DTOs/fixtures/exporters inventoried; planned contract reviewed. This investigation meets the research inventory boundary only. + +**Gate B — automated:** focused unit, supported relational integration and E2E checks pass on the final commit; include logs and test counts. Test doubles are not proof of production database concurrency. Axe findings are triage, not an accessibility certification. + +**Gate C — human:** keyboard and screen-reader walkthrough, real touch phone with keyboard, EN/NB copy review, and manually opened PDFs. Capture screenshots/results with synthetic data. Browser emulation is not real-device acceptance. + +**Gate D — release:** migration/data compatibility, rollback procedure, bounded performance and any production configuration checks approved separately. No production-readiness or security certification follows automatically from Gates A–C. + +## Known research limits carried forward + +FlowCV resume initial creation, successful paid duplication, revision history, manual/pinch zoom, paid AI result quality, reload durability, all advanced controls, real phone input and downloaded PDF fidelity were not tested. Letter mobile and live resume-to-letter synchronisation were not tested. Jobjakt was inspected from source only; no app, tests, database, build or deployed behaviour was exercised. The complete proposal remains **Not Tested** until the gates above are met. diff --git a/docs/cv-redesign/research/README.md b/docs/cv-redesign/research/README.md new file mode 100644 index 0000000..511cfe9 --- /dev/null +++ b/docs/cv-redesign/research/README.md @@ -0,0 +1,35 @@ +# FlowCV research and Jobjakt document-workflow plan + +Completed 21 October 2026. **Research and planning only. No Jobjakt code, database, migration, dependency or deployment changes.** All artifacts are outside the repository. + +## Read the deliverables + +1. [Detailed FlowCV UX audit](01-flowcv-audit.md) — final coverage matrix, manual sequences, network limits and **37 screenshot + DOM/accessibility checkpoints**. +2. [Component and interaction inventory](02-component-interaction-inventory.md) — controls, states, affordances, accessibility observations and evidence IDs. +3. [Jobjakt source inventory and gap analysis](03-jobjakt-gap-analysis.md) — existing routes, editors, models, renderers, design settings, localisation, tests and constraints, with source locations. +4. [Original Jobjakt design proposal](04-jobjakt-design-proposal.md) — application context, provenance, reversible design choice and a complete letter workflow using current systems. +5. [Desktop/mobile wireframe specifications](05-desktop-mobile-wireframes.md) — annotated layouts, responsive behaviour, focus, save/error states and interaction rules. +6. [Phased technical implementation plan](06-phased-implementation-plan.md) — files, proposed contracts, dependencies, six reviewable tasks and rollback/release boundaries. +7. [Acceptance criteria and test plan](07-acceptance-and-test-plan.md) — 15 criteria, existing tests to extend, failure/abuse/resilience matrix and a deliberate Break Jobjakt phase. + +## Decision summary + +**Verified — FlowCV:** split content/preview editing, template gallery → detail → explicit apply, one successful template undo/redo, mouse section reorder, responsive edit/preview, explicit resume contact/design copy into a letter, and completed PDF response paths. AI generation and successful duplication were blocked by plan gates. Network metadata supports automatic saving before Done; the exact persistence mechanism remains Inferred. + +**Verified — Jobjakt source:** the existing CV editor already has autosave, optimistic concurrency, recovery, settings history, undo/redo, responsive physical-page preview, custom content, design controls, PDF and reviewed AI proposals. It should be extended, not replaced. Runtime behaviour was not exercised. + +**Inferred priority:** improve rendered template candidates and ownership/history wording first. Complete application cover-letter preview, compatible design matching and PDF as a separate project. Before persistent letter design or autosave, unify revision/history handling across every writer; several source paths currently bypass the dedicated letter version service. This is a source-derived risk, not a reproduced race. + +**Proposed architecture:** existing React/MUI/theme/routes and .NET/EF services; no new dependency initially. Keep letters application-scoped and explicitly saved. Contact copy and design matching are reviewed snapshots; optional identity fields are excluded by default. Keep frozen application records distinct from live CV settings history. + +## Evidence and privacy + +Findings use **Verified**, **Inferred** or **Not Tested** throughout. Verified source is not a runtime pass. The browser was operated manually by the user; REA was passive. Only curated synthetic-document checkpoints are included. The initial pre-synthetic observation and raw session ledger are excluded. No passwords, cookies, auth tokens, raw request/response bodies or original personal CV content are in this package. + +Each checkpoint has a PNG plus `*-evidence.json` containing selected DOM/AX, findings, manual action and original REA evidence identifiers. Network metadata is limited to selected method/path/status/type; no identifiers/query values are retained. Proprietary sample-template screenshots are reference evidence only, not reusable design assets. [File integrity manifest](C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research/evidence-manifest.json) records SHA-256 hashes for the deliverables and curated evidence files; it is a packaging check, not an independent attestation of original capture time. + +Source baseline: `b2a9fd68b081a8cc1701b1c58eaea7e1070274af`, branch `codex/ui-redesign-phase4`, repository `E:/Storage/Projects/Active/Job tracker`. Working tree clean at initial and final verification. The gap report uses repository-relative `path:line` evidence for portability. + +## Limits and next decision + +No Jobjakt tests, build, database, runtime UI or production checks were run. FlowCV paid features, initial resume creation, live cross-document synchronisation, version history, manual/pinch zoom, real phone use and downloaded PDF fidelity remain untested. The proposal is ready for review; implementation requires your explicit approval. No production deployment is included in the plan. diff --git a/docs/cv-redesign/research/evidence-inventory.json b/docs/cv-redesign/research/evidence-inventory.json new file mode 100644 index 0000000..f206472 --- /dev/null +++ b/docs/cv-redesign/research/evidence-inventory.json @@ -0,0 +1,1798 @@ +{ + "sourceDirectory": "C:/Users/Connor/.codex/visualizations/2026/10/20/01a15834-7508-7352-9e5a-782bc5c4e6f5/flowcv-research", + "manifest": { + "schema_version": 1, + "scope": "Curated research package; excludes raw session ledger and original personal document observation", + "source_commit": "b2a9fd68b081a8cc1701b1c58eaea7e1070274af", + "checkpoint_count": 37, + "files": [ + { + "file": "01-flowcv-audit.md", + "bytes": 59272, + "sha256": "7e28275cd6c5d06a0e527fa7ccb60f140fa4a1d845a338497393927a092c6869" + }, + { + "file": "02-component-interaction-inventory.md", + "bytes": 8033, + "sha256": "b73e9fe403bc88acde17ebd97f6afd17df08ee647764ec67847c7a0b8af2ff8a" + }, + { + "file": "03-jobjakt-gap-analysis.md", + "bytes": 11702, + "sha256": "a9cab0d5fc231c9539b4df51720927ebb658f48d86b5235f0b4f5757d26fc46d" + }, + { + "file": "04-jobjakt-design-proposal.md", + "bytes": 11012, + "sha256": "aed573784ad0dacd6c5f040946d0601b1c2e87257cb2f81dd957ff2c15a4ce28" + }, + { + "file": "05-desktop-mobile-wireframes.md", + "bytes": 13871, + "sha256": "ae3ecf57e6aab3790f57b0de3c05d64cf9b0d007cf65d317916df01c06e646f7" + }, + { + "file": "06-phased-implementation-plan.md", + "bytes": 21933, + "sha256": "550517db7581071e7a488f0ec2b927dff45ec790995b24ad59b8a217643ea4fb" + }, + { + "file": "07-acceptance-and-test-plan.md", + "bytes": 11886, + "sha256": "d818dc6bfb23b5b30cbf4928ff1be6ffeb835f1d5b68042beddd69834ddb7400" + }, + { + "file": "D1-dashboard-evidence.json", + "bytes": 205077, + "sha256": "62d52df44f43a6d2b7b081fcd68b976787b2fb0e68d2ac1430b26d35973e5fdf" + }, + { + "file": "D1-dashboard.png", + "bytes": 68771, + "sha256": "3bdb50cd7cab638ecbe37d700f98c07a9394550bb694aeb24d286ce4ea91f246" + }, + { + "file": "D2-card-menu-evidence.json", + "bytes": 228974, + "sha256": "99c15236f3ba3c170795f2f29f31a803b27d9d438c49381b130876a45e561ea5" + }, + { + "file": "D2-card-menu.png", + "bytes": 72264, + "sha256": "ff46bb8b0302505a48eed228000e880805125ba7c38d78f709047e3fe2d0b264" + }, + { + "file": "E1-editor-evidence.json", + "bytes": 77182, + "sha256": "7dbe850e73361aed0fbba6e337b0bc5c0a6ad582ca608df4654a55d6124e0449" + }, + { + "file": "E1-editor.png", + "bytes": 124118, + "sha256": "ff1f8c8d1c9d66c66493ac4c315e85a4f37d045f12f1a96fa33167972c7f617b" + }, + { + "file": "E10-template-applied-evidence.json", + "bytes": 129555, + "sha256": "bd601114e866fbb546af85df94a3ca7e97be3fc52897d1e75cc233049b8f3b38" + }, + { + "file": "E10-template-applied.png", + "bytes": 147051, + "sha256": "f98fad9d9a6e305a143f90c429f94d35cc5ae7c733b392e90f00d534c7629431" + }, + { + "file": "E11-template-undo-evidence.json", + "bytes": 128361, + "sha256": "a908746d9d9289820936d716119582a620848d18f47e5959347385916e571f94" + }, + { + "file": "E11-template-undo.png", + "bytes": 146290, + "sha256": "6b81c237c305328c04eeb13a55044c65659c57099cf4c3b280edd471f98bf052" + }, + { + "file": "E12-redo-layout-evidence.json", + "bytes": 129872, + "sha256": "da1b4c8243639e41cda3a93c54764f80e78fb2028f07623995624e4e14efc287" + }, + { + "file": "E12-redo-layout.png", + "bytes": 125612, + "sha256": "40c49b450c682f27676320499981bc8575cc9d002bee6d4b7a0d949c7ea30e6e" + }, + { + "file": "E13-sections-reordered-evidence.json", + "bytes": 132151, + "sha256": "b3787ecb307e99fd0c8322370a5b0007c6cbe44de039bbdd5e3ede81c24c9367" + }, + { + "file": "E13-sections-reordered.png", + "bytes": 131055, + "sha256": "5c55733499bd65ba66eeb9774824fc449002f0405bf076e3ce7f0d758dee7c0a" + }, + { + "file": "E14-font-size-pagination-evidence.json", + "bytes": 132213, + "sha256": "a5073db5172cbc957f8a99929ad3b16cf627349960417baef0e771a6fafb371d" + }, + { + "file": "E14-font-size-pagination.png", + "bytes": 104188, + "sha256": "6657f98ad7d3c284dd40dc4504eed47bf71a746006f550dc0e5e39a4b08f7fcd" + }, + { + "file": "E15-body-font-picker-evidence.json", + "bytes": 148877, + "sha256": "766c00058b4173bfbbd34f01d4b8bbf42627233628024c9f3888efe538551366" + }, + { + "file": "E15-body-font-picker.png", + "bytes": 122072, + "sha256": "b39c33f535cca948120c22ad00eda9f645a372cd6c766ff43f120d9db9782f2d" + }, + { + "file": "E16-ai-tools-evidence.json", + "bytes": 39859, + "sha256": "ac133147783bca212333060a2e63e854e139476c90356bd65e50fff7fa4ed398" + }, + { + "file": "E16-ai-tools.png", + "bytes": 137485, + "sha256": "1ce84e46bdf1a34b599d14ccfffcb8704862fd5e380200ffecaeca3fbb667cf5" + }, + { + "file": "E17-ai-plan-gate-evidence.json", + "bytes": 41886, + "sha256": "b049bf14e0d627cf54185efa39fa767282960ed7c726df1970cbab5de8e81790" + }, + { + "file": "E17-ai-plan-gate.png", + "bytes": 146002, + "sha256": "e6909536a947b79241dc8ba349db3220f1b07868440ea29a83b0673053b1d842" + }, + { + "file": "E18-pdf-export-success-evidence.json", + "bytes": 43482, + "sha256": "79e027909cb6fd359fb6d3062dd8942cb03be67f049572d655dec680d0efbb5f" + }, + { + "file": "E18-pdf-export-success.png", + "bytes": 149368, + "sha256": "17abe6237e490bfd057ea0a9b5f1e03bbe28a540109f1e8eabd13f29d9bfab4b" + }, + { + "file": "E19-editor-menu-evidence.json", + "bytes": 5516, + "sha256": "831defbebd36b7eb3d1c0e1489d6f53df56ecb38c75f9e1520edc8d89ab219a5" + }, + { + "file": "E19-editor-menu.png", + "bytes": 147609, + "sha256": "5b08cf78215c03e1d51b69bd5ec67568550eab18c127ccdd2f20b99c01440e4a" + }, + { + "file": "E2-experience-form-evidence.json", + "bytes": 37378, + "sha256": "62cb86256281c74e3a139ce4215bffc79ee37556e6e6c364b1b9f3a92d0d41f9" + }, + { + "file": "E2-experience-form.png", + "bytes": 138901, + "sha256": "50096bc3066e19254a411d14624be775b4eaa5bfcdde8b98314f2c65c4d64fa7" + }, + { + "file": "E20-document-switcher-evidence.json", + "bytes": 41168, + "sha256": "ec423706cf48041d60ceda77990daefa48f763e9c175b813c0f54fa74ded11d2" + }, + { + "file": "E20-document-switcher.png", + "bytes": 154221, + "sha256": "36f1da74dc6c4ba1d7b4e37bfd01adc53f953ac519e7bfe8f01ba0f6f337a3b1" + }, + { + "file": "E21-duplicate-limit-evidence.json", + "bytes": 41064, + "sha256": "45e6a1eedadd51af79edaf270e5568946e4b998cb4e7115a3301b74985a180d5" + }, + { + "file": "E21-duplicate-limit.png", + "bytes": 140711, + "sha256": "93c8dc26fc373872be5aec9e982d1e91fa4cf40397dc554ecd66a0324847df86" + }, + { + "file": "E3-network-metadata.json", + "bytes": 990, + "sha256": "348e50bcc6796803a8ad817e03ee4cfca20a6d78d430eecb7145f8b78efd9844" + }, + { + "file": "E3-title-edit-evidence.json", + "bytes": 37530, + "sha256": "8f3bf69615d0ef14a68d82bad80096807656864d0e8ca03be56b3c2b2d3cd298" + }, + { + "file": "E3-title-edit.png", + "bytes": 140840, + "sha256": "7fe2f690844381c0dbf68f236a08f89f7a3b53e01121418e648c1748b8f5c33b" + }, + { + "file": "E4-section-customizations-evidence.json", + "bytes": 41382, + "sha256": "f0b993254a994c1ec41d94689af9c6e1a0b1c575eafbb8e7e2879cdf9e3c9dcc" + }, + { + "file": "E4-section-customizations.png", + "bytes": 146083, + "sha256": "71ffdf9a2964f43e33bfea28c5c738fd2cbbe8ffe33fccc4cd315554032ed2b0" + }, + { + "file": "E5-add-content-evidence.json", + "bytes": 74572, + "sha256": "e9284d4e0a9ea410050ce0fbdb03dd98212852f02b49ce4f1071c052c318d6ee" + }, + { + "file": "E5-add-content.png", + "bytes": 138763, + "sha256": "df06316e02f46c30d66d0413892456a80bf56c1604fa6e2be5d57d3d7ed0ebb0" + }, + { + "file": "E6-new-project-evidence.json", + "bytes": 34816, + "sha256": "481c5f186b046d9f3a4f3c40a980a4b5b8ac410fb9114bcc3ea2b08983a98fb6" + }, + { + "file": "E6-new-project.png", + "bytes": 123580, + "sha256": "b3e32e7f509c656989794d58fec7aaf6123959858846ef604c0220b58c359eda" + }, + { + "file": "E7-customize-overview-evidence.json", + "bytes": 129310, + "sha256": "57fc528513148062b5b1e65206d14941b977200a208a56b87cf0121604f5b2e3" + }, + { + "file": "E7-customize-overview.png", + "bytes": 146916, + "sha256": "89333b9c4dbd702c0b7f86c9ffa394df94d9dfe67053813bc75a1e090b817f46" + }, + { + "file": "E8-template-gallery-evidence.json", + "bytes": 281794, + "sha256": "4ef788154122d77f9c8a19a8bc11364209546d12748f0bf23a75d3a88a91f814" + }, + { + "file": "E8-template-gallery.png", + "bytes": 457728, + "sha256": "c72301c8103b07af1fc171cb18e4eeaf61ae352d9884e49effd4e7c053129b6c" + }, + { + "file": "E9-template-detail-evidence.json", + "bytes": 212185, + "sha256": "bdbb114d6ea497b998b0de867a0f995ff7f9d28fc39131d223b33ce494e93b78" + }, + { + "file": "E9-template-detail.png", + "bytes": 233838, + "sha256": "8a1d987ff4cb9598cac3c6dd6d5a2e49ce68eae3fabcc6e8bfe7d7bfbaaee46a" + }, + { + "file": "L1-cover-letter-creation-gallery-evidence.json", + "bytes": 47932, + "sha256": "5a022be86ea8aaf52cfb8158357e55a4dd01f304760a530a8ec351912ff70412" + }, + { + "file": "L1-cover-letter-creation-gallery.png", + "bytes": 209961, + "sha256": "3bc0da7b4ed9e26a8e233f28f856cf13f2aeb0ee147cae8aa77dcfd2ac1c80f1" + }, + { + "file": "L10-letter-export-dashboard-evidence.json", + "bytes": 17982, + "sha256": "43f49c20af8e181dcb46eed02b25833a37fec84d94f4581c5ef29a9caf4c1f23" + }, + { + "file": "L10-letter-export-dashboard.png", + "bytes": 53840, + "sha256": "6f1f6139fdfb0a9584ffa41607edb6e4f45e3b9f635fab96b5cd172d63ba9823" + }, + { + "file": "L2-blank-cover-letter-editor-evidence.json", + "bytes": 11450, + "sha256": "24e17900e9ffdec33d708d2320f1a852679184ff72b38871d8b8952e985dfe3a" + }, + { + "file": "L2-blank-cover-letter-editor.png", + "bytes": 52649, + "sha256": "a1f7b7d572a5b2c048d3d355fcdf3a092bea4231b839ca514142f85b6abb9925" + }, + { + "file": "L3-letter-sender-form-evidence.json", + "bytes": 20675, + "sha256": "18c9cc6af92d59f6a9d4ffdcde0036009f1e6bb884e374e8d2c4b400fa3ec223" + }, + { + "file": "L3-letter-sender-form.png", + "bytes": 78047, + "sha256": "67f697c4a071272b1efff91d0c214de555e71d66e18f1dc2b735d5a8f4e1200d" + }, + { + "file": "L4-copy-sender-prompt-evidence.json", + "bytes": 23806, + "sha256": "0e8ada0babb90c6da000315dd1e6cc92f06480fd4f6d91def81d98ca2afb7f9a" + }, + { + "file": "L4-copy-sender-prompt.png", + "bytes": 89341, + "sha256": "ef18e6875b7460d4b90489d5776f28f38f9fef21e935e3cc408167cff0ef6fff" + }, + { + "file": "L5-sender-copied-evidence.json", + "bytes": 44353, + "sha256": "dba8eb01cab922d1be7de997a1ae7dbe55385a737b8922e7329d170b3abdcd63" + }, + { + "file": "L5-sender-copied.png", + "bytes": 90619, + "sha256": "be4daa001bab79a9901d0ce6965b860d646e632d52959768248727672f472eff" + }, + { + "file": "L6-letter-body-autosave-evidence.json", + "bytes": 22202, + "sha256": "58f00115ba817b8c6f50593db12a5743bdfc44432748145e83ac9d5675345239" + }, + { + "file": "L6-letter-body-autosave.png", + "bytes": 71580, + "sha256": "a3128281f496e5119eef1bf705d146b3a86fd7cce89efed401edc2e7d81b42e5" + }, + { + "file": "L7-letter-customize-evidence.json", + "bytes": 85510, + "sha256": "868e83f3f221845df8aa15455d41dfc810fb493f50251393598c3b57f0eb5b91" + }, + { + "file": "L7-letter-customize.png", + "bytes": 105060, + "sha256": "1e6a0120a92483d9d6ca4140960c9210045456049bd91b8d47b09536ea0d35ed" + }, + { + "file": "L8-copy-resume-design-prompt-evidence.json", + "bytes": 88233, + "sha256": "bdd8fae2893f4adb87bd6b6ea4df4accb3c85c0173e30fc532660505e4ce2e34" + }, + { + "file": "L8-copy-resume-design-prompt.png", + "bytes": 111317, + "sha256": "5b005149588941e56625c36e6798c77d621dfc0ce02f02eee199d3c1fd5f6cca" + }, + { + "file": "L9-resume-design-copied-evidence.json", + "bytes": 85536, + "sha256": "24d3bdcd2581c6668749a6c7f4965e82b9e1b8140537e09f370b690c1f70470a" + }, + { + "file": "L9-resume-design-copied.png", + "bytes": 106643, + "sha256": "846db77a81092dbf6fde869a6b12ddd52105df5b4fa5ba1057fab35e83fd2e11" + }, + { + "file": "M1-mobile-content-evidence.json", + "bytes": 43219, + "sha256": "ca7cd07ad839edd60286d0b93a6b1fa2d1865f5b6c880fd7f770174ec8fab1b9" + }, + { + "file": "M1-mobile-content.png", + "bytes": 41597, + "sha256": "ab9e4988445075c7367cf71db9a5102705bee7e3712c66cbccedc5e9961e2816" + }, + { + "file": "M2-mobile-preview-evidence.json", + "bytes": 63210, + "sha256": "ea6252ea2e15638256af7575224f74e465e744164d48b98e417972089d3a993d" + }, + { + "file": "M2-mobile-preview.png", + "bytes": 39402, + "sha256": "a07671cac5369a20604cfb40a6fdf4069569425c9357aa232a1807437cd955a3" + }, + { + "file": "M3-mobile-experience-form-evidence.json", + "bytes": 19666, + "sha256": "6adb05dfcfe717fd59deca710aeffadf05bcdfdb2eb2e7954510897c11dcfd29" + }, + { + "file": "M3-mobile-experience-form.png", + "bytes": 39140, + "sha256": "fe1a927f9aa17bad227d7c0e708f6724fbc69621f0085360e87f19d07d20b44e" + }, + { + "file": "M4-date-range-edge-evidence.json", + "bytes": 24889, + "sha256": "3b24b2b8abf0b4d1171f71ecd09414095bde18562028a043b64b744ba70f66c0" + }, + { + "file": "M4-date-range-edge.png", + "bytes": 44335, + "sha256": "e28603ed3698de744d13dad404f1cdfe123c0bab9013b8054a49fe677e6e8b1b" + }, + { + "file": "README.md", + "bytes": 4748, + "sha256": "7bd00ed1a59ea390a2b29400bcab49524bbffc0ab674bf6c23b63709505ef615" + } + ] + }, + "checkpoints": [ + { + "file": "D1-dashboard-evidence.json", + "sha256": "62d52df44f43a6d2b7b081fcd68b976787b2fb0e68d2ac1430b26d35973e5fdf", + "checkpoint": "D1", + "manualAction": "User prepared synthetic Resume 1 before capture; creation actions not observed.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 468, + "findings": [ + { + "status": "Verified", + "finding": "Navigation links, New resume button, A4 document preview, relative edited time, card overflow." + }, + { + "status": "Verified", + "finding": "Focusable overflow button has empty accessible name.", + "node_id": "1662" + }, + { + "status": "Not Tested", + "finding": "Creation, overflow actions, keyboard behavior and autosave." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "D2-card-menu-evidence.json", + "sha256": "99c15236f3ba3c170795f2f29f31a803b27d9d438c49381b130876a45e561ea5", + "checkpoint": "D2", + "manualAction": "User clicked the Resume 1 card overflow control and left it open.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 494, + "findings": [ + { + "status": "Verified", + "finding": "Overflow opens a panel positioned upward over the card preview, with Edit title, Duplicate, AI translate Beta, Download and Delete." + }, + { + "status": "Verified", + "finding": "Panel actions are exposed as buttons; no menu or menuitem role appears in this accessibility snapshot. Trigger remains focused; expanded state is not reported." + }, + { + "status": "Not Tested", + "finding": "Successful duplication, translation, download, deletion, rename validation, keyboard navigation, focus trapping/restoration and versions." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E1-editor-evidence.json", + "sha256": "7dbe850e73361aed0fbba6e337b0bc5c0a6ad582ca608df4654a55d6124e0449", + "checkpoint": "E1", + "manualAction": "User opened Resume 1 editor and reports adding one of every content type. Add operations happened before capture.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 346, + "findings": [ + { + "status": "Verified", + "finding": "Content editor is at /resume/content. Header links: Overview, Content, Customize, AI Tools; document switcher, Download and overflow control." + }, + { + "status": "Verified", + "finding": "Desktop split view: section accordions left, document preview right. Current screenshot is scrolled near bottom of content list." + }, + { + "status": "Verified", + "finding": "15 headings: Summary, Skills, Languages, Professional Experience, Education, Certificates, Awards, Courses, Projects, Interests, References, Declaration, Publications, Organisations, Custom. Add Content control present." + }, + { + "status": "Verified", + "finding": "Entry drag buttons expose instructions for Space to lift, arrow keys to move and Escape to cancel. Add Entry and Delete section controls exist." + }, + { + "status": "Not Tested", + "finding": "Keyboard reorder success, section reorder, add workflow, save state, preview update timing, undo/redo and zoom. No save indicator text observed in this snapshot; this does not prove absence." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E10-template-applied-evidence.json", + "sha256": "bd601114e866fbb546af85df94a3ca7e97be3fc52897d1e75cc233049b8f3b38", + "checkpoint": "E10", + "manualAction": "User clicked Use this template; returned to editor.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 622, + "findings": [ + { + "status": "Verified", + "finding": "Use this template closes modal and returns to Customize. Layout changed from Two to One; preview changed to single column, centered header, uppercase ruled headings and Alegreya body font." + }, + { + "status": "Verified", + "finding": "Synthetic experience title, original section content and new Project B remain in AX/preview after application. No field-by-field export or backend comparison performed." + }, + { + "status": "Verified", + "finding": "Template changes a bundle of settings: section order, typography, spacing, margins, color/header choices and entry layout. Base font remains 10.5pt; line height is now 1.15 and margins 22mm/12mm." + }, + { + "status": "Not Tested", + "finding": "Undo/redo reversibility, template persistence after reload, full data equivalence, original design recovery and pagination/export fidelity." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E11-template-undo-evidence.json", + "sha256": "a908746d9d9289820936d716119582a620848d18f47e5959347385916e571f94", + "checkpoint": "E11", + "manualAction": "User clicked left curved arrow once and reported previous design returned.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 617, + "findings": [ + { + "status": "Verified", + "finding": "One click on left curved-arrow control restores observed two-column layout, left header, Zilla Slab font, previous spacing/margins, color settings and section ordering after template application." + }, + { + "status": "Verified", + "finding": "New synthetic Project B remains present after undo; title and content edits predate template change." + }, + { + "status": "Verified", + "finding": "Right curved arrow changes from visually muted to active-looking. Both controls remain unnamed in AX; actual redo still needs testing." + }, + { + "status": "Not Tested", + "finding": "Redo, history depth, content-edit undo scope, cross-route history and persistence across reload." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E12-redo-layout-evidence.json", + "sha256": "da1b4c8243639e41cda3a93c54764f80e78fb2028f07623995624e4e14efc287", + "checkpoint": "E12", + "manualAction": "User clicked right curved arrow and Layout anchor; reported single-column design returned.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 622, + "findings": [ + { + "status": "Verified", + "finding": "Right curved-arrow restores applied single-column template: One selected, Alegreya font, template settings and reordered sections; synthetic content remains observed." + }, + { + "status": "Verified", + "finding": "Layout anchor scrolls controls into view while fixed top navigation remains. Section layout uses a vertical list of draggable labeled rows with grip icons and a fixed Personal Details block above." + }, + { + "status": "Verified", + "finding": "Current section order starts Summary, Professional Experience, Education, Skills, Certificates, Languages. Rows expose keyboard drag instructions." + }, + { + "status": "Not Tested", + "finding": "Actual section reorder, column reassignment, mixed columns, page-break placement, undo beyond this template change and layout save errors." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E13-sections-reordered-evidence.json", + "sha256": "b3787ecb307e99fd0c8322370a5b0007c6cbe44de039bbdd5e3ede81c24c9367", + "checkpoint": "E13", + "manualAction": "User dragged Skills grip above Education and reported rows moving aside with no confirmation.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 639, + "findings": [ + { + "status": "Verified", + "finding": "Mouse drag moves Skills above Education in both section layout list and document preview; neighboring rows shifted during dragging per user report; no visible confirmation reported." + }, + { + "status": "Verified", + "finding": "AX contains drop announcement: You have dropped the item. You have moved the item from position 3 to position 3." + }, + { + "status": "Inferred", + "finding": "Drop announcement may be misleading because before/after section order changed while reported source/destination positions are equal. Needs keyboard/screen-reader reproduction before treating as general defect." + }, + { + "status": "Not Tested", + "finding": "Keyboard drop success/cancel, drag across columns, entry reorder, persistence after reload and multi-page page-break behavior." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E14-font-size-pagination-evidence.json", + "sha256": "a5073db5172cbc957f8a99929ad3b16cf627349960417baef0e771a6fafb371d", + "checkpoint": "E14", + "manualAction": "User clicked Font Size anchor and Base Font Size plus once; reported 11pt and preview update.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 639, + "findings": [ + { + "status": "Verified", + "finding": "One plus click increases Base Font Size from 10.5pt to 11pt. User observed preview update; final screenshot shows changed typography and two physical page surfaces separated by a gap." + }, + { + "status": "Verified", + "finding": "Font Size card offers base size and relative offsets for Full Name, Professional Title, Section Headings and Entry Header using segmented-looking tracks plus minus/plus controls." + }, + { + "status": "Verified", + "finding": "Spacing card begins with Line Height and Space Between Elements; line height remains 1.15. Increment/decrement buttons are unnamed in AX, and no slider role appears in this snapshot." + }, + { + "status": "Not Tested", + "finding": "Whether 11pt caused page count to increase, numeric ranges/limits, keyboard slider operation, zoom, typography persistence and export pagination parity." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E15-body-font-picker-evidence.json", + "sha256": "766c00058b4173bfbbd34f01d4b8bbf42627233628024c9f3888efe538551366", + "checkpoint": "E15", + "manualAction": "User opened Font anchor and Body Font selector, leaving list open.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 751, + "findings": [ + { + "status": "Verified", + "finding": "Body Font opens scrollable option list grouped SERIF, SANS and MONO, with each font name rendered as a sample. Current Alegreya has visible checkmark." + }, + { + "status": "Verified", + "finding": "AX exposes 35 font options in this capture, including Source Sans Pro, Roboto, Lora, EB Garamond and Courier Prime. Body Font trigger expanded=true with listbox popup semantics." + }, + { + "status": "Verified", + "finding": "No search field observed in this captured picker. Do not infer font upload is unsupported from this view." + }, + { + "status": "Not Tested", + "finding": "Changing body/name font, keyboard selection, multilingual glyph coverage, font embedding and export matching." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E16-ai-tools-evidence.json", + "sha256": "ac133147783bca212333060a2e63e854e139476c90356bd65e50fff7fa4ed398", + "checkpoint": "E16", + "manualAction": "User selected Source Sans Pro, reported preview also changes on hover, then opened AI Tools without submitting.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 254, + "findings": [ + { + "status": "Verified", + "finding": "AI Tools route /resume/ai-tools shows Pro-plan notice and Upgrade to Pro action, plus Translate resume, Improve writing, Draft Cover Letter, Generate Summary, Check spelling & grammar cards." + }, + { + "status": "Verified", + "finding": "Draft Cover Letter copy says it uses resume and target job description. Grammar check copy distinguishes checking from rewriting. These are interface claims; resulting behavior not tested." + }, + { + "status": "Verified", + "finding": "Document preview remains alongside AI tool navigation." + }, + { + "status": "Inferred", + "finding": "User reports choosing Source Sans Pro changes preview, including temporary preview on font hover. Current screenshot is visibly sans serif; selected font value and hover cancellation not independently captured." + }, + { + "status": "Not Tested", + "finding": "AI input forms, gating enforcement, privacy disclosure, quota, generation latency/result quality, apply/reject/undo behavior and AI network requests." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E17-ai-plan-gate-evidence.json", + "sha256": "b049bf14e0d627cf54185efa39fa767282960ed7c726df1970cbab5de8e81790", + "checkpoint": "E17", + "manualAction": "User clicked Draft now and paused; resulting screen is a Pro-plan gate.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 268, + "findings": [ + { + "status": "Verified", + "finding": "Draft now opens a plan gate stating AI features are available on Pro, with Stay on Free, Upgrade to Pro and close controls. No drafting form or generation result observed." + }, + { + "status": "Verified", + "finding": "Gate copy advertises unlimited PDF downloads, all resume templates and design options on free plan. This verifies messaging, not unlimited use or export behavior." + }, + { + "status": "Not Tested", + "finding": "Paid AI input fields, generation, resume/job data use, privacy options, quotas and apply/reject results. No upgrade or generation requested." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E18-pdf-export-success-evidence.json", + "sha256": "79e027909cb6fd359fb6d3062dd8942cb03be67f049572d655dec680d0efbb5f", + "checkpoint": "E18", + "manualAction": "User dismissed Pro gate and clicked Download; observed spinner popup then download. Passive 45-second window captured export metadata and final success state.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 273, + "findings": [ + { + "status": "Verified", + "finding": "Manual Download observed successful GET /api/resumes/download with 200 application/pdf. No response body, query identifiers, cookies or raw headers retained." + }, + { + "status": "Verified", + "finding": "Final AX/screenshot shows Resume downloaded success popup with encouragement and return-to-editing action. User reports spinner popup then completed download; spinner pixels not captured." + }, + { + "status": "Not Tested", + "finding": "Actual local PDF contents, page size/count, font embedding, selectable text, output accessibility, retry/failure path and alternative export formats." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E19-editor-menu-evidence.json", + "sha256": "831defbebd36b7eb3d1c0e1489d6f53df56ecb38c75f9e1520edc8d89ab219a5", + "checkpoint": "E19", + "manualAction": "User closed export success popup and opened top-right editor overflow.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 9, + "findings": [ + { + "status": "Verified", + "finding": "Top-right editor overflow exposes two menuitems: Download via email and Get shareable link. No version/history/zoom control appears in this menu state." + }, + { + "status": "Verified", + "finding": "Unlike earlier custom dialogs, current AX snapshot is restricted to menu content with menuitem roles. No keyboard navigation test performed." + }, + { + "status": "Not Tested", + "finding": "Email delivery, publishing/sharing, link permissions, revocation and history/version availability elsewhere. Neither action was invoked." + } + ], + "namedInteractiveControls": [ + [ + "menuitem", + "Download via email" + ], + [ + "menuitem", + "Get shareable link" + ] + ] + }, + { + "file": "E2-experience-form-evidence.json", + "sha256": "62cb86256281c74e3a139ce4215bffc79ee37556e6e6c364b1b9f3a92d0d41f9", + "checkpoint": "E2", + "manualAction": "User expanded Professional Experience and opened the synthetic entry; no edits made during capture.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 213, + "findings": [ + { + "status": "Verified", + "finding": "Experience editing replaces the left accordion pane with an Edit Entry form while the resume preview remains alongside." + }, + { + "status": "Verified", + "finding": "Employer autocomplete combobox plus Link button; Job Title and Location text inputs; Start Date/End Date inputs with Clear date controls; richtext Description." + }, + { + "status": "Verified", + "finding": "Richtext tools: Bold, Italic, Underline, Bulleted list, Insert link, left/center/right/justified alignment. AI shortcuts: Improve Writing, Suggest Content, Grammar Check, Shorter." + }, + { + "status": "Verified", + "finding": "Done button, Get Tips, eye and trash icons, section customization disclosure. Eye/trash buttons have empty names in this snapshot." + }, + { + "status": "Verified", + "finding": "Both date inputs expose accessible name MM/YYYY despite separate visible Start Date and End Date labels." + }, + { + "status": "Not Tested", + "finding": "Autocomplete suggestions, date validation, AI results, hide/delete effects, Done semantics and autosave." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Job Title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Description" + ] + ] + }, + { + "file": "E20-document-switcher-evidence.json", + "sha256": "ec423706cf48041d60ceda77990daefa48f763e9c175b813c0f54fa74ded11d2", + "checkpoint": "E20", + "manualAction": "User opened Resume 1 dropdown beside Download.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 266, + "findings": [ + { + "status": "Verified", + "finding": "Resume selector opens My Resumes popover listing Resume 1 with Switch to Resume 1, Duplicate, More actions and Add new resume controls." + }, + { + "status": "Verified", + "finding": "Duplicate and More actions controls are named in AX, unlike the editor top-level overflow. No revision or version selector appears in current popover." + }, + { + "status": "Not Tested", + "finding": "Switching between distinct documents, duplication result, per-document actions, creation limit and revision/history availability elsewhere." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E21-duplicate-limit-evidence.json", + "sha256": "45e6a1eedadd51af79edaf270e5568946e4b998cb4e7115a3301b74985a180d5", + "checkpoint": "E21", + "manualAction": "User clicked Duplicate beside Resume 1 and paused at the free-plan limit prompt.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 265, + "findings": [ + { + "status": "Verified", + "finding": "Duplicate opens Need more than one resume? gate stating free plan includes one resume and upgrade is required to create another. No successful duplicate observed." + }, + { + "status": "Verified", + "finding": "Gate offers upgrade and close; no purchase or upgrade performed." + }, + { + "status": "Not Tested", + "finding": "Copy naming, independent editing, copied content/design ownership, version history and duplicate behavior on paid plan." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E3-title-edit-evidence.json", + "sha256": "8f3bf69615d0ef14a68d82bad80096807656864d0e8ca03be56b3c2b2d3cd298", + "checkpoint": "E3", + "manualAction": "User replaced Job Title with UX Test Engineer, paused without clicking Done and reported no visible feedback.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 215, + "findings": [ + { + "status": "Verified", + "finding": "UX Test Engineer appears in document preview while entry form remains open; user did not click Done." + }, + { + "status": "Verified", + "finding": "45-second attach window observed GET /api/resumes/:document-id 200, PATCH /api/resumes/save_entry 200 and POST /clientlog 200. No payloads or raw headers captured." + }, + { + "status": "Inferred", + "finding": "Successful save_entry PATCH during the manual title edit is consistent with automatic saving before Done; no reload persistence or conflict behavior tested." + }, + { + "status": "Verified", + "finding": "User reported seeing no feedback; final AX snapshot has no saving/saved text. Transient visual indicators may have been missed." + }, + { + "status": "Not Tested", + "finding": "Reload persistence, exact debounce timing, error/retry, offline behavior, undo/redo, whether Done triggers additional saves." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Job Title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Description" + ] + ] + }, + { + "file": "E4-section-customizations-evidence.json", + "sha256": "f0b993254a994c1ec41d94689af9c6e1a0b1c575eafbb8e7e2879cdf9e3c9dcc", + "checkpoint": "E4", + "manualAction": "User clicked Done, reopened experience, confirmed title retention and expanded section customizations.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 237, + "findings": [ + { + "status": "Verified", + "finding": "UX Test Engineer remains visible after user reports Done then reopening the same entry. This verifies in-app reopen retention, not browser reload persistence." + }, + { + "status": "Verified", + "finding": "Section disclosure expands and changes name to Hide customizations for this section with expanded=true." + }, + { + "status": "Verified", + "finding": "Work Experience customizations show two Title/Subtitle Order choices: Job Title - Employer and Employer - Job Title; latter visibly selected. Group promotions checkbox is unchecked." + }, + { + "status": "Verified", + "finding": "Hint links to Customize > Entry Layout for more options." + }, + { + "status": "Not Tested", + "finding": "Applying order choice, grouping multiple promotions, history/undo, reload persistence and date validation." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Job Title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Description" + ] + ] + }, + { + "file": "E5-add-content-evidence.json", + "sha256": "e9284d4e0a9ea410050ce0fbdb03dd98212852f02b49ce4f1071c052c318d6ee", + "checkpoint": "E5", + "manualAction": "User chose Job Title - Employer and reported preview order swapped; clicked Done and Add Content, leaving chooser open.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 441, + "findings": [ + { + "status": "Verified", + "finding": "Add Content opens a large modal with icon/title/help-text tiles in four columns at this desktop viewport." + }, + { + "status": "Verified", + "finding": "Current chooser lists Education, Professional Experience, Skills, Languages, Certificates, Interests, Projects, Courses, Awards, Organisations, Publications, References and two Custom tiles (existing custom section and add-custom tile)." + }, + { + "status": "Verified", + "finding": "Summary and Declaration exist in this document but are not offered in this captured chooser state. Do not infer they are unsupported or why they are omitted." + }, + { + "status": "Verified", + "finding": "Dialog has modal=true but an empty accessible name. Close icon is an unnamed button. Background controls remain in the captured AX tree; focus is reported on Add Content. Keyboard containment was not tested." + }, + { + "status": "Verified", + "finding": "Experience entry name now reads UX Test Engineer, employer after presentation change; user reports preview swapped their order." + }, + { + "status": "Not Tested", + "finding": "Choosing a new section, duplicate section rules, custom schema editing, modal keyboard behavior and add cancellation." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E6-new-project-evidence.json", + "sha256": "481c5f186b046d9f3a4f3c40a980a4b5b8ac410fb9114bcc3ea2b08983a98fb6", + "checkpoint": "E6", + "manualAction": "User selected Projects from Add Content and left the blank form untouched.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 203, + "findings": [ + { + "status": "Verified", + "finding": "Choosing Projects when a Projects section already exists opens a blank Edit Entry form at /resume/content/edit/project/:entry-id. The existing project remains visible in the preview." + }, + { + "status": "Verified", + "finding": "Project fields: Project title with Link, Sub title, Start Date, End Date and richtext Description. Project title is focused; exposed required states are false. Done, hide/delete icons, AI shortcuts and customization disclosure are present." + }, + { + "status": "Inferred", + "finding": "Chooser appears to add a new entry to the existing typed section; successful completion and section count still need corroboration." + }, + { + "status": "Not Tested", + "finding": "Empty-submit validation, date validation, new entry persistence, cancellation and reordering." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Project title" + ], + [ + "textbox", + "Sub title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Description" + ] + ] + }, + { + "file": "E7-customize-overview-evidence.json", + "sha256": "57fc528513148062b5b1e65206d14941b977200a208a56b87cf0121604f5b2e3", + "checkpoint": "E7", + "manualAction": "User completed new synthetic Project B, clicked Done and opened Customize; reported no save feedback.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 617, + "findings": [ + { + "status": "Verified", + "finding": "Customize route /resume/customization retains preview and shows anchor navigation: Document, Templates, Layout, Font Size, Spacing, Entries, Headings, Font, Colors, Header, Photo, Links, Footer, Sections." + }, + { + "status": "Verified", + "finding": "Document defaults currently English (UK), DD/MM/YYYY, A4; Browse templates control present. Existing and new UX Test Project B appear together under Projects in preview." + }, + { + "status": "Verified", + "finding": "Layout controls include One/Two/Mix columns, Top/Left/Right header, section drag list with page breaks and 45%/55% column widths. Two and Left currently selected." + }, + { + "status": "Verified", + "finding": "AX exposes font size offsets, line height, spacing, margins, entry/date layout, heading styles, fonts, color area/modes, accent targets, header alignment/icon styling, photo options, link styling, footer fields and section customizations. Presence only; effects not tested." + }, + { + "status": "Verified", + "finding": "Current fonts: Zilla Slab body and Same as body font for name. Color modes Single/Multi/Image; current Multi. Photo controls explain options appear after photo added." + }, + { + "status": "Inferred", + "finding": "Floating curved-arrow pair resembles undo/redo; both are unnamed buttons in AX, so function and scope need testing." + }, + { + "status": "Verified", + "finding": "User reports no save feedback while adding project and moving to Customize." + }, + { + "status": "Not Tested", + "finding": "Template selection effects, typography changes, page format/language effects, undo/redo, drag/drop success, preview zoom and pagination behavior." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E8-template-gallery-evidence.json", + "sha256": "4ef788154122d77f9c8a19a8bc11364209546d12748f0bf23a75d3a88a91f814", + "checkpoint": "E8", + "manualAction": "User clicked Browse templates and left gallery open without selecting a design.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 964, + "findings": [ + { + "status": "Verified", + "finding": "Browse templates opens Apply a design template modal at ?modal=resume-templates. Four preview cards per row at 1912px, labeled names beneath; gallery extends below viewport." + }, + { + "status": "Verified", + "finding": "Filter controls All Templates, Popular, Simple, Modern, Creative are exposed as checkboxes, All Templates checked. Their filtering behavior is not yet tested." + }, + { + "status": "Verified", + "finding": "Gallery previews show sample content rather than the current synthetic resume content. Original assets are retained only in audit screenshots; no template or asset extraction/reuse." + }, + { + "status": "Verified", + "finding": "Modal and close button have empty accessible names in this snapshot. Underlying Browse templates remains the reported focused control; keyboard behavior not tested." + }, + { + "status": "Not Tested", + "finding": "Template application/confirmation, content retention, filter combinations, paywalls, undo and persistence." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "E9-template-detail-evidence.json", + "sha256": "bdbb114d6ea497b998b0de867a0f995ff7f9d28fc39131d223b33ce494e93b78", + "checkpoint": "E9", + "manualAction": "User selected CLASSIC CLEAR; observed larger preview/details and Use this template action.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 649, + "findings": [ + { + "status": "Verified", + "finding": "Selecting Classic Clear opens a larger sample preview and detail modal, preserving underlying editor design until Use this template is chosen. URL gains template=classic-clear." + }, + { + "status": "Verified", + "finding": "Use this template is a named button. Detail copy advertises A4/US-Letter, editable text, customization, print readiness and online sharing. Only copy presence is verified; exported output/sharing not tested." + }, + { + "status": "Verified", + "finding": "Selected design preview uses sample content, not the synthetic current document. No confirmation warning observed before this intermediate screen." + }, + { + "status": "Not Tested", + "finding": "Applying design, data retention, undo/redo, export format and online sharing." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L1-cover-letter-creation-gallery-evidence.json", + "sha256": "5a022be86ea8aaf52cfb8158357e55a4dd01f304760a530a8ec351912ff70412", + "checkpoint": "L1", + "manualAction": "User restored synthetic experience date per report, returned desktop width and opened cover-letters landing page.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 263, + "findings": [ + { + "status": "Verified", + "finding": "At /cover-letters with no user letters displayed, landing state is Create a cover letter with New blank tile and template gallery. Sidebar includes Resume, Cover Letter and Job Tracker." + }, + { + "status": "Verified", + "finding": "Filters All Templates/Simple/Modern/Creative appear as checkboxes; All Templates selected. At observed 1661x948, first row has New blank and two named template previews." + }, + { + "status": "Verified", + "finding": "Copy promises first cover letter free, all features and unlimited downloads. This verifies messaging, not paid-plan behavior or download limits." + }, + { + "status": "Not Tested", + "finding": "Blank/template creation, populated document card dashboard, letter limits, resume data reuse and matching design." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L10-letter-export-dashboard-evidence.json", + "sha256": "43f49c20af8e181dcb46eed02b25833a37fec84d94f4581c5ef29a9caf4c1f23", + "checkpoint": "L10", + "manualAction": "User downloaded letter, dismissed any success popup and clicked Overview; 45-second passive window observed export and final dashboard.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 98, + "findings": [ + { + "status": "Verified", + "finding": "Letter Download returned200 application/pdf from GET /api/letters/download. User reports completed export; no PDF body or local file inspected." + }, + { + "status": "Verified", + "finding": "Overview opens populated My Cover Letters dashboard at /cover-letters with New letter tile, Letter1 thumbnail, relative edit time, A4 metadata and unnamed overflow button." + }, + { + "status": "Verified", + "finding": "Dashboard thumbnail and AX retain copied sender, edited synthetic paragraph and new design after returning from editor." + }, + { + "status": "Not Tested", + "finding": "Local PDF fidelity/accessibility, letter duplication/versions/overflow actions, letter mobile behavior, multiple-letter limit and live resume synchronization." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L2-blank-cover-letter-editor-evidence.json", + "sha256": "24e17900e9ffdec33d708d2320f1a852679184ff72b38871d8b8952e985dfe3a", + "checkpoint": "L2", + "manualAction": "User clicked New blank in cover-letter gallery and left initial editor untouched.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 55, + "findings": [ + { + "status": "Verified", + "finding": "New blank creates Letter 1 and opens /cover-letter/write with desktop content/preview split and Overview, Content, Customize, letter selector and Download controls." + }, + { + "status": "Verified", + "finding": "Content cards: Sender details (Modern header), Date, Recipient details, Subject, Body, Signature. Cards have named Edit controls in AX." + }, + { + "status": "Verified", + "finding": "Initial date is 21st October 2026; sender/recipient/subject/body/signature show Not added. Preview includes date and default greeting/signoff placeholders." + }, + { + "status": "Verified", + "finding": "Existing resume contact data was not automatically populated into this initial blank letter state. No resume-data/design prompt observed after New blank." + }, + { + "status": "Not Tested", + "finding": "Explicit resume-data import, sender editing, body formatting, signature input, letter autosave, matching designs, export and mobile letter editing." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L3-letter-sender-form-evidence.json", + "sha256": "18c9cc6af92d59f6a9d4ffdcde0036009f1e6bb884e374e8d2c4b400fa3ec223", + "checkpoint": "L3", + "manualAction": "User opened Sender details without entering personal information.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 92, + "findings": [ + { + "status": "Verified", + "finding": "Sender editor provides explicit Copy from resume button with accessible name Copy sender details from resume." + }, + { + "status": "Verified", + "finding": "Sender style radios Modern Header (selected) and Classic Sender; fields Full name, Professional title, Email, Phone, Location; photo affordance and reorder grips for contact details." + }, + { + "status": "Verified", + "finding": "Add details options include LinkedIn, Website, Nationality, Date of Birth, Visa, Passport or Id, Availability and Show More. Presence does not establish data validation or privacy defaults." + }, + { + "status": "Not Tested", + "finding": "Copy source selection, which fields copy, one-time copy versus live synchronization, sender style change, photo upload and reorder behavior." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Full name" + ], + [ + "textbox", + "Professional title" + ], + [ + "textbox", + "Email" + ], + [ + "textbox", + "Phone" + ], + [ + "textbox", + "Location" + ] + ] + }, + { + "file": "L4-copy-sender-prompt-evidence.json", + "sha256": "0e8ada0babb90c6da000315dd1e6cc92f06480fd4f6d91def81d98ca2afb7f9a", + "checkpoint": "L4", + "manualAction": "User clicked Copy from resume and paused at source-selection prompt.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 110, + "findings": [ + { + "status": "Verified", + "finding": "Copy from resume opens source selector and explicit warning that current personal details and photo will be replaced." + }, + { + "status": "Verified", + "finding": "Resume dropdown initially Select resume; Copy sender details disabled until source chosen. Cancel action present." + }, + { + "status": "Inferred", + "finding": "Wording describes replacement/copy, suggesting snapshot semantics rather than live synchronization; actual cross-document update behavior remains untested." + }, + { + "status": "Not Tested", + "finding": "Source selection list, successful import, copied field completeness, overwrite behavior with populated sender and later resume edits." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Full name" + ], + [ + "textbox", + "Professional title" + ], + [ + "textbox", + "Email" + ], + [ + "textbox", + "Phone" + ], + [ + "textbox", + "Location" + ] + ] + }, + { + "file": "L5-sender-copied-evidence.json", + "sha256": "dba8eb01cab922d1be7de997a1ae7dbe55385a737b8922e7329d170b3abdcd63", + "checkpoint": "L5", + "manualAction": "User selected synthetic Resume 1 and confirmed Copy sender details; populated sender form and preview observed.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 219, + "findings": [ + { + "status": "Verified", + "finding": "Copying from synthetic Resume 1 populates name, professional title, email, phone, location and optional website/nationality/ID/LinkedIn/birth-date/visa/availability fields. Those details appear in letter preview." + }, + { + "status": "Verified", + "finding": "Modern Header remains selected and letter body stays blank with default greeting/signoff. Copy did not import experience or project paragraphs into body." + }, + { + "status": "Inferred", + "finding": "Copy imports optional personal fields broadly rather than only core contact fields; a design recommendation should make this scope clear before replacement." + }, + { + "status": "Not Tested", + "finding": "Photo copying, omitted-field removal, data synchronization after later edits, copy rollback, source provenance display and server persistence." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Full name" + ], + [ + "textbox", + "Professional title" + ], + [ + "textbox", + "Email" + ], + [ + "textbox", + "Phone" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Website" + ], + [ + "textbox", + "Nationality" + ], + [ + "textbox", + "ID Number" + ], + [ + "textbox", + "LinkedIn" + ], + [ + "textbox", + "Date of Birth" + ], + [ + "textbox", + "Visa Status" + ], + [ + "textbox", + "Availability" + ] + ] + }, + { + "file": "L6-letter-body-autosave-evidence.json", + "sha256": "58f00115ba817b8c6f50593db12a5743bdfc44432748145e83ac9d5675345239", + "checkpoint": "L6", + "manualAction": "User clicked sender Done, opened Body, entered synthetic paragraph and paused without Done.", + "viewport": { + "width": 1661, + "height": 948 + }, + "accessibilityNodes": 118, + "findings": [ + { + "status": "Verified", + "finding": "Body editor has Bold, Italic, Underline, Bulleted list, Insert link and four text alignment controls. Synthetic paragraph appears in editor and document preview before Done." + }, + { + "status": "Verified", + "finding": "45-second window recorded two successful POST /api/letters/save_body requests, both 200 application/json. No content bodies, credential headers or query values retained." + }, + { + "status": "Inferred", + "finding": "Save requests while form remains open are consistent with automatic saving before Done. Exact debounce, duplicate-request cause, storage semantics and reload durability remain unknown." + }, + { + "status": "Not Tested", + "finding": "Richtext formatting effects, preview latency, request-error feedback, undo/redo for body content, grammar/AI assistance, signature image input and backend persistence after reload." + }, + { + "status": "Verified", + "finding": "Body richtext textbox has an empty accessible name. Screenshot and AX show paragraph in bold in editor and preview; direct toolbar action sequence was not observed." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L7-letter-customize-evidence.json", + "sha256": "868e83f3f221845df8aa15455d41dfc810fb493f50251393598c3b57f0eb5b91", + "checkpoint": "L7", + "manualAction": "User clicked body Done and opened letter Customize.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 413, + "findings": [ + { + "status": "Verified", + "finding": "Letter Customize at /cover-letter/design has Copy resume design and Browse templates, plus anchor navigation for document, templates, layout, header, photo, font size, spacing, font, colors, links and footer." + }, + { + "status": "Verified", + "finding": "Letter-specific controls include sender style, date/recipient drag reorder, position choices, declaration position/line and name emphasis; common typography/color/header/link/footer controls also appear." + }, + { + "status": "Verified", + "finding": "Current design shows Modern Header, Source Sans Pro body, name Same as body font, base 11pt, line height1.5 and 16mm margins. Letter remains alongside controls; synthetic body and copied sender retained." + }, + { + "status": "Not Tested", + "finding": "Copy resume design mapping/confirmation, letter template application, reordering letter blocks, photo/signature behavior, cover-letter undo/redo and matching export." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L8-copy-resume-design-prompt-evidence.json", + "sha256": "bdd8fae2893f4adb87bd6b6ea4df4accb3c85c0173e30fc532660505e4ce2e34", + "checkpoint": "L8", + "manualAction": "User opened Copy resume design and selected Resume 1, pausing before Copy design.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 430, + "findings": [ + { + "status": "Verified", + "finding": "Copy resume design opens source selector with explicit scope: matching colors, typography, spacing, layout, header and footer settings will be replaced." + }, + { + "status": "Verified", + "finding": "Selected synthetic Resume 1 is shown; Copy design enabled and Cancel available. Data import is separate from design import." + }, + { + "status": "Not Tested", + "finding": "Which settings map exactly, copied sender style, content preservation after apply, undo and continued synchronization." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "L9-resume-design-copied-evidence.json", + "sha256": "24d3bdcd2581c6668749a6c7f4965e82b9e1b8140537e09f370b690c1f70470a", + "checkpoint": "L9", + "manualAction": "User confirmed Copy design from synthetic Resume 1 and left resulting letter Customize visible.", + "viewport": { + "width": 1912, + "height": 948 + }, + "accessibilityNodes": 413, + "findings": [ + { + "status": "Verified", + "finding": "Copy design closes dialog and updates letter preview/settings while retaining synthetic body and copied sender." + }, + { + "status": "Verified", + "finding": "Name/professional-title offsets change +8/+2 to +11/+5; margins change from16mm to22mm horizontal/12mm vertical. Link icon becomes checked. Base11pt, Source Sans Pro and centered Modern Header remain." + }, + { + "status": "Verified", + "finding": "Letter line-height now displays1.2, while captured resume line-height was1.15. This is a mapped compatible design, not demonstrated pixel-identical settings." + }, + { + "status": "Inferred", + "finding": "Line-height difference may be rounding, clamping or document-specific mapping; implementation unknown and not inferred from pixels alone." + }, + { + "status": "Not Tested", + "finding": "Live synchronization after resume changes, complete copied-setting equivalence, design-copy undo, export matching and letter-specific layout edge cases." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "M1-mobile-content-evidence.json", + "sha256": "ca7cd07ad839edd60286d0b93a6b1fa2d1865f5b6c880fd7f770174ec8fab1b9", + "checkpoint": "M1", + "manualAction": "User opened Content and manually configured narrow responsive viewport, then scrolled top. REA observed 390x840.", + "viewport": { + "width": 390, + "height": 840 + }, + "accessibilityNodes": 228, + "findings": [ + { + "status": "Verified", + "finding": "At observed 390x840 viewport desktop split view becomes a single editing column. Top bar contains FlowCV logo and Menu; content cards remain full-width." + }, + { + "status": "Verified", + "finding": "Fixed bottom action bar exposes Preview and Add Content. Preview document text is absent from current AX snapshot; content editor remains available." + }, + { + "status": "Verified", + "finding": "Section order retains Skills above Education; synthetic new project remains in section inventory. Resume data survives the tested route and viewport transitions." + }, + { + "status": "Not Tested", + "finding": "Real phone input/touch, mobile keyboard, screen rotation, horizontal overflow measurements, focus containment, mobile form editing, preview zoom and responsive breakpoints between desktop/mobile." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "M2-mobile-preview-evidence.json", + "sha256": "ea6252ea2e15638256af7575224f74e465e744164d48b98e417972089d3a993d", + "checkpoint": "M2", + "manualAction": "User tapped Preview from mobile bottom action bar and left overlay open without zooming.", + "viewport": { + "width": 390, + "height": 840 + }, + "accessibilityNodes": 380, + "findings": [ + { + "status": "Verified", + "finding": "Preview opens an overlay with document pages scaled to narrow viewport width and stacked vertically. Keep editing and Download remain fixed at bottom." + }, + { + "status": "Verified", + "finding": "Two page surfaces are visible, showing synthetic content and manual section order. No dedicated zoom or page-jump control is visible or named in current AX snapshot." + }, + { + "status": "Verified", + "finding": "Underlying content controls remain in AX with Preview reported focused; overlay has no dialog role in this capture. Keyboard/focus behavior needs direct testing." + }, + { + "status": "Not Tested", + "finding": "Pinch zoom, keyboard zoom, scroll-to-page behavior, background scroll lock, focus restoration, mobile export success and real-device viewport behavior." + } + ], + "namedInteractiveControls": [] + }, + { + "file": "M3-mobile-experience-form-evidence.json", + "sha256": "6adb05dfcfe717fd59deca710aeffadf05bcdfdb2eb2e7954510897c11dcfd29", + "checkpoint": "M3", + "manualAction": "User returned from Preview and opened synthetic experience entry at mobile viewport.", + "viewport": { + "width": 390, + "height": 840 + }, + "accessibilityNodes": 81, + "findings": [ + { + "status": "Verified", + "finding": "At 390x840, experience form stacks Job Title/Employer/Location/Description; Start Date and End Date remain side by side. Fixed bottom Preview and Done actions replace desktop Done card." + }, + { + "status": "Verified", + "finding": "Richtext alignment changes from four separate desktop alignment buttons to named Text alignment: left dropdown. Bold/Italic/Underline/Bullets/Link remain visible." + }, + { + "status": "Verified", + "finding": "Mobile top bar provides Content back navigation and Menu. Tips, hide and delete icons remain; date inputs still have identical MM/YYYY accessible names." + }, + { + "status": "Not Tested", + "finding": "On-screen keyboard occlusion, typing/autosave on real phone, date validation, touch target sizes, mobile richtext editing and focus behavior." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Job Title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Description" + ] + ] + }, + { + "file": "M4-date-range-edge-evidence.json", + "sha256": "3b24b2b8abf0b4d1171f71ecd09414095bde18562028a043b64b744ba70f66c0", + "checkpoint": "M4", + "manualAction": "User tried earlier end date via picker, reported earlier year unavailable, and selected Jan 2026 while start remained Feb 2026. No Done/submit performed.", + "viewport": { + "width": 390, + "height": 840 + }, + "accessibilityNodes": 105, + "findings": [ + { + "status": "Verified", + "finding": "Captured form simultaneously displays Start Date 02/2026 and End Date 01/2026, with Done available, no visible error and both AX textbox invalid states false." + }, + { + "status": "Verified", + "finding": "Open end-date picker has Present (Current) unchecked, month selector including Jan-Dec/Remove month, and year option 2026/Remove year in captured AX." + }, + { + "status": "Inferred", + "finding": "Likely month-level date-range validation gap: picker appears to restrict year but permits end month before start in same year. User could not choose 2025; server-side validation and persistence of invalid range not tested." + }, + { + "status": "Not Tested", + "finding": "Done/submit behavior for invalid range, backend acceptance, direct typed values, current-date upper bound, year-only semantics, localization, validation after start-date change and exported invalid range." + } + ], + "namedInteractiveControls": [ + [ + "textbox", + "Job Title" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "MM/YYYY" + ], + [ + "textbox", + "Location" + ], + [ + "textbox", + "Description" + ] + ] + } + ], + "limits": "Original third-party PNG and DOM remain external research references. Contact-sheet visual inspection and selected DOM/AX inspection do not establish human/device testing." +} \ No newline at end of file