CV-Engine/README.md
geulah 1bede93cd1 feat: initialize CV Engine project with core functionality
- Set up React + TypeScript + Vite project with TailwindCSS
- Implement Zustand store for CV data management
- Create personal details editor with validation
- Add ATS-friendly template for CV preview
- Build stepper navigation component
- Include schema validation with Zod
- Configure ESLint and Prettier for code quality
2025-10-05 22:53:40 +01:00

243 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# CV Editor Engine — Development Guide
This guide turns the CV editor engine plan into concrete, incremental tasks you can implement. It defines scope, architecture, data model, workflows, templates, preview/export, validation, accessibility, security, performance, testing, and milestones with acceptance criteria.
## Objectives
- Deliver a fast, accessible CV builder with live preview and high-quality PDF export.
- Keep data structured and templates decoupled for ATS-friendly and visual layouts.
- Ensure printable parity between inline preview and final PDF output.
## Tech Stack
- Client: React, TailwindCSS, Zustand, TanStack Query, Tiptap (+ DOMPurify)
- Server: Node.js + Express for export, Puppeteer/Playwright for PDF rendering
- Validation: Zod (or Yup)
- Testing: Vitest/Jest, React Testing Library, Playwright for E2E
## Repo Layout (proposed)
```
src/
components/ # UI building blocks (forms, lists, stepper)
editors/ # Step editors (Heading, Work, Education, Skills, Summary)
templates/ # Inline templates (ATS, Visual) + shared formatters
printable/ # Printable HTML builder and styles (@page, A4)
store/ # Zustand store, mutations and selectors
services/ # API calls (save/load/export) and helpers
utils/ # escapeHtml, sanitizers, validators, formatters
hooks/ # autosave, debounced change tracking, accessibility
server/
export/ # Express route for PDF export
tests/ # Unit, integration, E2E, visual regression
```
## Conventions
- Strictly sanitize user HTML via `DOMPurify` and escape all text in templates.
- Keep templates pure: accept CV JSON and return JSX/HTML; no side effects.
- Scope styles via CSS modules or Tailwind; avoid global leakage.
- Maintain preview ↔ printable parity using shared formatters and data.
## Data Model (Zod-style)
```ts
const CvSchema = z.object({
personal: z.object({
firstName: z.string().min(1),
lastName: z.string().min(1),
email: z.string().email(),
phone: z.string().optional(),
street: z.string().optional(),
city: z.string().optional(),
country: z.string().optional(),
postcode: z.string().optional(),
links: z.array(z.object({ label: z.string(), url: z.string().url() })).optional(),
extras: z.array(z.string()).optional(), // e.g., LinkedIn, Website, Driving licence
}),
summary: z.string().max(600).optional(),
work: z.array(z.object({
id: z.string(),
title: z.string().min(1),
company: z.string().min(1),
location: z.string().optional(),
startDate: z.string(), // ISO or YYYY-MM
endDate: z.string().optional(),
bullets: z.array(z.string().max(160)).max(6),
employmentType: z.enum(['full_time','part_time','contract','intern','freelance']).optional(),
})),
education: z.array(z.object({
id: z.string(),
degree: z.string().min(1),
school: z.string().min(1),
startDate: z.string(),
endDate: z.string().optional(),
notes: z.string().optional(),
})),
skills: z.array(z.object({ name: z.string(), level: z.enum(['Beginner','Intermediate','Advanced']).optional() })),
languages: z.array(z.object({ name: z.string(), level: z.enum(['Basic','Conversational','Fluent','Native']) })).optional(),
certifications: z.array(z.object({ name: z.string(), issuer: z.string().optional(), date: z.string().optional() })).optional(),
templateId: z.string().default('ats'),
});
```
Validation rules
- Required: `firstName`, `lastName`, `email`; at least one of `work` or `education`.
- Bullets: 16 per role; each ≤160 chars; avoid trailing punctuation.
- Summary: ≤600 chars; discourage emojis; sanitize on save/render.
- Links: normalize to `https://`; restrict protocols to `http`, `https`.
## Editor Flow
- Stepper: Heading → Work → Education → Skills → Summary → Finalize
- Each step runs field validation on blur and pre-navigation; critical errors block Next (e.g., invalid email).
- Drag-and-drop reorder for Work and Skills; inline error messages with `aria-describedby`.
## Template System
- Template API: `{ id, name, renderer(cv), thumbnail? }`
- Shared formatters: `formatDate`, `formatLocation`, `escapeText`, `sanitizeHtml`.
- Templates
- ATS: semantic lists, neutral styles, no sidebars, simple typographic accents.
- Visual: sidebar contact, accented headings, subtle color blocks (similar to sample CV).
## Inline Preview
- Render chosen template directly from CV JSON; debounce heavy updates.
- Memoize template components; isolate styles via Tailwind scopes or modules.
## Printable Preview (Iframe)
- `buildPrintableHtml(cv)` returns a complete HTML document:
- `<html>` with embedded CSS: `@page { size: A4; margin: 18mm }` and print-safe font stack.
- No external scripts; all assets inline; background printing enabled.
- Load via `iframe srcDoc`; maintain parity with inline by sharing formatters and sanitized summary.
## Export Service
- Express `POST /export/pdf`
- Input: CV JSON (validated on server)
- Compose: `buildPrintableHtml(cv)`
- Render: Puppeteer `page.setContent(html, { waitUntil: 'networkidle0' })`, `page.pdf({ format: 'A4', printBackground: true })`
- Output: `application/pdf` stream with filename `cv-<lastName>-<YYYYMMDD>.pdf`
- Client: Export button calls endpoint; stream download; show progress & errors.
## Persistence & Autosave
- Autosave: debounce 12s after idle; mark dirty while saving; show last-saved timestamp.
- API
- `GET /cv/:id` → load draft
- `PUT /cv/:id` → save draft
- `POST /export/pdf` → export
- Store integration via TanStack Query mutations and selectors in Zustand.
## Accessibility
- Labels with `htmlFor`; inputs with `aria-describedby` for errors; ensure WCAG AA contrast.
- Keyboard navigation for stepper and list CRUD; focus management after add/delete.
- Templates use semantic elements: `header`, `section`, `ul`, avoiding purely presentational markup.
## Security
- Sanitize summary on input and before render; escape all template-bound text.
- Restrict allowed URL protocols; validate `mailto:` only for email display links (never user-provided).
- No inline scripts; printable builder is self-contained HTML/CSS.
## Performance
- Debounce preview/autosave; throttle rapid list operations.
- Lazy-load noncritical components (template gallery); memoize heavy subtrees.
- Avoid large assets; prefer CSS accents; keep DOM size lean.
## Testing Strategy
- Unit
- `escapeHtml`, `sanitizeHtml`, formatters, Zod validators, store selectors
- Integration
- Inline ↔ printable parity across templates
- Autosave flows and error handling
- Export success/failure
- E2E (Playwright)
- Create CV → navigate steps → validate errors → switch templates → preview → export PDF
- Visual Regression
- Printable HTML screenshots per template and key data permutations
## Error Handling
- Centralized error boundary; step-level error summaries; non-blocking for non-critical issues.
- Graceful server errors with retry; maintain local draft if save/export fails.
## Milestones & Tasks
### M1 — Foundations
Tasks
- Initialize client app and Tailwind; set up routing.
- Create `CvSchema`, types, and helpers (normalization, IDs).
- Implement Zustand store: CV draft, active step, templateId, UI flags.
- Build Stepper and Heading editor form with validation.
- Implement ATS inline template and preview panel.
Acceptance
- User can enter heading details with inline validation and see preview update.
- Data stored in Zustand; template renders from CV JSON.
### M2 — Content Steps
Tasks
- Work editor: CRUD, reorder, bullet editor with length guidance.
- Education editor: CRUD; reuse shared list components.
- Skills editor: tag input + quick-add chips; optional level.
Acceptance
- Add/update/delete/reorder across steps; errors appear in-place; preview updates live.
### M3 — Summary & Printable
Tasks
- Integrate Tiptap (StarterKit + Placeholder); toolbar with basic marks.
- Sanitize output; store HTML + optional JSON.
- Implement `buildPrintableHtml(cv)` and iframe preview with A4 styles.
Acceptance
- Printable preview matches inline layout (content, spacing, formatting); summary sanitized.
### M4 — Persistence
Tasks
- Wire autosave with debounced mutations; load on mount.
- Add last-saved timestamp and dirty state.
- Handle save/load errors gracefully.
Acceptance
- Draft persists across reloads; autosave feels responsive and safe.
### M5 — Export
Tasks
- Server: Express route for `POST /export/pdf` using Puppeteer.
- Client: Export button; download with progress; error UI.
Acceptance
- PDF export produces a visually faithful A4 document with correct filename.
### M6 — Templates
Tasks
- Add Visual template; gallery picker with thumbnails and filters (ATS vs Visual).
- Persist `templateId`; ensure both inline and printable support switching.
Acceptance
- Users switch templates instantly; parity holds across preview and PDF.
### M7 — QA & Polish
Tasks
- Accessibility pass; performance tuning; code cleanup.
- Unit, integration, E2E, visual tests; CI workflow.
Acceptance
- Tests green; meets accessibility and performance targets.
### M8 — Enhancements (optional)
Tasks
- Import structured CV (JSON); version history; i18n; AI assist.
Acceptance
- Optional features are behind flags and do not regress core flows.
## Setup (placeholder)
Commands to run once you scaffold the app:
```
npm create vite@latest cv-engine -- --template react-ts
cd cv-engine
npm i tailwindcss @tiptap/react @tiptap/starter-kit dompurify zustand @tanstack/react-query zod puppeteer express
npx tailwindcss init -p
```
Adapt paths to your chosen structure. This repo currently contains planning documents only.
## Acceptance Criteria Checklist (global)
- Structured CV JSON validated end-to-end
- Live inline preview with ATS template by M1
- Printable HTML parity by M3 (layout, spacing, typography, sanitization)
- Autosave with clear feedback by M4
- Reliable PDF export by M5
- At least two templates with instant switching by M6
- Accessibility AA and test coverage by M7
## Glossary
- ATS: Applicant Tracking System; favors semantic, minimal styling.
- Parity: Inline preview and exported PDF display equivalent content/layout.
- Printable builder: Function that returns a self-contained HTML document for PDF rendering.
---
Use this README as the source of truth during implementation. Update sections as architecture evolves, but keep template parity, sanitization, and accessibility as non-negotiable constraints.