v2: introduce cv/v2 master pattern (data/theme/components/presets)#45
Merged
Conversation
…yering
Adds a side-by-side rewrite of the CV template surface under
com.demcha.compose.document.templates.cv.v2 with strict layer
separation:
- data/ — pure CV records: CvName/CvContact/CvLink/CvIdentity
plus a sealed CvSection (ParagraphSection, RowsSection
with RowStyle, EntriesSection). No rendering deps.
- theme/ — cosmetic tokens: CvPalette + CvTypography + CvSpacing
aggregated as CvTheme with a boxedClassic() factory.
- components/ — reusable renderers (HeadlineRenderer, ContactRenderer,
BannerRenderer, ParagraphRenderer, RowRenderer,
EntryRenderer, SectionDispatcher) that take theme as
a parameter — no statics, no parsing.
- presets/ — BoxedSections composition example.
Includes 15 passing tests (CvNameTest, CvContactTest,
BoxedSectionsSmokeTest) plus a sample CvDocument fixture and a
CvBoxedV2Example runner that renders pixel-identical output to the
legacy cv-boxed-sections.pdf reference.
v1 surface (cv/spec, cv/builder, cv/layouts, cv/presets) is left
untouched — both pipelines coexist while v2 is evaluated.
6 tasks
DemchaAV
added a commit
that referenced
this pull request
May 24, 2026
…h audit Phase 3 of the documentation work after audit (#50 added the templates-layered/ guide; #51 here restructures the entire docs/ tree and fixes terminology + link hygiene). Reorg — docs/ structure ----------------------- Was: 21 flat .md files in docs/ with no obvious category. Now grouped by purpose, mirroring the personas: docs/ ├── README.md ← NEW real docs index ├── SHOWCASE.md ← renamed from docs/README.md │ (GitHub Pages showcase doc) ├── getting-started.md ← kept flat (high traffic) ├── recipes.md ← kept flat (recipes index) ├── adr/ ← unchanged (8 ADRs) ├── archive/ ← unchanged (3 archived docs) ├── recipes/ ← unchanged (7 recipes) ├── architecture/ ← NEW (5 files moved) │ ├── overview.md ← was architecture.md │ ├── lifecycle.md │ ├── pagination-ordering.md │ ├── canonical-legacy-parity.md │ └── package-map.md ├── operations/ ← NEW (5 files moved) │ ├── benchmarks.md │ ├── logging.md │ ├── performance.md │ ├── production-rendering.md │ └── layout-snapshot-testing.md ├── contributing/ ← NEW (3 files moved) │ ├── extension-guide.md │ ├── implementation-guide.md │ └── release-process.md ├── roadmaps/ ← NEW (3 files moved) │ ├── v1.6-roadmap.md │ ├── migration-v1-4-to-v1-5.md │ └── migration-v1-5-to-v1-6.md └── templates/ ← NEW (groups both surfaces) ├── v1-classic/ ← was docs/templates-v2.md + template-authoring.md │ ├── README.md ← v1.6 "Templates v2" landing │ └── authoring.md ← was template-authoring.md └── v2-layered/ ← was docs/templates-layered/ ├── README.md ├── quickstart.md ├── using-templates.md ├── authoring-presets.md └── contributor-guide.md 20 files moved via `git mv` so the history is preserved. Documentation index — docs/README.md ------------------------------------ The old docs/README.md was about the GitHub Pages showcase site, not a docs index — opening docs/ on GitHub showed the wrong thing. - Renamed old docs/README.md → docs/SHOWCASE.md - Wrote new docs/README.md as the canonical docs landing: persona map + category map + ADR list + recipe list + quick links. v1/v2 terminology — explicit callouts ------------------------------------- The codebase has TWO surfaces both casually called "v2": - The v1.6 rebuilt templates (CvSpec / CvBuilder / *Presets) which the project calls "Templates v2" internally (ADR-0011). - The newer layered cv/v2/ architecture introduced in PRs #45-#49. Added clarifying callouts at the top of: - docs/templates/v1-classic/README.md — "this is the v1.6 surface; for the newer layered pattern see v2-layered/" - docs/templates/v1-classic/authoring.md — same callout - docs/templates/v2-layered/README.md — "this is the layered architecture; NOT the older v1.6 'Templates v2'" Both surfaces are still shipped and supported; neither is deprecated. The callouts just kill the confusion. CONTRIBUTING.md update ---------------------- The "New built-in template" section now opens with a fork: - For a NEW template family from scratch → layered architecture (with link to contributor-guide.md) - For a new preset inside an existing v1-classic family → keep using BusinessTheme + CvBuilder + the existing presets pattern Plus a "📚 Map of template docs" pointer to docs/README.md so contributors don't have to guess. Orphan resolution ----------------- - docs/performance.md was nowhere-linked. Moved to operations/ and indexed from docs/README.md. - docs/recipes/shapes.md was nowhere-linked-from-root-README but IS linked from recipes.md (the recipe index). Root README now links recipes.md so it's discoverable. - ADR numbering gap (0005-0010 missing) explained inline in docs/README.md as a note next to the ADR list. Link integrity -------------- - sed sweep across 58 .md files updated every absolute `docs/X.md` reference to its new categorised path. - Internal relative links inside moved files (e.g. `./benchmarks.md` from within docs/architecture/) updated by hand for every affected file. - Final automated sweep verifies **zero broken markdown links** repo-wide. Tech accuracy spot-check ------------------------ Sampled 4 high-traffic docs against the current code: - getting-started.md — every referenced class (DocumentSession, BusinessTheme, etc.) exists in src/. - templates/v1-classic/authoring.md — every layout class (SingleColumn, TwoColumnSidebar, ThreeColumnMagazine, etc.) exists. - templates/v1-classic/README.md — accurate. - contributing/extension-guide.md — accurate. No stale class references found. Root README update ------------------ Documentation section reorganised: - New "📚 Full docs index" link to docs/README.md. - Templates split into v2-layered (new) and v1-classic (legacy but shipped) with cross-link to authoring guides. - Sub-grouped: Templates / Architecture & operations / Recipes & examples / Contributing & releases. No engine, source, or test changes. Pure documentation.
DemchaAV
added a commit
that referenced
this pull request
May 24, 2026
…h audit Phase 3 of the documentation work after audit (#50 added the templates-layered/ guide; #51 here restructures the entire docs/ tree and fixes terminology + link hygiene). Reorg — docs/ structure ----------------------- Was: 21 flat .md files in docs/ with no obvious category. Now grouped by purpose, mirroring the personas: docs/ ├── README.md ← NEW real docs index ├── SHOWCASE.md ← renamed from docs/README.md │ (GitHub Pages showcase doc) ├── getting-started.md ← kept flat (high traffic) ├── recipes.md ← kept flat (recipes index) ├── adr/ ← unchanged (8 ADRs) ├── archive/ ← unchanged (3 archived docs) ├── recipes/ ← unchanged (7 recipes) ├── architecture/ ← NEW (5 files moved) │ ├── overview.md ← was architecture.md │ ├── lifecycle.md │ ├── pagination-ordering.md │ ├── canonical-legacy-parity.md │ └── package-map.md ├── operations/ ← NEW (5 files moved) │ ├── benchmarks.md │ ├── logging.md │ ├── performance.md │ ├── production-rendering.md │ └── layout-snapshot-testing.md ├── contributing/ ← NEW (3 files moved) │ ├── extension-guide.md │ ├── implementation-guide.md │ └── release-process.md ├── roadmaps/ ← NEW (3 files moved) │ ├── v1.6-roadmap.md │ ├── migration-v1-4-to-v1-5.md │ └── migration-v1-5-to-v1-6.md └── templates/ ← NEW (groups both surfaces) ├── v1-classic/ ← was docs/templates-v2.md + template-authoring.md │ ├── README.md ← v1.6 "Templates v2" landing │ └── authoring.md ← was template-authoring.md └── v2-layered/ ← was docs/templates-layered/ ├── README.md ├── quickstart.md ├── using-templates.md ├── authoring-presets.md └── contributor-guide.md 20 files moved via `git mv` so the history is preserved. Documentation index — docs/README.md ------------------------------------ The old docs/README.md was about the GitHub Pages showcase site, not a docs index — opening docs/ on GitHub showed the wrong thing. - Renamed old docs/README.md → docs/SHOWCASE.md - Wrote new docs/README.md as the canonical docs landing: persona map + category map + ADR list + recipe list + quick links. v1/v2 terminology — explicit callouts ------------------------------------- The codebase has TWO surfaces both casually called "v2": - The v1.6 rebuilt templates (CvSpec / CvBuilder / *Presets) which the project calls "Templates v2" internally (ADR-0011). - The newer layered cv/v2/ architecture introduced in PRs #45-#49. Added clarifying callouts at the top of: - docs/templates/v1-classic/README.md — "this is the v1.6 surface; for the newer layered pattern see v2-layered/" - docs/templates/v1-classic/authoring.md — same callout - docs/templates/v2-layered/README.md — "this is the layered architecture; NOT the older v1.6 'Templates v2'" Both surfaces are still shipped and supported; neither is deprecated. The callouts just kill the confusion. CONTRIBUTING.md update ---------------------- The "New built-in template" section now opens with a fork: - For a NEW template family from scratch → layered architecture (with link to contributor-guide.md) - For a new preset inside an existing v1-classic family → keep using BusinessTheme + CvBuilder + the existing presets pattern Plus a "📚 Map of template docs" pointer to docs/README.md so contributors don't have to guess. Orphan resolution ----------------- - docs/performance.md was nowhere-linked. Moved to operations/ and indexed from docs/README.md. - docs/recipes/shapes.md was nowhere-linked-from-root-README but IS linked from recipes.md (the recipe index). Root README now links recipes.md so it's discoverable. - ADR numbering gap (0005-0010 missing) explained inline in docs/README.md as a note next to the ADR list. Link integrity -------------- - sed sweep across 58 .md files updated every absolute `docs/X.md` reference to its new categorised path. - Internal relative links inside moved files (e.g. `./benchmarks.md` from within docs/architecture/) updated by hand for every affected file. - Final automated sweep verifies **zero broken markdown links** repo-wide. Tech accuracy spot-check ------------------------ Sampled 4 high-traffic docs against the current code: - getting-started.md — every referenced class (DocumentSession, BusinessTheme, etc.) exists in src/. - templates/v1-classic/authoring.md — every layout class (SingleColumn, TwoColumnSidebar, ThreeColumnMagazine, etc.) exists. - templates/v1-classic/README.md — accurate. - contributing/extension-guide.md — accurate. No stale class references found. Root README update ------------------ Documentation section reorganised: - New "📚 Full docs index" link to docs/README.md. - Templates split into v2-layered (new) and v1-classic (legacy but shipped) with cross-link to authoring guides. - Sub-grouped: Templates / Architecture & operations / Recipes & examples / Contributing & releases. No engine, source, or test changes. Pure documentation.
DemchaAV
added a commit
that referenced
this pull request
May 24, 2026
…h audit (#51) Phase 3 of the documentation work after audit (#50 added the templates-layered/ guide; #51 here restructures the entire docs/ tree and fixes terminology + link hygiene). Reorg — docs/ structure ----------------------- Was: 21 flat .md files in docs/ with no obvious category. Now grouped by purpose, mirroring the personas: docs/ ├── README.md ← NEW real docs index ├── SHOWCASE.md ← renamed from docs/README.md │ (GitHub Pages showcase doc) ├── getting-started.md ← kept flat (high traffic) ├── recipes.md ← kept flat (recipes index) ├── adr/ ← unchanged (8 ADRs) ├── archive/ ← unchanged (3 archived docs) ├── recipes/ ← unchanged (7 recipes) ├── architecture/ ← NEW (5 files moved) │ ├── overview.md ← was architecture.md │ ├── lifecycle.md │ ├── pagination-ordering.md │ ├── canonical-legacy-parity.md │ └── package-map.md ├── operations/ ← NEW (5 files moved) │ ├── benchmarks.md │ ├── logging.md │ ├── performance.md │ ├── production-rendering.md │ └── layout-snapshot-testing.md ├── contributing/ ← NEW (3 files moved) │ ├── extension-guide.md │ ├── implementation-guide.md │ └── release-process.md ├── roadmaps/ ← NEW (3 files moved) │ ├── v1.6-roadmap.md │ ├── migration-v1-4-to-v1-5.md │ └── migration-v1-5-to-v1-6.md └── templates/ ← NEW (groups both surfaces) ├── v1-classic/ ← was docs/templates-v2.md + template-authoring.md │ ├── README.md ← v1.6 "Templates v2" landing │ └── authoring.md ← was template-authoring.md └── v2-layered/ ← was docs/templates-layered/ ├── README.md ├── quickstart.md ├── using-templates.md ├── authoring-presets.md └── contributor-guide.md 20 files moved via `git mv` so the history is preserved. Documentation index — docs/README.md ------------------------------------ The old docs/README.md was about the GitHub Pages showcase site, not a docs index — opening docs/ on GitHub showed the wrong thing. - Renamed old docs/README.md → docs/SHOWCASE.md - Wrote new docs/README.md as the canonical docs landing: persona map + category map + ADR list + recipe list + quick links. v1/v2 terminology — explicit callouts ------------------------------------- The codebase has TWO surfaces both casually called "v2": - The v1.6 rebuilt templates (CvSpec / CvBuilder / *Presets) which the project calls "Templates v2" internally (ADR-0011). - The newer layered cv/v2/ architecture introduced in PRs #45-#49. Added clarifying callouts at the top of: - docs/templates/v1-classic/README.md — "this is the v1.6 surface; for the newer layered pattern see v2-layered/" - docs/templates/v1-classic/authoring.md — same callout - docs/templates/v2-layered/README.md — "this is the layered architecture; NOT the older v1.6 'Templates v2'" Both surfaces are still shipped and supported; neither is deprecated. The callouts just kill the confusion. CONTRIBUTING.md update ---------------------- The "New built-in template" section now opens with a fork: - For a NEW template family from scratch → layered architecture (with link to contributor-guide.md) - For a new preset inside an existing v1-classic family → keep using BusinessTheme + CvBuilder + the existing presets pattern Plus a "📚 Map of template docs" pointer to docs/README.md so contributors don't have to guess. Orphan resolution ----------------- - docs/performance.md was nowhere-linked. Moved to operations/ and indexed from docs/README.md. - docs/recipes/shapes.md was nowhere-linked-from-root-README but IS linked from recipes.md (the recipe index). Root README now links recipes.md so it's discoverable. - ADR numbering gap (0005-0010 missing) explained inline in docs/README.md as a note next to the ADR list. Link integrity -------------- - sed sweep across 58 .md files updated every absolute `docs/X.md` reference to its new categorised path. - Internal relative links inside moved files (e.g. `./benchmarks.md` from within docs/architecture/) updated by hand for every affected file. - Final automated sweep verifies **zero broken markdown links** repo-wide. Tech accuracy spot-check ------------------------ Sampled 4 high-traffic docs against the current code: - getting-started.md — every referenced class (DocumentSession, BusinessTheme, etc.) exists in src/. - templates/v1-classic/authoring.md — every layout class (SingleColumn, TwoColumnSidebar, ThreeColumnMagazine, etc.) exists. - templates/v1-classic/README.md — accurate. - contributing/extension-guide.md — accurate. No stale class references found. Root README update ------------------ Documentation section reorganised: - New "📚 Full docs index" link to docs/README.md. - Templates split into v2-layered (new) and v1-classic (legacy but shipped) with cross-link to authoring guides. - Sub-grouped: Templates / Architecture & operations / Recipes & examples / Contributing & releases. No engine, source, or test changes. Pure documentation.
4 tasks
DemchaAV
added a commit
that referenced
this pull request
May 24, 2026
Phase 4 — defensive infrastructure. After 5 PRs (#45-#51, ~4000 lines) of layered architecture work, there was no automated guard against silent visual regression. Refactoring widgets / theme tokens / renderers could change the rendered PDF and nothing would fail the build. This PR closes that gap. What's new ---------- - src/test/java/.../cv/v2/presets/CvV2VisualParityTest.java Parameterised over the 3 shipped v2 presets (BoxedSections, MinimalUnderlined, ModernProfessional). Each renders a canonical CvDocument fixture (Jordan Rivera — exercises every section subtype: ParagraphSection, RowsSection with all 3 RowStyle variants, EntriesSection), rasterises page-by-page via PDFBox, and asserts per-pixel diff against a checked-in baseline PNG. - src/test/resources/visual-baselines/cv-v2-layered/ 6 baseline PNGs — 3 presets × 2 pages each. Captured via `-Dgraphcompose.visual.approve=true` against the current develop-state rendering. - Reused PdfVisualRegression harness (already in the codebase — used by v1's PresetVisualParityTest). Same budget calibration: 20 000 mismatched pixels per page at per-channel tolerance 8 — calibrated for cross-platform PDFBox font/colour drift. - Inline canonical document (not pulled from examples module) so the test depends only on main + main-test code. Mirrors the pattern from v1 PresetVisualParityTest.canonicalCvSpec(). Workflow -------- After a deliberate visual change (theme rebalance, widget tweak, etc.): ./mvnw test -Dtest=CvV2VisualParityTest -Dgraphcompose.visual.approve=true git add src/test/resources/visual-baselines/cv-v2-layered/*.png git commit -m "test: refresh visual baselines after <reason>" Normal CI run (default) just diffs. Failures write <slug>-page-N.actual.png and <slug>-page-N.diff.png next to the baseline for review. Docs ---- - docs/templates/v2-layered/contributor-guide.md gains a "Visual regression — pixel-diff parity gate" section under "Test checklist": explains the workflow, where baselines live, the budget calibration rationale, and points contributors at this test file as a drop-in template for new template families. Test results ------------ - 3/3 visual parity tests pass against fresh baselines - 8/8 CanonicalSurfaceGuardTest still green (no docs surface drift from this change) - No engine, source, or v1 surface edits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a side-by-side rewrite of the CV template surface under
com.demcha.compose.document.templates.cv.v2organised as four strictlayers:
data/— pure CV records:CvName,CvContact,CvLink,CvIdentity+ sealedCvSection(ParagraphSection,RowsSectionwithRowStyle,EntriesSection). No rendering deps.theme/— cosmetic tokens:CvPalette,CvTypography,CvSpacingaggregated asCvThemewith aboxedClassic()factory.components/— reusable renderers (HeadlineRenderer,ContactRenderer,BannerRenderer,ParagraphRenderer,RowRenderer,EntryRenderer,SectionDispatcher) that take themeas a parameter — no statics, no parsing.
presets/—BoxedSectionscomposition example.What's included
cv/v2/(~1500 lines)ExampleDataFactory.sampleCvDocumentV2()CvBoxedV2Examplerendering pixel-identical output to thelegacy
cv-boxed-sections.pdfreferenceCvNameTest,CvContactTest,BoxedSectionsSmokeTest)What's NOT changed
document/api,document/dsl,document/engine,document/node,document/style) — zero editscv/spec,cv/builder,cv/layouts,cv/presets) — zero edits. All 14 v1 presets continue to work.Follow-ups (separate PRs)
feature/cv-v2-extensible—CvDecorationtoken,ParagraphPrimitivehelper, author docs, second demo preset
migration doc, eventual v1 deprecation
Test plan
mvn test— 15/15 v2 tests passmvn compile— main + examples + tests cleancv-boxed-sections-v2.pdf— visual parity vs legacy