refactor(career): Phase 1 increment 2 — extract editor sections, hide duplicate CV concepts
UI-only. No change to APIs, save payloads, extraction behaviour, or data
models. The parent CareerProfilePage still owns loading, state, saving,
and all extraction/import actions; the new sections are presentational
(value + onChange, plus a getMetadata callback for review chips).
Extracted into src/views/career/CareerProfileSections.tsx:
PersonalInformation, ProfessionalSummary, Skills, Interests, Languages,
WorkExperience, Education, OtherSections. FieldReviewNote + confidenceTone
moved there verbatim and shared with the parent. CareerProfilePage went
from 1376 to ~1200 lines.
No Projects/Certifications sections were created -- the editor never had
them (they are not editable structured fields here). Inventing them would
add functionality, which this refactor avoids; noted for a product
decision later.
Hid the duplicate CV concepts behind an "Advanced CV tools" toggle,
collapsed by default: the CV Structure Overview parse block and the
Template-driven CV builder. Both stay mounted and functional (gated with
display:none), so no tested functionality is removed -- the real CV
Builder at /career/builder is the single generation surface. Future
removal plan documented.
Tests: added "editing a field in an extracted section updates parent
state and flows into save" (render -> edit -> PUT /career/profile
{profile,cvText}); existing parse/rewrite tests reveal the advanced tools
first. The increment-1 save-invariant test still pins the payload.
Verified: tsc clean, production build clean, 137 frontend tests pass.
Backend untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -106,20 +106,57 @@ tests were re-pointed to the new labels; all behavioural assertions (save, parse
|
||||
*Verified:* tsc clean, production build clean, 136 frontend tests pass (was 135; +1 invariant test).
|
||||
Sidebar fix from the previous task still passes.
|
||||
|
||||
**Remaining in Phase 1 (staged, needs the app running to click-verify each section's save
|
||||
round-trip):**
|
||||
- Extract the editing sections into `PersonalInformationSection … LanguagesSection` components and a
|
||||
`CareerProfileHeader`, keeping `structuredCv` + `setStructuredCv` + the save handler in the parent
|
||||
(so behaviour stays identical). This is voluminous mechanical JSX movement through a 1376-line file.
|
||||
- Hide the **template-driven CV builder** (rewrite templates + PDF carousel) and the **structure
|
||||
overview** parse block from the user surface. Both are tested against live extraction behaviour, so
|
||||
each removal must move its test coverage, not delete it — done incrementally with verification.
|
||||
- Per-section actionable empty states ("No work experience added yet" → [Add experience]); the Add
|
||||
affordances already exist, so this is copy + wiring.
|
||||
**Delivered 2026-07-20 (increment 2 — COMPLETED):**
|
||||
|
||||
Rationale for staging: these touch the live CV/extraction test surface and are best verified by
|
||||
driving the authenticated UI. Increment 1 is a clean, non-regressing checkpoint per the "reviewed and
|
||||
verified before Phase 2" instruction.
|
||||
*Sections extracted* into `src/views/career/CareerProfileSections.tsx` (one file, one component per
|
||||
export), plus `FieldReviewNote` + `confidenceTone` moved there verbatim and shared with the parent:
|
||||
|
||||
| Component | Slice | Props |
|
||||
|---|---|---|
|
||||
| `PersonalInformationSection` | `contact` | `value`, `onChange`, `getMetadata` |
|
||||
| `ProfessionalSummarySection` | `summary` | `value`, `onChange`, `getMetadata` |
|
||||
| `SkillsSection` | `skills` | `value`, `onChange`, `getMetadata` |
|
||||
| `InterestsSection` | `interests` | `value`, `onChange`, `getMetadata` |
|
||||
| `LanguagesSection` | `languages` | `value`, `onChange`, `getMetadata` |
|
||||
| `WorkExperienceSection` | `jobs` | `value`, `onChange` |
|
||||
| `EducationSection` | `education` | `value`, `onChange` |
|
||||
| `OtherSectionsSection` | `otherSections` | `value`, `onChange` |
|
||||
|
||||
Each section is presentational: it receives its slice + `onChange(next)`; the parent still holds
|
||||
`structuredCv`, loads, saves, and owns every extraction/import action. `getMetadata` is a callback
|
||||
(`getStructuredCvFieldMetadata` over the whole profile) so sections stay decoupled from the full shape.
|
||||
No section makes an API call. `CareerProfilePage` dropped from 1376 → ~1200 lines.
|
||||
|
||||
**No `ProjectsSection` / `CertificationsSection` were created** — the editor never had those sections
|
||||
(`StructuredCvProfile` has no editable projects/certifications UI here; such content lives in "Other
|
||||
sections"). Inventing them would add functionality, which this refactor explicitly avoids. Flagged for
|
||||
a product decision in a later phase.
|
||||
|
||||
*Duplicate concepts hidden* (not deleted) behind an **"Advanced CV tools"** toggle on the Career
|
||||
Profile page, collapsed by default:
|
||||
- **CV Structure Overview** ("Profile sections" parse block)
|
||||
- **Template-driven CV Builder** (rewrite templates + PDF carousel)
|
||||
|
||||
Both stay mounted and fully functional — gated with `display: none` via `showAdvancedCvTools`, so the
|
||||
underlying flows (and their tests) are intact and reachable, just out of the default workflow. The
|
||||
real CV Builder at `/career/builder` is the single CV-generation surface.
|
||||
|
||||
*Tests* (all green): existing profile-page tests re-pointed to reveal advanced tools before touching
|
||||
those controls; added "editing a field in an extracted section updates parent state and flows into
|
||||
save" (proves render → edit → `PUT /career/profile { profile, cvText }`). The save-invariant test from
|
||||
increment 1 still pins the exact payload.
|
||||
|
||||
*Verified:* tsc clean, production build clean, **137 frontend tests pass**. No API, save-payload,
|
||||
extraction, or data-model change.
|
||||
|
||||
**Future removal plan (later phase, not now):** once Phase 2 (Import CV review) and the real CV
|
||||
Builder cover every flow the hidden blocks serve, delete the structure-overview parse block and the
|
||||
template-driven builder from `CareerProfilePage` entirely, and drop the `showAdvancedCvTools` toggle.
|
||||
Until then they remain behind the toggle so no tested functionality is lost.
|
||||
|
||||
**Still open for Phase 1 polish (optional, low priority):** a dedicated `CareerProfileHeader`
|
||||
component and per-section actionable empty-state copy ("No work experience added yet" → the Add button
|
||||
already present). Neither is blocking; both are cosmetic.
|
||||
|
||||
### Phase 2 — Import CV review screen
|
||||
Add a post-upload "New information found" review (Experience / Skills / Languages / Education) with
|
||||
|
||||
Reference in New Issue
Block a user