Phase 3, API layer. GET/PUT /api/career/profile — the endpoint the /career editor
uses to read and write the master profile.
- GET: returns the structured profile (assembled from the relational children,
backfilled from the blob if needed) plus a completeness scorecard.
- PUT: validates limits, persists via CareerProfileService (relational children +
append-only version), then serializes the result into
ApplicationUser.ProfileCvStructureJson so the legacy read paths stay in sync.
Identity fields are untouched (they belong to /profile).
- GET /completeness: just the scorecard, for the overview.
- CareerCompleteness: weighted percent + missing sections.
- CareerProfileValidator: item-count/length limits (abuse guard, NOT completeness
— a work-in-progress profile always saves).
Tests (+4): put/get round-trip + projection sync, completeness, over-limit
rejection, empty WIP profile accepted.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>