Skip to content

Commit bb0ccab

Browse files
authored
refactor(templates): remove the V1 invoice/proposal builtins (#273)
* refactor(templates): remove the V1 invoice/proposal builtins InvoiceTemplateV1 and ProposalTemplateV1 are pre-rebuild builtins superseded by the layered v2 presets (ModernInvoice / ModernProposal), which render the same InvoiceDocumentSpec / ProposalDocumentSpec. They still had live consumers, so de-consume before deleting. Delete the two V1 builtins and the two V1-only file examples. Repoint the three benchmarks (AllocationRateProbe, CurrentSpeedBenchmark, ColdStartJmhBenchmark) and the documentation example test onto ModernInvoice/ModernProposal — the benchmarks now exercise the v2 presets (the workload renderer changes, so absolute numbers shift). Clean the dropped examples out of GenerateAllExamples, ShowcaseMetadata, and the examples README, and point the surviving InvoiceTemplate/ProposalTemplate Javadoc snippets at the V2 implementer. Tests: ./mvnw verify javadoc:javadoc -pl . — 1621 tests, 0 failures, javadoc gate clean; examples and benchmarks compile against the new jar. * fix(benchmarks): trim canonical proposal table cells to fit A4 ModernProposal sizes its timeline and pricing description columns to their content with no wrap, so once the proposal benchmark moved onto the v2 preset the long-form fixture overflowed the page ("Table ProposalTimeline width 826.5 exceeds available 551.3") and failed the perf-smoke run. Shorten the timeline and pricing-row descriptions in the benchmark proposal fixture so both tables fit A4 at the benchmark's 22pt margin. The long section paragraphs that drive the multi-page pagination workload are unchanged, so the benchmark still exercises long content. longProposal() has no other live consumer (canonicalProposalData() is uncalled; the v2 parity test builds its own data). Tests: ./mvnw -f benchmarks/pom.xml -DskipTests exec:java -Dexec.mainClass=com.demcha.compose.CurrentSpeedBenchmark -Dgraphcompose.benchmark.profile=smoke now renders invoice/cv/proposal (BUILD SUCCESS); engine verify + benchmark gates green.
1 parent dcdabe9 commit bb0ccab

14 files changed

Lines changed: 30 additions & 247 deletions

File tree

benchmarks/src/main/java/com/demcha/compose/AllocationRateProbe.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import com.demcha.compose.document.api.DocumentPageSize;
44
import com.demcha.compose.document.api.DocumentSession;
5-
import com.demcha.compose.document.templates.builtins.InvoiceTemplateV1;
6-
import com.demcha.compose.document.templates.builtins.ProposalTemplateV1;
5+
import com.demcha.compose.document.templates.api.DocumentTemplate;
76
import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec;
87
import com.demcha.compose.document.templates.data.proposal.ProposalDocumentSpec;
8+
import com.demcha.compose.document.templates.invoice.v2.presets.ModernInvoice;
9+
import com.demcha.compose.document.templates.proposal.v2.presets.ModernProposal;
910

1011
import java.lang.management.GarbageCollectorMXBean;
1112
import java.lang.management.ManagementFactory;
@@ -46,9 +47,9 @@ public static void main(String[] args) throws Exception {
4647
enableAllocationMeasurement();
4748

4849
InvoiceDocumentSpec invoice = CanonicalBenchmarkSupport.canonicalInvoice();
49-
InvoiceTemplateV1 invoiceTemplate = new InvoiceTemplateV1();
50+
DocumentTemplate<InvoiceDocumentSpec> invoiceTemplate = ModernInvoice.create();
5051
ProposalDocumentSpec proposal = CanonicalBenchmarkSupport.canonicalProposal();
51-
ProposalTemplateV1 proposalTemplate = new ProposalTemplateV1();
52+
DocumentTemplate<ProposalDocumentSpec> proposalTemplate = ModernProposal.create();
5253

5354
System.out.println("GraphCompose allocation-rate / GC-pressure probe (" + MEASURE + " warm renders each)");
5455
System.out.printf("%-12s | %14s | %10s | %12s | %12s%n",

benchmarks/src/main/java/com/demcha/compose/CurrentSpeedBenchmark.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
import com.demcha.compose.document.style.DocumentTextStyle;
1414
import com.demcha.compose.document.svg.SvgIcon;
1515
import com.demcha.compose.document.templates.api.DocumentTemplate;
16-
import com.demcha.compose.document.templates.builtins.InvoiceTemplateV1;
17-
import com.demcha.compose.document.templates.builtins.ProposalTemplateV1;
1816
import com.demcha.compose.document.templates.cv.presets.ModernProfessional;
1917
import com.demcha.compose.document.templates.cv.spec.CvSpec;
2018
import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec;
2119
import com.demcha.compose.document.templates.data.proposal.ProposalDocumentSpec;
20+
import com.demcha.compose.document.templates.invoice.v2.presets.ModernInvoice;
21+
import com.demcha.compose.document.templates.proposal.v2.presets.ModernProposal;
2222
import com.demcha.compose.document.theme.BusinessTheme;
2323
import com.demcha.compose.engine.components.style.Margin;
2424
import org.apache.pdfbox.pdmodel.common.PDRectangle;
@@ -85,9 +85,9 @@ public final class CurrentSpeedBenchmark {
8585
.color(DocumentColor.of(new Color(58, 69, 84)))
8686
.build();
8787

88-
private final InvoiceTemplateV1 invoiceTemplate = new InvoiceTemplateV1();
88+
private final DocumentTemplate<InvoiceDocumentSpec> invoiceTemplate = ModernInvoice.create();
8989
private final DocumentTemplate<CvSpec> cvTemplate = ModernProfessional.create(BusinessTheme.modern());
90-
private final ProposalTemplateV1 proposalTemplate = new ProposalTemplateV1();
90+
private final DocumentTemplate<ProposalDocumentSpec> proposalTemplate = ModernProposal.create();
9191
private final InvoiceDocumentSpec invoice = CanonicalBenchmarkSupport.canonicalInvoice();
9292
private final ProposalDocumentSpec proposal = CanonicalBenchmarkSupport.canonicalProposal();
9393
private final CvSpec cv = CanonicalBenchmarkSupport.canonicalCv();

benchmarks/src/main/java/com/demcha/compose/jmh/ColdStartJmhBenchmark.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
import com.demcha.compose.document.api.DocumentPageSize;
66
import com.demcha.compose.document.api.DocumentSession;
77
import com.demcha.compose.document.style.DocumentInsets;
8-
import com.demcha.compose.document.templates.builtins.InvoiceTemplateV1;
98
import com.demcha.compose.document.templates.cv.presets.ModernProfessional;
109
import com.demcha.compose.document.templates.cv.spec.CvSpec;
1110
import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec;
11+
import com.demcha.compose.document.templates.invoice.v2.presets.ModernInvoice;
1212
import com.demcha.compose.document.theme.BusinessTheme;
1313
import com.demcha.compose.document.templates.api.DocumentTemplate;
1414
import org.openjdk.jmh.annotations.Benchmark;
@@ -37,7 +37,7 @@
3737
* reported number is a distribution of cold first-renders, not one lucky start.
3838
* The spec/template objects are built in {@link #setUp()} so the measured shot is
3939
* the cold render path, not fixture assembly. Same workloads as the warm benches
40-
* ({@code engine-simple} inline, {@code InvoiceTemplateV1}, {@code ModernProfessional})
40+
* ({@code engine-simple} inline, {@code ModernInvoice}, {@code ModernProfessional})
4141
* so cold and warm numbers are directly comparable.</p>
4242
*
4343
* <pre>
@@ -56,15 +56,15 @@
5656
public class ColdStartJmhBenchmark {
5757

5858
private InvoiceDocumentSpec invoice;
59-
private InvoiceTemplateV1 invoiceTemplate;
59+
private DocumentTemplate<InvoiceDocumentSpec> invoiceTemplate;
6060
private CvSpec cv;
6161
private DocumentTemplate<CvSpec> cvTemplate;
6262

6363
/** Builds the specs and templates once per fork, outside the measured cold shot. */
6464
@Setup
6565
public void setUp() {
6666
invoice = CanonicalBenchmarkSupport.canonicalInvoice();
67-
invoiceTemplate = new InvoiceTemplateV1();
67+
invoiceTemplate = ModernInvoice.create();
6868
cv = CanonicalBenchmarkSupport.canonicalCv();
6969
cvTemplate = ModernProfessional.create(BusinessTheme.modern());
7070
}
@@ -96,7 +96,7 @@ public byte[] coldEngineSimple() throws Exception {
9696
}
9797

9898
/**
99-
* Cold first render of the canonical invoice through {@code InvoiceTemplateV1}.
99+
* Cold first render of the canonical invoice through {@code ModernInvoice}.
100100
*
101101
* @return the rendered PDF bytes (consumed by JMH)
102102
* @throws Exception if rendering fails

examples/README.md

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,8 @@ are with the canonical DSL, then jump to its detailed section below.
127127

128128
| Example | What it shows | Preview · Source |
129129
|---|---|---|
130-
| [Invoice (V1)](#invoice-v1) | `InvoiceTemplateV1` driven from `InvoiceDocumentSpec` — pre-rebuild surface, supported only | [PDF](../assets/readme/examples/invoice.pdf) · [Source](src/main/java/com/demcha/examples/templates/invoice/InvoiceFileExample.java) |
131-
| [Proposal (V1)](#proposal-v1) | `ProposalTemplateV1` driven from `ProposalDocumentSpec` — pre-rebuild surface, supported only | [PDF](../assets/readme/examples/proposal.pdf) · [Source](src/main/java/com/demcha/examples/templates/proposal/ProposalFileExample.java) |
132130
| [Handcrafted Proposal](#handcrafted-proposal) | v1.4-style cinematic proposal composed by hand — pre-template authoring; kept for parity reference | [PDF](../assets/readme/examples/project-proposal-cinematic.pdf) · [Source](src/main/java/com/demcha/examples/templates/proposal/CinematicProposalFileExample.java) |
133-
| [Weekly schedule](#weekly-schedule) | Bar / restaurant shift schedule via `WeeklyScheduleRenderer` (`WeeklyScheduleTemplateV1` — no V2 yet; will be re-shaped before 2.0) | [PDF](../assets/readme/examples/weekly-schedule.pdf) · [Source](src/main/java/com/demcha/examples/templates/schedule/WeeklyScheduleFileExample.java) |
131+
| [Weekly schedule](#weekly-schedule) | Bar / restaurant shift schedule via `WeeklyScheduleRenderer` | [PDF](../assets/readme/examples/weekly-schedule.pdf) · [Source](src/main/java/com/demcha/examples/templates/schedule/WeeklyScheduleFileExample.java) |
134132

135133
---
136134

@@ -177,45 +175,6 @@ try (DocumentSession document = GraphCompose.document(outputFile)
177175
[📄 View PDF](../assets/readme/examples/cover-letter.pdf) ·
178176
[📜 Full source](src/main/java/com/demcha/examples/templates/coverletter/CoverLetterFileExample.java)
179177

180-
### Invoice (V1)
181-
182-
`InvoiceTemplateV1.compose(document, spec)` handles the full layout —
183-
header band, parties row, line-items table, totals row, payment-terms
184-
footer — driven from a `InvoiceDocumentSpec`. Use this when you want
185-
the legacy hard-coded theme; for V2 cinematic, see below.
186-
187-
```java
188-
InvoiceDocumentSpec spec = InvoiceDocumentSpec.builder()
189-
.invoiceNumber("GC-2026-041")
190-
.issueDate("02 Apr 2026")
191-
.dueDate("16 Apr 2026")
192-
.fromParty(p -> p.name("GraphCompose Studio"))
193-
.billToParty(p -> p.name("Northwind Systems"))
194-
.lineItem("Template architecture", "Reusable invoice flow", "2", "GBP 980", "GBP 1,960")
195-
.totalRow("Total", "GBP 1,960")
196-
.build();
197-
198-
try (DocumentSession document = GraphCompose.document(outputFile)
199-
.pageSize(DocumentPageSize.A4)
200-
.margin(28, 28, 28, 28)
201-
.create()) {
202-
new InvoiceTemplateV1().compose(document, spec);
203-
document.buildPdf();
204-
}
205-
```
206-
207-
[📄 View PDF](../assets/readme/examples/invoice.pdf) ·
208-
[📜 Full source](src/main/java/com/demcha/examples/templates/invoice/InvoiceFileExample.java)
209-
210-
### Proposal (V1)
211-
212-
`ProposalTemplateV1` rendered against a `ProposalDocumentSpec`
213-
sections, scope items, deliverables, sign-off. Pairs naturally with
214-
`InvoiceTemplateV1` for consistent "spec → PDF" pipelines.
215-
216-
[📄 View PDF](../assets/readme/examples/proposal.pdf) ·
217-
[📜 Full source](src/main/java/com/demcha/examples/templates/proposal/ProposalFileExample.java)
218-
219178
### Module-first profile
220179

221180
Authoring against `DocumentSession.pageFlow().module(...)` — no

examples/src/main/java/com/demcha/examples/GenerateAllExamples.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,10 @@
8080
import com.demcha.examples.templates.cv.v2.CvSidebarPortraitExample;
8181
import com.demcha.examples.templates.cv.v2.CvTimelineMinimalExample;
8282
import com.demcha.examples.templates.invoice.InvoiceCinematicFileExample;
83-
import com.demcha.examples.templates.invoice.InvoiceFileExample;
8483
import com.demcha.examples.templates.invoice.v2.ModernInvoiceV2Example;
8584
import com.demcha.examples.templates.proposal.CinematicProposalFileExample;
8685
import com.demcha.examples.templates.proposal.ProposalCinematicFileExample;
8786
import com.demcha.examples.templates.proposal.v2.ModernProposalV2Example;
88-
import com.demcha.examples.templates.proposal.ProposalFileExample;
8987
import com.demcha.examples.templates.schedule.WeeklyScheduleFileExample;
9088

9189
/**
@@ -138,12 +136,10 @@ public static void main(String[] args) throws Exception {
138136
System.out.println("Generated: " + CvTimelineMinimalLetterV2Example.generate());
139137

140138
// Invoices
141-
System.out.println("Generated: " + InvoiceFileExample.generate());
142139
System.out.println("Generated: " + InvoiceCinematicFileExample.generate());
143140
System.out.println("Generated: " + ModernInvoiceV2Example.generate());
144141

145142
// Proposals
146-
System.out.println("Generated: " + ProposalFileExample.generate());
147143
System.out.println("Generated: " + ProposalCinematicFileExample.generate());
148144
System.out.println("Generated: " + ModernProposalV2Example.generate());
149145
System.out.println("Generated: " + CinematicProposalFileExample.generate());

examples/src/main/java/com/demcha/examples/support/ShowcaseMetadata.java

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,9 @@ record Entry(String title, String description, List<String> tags, String codeUrl
7878
letter("cover-letter-mint-editorial-v2", "CvMintEditorialLetterV2Example", "Mint Editorial letter", "Letter paired with Mint Editorial CV — magazine-style mint accent.");
7979

8080
// ===== Templates / Invoice =====
81-
invoice("invoice", "Invoice (canonical)", "Single-page invoice with line items, totals, and structured chrome — InvoiceTemplateV1.", "invoice");
8281
invoice("invoice-cinematic", "Cinematic Invoice", "Polished V2 invoice template with theme-driven layout, advanced tables, and totals.", "invoice", "cinematic");
8382

8483
// ===== Templates / Proposal =====
85-
proposal("proposal", "Proposal (canonical)", "Multi-section proposal with cover, scope, deliverables, and pricing — ProposalTemplateV1.", "proposal");
8684
proposal("proposal-cinematic", "Cinematic Proposal", "Cinematic V2 proposal layout with cover panel, hero spread, and rich typography.", "proposal", "cinematic");
8785
proposal("project-proposal-cinematic", "Project Proposal (cinematic)", "End-to-end project proposal with mountain hero, scope panels, and pricing summary.", "proposal", "cinematic");
8886

@@ -183,16 +181,13 @@ private static void letter(String id, String exampleClass, String title, String
183181
}
184182

185183
private static void invoice(String id, String title, String desc, String... tags) {
186-
String file = id.contains("cinematic") ? "InvoiceCinematicFileExample" : "InvoiceFileExample";
187184
ENTRIES.put(id, entry(title, desc, withCategory("invoice", tags),
188-
EX_BASE + "/templates/invoice/" + file + ".java"));
185+
EX_BASE + "/templates/invoice/InvoiceCinematicFileExample.java"));
189186
}
190187

191188
private static void proposal(String id, String title, String desc, String... tags) {
192-
String file;
193-
if (id.equals("project-proposal-cinematic")) file = "CinematicProposalFileExample";
194-
else if (id.contains("cinematic")) file = "ProposalCinematicFileExample";
195-
else file = "ProposalFileExample";
189+
String file = id.equals("project-proposal-cinematic")
190+
? "CinematicProposalFileExample" : "ProposalCinematicFileExample";
196191
ENTRIES.put(id, entry(title, desc, withCategory("proposal", tags),
197192
EX_BASE + "/templates/proposal/" + file + ".java"));
198193
}

examples/src/main/java/com/demcha/examples/templates/invoice/InvoiceFileExample.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

examples/src/main/java/com/demcha/examples/templates/proposal/ProposalFileExample.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/main/java/com/demcha/compose/document/templates/api/InvoiceTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* {@link DocumentSession}.</p>
1212
*
1313
* <pre>{@code
14-
* InvoiceTemplate template = new InvoiceTemplateV1();
14+
* InvoiceTemplate template = new InvoiceTemplateV2();
1515
* InvoiceDocumentSpec invoice = InvoiceDocumentSpec.builder()
1616
* .invoiceNumber("GC-2026-041")
1717
* .fromParty(party -> party.name("GraphCompose Studio"))

src/main/java/com/demcha/compose/document/templates/api/ProposalTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* {@link DocumentSession}.</p>
1212
*
1313
* <pre>{@code
14-
* ProposalTemplate template = new ProposalTemplateV1();
14+
* ProposalTemplate template = new ProposalTemplateV2();
1515
* ProposalDocumentSpec proposal = ProposalDocumentSpec.builder()
1616
* .projectTitle("GraphCompose rollout")
1717
* .section("Scope", "Introduce reusable invoice and proposal templates.")

0 commit comments

Comments
 (0)