feat(cv): rebuild professional resume studio
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user