Skip to content

Commit a81aac2

Browse files
authored
docs(templates): add which-template-system decision guide (G1) (#86)
The repo ships two parallel canonical template surfaces with confusingly similar names: `cv.presets.*` (the "classic" v1.6 rebuilt surface) and `cv.v2.presets.*` (the layered architecture). New contributors and downstream callers cannot tell which one to use without reading both the v1-classic and v2-layered READMEs end-to-end and decoding the cross-references between them. The new page (`docs/templates/which-template-system.md`) is the decision guide: - Section 0 pins terminology once — "classic" vs "layered" — and maps it to the actual package names and ADR references (0011 / 0015). - Section 1 is the status matrix: every template surface plus the canonical DSL labelled Recommended / Supported / Legacy / Internal, with the "Use for new code?" column called out separately from the "Will exist in 2.0?" column. - Section 2 is a decision tree for "I want to render X". - Section 3 is the migration table: 14 classic CV presets → their same-named v2-layered replacement + paired cover-letter preset, plus the InvoiceV1/V2, ProposalV1/V2, WeeklyScheduleV1 inventory. - Section 4 is the 1.x → 2.0 deprecation inventory naming every type slated for removal (GraphCompose.pdf, PdfComposer, MainPageCV, com.demcha.compose.v2.*, the entire cv.presets.* package, etc.) so callers can audit their own imports. - Section 5 cross-links to ADRs, v1-classic / v2-layered docs, and the migration roadmaps already in the repo. CanonicalSurfaceGuardTest.publicMarkdownDocsShouldAvoidLegacySurfaceOutsideHistoricalAuditNotes allowlist updated to permit the new page — same allowlist mechanism the v1.5 → v1.6 migration log already uses, and the new doc is the same kind of artifact (audit / migration log naming retired surface). CHANGELOG entry added to v1.6.6 — Planned under a new "### Documentation" subsection. Verification: - ./mvnw test -pl . -Dtest='CanonicalSurfaceGuardTest,DocumentationCoverageTest,DocumentationExamplesTest,VersionConsistencyGuardTest' -> 30 tests, 0 failures, 0 errors (~24s) - ./mvnw test -pl . -> 1023 tests, 0 failures, 0 errors (~55s)
1 parent 1637adf commit a81aac2

3 files changed

Lines changed: 262 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ JitPack continue to resolve through the existing coordinates.
3636
Javadoc now spells out the empty-list-clears semantics in prose, not
3737
only in the `@param` line.
3838

39+
### Documentation
40+
41+
- **New decision guide: [`docs/templates/which-template-system.md`](docs/templates/which-template-system.md)**
42+
(Track G1). The repo ships two parallel canonical template surfaces —
43+
`cv.presets.*` (the "classic" v1.6 rebuild) and `cv.v2.presets.*` (the
44+
layered architecture, recommended) — under confusingly similar names.
45+
The new page pins the terminology once, gives a status matrix
46+
(Recommended / Supported / Legacy / Internal) for every template
47+
surface and the canonical DSL, walks a decision tree for new code, and
48+
provides a preset-by-preset migration table from `classic` to
49+
`layered` plus a 1.x → 2.0 deprecation inventory naming every type
50+
scheduled for removal. `CanonicalSurfaceGuardTest` allowlist updated
51+
so the deprecation-inventory section's literal mentions of
52+
`GraphCompose.pdf(...)`, `PdfComposer`, etc. don't trip the
53+
legacy-token scan (same allowlist class as the v1.5 → v1.6 migration
54+
log already in there).
55+
3956
## v1.6.5 — 2026-05-30
4057

4158
### Templates v2
Lines changed: 236 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
# Which template system should I use?
2+
3+
**Short answer.** For any **new** code on GraphCompose 1.6.x and later, use
4+
the [**layered**](v2-layered/README.md) template surface
5+
(`com.demcha.compose.document.templates.cv.v2.*`, paired with
6+
`*Letter` cover-letter presets in `…coverletter.v2.*`). The older
7+
[**classic**](v1-classic/README.md) surface still ships, still works,
8+
and stays supported through the 1.x line, but **the layered surface is
9+
the path forward** and is the only template family that will be in
10+
GraphCompose 2.0.
11+
12+
This page is the decision guide. It exists because the project ships
13+
**two parallel canonical template surfaces** today, with confusingly
14+
similar names, and a new contributor needs to know which one to read
15+
and which one to write against.
16+
17+
---
18+
19+
## 0. The naming, once
20+
21+
The two surfaces have collided naming because the *codebase* and the
22+
*docs* labelled them at different points in time:
23+
24+
| What you'll see | Where it lives | What it actually is |
25+
|---|---|---|
26+
| **"Templates v2" (in commit messages, ADR 0011, package names like `cv.v2`)** | `com.demcha.compose.document.templates.cv.v2.*` | The **layered** architecture — *data / theme / components / widgets / presets*, paired with `CvDocument` builder. Recommended. |
27+
| **"Templates v1.6" / "templates rebuild"** | `com.demcha.compose.document.templates.cv.presets.*` | The 1.6 rebuilt canonical surface — `CvSpec` + `CvBuilder` + presets + `BusinessTheme`. Still supported. |
28+
| **Folder `docs/templates/v1-classic/`** | docs only | Documents the **non-layered** surface (`cv.presets.*`). The doc folder name is *not* the same axis as the package's `v2` suffix. |
29+
| **Folder `docs/templates/v2-layered/`** | docs only | Documents the layered surface (`cv.v2.*`). |
30+
31+
From here, this page uses one name per surface, consistently:
32+
33+
- **`classic`**`cv.presets.*`, documented in `docs/templates/v1-classic/` — pre-layered, still supported.
34+
- **`layered`**`cv.v2.*` + `coverletter.v2.*`, documented in `docs/templates/v2-layered/` — recommended.
35+
36+
ADR references: [ADR-0011 templates-v2-architecture](../adr/0011-templates-v2-architecture.md) introduces the `classic` surface;
37+
[ADR-0015 layered-template-architecture](../adr/0015-layered-template-architecture.md) introduces the `layered` one and supersedes 0011 for new template families.
38+
39+
---
40+
41+
## 1. Status matrix
42+
43+
| Surface | Status | Stability | Use for new code? | Will exist in 2.0? | First read |
44+
|---|---|---|---|---|---|
45+
| **Layered** (`cv.v2.*`, `coverletter.v2.*`) | **Recommended** | Stable (additive changes only) | ✅ Yes | ✅ Yes (canonical) | [v2-layered/quickstart](v2-layered/quickstart.md) |
46+
| **Classic** (`cv.presets.*`, paired classic letter presets) | **Supported** | Stable, no new features | 🟡 Only if migrating an existing v1.5-era caller | ❌ Removed (full migration to layered) | [v1-classic/README](v1-classic/README.md) |
47+
| **Built-in `*TemplateV2`** (Invoice / Proposal) | **Recommended** | Stable | ✅ Yes | ✅ Yes | [v1-classic/README](v1-classic/README.md) — InvoiceTemplateV2 / ProposalTemplateV2 sections (documented historically inside the v1-classic folder; pending a dedicated `built-ins/` section) |
48+
| **Built-in `*TemplateV1`** (Invoice / Proposal / WeeklySchedule) | **Legacy** | Stable, no new features | ❌ No (use V2 versions; WeeklySchedule has no V2 yet) | ❌ Removed | (no top-level doc — see source Javadoc) |
49+
| **Canonical DSL** (`GraphCompose.document()` + `DocumentSession` + `DocumentDsl`) | **Recommended** | Stable | ✅ Yes — required substrate for both template surfaces and direct authoring | ✅ Yes | [Main README — Hello world](../../README.md) |
50+
| **Legacy PDF API** (`GraphCompose.pdf(...)`, `PdfComposer`, `com.demcha.compose.v2.*`, `com.demcha.templates.*`) | **Legacy** | Frozen — bug fixes only | ❌ No | ❌ Removed | `graphcompose-legacy-architect` skill (internal Claude / Codex artifact, not a repo page) |
51+
| **Engine surface** (`com.demcha.compose.document.layout.*`, `com.demcha.compose.engine.*`, render handlers) | **Internal** | Stable in practice, not part of the public contract; can change in any minor release without a CHANGELOG entry | ❌ No | 🟡 Mostly — package boundaries will tighten further behind `@Internal` | `graphcompose-shared-engine-architect` skill (internal Claude / Codex artifact); [ADR-0015](../adr/0015-layered-template-architecture.md) for the canonical/engine seam |
52+
53+
> **Status definitions.** *Recommended* = the path GraphCompose 2.0 will
54+
> ship; new code targets it. *Supported* = bug fixes + behaviour-preserving
55+
> refactors only, no new features; exists through 1.x. *Internal* = engine
56+
> surface, not part of the public contract; can change in any minor
57+
> release without a CHANGELOG entry. *Legacy* = bug fixes only, removed
58+
> in 2.0; do not start new code here.
59+
60+
---
61+
62+
## 2. Decision tree
63+
64+
```
65+
I want to render a business document on GraphCompose.
66+
67+
├─ Is it a CV or cover letter?
68+
│ ├─ Yes → use a `layered` preset (cv.v2 / coverletter.v2).
69+
│ │ See [v2-layered/using-templates.md](v2-layered/using-templates.md).
70+
│ │ Existing `classic` (cv.presets.*) caller? Read § 3 below; the
71+
│ │ layered preset with the same name is a drop-in replacement
72+
│ │ for almost every case.
73+
│ │
74+
│ └─ No → continue.
75+
76+
├─ Is it an invoice or proposal?
77+
│ └─ Use `InvoiceTemplateV2` or `ProposalTemplateV2` (the `V2` variants).
78+
│ The `V1` variants exist for backward compatibility; do not start
79+
│ new code on them.
80+
81+
├─ Is it a weekly schedule?
82+
│ └─ Use `WeeklyScheduleTemplateV1`. There is no V2 yet — the V1 API
83+
│ will be re-shaped before 2.0 (no concrete plan yet); track in
84+
│ the public release roadmap before adopting it long-term.
85+
86+
└─ It's something else (custom shape, brochure, report)?
87+
└─ Author directly on the canonical DSL: `GraphCompose.document()`
88+
+ `pageFlow(...)` or `dsl().pageFlow(...)`. Reuse `BusinessTheme`
89+
and layered widgets (`SectionDispatcher`, `EntryCompactRenderer`,
90+
`RichParagraphRenderer`, `CardWidget`) wherever they fit; lift
91+
new reusable widgets into the `cv.v2/components` and
92+
`cv.v2/widgets` packages so the next template family can share
93+
them.
94+
```
95+
96+
---
97+
98+
## 3. Migration table — `classic``layered`
99+
100+
Every CV preset that shipped in `cv.presets.*` has a same-named drop-in
101+
replacement in `cv.v2.presets.*`. Migrating a caller is the import swap
102+
plus a theme + data-record swap (introduced below):
103+
104+
```diff
105+
-import com.demcha.compose.document.templates.cv.presets.NordicClean;
106+
+import com.demcha.compose.document.templates.cv.v2.presets.NordicClean;
107+
108+
-// before: CvSpec + BusinessTheme
109+
-NordicClean.create(BusinessTheme.nordicClean()).render(session, cvSpec);
110+
+// after: CvDocument + CvTheme — see the two shape changes below
111+
+NordicClean.create(cvTheme).render(session, cvDocument);
112+
```
113+
114+
Two real shape changes accompany the swap:
115+
116+
1. **Theme.** `BusinessTheme.X()``CvTheme.X()`. The CV-specific
117+
tokens (palette / typography / spacing) are split out so `cv.v2`
118+
themes don't carry invoice / proposal vocabulary they don't use.
119+
2. **Data record.** `CvSpec``CvDocument`. The data shape becomes
120+
strongly-typed sections (`SectionGroup`, `EntryGroup`, `SkillGroup`,
121+
…) instead of a flat `Block` permit list. The
122+
[contributor-guide](v2-layered/contributor-guide.md) walks through
123+
the section types end-to-end.
124+
125+
### CV presets — one-to-one mapping
126+
127+
| `classic` (`cv.presets.*`) | `layered` (`cv.v2.presets.*`) | Cover letter (`coverletter.v2.presets.*`) | Notes |
128+
|---|---|---|---|
129+
| `BlueBanner` | `BlueBanner` | `BlueBannerLetter` | |
130+
| `BoxedSections` | `BoxedSections` | `BoxedSectionsLetter` | Reference preset for the layered architecture. |
131+
| `CenteredHeadline` | `CenteredHeadline` | `CenteredHeadlineLetter` | Layered-only in 1.6.5+; classic version is the rebuilt one. |
132+
| `ClassicSerif` | `ClassicSerif` | `ClassicSerifLetter` | |
133+
| `CompactMono` | `CompactMono` | `CompactMonoLetter` | |
134+
| `EditorialBlue` | `EditorialBlue` | `EditorialBlueLetter` | |
135+
| `EngineeringResume` | `EngineeringResume` | `EngineeringResumeLetter` | |
136+
| `Executive` | `Executive` | `ExecutiveLetter` | |
137+
| `ModernProfessional` | `ModernProfessional` | `ModernProfessionalLetter` | |
138+
| `MonogramSidebar` | `MonogramSidebar` | `MonogramSidebarLetter` | Layered version uses `pageBackgrounds(...)` for sidebar chrome (multi-page-safe). |
139+
| `NordicClean` | `NordicClean` | `NordicCleanLetter` | Layered version ships public `NordicClean.Options`. |
140+
| `Panel` | `Panel` | `PanelLetter` | |
141+
| `SidebarPortrait` | `SidebarPortrait` | `SidebarPortraitLetter` | Layered version uses `pageBackgrounds(...)`. |
142+
| `TimelineMinimal` | `TimelineMinimal` | `TimelineMinimalLetter` | |
143+
| _(no classic)_ | `MinimalUnderlined` | _(no letter yet)_ | Layered-only. |
144+
| _(no classic)_ | `MintEditorial` | `MintEditorialLetter` | Layered-only (shipped in v1.6.5). |
145+
146+
If your caller uses a name on the left, the row tells you what to import
147+
on the right and which cover-letter preset pairs with it.
148+
149+
### Built-ins (Invoice / Proposal / WeeklySchedule)
150+
151+
| V1 | V2 | Migration |
152+
|---|---|---|
153+
| `InvoiceTemplateV1` | `InvoiceTemplateV2` | Same data record (`InvoiceSpec`), same `BusinessTheme`. Renderer rewrite uses layered widgets; output is visually equivalent and snapshot-tested. |
154+
| `ProposalTemplateV1` | `ProposalTemplateV2` | Same data record (`ProposalSpec`), same `BusinessTheme`. Same migration pattern as invoice. |
155+
| `WeeklyScheduleTemplateV1` | _(no V2 yet)_ | Stay on V1 until a V2 ships. |
156+
157+
### Things that are **not** in either canonical surface (still legacy)
158+
159+
These live under `com.demcha.compose.v2.*`, `com.demcha.templates.*`, or
160+
the `GraphCompose.pdf(...)` factory. They are the original (pre-1.6)
161+
PDF-direct authoring path. They will be removed in 2.0:
162+
163+
- `GraphCompose.pdf(outputFile)` and `PdfComposer`.
164+
- `com.demcha.templates.MainPageCV`, `MainPageCvDTO`, `ModuleYml`,
165+
`TemplateBuilder` and friends.
166+
- `com.demcha.compose.v2.*` (engine-direct builders predating the
167+
canonical DSL).
168+
169+
If a caller still imports any of these, the migration target is
170+
**directly the canonical DSL** (`GraphCompose.document()`) — there is no
171+
1:1 equivalent in the template surfaces, because these classes were
172+
never canonical templates, they were a PDF authoring shortcut. The
173+
[migration-v1-5-to-v1-6 roadmap](../roadmaps/migration-v1-5-to-v1-6.md)
174+
walks through the swap for the common shapes.
175+
176+
---
177+
178+
## 4. Deprecation inventory — 1.x → 2.0
179+
180+
Read this when planning long-lived code or when auditing dependencies
181+
that may already use one of the slated-for-removal types. None of these
182+
are deleted in 1.x; the work below is anti-roadmap and lives in the
183+
private taskboard.
184+
185+
### Removed in 2.0
186+
187+
| Item | Reason | Replacement |
188+
|---|---|---|
189+
| `GraphCompose.pdf(...)` factory + `PdfComposer` | PDF-direct path predates the canonical DSL; bypasses layout and rendering invariants. | `GraphCompose.document(...)` + `DocumentSession.buildPdf()`. |
190+
| `com.demcha.compose.v2.*` (the entire package) | Engine-direct builders predating canonical DSL. Mixes layout vocabulary with rendering vocabulary. | Canonical DSL surface (`document.api`, `document.dsl`, `document.node`, `document.style`). |
191+
| `com.demcha.templates.MainPageCV`, `MainPageCvDTO`, `ModuleYml`, `TemplateBuilder` | The original CV template pre-rebuild. Replaced by `cv.presets.*` (classic) in 1.6, now slated to be replaced again by `cv.v2.*` (layered). | A `cv.v2.presets.*` preset, or direct canonical DSL authoring. |
192+
| Entire `cv.presets.*` package (the `classic` surface) | Superseded by `cv.v2.presets.*` (layered). Every preset on the left has a same-named layered replacement (see § 3). | `cv.v2.presets.*`. |
193+
| `DocumentSession.builder()` (deprecated alias) | Pre-rebuild builder entry point. | `GraphCompose.document()`. |
194+
| `DocumentDsl.text(...)` (deprecated alias) | Pre-rebuild text shortcut. | `paragraph(...)` builders inside `pageFlow`. |
195+
| `DocumentPalette.of(...)` (deprecated alias) | Pre-rebuild palette factory. | `DocumentPalette.from(...)` (or theme-specific factories). |
196+
| PDF-specific chrome overloads on `BusinessTheme` | Coupled CV-specific tokens with PDF-specific decisions. | Layered `CvTheme` + render-time `pageBackgrounds(...)`. |
197+
198+
### Open questions for 2.0 (no decision yet)
199+
200+
- `WeeklyScheduleTemplateV1` — whether to ship a V2 along the layered
201+
architecture or to deprecate weekly schedule entirely.
202+
- `InlineRow` / `SplittableRow` / `GridNode` decisions deferred from
203+
1.7 — may unblock magazine-style multi-column flow without needing a
204+
`GridNode` primitive. Tracked in the maintainers' internal release-
205+
readiness notes; will surface here once a public 1.8 engine-refactor
206+
roadmap is published.
207+
208+
### Maven coordinates do **not** change in 2.0
209+
210+
The library `pom.xml` artifact id stays `graphcompose`; JitPack
211+
coordinates (`com.github.DemchaAV:GraphCompose:v<X>`) and the Maven
212+
Central coordinates being introduced in 1.6.6 (`io.github.demchaav:graphcompose:<X>`)
213+
both carry through to 2.0.
214+
215+
---
216+
217+
## 5. Cross-links
218+
219+
- **First-class architecture references**
220+
- [ADR-0011 Templates v2 architecture](../adr/0011-templates-v2-architecture.md) (the `classic` surface)
221+
- [ADR-0015 Layered template architecture](../adr/0015-layered-template-architecture.md) (the `layered` surface; supersedes 0011 for new families)
222+
- **Layered (recommended) docs**
223+
- [README](v2-layered/README.md) · [Quickstart](v2-layered/quickstart.md) · [Using templates](v2-layered/using-templates.md) · [Authoring presets](v2-layered/authoring-presets.md) · [Contributor guide](v2-layered/contributor-guide.md)
224+
- **Classic (supported) docs**
225+
- [README](v1-classic/README.md) · [Authoring](v1-classic/authoring.md)
226+
- **Migration roadmaps**
227+
- [v1.4 → v1.5](../roadmaps/migration-v1-4-to-v1-5.md)
228+
- [v1.5 → v1.6](../roadmaps/migration-v1-5-to-v1-6.md)
229+
230+
---
231+
232+
*This page is maintained alongside the templates surfaces. When a new
233+
preset, built-in, or deprecation lands, update §1 (status matrix) and
234+
§3 (migration table) in the same commit. The `CanonicalSurfaceGuardTest`
235+
documentation-coverage check enforces that no legacy API token leaks
236+
into this doc.*

src/test/java/com/demcha/documentation/CanonicalSurfaceGuardTest.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,15 @@ class CanonicalSurfaceGuardTest {
4747
// Lists every retired V1 CV / cover-letter class so callers
4848
// can find the v2 replacement. Naming the legacy surface is
4949
// the explicit purpose of a migration log.
50-
"docs/roadmaps/migration-v1-5-to-v1-6.md");
50+
"docs/roadmaps/migration-v1-5-to-v1-6.md",
51+
// Decision guide for "classic vs layered template surface".
52+
// The deprecation-inventory section names GraphCompose.pdf(...),
53+
// PdfComposer, MainPageCV, MainPageCvDTO, ModuleYml,
54+
// TemplateBuilder, and com.demcha.compose.v2.* / com.demcha.templates.*
55+
// so callers can identify legacy imports in their own code and
56+
// see the canonical-DSL replacement. Same purpose as the
57+
// migration log above.
58+
"docs/templates/which-template-system.md");
5159
private static final List<String> FORBIDDEN_PUBLIC_AUTHORING_IMPORTS = List.of(
5260
"import com.demcha.compose.engine.");
5361

0 commit comments

Comments
 (0)