Files
jobtrackingapp/docs/cv-integration-qa/ARCHITECTURE_AND_COVERAGE.md
T

11 KiB
Raw Blame History

CV-QA-00 architecture and baseline coverage

26 October 2026. Baseline ef425c288b38ae0e91dcc216a5c8b6c02c433ab5; branch test/cv-integration-acceptance, containing CV-UX 4a0af62. Clean local/fetched import HEAD matched. All 84 CV-import indexed evidence hashes matched. Fresh isolated MariaDB entry run: 70/70, no skips (.artifacts/cv-integration-qa/entry-mariadb-01), not production.

Authority: docs/architecture/current.md → overview.md; CV-UX/CV-import ACCEPTANCE reports and CV-QA handoff; RD21 SAVE_CONTRACT; latest P9-SEC-02 addendum/verdicts; Phase 9 preservation inventory/Phase10 handoff. Historical RD21/provider blocks were superseded by actual provider qualification. P9-SEC-02 records RD21 RESOLVED and narrow trained-BART/cache compatibility PASS, with Python security CONDITIONAL PASS (vendor PyPI query gap), hosted MariaDB BLOCKED/isolation UNVERIFIED. That is not qualification of the new CV Ollama adapter or production. Original Phase10 deletion eligibility requires candidate-specific caller/route/inventory/test proof; production-only gates do not automatically block separately scoped development.

Lifecycle and owners

flowchart LR
 U[CareerProfilePage upload] --> V[ProfileCvController.Import validation]
 V --> A[CvUploadArtifact + CvExtractionRun]
 A --> Q[cv.process operation / worker lease]
 Q --> S[SummarizerService → FastAPI app.py]
 S --> P[bounded parser_child.py / Docling native]
 P --> B[ordered id/text/kind/page blocks]
 B --> I[CvDocumentInterpreter]
 I --> G[CvDocumentReview.Ground]
 G --> R[CvImportReview / owned source endpoint]
 R --> T[apply-reviewed / expectedVersion / ExecuteAtomicAsync]
 T --> C[CareerProfileService + Mapper + children/history/Identity]
 C --> E[CvBuilderEditor / resolver / variant overrides]
 E --> D[template physical renderer / preview / revisioned PDF]
 D --> J[ApplicationAssetsService / frozen application package]

Historical entry findings (before remediation): CvDocumentReview/CvImportReview exposed only nonempty incoming typed leaves. add meant accepting an emitted field; it could not create missing fields/records. New extracted records were already appended, but missing-record authoring, explicit target selection and source assignment were absent. CvDocumentInterpreter handled positional pipe rows and section lists; later undelimited lines could be wrongly attached to the last global record. Transport discarded Docling hierarchy/geometry/table cells, so the order of two unlabeled text lines could not prove employer versus title. Ground selected the first document-wide substring, losing repeated-occurrence association. Current remediations and remaining limits are documented in CAREER_PROFILE_MAPPING.md and EXTRACTION_ACCURACY.md; the entry matrix below remains historical rather than being silently rewritten.

Canonical writes remain CareerProfileService.ExecuteAtomicAsync/SaveVersionAsync, CareerProfileMapper and CareerProfileValidator. CV documents/settings/overrides/history retain CvVariantService, existing resolver/editor and physical renderers. Letter/application revisions remain JobApplication.Version/ApplicationAssetsService. No second profile, queue, revision or renderer is proposed.

Field-level entry matrix

Each row follows source → interpreted field → generic emitted-field review → canonical destination → existing atomic persistence → CV Editor output. CvDocumentImportTests covers grounding/selected fields/provenance/duplicates; CvImportReviewedPersistenceTests covers durable transactional apply. CvBuilderTests and native document suites cover output owners, but do not by themselves prove imported-field integration. Statuses below are entry evidence, not final decisions.

Source / extracted canonical field Review control at entry Destination / editor output Entry classification and existing evidence
Labelled name → contact.fullName emitted string correction contact / CV header Supported with incomplete evidence: real import journeys
Email → contact.email emitted string correction contact / header Supported with incomplete evidence: parser + import journeys
Phone → contact.phone emitted string correction contact / header Supported with incomplete evidence: labelled parser, PDF fixture
Title → contact.headline emitted string correction contact / header Partially implemented: labelled only
Location → contact.location emitted string correction contact / header Partially implemented: labelled only
Website/LinkedIn/GitHub → contact.website/linkedIn/gitHub emitted string correction contact / links Supported with incomplete evidence: links regression; missing values cannot be authored
Portfolio/other links → contact.links[].label/url emitted leaves contact / labelled links Partially implemented: existing link preservation tested, missing creation absent
Summary/specialisms → summary[] emitted item correction long-tail summary / summary Supported with incomplete evidence: real PDF journey
Role/employer → jobs[].title/company emitted leaves work children / experience Partially implemented: pipe grammar, extracted-add tests; missing authoring absent
Employment start/end → jobs[].start/end emitted leaves work children / original date strings Partially implemented: partial-date/current tests; multiline dates unresolved
Current employment → jobs[].isCurrent emitted true only work children / current-date output Partially implemented: cannot author false/missing field
Job location → jobs[].location absent unless emitted work children / experience Missing deterministic mapping/review authoring
Responsibilities/achievements → jobs[].bullets[] emitted item correction work children / bullets Partially implemented: list merge/provenance tested, next-record misattribution gap
Explicit job technologies → jobs[].skills[] absent unless emitted work children / skills Missing deterministic mapping/review authoring
Institution/qualification → education[].institution/qualification emitted leaves education children / education Partially implemented: pipe grammar; missing authoring absent
Qualification level → education[].qualificationLevel absent unless emitted education children / education Missing stated-level mapping/review authoring; must not infer
Study dates → education[].start/end emitted leaves education children / dates Partially implemented: partial dates supported, multiline segmentation absent
Education location/details → education[].location/details[] emitted details only education children / details Partially implemented: location missing, continuation unsafe
Skills/frameworks/tools → skills[] emitted scalar correction skills long-tail / skills Supported with incomplete evidence: normalized source indices tested; no schema for categories/proficiency
Language/proficiency/notes → languages[].name/level/notes nonempty emitted leaves languages long-tail / languages Partially implemented: missing level stays unknown, missing authoring absent
Certification → certifications[].name/issuer/location/date/details[] emitted name/issuer/date certification children / certifications Partially implemented: PDF table association defect, location/details missing
Project → projects[].name/role/location/start/end/bullets[]/skills[] emitted name/role/bullets project children / projects Partially implemented: other fields/missing-record authoring absent
Awards → awards[] emitted items long-tail / awards Supported with incomplete end-to-end evidence
Publications → publications[] emitted items long-tail / publications Supported with incomplete end-to-end evidence
Organisations → organisations[] emitted items long-tail / organisations Supported with incomplete end-to-end evidence
Interests → interests[] emitted items long-tail / interests Supported with incomplete end-to-end evidence
References → references[] emitted items long-tail / references Supported with incomplete end-to-end evidence
Courses/custom → otherSections[].title/items[] emitted items long-tail / custom sections Partially implemented: retained source; cannot reclassify missing typed records
Stable IDs, normalized sorting dates, metadata/version no caller authoring canonical owner-generated/internal Unsupported by design as extracted facts; source date precision retained
Experience duration, new skill-category/proficiency entities none no corresponding canonical contract Unsupported by design; preserve source in custom/detail instead
AI interpretations / OCR/layout model results none active disabled/disconnected seam Blocked by external qualification; no real CV-model evidence

Current supported-document boundary (27 October addendum)

Pinned extraction remains docling-slim==2.142.1, docling-core==2.104.0, docling-parse==7.23.0 in the isolated hash-locked import runtime; no new dependency/model download was required for QA. Real document conversion is separate from generative interpretation.

Input Qualified behavior and limit
Text PDF, single/multi-page Actual local text/block/page extraction. Explicit semantic labels and supported pipe grammar can form records; complex columns/tables can require source mapping. Full arbitrary-layout semantic accuracy is not qualified.
DOCX paragraphs/headings/lists/header-defined tables Actual structured extraction and deterministic labelled records; page numbers remain unknown and excerpts are shown. Frozen labelled cases passed; headerless relationships can remain unresolved.
Genuinely ambiguous employer/title or institution/qualification Preserve visible source; user chooses fields and new/existing destination. No relationship guessed from capitalization or employer dictionaries. Legacy headerless pipe order remains an explicit compatibility limitation.
Scanned/image-only PDF OCR disabled in qualified import configuration; unsupported/unreadable outcome is explicit. No scan-accuracy claim.
Active/malformed/oversized/archive-bomb documents Reject under bounded security rules rather than claim extraction support.
Other legacy file types Existing older importer retains its supported path; this QA does not qualify them as Docling PDF/DOCX workflow.

No real CV-model inference was run. Model adapter contracts/synthetic responses establish integration seams only. Partial deterministic recall and open human/device/security/release qualifications remain independent.

Preservation impact

All 57 groups / 33 routes remain in scope; no historical status is upgraded by this audit. Direct changes: PRES-C01/C02/C03 (canonical/import), C05–C10/C12 (consumption/overrides/history/rendering), W05/W06/W07/W12 (associations/letters/frozen/progress), E05/E07/E08/E09 (draft/keyboard/access/ownership), S04/S05 (privacy/portability). Other groups remain regression coverage. No route removal or cleanup. See the dated Phase 9 preservation addendum and final checkpoint reconciliation.