docs(architecture): mark Phase 3 career foundation shipped
CI and Deploy / test (push) Failing after 1m51s
CI and Deploy / deploy (push) Has been skipped

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
cesnimda
2026-07-18 01:03:40 +02:00
parent a1dd447091
commit 707d8c59d2
2 changed files with 30 additions and 1 deletions
+21
View File
@@ -7,6 +7,27 @@
> Companion to `docs/architecture/current.md` §4a (profile/career separation) and > Companion to `docs/architecture/current.md` §4a (profile/career separation) and
> `docs/decisions/ADR-002-job-application-model.md`. Verified against code on 2026-07-18. > `docs/decisions/ADR-002-job-application-model.md`. Verified against code on 2026-07-18.
> ## Implementation status (2026-07-18) — SHIPPED
>
> The model below is implemented on `main` and verified against the live database:
> - **Entities** (`Models/CareerEntities.cs`): `CareerExperience`, `CareerEducation`, `CareerSkill`,
> `CareerProject`, `CareerCertification`, `CareerLanguage` — relational children of `CareerProfile`;
> long tail in `CareerProfile.LongTailJson`. Migration `AddCareerProfileRelationalChildren`
> (applied cleanly on the real dev DB and the running container).
> - **Projection** (`CareerProfileService` + `CareerProfileMapper`): relational is the source of
> truth; `SaveVersionAsync` syncs children + long tail; `LoadStructuredAsync` reads relationally
> with lazy backfill from the blob; the `ProfileCvStructureJson` blob is kept as the derived
> projection.
> - **API** (`CareerProfileController`, `/api/career/profile`): GET/PUT profile, GET completeness,
> GET versions, POST version restore. Validation via `CareerProfileValidator` (abuse limits).
> - **Frontend** (`/career`): reads/writes the relational API, profile-completeness overview,
> version-history restore.
> - **Tests**: 23 career-focused backend tests (round-trip, item-key stability, replace-all,
> backfill, completeness, validation, versioning/restore) + frontend save/completeness tests.
>
> Not yet done (later): promote the long tail to relational if needed; a full section-by-section UX
> redesign of the editor; the eventual removal of the derived blob once every reader flips.
--- ---
## 1. Where we start (F1, on `main`) ## 1. Where we start (F1, on `main`)
+9 -1
View File
@@ -72,9 +72,17 @@ Goal: the guide's "users should always understand where they are, what they can
Goal: one professional source of truth that can actually feed outputs. Goal: one professional source of truth that can actually feed outputs.
> **Foundation SHIPPED 2026-07-18** (commits `9c8644e`…`a1dd447`). The relational master career
> profile is built, tested (23 backend + frontend tests), migrated (verified on the live DB), wired
> to `/career`, with completeness overview + version-history restore. See
> `docs/architecture/career-profile-model.md` (Implementation status). Tasks 3.1, 3.3, 3.4 and the
> versioning/validation goals are delivered. Remaining below: 3.2 (long-tail-as-relational, deferred
> — currently JSON), 3.5 (CV variants — Phase 4), 3.6 (retention), plus a full section-by-section UX
> redesign of the editor (polish; the functional workspace exists).
| # | Task | Priority | Difficulty | Dependencies | Expected value | | # | Task | Priority | Difficulty | Dependencies | Expected value |
|---|---|---|---|---|---| |---|---|---|---|---|---|
| 3.1 | **Model Experience/Education/Skills/Projects relationally**; keep the long tail (awards, publications, organisations, references, custom sections) as a JSON blob. **Decided 2026-07-17** — no longer an open question. | **P1** | **L** | 1.9 | Buys queryable skills (needed for real matching + keyword gaps), section-level history, and concurrent-edit safety. Hybrid avoids a full rewrite of `StructuredCvProfile`. **Check task 1.9 first** — orphan `CareerProfiles`/`CvVersions` tables suggest this was attempted before. | | 3.1 | **DONE** Experience/Education/Skills/Projects/Certifications/Languages are relational children of `CareerProfile`; long tail is JSON. Projection service keeps the blob as a derived read-model; lazy backfill from existing data. | **P1** | **L** | 1.9 | Delivered. Queryable structured career data is now the source of truth; the blob is derived. |
| 3.2 | **Add the missing profile sections** — Awards, Publications, Organisations, References | **P1** | **S** | 3.1 | The guide names them; `StructuredCvProfile` has no home for them beyond generic `OtherSections`. These are the blob half of 3.1. | | 3.2 | **Add the missing profile sections** — Awards, Publications, Organisations, References | **P1** | **S** | 3.1 | The guide names them; `StructuredCvProfile` has no home for them beyond generic `OtherSections`. These are the blob half of 3.1. |
| 3.3 | **Real Career Workspace page** — replace the 36-line tab facade | **P1** | **M** | 2.1, 2.2 | Currently a wrapper around `ProfilePage`. | | 3.3 | **Real Career Workspace page** — replace the 36-line tab facade | **P1** | **M** | 2.1, 2.2 | Currently a wrapper around `ProfilePage`. |
| 3.4 | **Separate Career Profile from Master CV** | **P1** | **M** | 3.1 | The glossary is explicit — "The career profile is NOT a CV"; Master CV is a *generated representation*. Code has one blob. Getting this wrong makes Phase 4 impossible. | | 3.4 | **Separate Career Profile from Master CV** | **P1** | **M** | 3.1 | The glossary is explicit — "The career profile is NOT a CV"; Master CV is a *generated representation*. Code has one blob. Getting this wrong makes Phase 4 impossible. |