feat(cv): rebuild professional resume studio

This commit is contained in:
cesnimda
2026-08-24 20:21:23 +02:00
parent dca5daa1a2
commit 367b70681a
27 changed files with 827 additions and 187 deletions
+18 -6
View File
@@ -29,7 +29,9 @@ The master profile is never written by the builder. A variant references career
`SettingsJson` blob (`CvVariantSettings`, `JobTrackerApi/Models/CvVariantSettings.cs`) because it is edited and saved
as a unit — never queried field-by-field. A variant stores:
- `ThemeId` + overrides: accent, heading/body font, density, page size, photo/icons/page-numbers.
- `ThemeId` + normalized overrides: printable colours, curated heading/body fonts, typography,
density, A4/Letter, margins/gaps, one/two-column layout, sidebar assignment, heading/header and
skills treatments, photo/icons and the retained page-number extension point.
- `Sections`: ordered list with per-section `Hidden` + optional renamed `Title`.
- `Overrides`: keyed by `ItemKey``{ Hidden, Title, Subtitle, Bullets }` (per-item, job-specific).
- `CustomSections`: variant-only sections not in the master profile.
@@ -46,7 +48,8 @@ as a unit — never queried field-by-field. A variant stores:
## API
Authenticated (`/api/cv`, `CvVariantController`): `GET themes`; `GET/POST variants`;
Authenticated (`/api/cv`, `CvVariantController`): `GET themes`; `GET themes/{id}/preview`;
`GET/POST variants`;
`GET/PUT/DELETE variants/{id}`; `POST variants/{id}/duplicate`; `PUT variants/{id}/public`;
`GET variants/{id}/versions`, `POST …/versions/{v}/restore`; `GET variants/{id}/preview` and
`POST preview` (live preview of unsaved settings); `POST variants/{id}/export-pdf`; `POST ai/assist`.
@@ -61,10 +64,16 @@ The endpoint applies the identical public/private slug check; unknown, revoked,
404 without invoking the exporter. Anonymous PDF generation is limited to three requests per minute
per public link because it launches Chromium. `PublicCvPage` exposes it as a native **Download PDF** link.
CV/job associations are authorized server-side during creation. A caller cannot attach a CV to
another user's job merely by supplying its numeric ID. List cards resolve an associated job's title
and company only through the owner-filtered relationship.
## Builder workflow (frontend)
`/career/builder` lists variants (`CvBuilderPage`); the editor (`CvBuilderEditor`) is three tabs —
**Content**, **Customize**, **AI Tools** (plus **History**) — beside an always-on live preview that
`/career/builder` lists variants (`CvBuilderPage`) with real rendered template thumbnails, language,
modified/version state and associated-job context. Creation asks only for a name and template. The
editor (`CvBuilderEditor`) separates **Content**, **Template**, **Design**, **Layout**, **AI** and
**History** beside an always-on desktop preview that
re-renders through `POST /api/cv/preview` on a 300 ms debounce. Edits autosave on an 800 ms debounce
(`source: autosave`), appending a version each save; the header shows Unsaved / Saving / Saved.
`/cv/:slug` (`PublicCvPage`) renders a public CV in a sandboxed iframe.
@@ -75,9 +84,12 @@ buttons (the keyboard-accessible path); entry order is stored per section as `It
variant, never on the profile. Each entry exposes hide, title/subtitle override, and rich-text bullet
editing (`RichTextField` — a markdown toolbar over a textarea; storage stays plain text, the server
renderer converts the `**bold** *italic* __underline__ [text](url)` whitelist to safe HTML).
Contact details and career history remain master data; the Content tab explains this boundary and
links to the master editor while variant-specific wording, order, headings and visibility stay local.
**Preview** has zoom presets (±, slider, measured Fit), physical A4/Letter dimensions, a ceiling-based
page count with prev/next navigation and page-break indicators, and an "updating…" chip. Three-page
**Preview** displays separate labelled A4/Letter page sheets rather than one infinite document. It has
zoom controls, measured Fit, a ceiling-based page count with prev/next navigation, and an "updating…"
chip. Three-page
and longer documents receive content-focus guidance rather than automatic font shrinking. Preview
requests and autosaves are ordered so stale responses cannot replace newer edits; PDF/public actions
save the current variant before consuming the stored render. **Customize** badges ATS-friendly themes.