From e27fb02c15f1809590a5115e98e6fe1347e1094d Mon Sep 17 00:00:00 2001 From: DemchaAV Date: Tue, 30 Jun 2026 22:57:18 +0100 Subject: [PATCH] refactor(templates): remove the classic cover-letter family MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Gen-2 cover-letter stack (coverletter.{presets,builder,spec,layouts} + data.coverletter) is superseded by the layered coverletter.v2 surface. It is removed before the classic CV family because each classic cover-letter preset cross-references its paired cv.presets preset in Javadoc, which the javadoc gate would reject once cv.presets is gone; CV does not reference cover-letter. Delete the classic cover-letter packages, their tests, and the CoverLetterMock fixture; repoint the cover-letter package-info at the v2 stack. Strip the classic cover-letter helpers from TemplateTestSupport and ExampleDataFactory (the v2 sample and sampleHeader stay) and the data.coverletter entry from the data package-info. Also drop an orphaned classic cover-letter layout snapshot that no test loads. Tests: ./mvnw verify javadoc:javadoc -pl . — 1553 tests, 0 failures, javadoc clean; examples + benchmarks compile; examples-generation smoke (85) green, including the v2 cover-letter gallery. --- .../examples/support/ExampleDataFactory.java | 28 -- .../builder/CoverLetterBuilder.java | 260 ------------------ .../coverletter/builder/package-info.java | 14 - .../coverletter/layouts/LetterFormat.java | 93 ------- .../coverletter/layouts/package-info.java | 23 -- .../templates/coverletter/package-info.java | 43 +-- .../coverletter/presets/BlueBannerLetter.java | 85 ------ .../presets/BoxedSectionsLetter.java | 83 ------ .../presets/CenteredHeadlineLetter.java | 84 ------ .../presets/ClassicSerifLetter.java | 83 ------ .../presets/CompactMonoLetter.java | 84 ------ .../presets/EditorialBlueLetter.java | 84 ------ .../presets/EngineeringResumeLetter.java | 84 ------ .../coverletter/presets/ExecutiveLetter.java | 83 ------ .../presets/ModernProfessionalLetter.java | 98 ------- .../presets/MonogramSidebarLetter.java | 86 ------ .../presets/NordicCleanLetter.java | 87 ------ .../coverletter/presets/PanelLetter.java | 83 ------ .../presets/SidebarPortraitLetter.java | 86 ------ .../presets/TimelineMinimalLetter.java | 83 ------ .../coverletter/presets/package-info.java | 24 -- .../coverletter/spec/CoverLetterHeader.java | 180 ------------ .../coverletter/spec/CoverLetterSpec.java | 131 --------- .../coverletter/spec/package-info.java | 32 --- .../coverletter/CoverLetterDocumentSpec.java | 150 ---------- .../data/coverletter/JobDetails.java | 149 ---------- .../data/coverletter/package-info.java | 4 - .../document/templates/data/package-info.java | 6 +- .../templates/TemplateTestSupport.java | 18 -- .../presets/CoverLetterGalleryTest.java | 158 ----------- .../presets/CoverLetterPilotTest.java | 113 -------- .../presets/PresetLayoutSnapshotTest.java | 94 ------- .../presets/PresetVisualParityTest.java | 126 --------- .../CoverLetterDocumentSpecTest.java | 40 --- .../coverletter/JobDetailsBuilderTest.java | 29 -- .../java/com/demcha/mock/CoverLetterMock.java | 19 -- .../cover-letter/cover_letter_standard.json | 257 ----------------- 37 files changed, 11 insertions(+), 3173 deletions(-) delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/layouts/LetterFormat.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/BlueBannerLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/CenteredHeadlineLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/PanelLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterHeader.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpec.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java delete mode 100644 src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterGalleryTest.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterPilotTest.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetLayoutSnapshotTest.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpecTest.java delete mode 100644 src/test/java/com/demcha/compose/document/templates/data/coverletter/JobDetailsBuilderTest.java delete mode 100644 src/test/java/com/demcha/mock/CoverLetterMock.java delete mode 100644 src/test/resources/layout-snapshots/canonical-templates/cover-letter/cover_letter_standard.json diff --git a/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java b/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java index 8d1581dca..e1fc61a1e 100644 --- a/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java +++ b/examples/src/main/java/com/demcha/examples/support/ExampleDataFactory.java @@ -11,7 +11,6 @@ import com.demcha.compose.document.templates.cv.v2.data.SkillsSection; import com.demcha.compose.document.templates.data.common.EmailYaml; import com.demcha.compose.document.templates.data.common.Header; -import com.demcha.compose.document.templates.data.coverletter.CoverLetterDocumentSpec; import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec; import com.demcha.compose.document.templates.data.cv.CvDocumentSpec; import com.demcha.compose.document.templates.data.proposal.ProposalDocumentSpec; @@ -65,33 +64,6 @@ public static Header sampleHeader() { .build(); } - public static String sampleCoverLetter() { - return """ - Hiring team at ${companyName}, - - I am excited to share my interest in the Senior Platform Engineer role. My recent work has focused on building reusable document-generation systems that balance public API design, render quality, and maintainability. - - I enjoy translating fuzzy workflow requirements into clear template abstractions, reliable test coverage, and examples that make adoption easier for the rest of the team. - - I would welcome the opportunity to bring that same mix of engineering rigor and product thinking to your platform group. - """; - } - - public static CoverLetterDocumentSpec sampleCoverLetterDocument() { - return CoverLetterDocumentSpec.builder() - .header(sampleHeader()) - .letter(sampleCoverLetter()) - .job(job -> job - .url("https://northwind.example/jobs/platform") - .title("Senior Platform Engineer") - .company("Northwind Systems") - .location("London / Remote") - .description("Lead reusable internal platform capabilities.") - .seniorityLevel("Senior") - .employmentType("Full-time")) - .build(); - } - public static InvoiceDocumentSpec sampleInvoice() { return InvoiceDocumentSpec.builder() .title("Invoice") diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java b/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java deleted file mode 100644 index 6b976eece..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/CoverLetterBuilder.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.builder; - -import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.node.ContainerNode; -import com.demcha.compose.document.node.DocumentNode; -import com.demcha.compose.document.node.ParagraphNode; -import com.demcha.compose.document.node.TextAlign; -import com.demcha.compose.document.style.DocumentInsets; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.core.text.MarkdownText; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Fluent builder for assembling a Templates v2 cover-letter - * {@link DocumentTemplate}. - * - *

A cover-letter preset wraps one builder call inside its - * {@code create(BusinessTheme)} factory — the same flat-recipe - * pattern used by CV presets. Each preset shares the typography - * palette of its paired CV preset (same heading style, same body - * style, same spacing rhythm) so a writer's CV and cover letter - * read as one matched set.

- * - *

All seven knobs ({@code id}, {@code displayName}, - * {@code header}, {@code layout}, {@code bodyStyle}, {@code spacing}, - * and at least implicit alignment via the layout / body style) must - * be configured before calling {@link #build()}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard) — the layered model - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument} - * plus the {@code coverletter.v2} presets. Kept for backward - * compatibility; scheduled for removal in a future major. See - * {@code docs/templates/v2-layered/}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class CoverLetterBuilder { - - private String id; - private String displayName; - private Header header; - private LetterFormat layout; - private DocumentTextStyle bodyStyle; - private Spacing spacing; - - private CoverLetterBuilder() { - } - - /** - * Returns a fresh builder. - * - * @return new builder instance - */ - public static CoverLetterBuilder builder() { - return new CoverLetterBuilder(); - } - - /** - * Sets the stable identifier exposed via - * {@link DocumentTemplate#id()}. - * - * @param value non-null identifier - * @return this builder - */ - public CoverLetterBuilder id(String value) { - this.id = Objects.requireNonNull(value, "id"); - return this; - } - - /** - * Sets the human-readable display name. - * - * @param value non-null display name - * @return this builder - */ - public CoverLetterBuilder displayName(String value) { - this.displayName = Objects.requireNonNull(value, "displayName"); - return this; - } - - /** - * Sets the header component used to render the document header. - * - * @param value non-null header component - * @return this builder - */ - public CoverLetterBuilder header(Header value) { - this.header = Objects.requireNonNull(value, "header"); - return this; - } - - /** - * Sets the layout responsible for arranging header + letter - * blocks. - * - * @param value non-null layout - * @return this builder - */ - public CoverLetterBuilder layout(LetterFormat value) { - this.layout = Objects.requireNonNull(value, "layout"); - return this; - } - - /** - * Sets the text style applied to greeting, body paragraphs, and - * closing. - * - * @param value non-null body text style - * @return this builder - */ - public CoverLetterBuilder bodyStyle(DocumentTextStyle value) { - this.bodyStyle = Objects.requireNonNull(value, "bodyStyle"); - return this; - } - - /** - * Sets the active spacing tokens. - * - * @param value non-null spacing tokens - * @return this builder - */ - public CoverLetterBuilder spacing(Spacing value) { - this.spacing = Objects.requireNonNull(value, "spacing"); - return this; - } - - /** - * Validates configuration and returns the assembled - * {@link DocumentTemplate}. - * - * @return ready-to-use template instance - * @throws NullPointerException if any required setter has not been - * called - */ - public DocumentTemplate build() { - Objects.requireNonNull(id, "id"); - Objects.requireNonNull(displayName, "displayName"); - Objects.requireNonNull(header, "header"); - Objects.requireNonNull(layout, "layout"); - Objects.requireNonNull(bodyStyle, "bodyStyle"); - Objects.requireNonNull(spacing, "spacing"); - - final String capturedId = id; - final String capturedDisplay = displayName; - final Header capturedHeader = header; - final LetterFormat capturedLayout = layout; - final DocumentTextStyle capturedBody = bodyStyle; - final Spacing capturedSpacing = spacing; - - return new DocumentTemplate() { - @Override - public String id() { - return capturedId; - } - - @Override - public String displayName() { - return capturedDisplay; - } - - @Override - public void compose(DocumentSession session, CoverLetterSpec spec) { - Objects.requireNonNull(session, "session"); - Objects.requireNonNull(spec, "spec"); - - DocumentNode headerNode = composeHeader(spec); - List blocks = new ArrayList<>(3); - if (!spec.greeting().isBlank()) { - blocks.add(paragraph( - "letter.greeting", - spec.greeting(), - /* topMargin */ capturedSpacing.moduleGap(), - /* bottomMargin */ capturedSpacing.paragraphSpacing())); - } - blocks.add(bodyContainer(spec.bodyParagraphs())); - if (!spec.closing().isBlank()) { - blocks.add(paragraph( - "letter.closing", - spec.closing(), - /* topMargin */ capturedSpacing.paragraphSpacing(), - /* bottomMargin */ 0.0)); - } - - DocumentNode root = capturedLayout.compose(headerNode, blocks); - session.add(root); - } - - private DocumentNode composeHeader(CoverLetterSpec spec) { - Header.Input input = new Header.Input( - spec.header().name(), - spec.header().contactItems(), - headerLinks(spec.header())); - return capturedHeader.compose(input); - } - - private List headerLinks(CoverLetterHeader header) { - List result = new ArrayList<>(); - if (!header.email().isBlank()) { - result.add(Header.Link.active( - header.email(), - "mailto:" + header.email())); - } - for (CoverLetterHeader.Link link : header.links()) { - if (link.url().isBlank()) { - result.add(Header.Link.plain(link.label())); - } else { - result.add(Header.Link.active(link.label(), link.url())); - } - } - return result; - } - - private DocumentNode bodyContainer(List paragraphs) { - List children = new ArrayList<>(paragraphs.size()); - for (int i = 0; i < paragraphs.size(); i++) { - children.add(paragraph( - "letter.body[" + i + "]", - paragraphs.get(i), - /* topMargin */ 0.0, - /* bottomMargin */ 0.0)); - } - return new ContainerNode( - "letter.body", - children, - /* spacing */ capturedSpacing.paragraphSpacing(), - DocumentInsets.zero(), - DocumentInsets.zero(), - null, null, null, null); - } - - private ParagraphNode paragraph(String name, String text, - double topMargin, double bottomMargin) { - return new ParagraphNode( - name, - /* text */ "", - /* inlineRuns */ MarkdownText.parse(text, capturedBody), - capturedBody, - TextAlign.LEFT, - capturedSpacing.lineSpacing(), - /* bulletOffset */ "", - /* indentStrategy */ null, - /* link */ null, - /* bookmark */ null, - /* padding */ DocumentInsets.zero(), - /* margin */ new DocumentInsets( - topMargin, 0.0, bottomMargin, 0.0), - /* autoSize */ null); - } - }; - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java deleted file mode 100644 index 6d8c55f67..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/builder/package-info.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Templates v2 cover-letter preset builder — fluent assembly of - * {@link com.demcha.compose.document.templates.api.DocumentTemplate} - * instances for cover letters. - * - *

The single class of interest is - * {@link com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder}. - * Preset classes wrap one builder call inside their - * {@code create(BusinessTheme)} factory; users wanting a custom - * cover-letter preset copy that factory body and tweak the chain.

- * - * @since 1.6.0 - */ -package com.demcha.compose.document.templates.coverletter.builder; diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/LetterFormat.java b/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/LetterFormat.java deleted file mode 100644 index 4d5c5227a..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/LetterFormat.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.layouts; - -import com.demcha.compose.document.node.ContainerNode; -import com.demcha.compose.document.node.DocumentNode; -import com.demcha.compose.document.style.DocumentInsets; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -/** - * Templates v2 cover-letter layout. - * - *

Single-column layout with generous paragraph spacing — header - * sits at the top, then greeting, body paragraphs, and closing - * stack vertically beneath it. There is no slot map: a cover - * letter is structurally simpler than a CV (one continuous reading - * flow), so the layout takes the rendered nodes in source order and - * emits one container.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard) — the layered model - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument} - * plus the {@code coverletter.v2} presets. Kept for backward - * compatibility; scheduled for removal in a future major. See - * {@code docs/templates/v2-layered/}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class LetterFormat { - - private static final String LAYOUT_NAME = "layout.letterFormat"; - - private double moduleGap = 0.0; - - private LetterFormat() { - } - - /** - * Returns a fresh layout with zero gap (caller drives spacing - * through node margins). - * - * @return new layout instance - */ - public static LetterFormat layout() { - return new LetterFormat(); - } - - /** - * Sets the vertical gap between top-level letter blocks (header, - * greeting, body, closing). - * - * @param value non-negative finite gap in points - * @return this layout (for chaining) - * @throws IllegalArgumentException if {@code value} is negative, - * {@code NaN}, or infinite - */ - public LetterFormat moduleGap(double value) { - if (Double.isNaN(value) || Double.isInfinite(value) || value < 0) { - throw new IllegalArgumentException("moduleGap must be finite and non-negative: " + value); - } - this.moduleGap = value; - return this; - } - - /** - * Composes the final {@link DocumentNode} from a header plus - * ordered list of letter blocks (greeting, body, closing). - * - * @param header non-null header node - * @param blocks non-null ordered list of letter blocks - * @return container node holding the header and blocks in order - * @throws NullPointerException if either argument is null - */ - public DocumentNode compose(DocumentNode header, List blocks) { - Objects.requireNonNull(header, "header"); - Objects.requireNonNull(blocks, "blocks"); - - List children = new ArrayList<>(blocks.size() + 1); - children.add(header); - children.addAll(blocks); - - return new ContainerNode( - LAYOUT_NAME, - children, - moduleGap, - DocumentInsets.zero(), - DocumentInsets.zero(), - /* fillColor */ null, - /* stroke */ null, - /* cornerRadius */ null, - /* borders */ null); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java deleted file mode 100644 index 085dabf0c..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/layouts/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Superseded Gen-2 cover-letter layouts — frames that arrange a header - * plus letter blocks (greeting, body paragraphs, closing) into a - * final document tree. - * - *

Deprecated surface. These are the older Gen-2 - * cover-letter layouts. They are not the current standard. The - * current standard is the layered surface - * {@code com.demcha.compose.document.templates.coverletter.v2} (data / theme / - * components / widgets / presets). This package is kept only for backward - * compatibility and is scheduled for removal in a future major.

- * - *

Currently a single layout - * ({@link com.demcha.compose.document.templates.coverletter.layouts.LetterFormat}) - * covers all 14 cover-letter pair presets.

- * - *

New code should target the layered {@code coverletter.v2} surface - * instead. See {@code docs/templates/v2-layered/}.

- * - * @since 1.6.0 - */ -@Deprecated(since = "1.7.0", forRemoval = true) -package com.demcha.compose.document.templates.coverletter.layouts; diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/package-info.java index 818e6a9bf..2bd13f3c7 100644 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/package-info.java +++ b/src/main/java/com/demcha/compose/document/templates/coverletter/package-info.java @@ -1,42 +1,15 @@ /** - * Superseded Gen-2 cover-letter domain — layout, presets, builder, and spec - * data types. + * Cover-letter template family. * - *

Deprecated surface. This package is the older Gen-2 - * cover-letter template stack. It is not the current standard. The - * current standard is the layered surface - * {@code com.demcha.compose.document.templates.coverletter.v2} (data / theme / - * components / widgets / presets). This package is kept only for backward - * compatibility and is scheduled for removal in a future major.

+ *

The shipping cover-letter surface is the layered stack under + * {@code coverletter.v2} (data / theme / components / widgets / presets), + * built on the shared {@code templates.core} layer and a {@code BrandTheme}.

* - *

Sub-packages partition the (deprecated) domain by concern:

- * - *
    - *
  • {@code coverletter.layouts} — slot frames (LetterFormat — a - * single-column layout with generous side margins for letter body - * text).
  • - *
  • {@code coverletter.presets} — flat copy-and-tweak preset classes, - * one per CV preset (ModernProfessionalLetter, NordicCleanLetter, - * ClassicSerifLetter, CompactMonoLetter, ExecutiveLetter, - * EngineeringResumeLetter, PanelLetter, SidebarPortraitLetter, - * MonogramSidebarLetter, TimelineMinimalLetter, BoxedSectionsLetter, - * CenteredHeadlineLetter, BlueBannerLetter, EditorialBlueLetter).
  • - *
  • {@code coverletter.builder} — {@code CoverLetterBuilder} for - * users composing their own preset.
  • - *
  • {@code coverletter.spec} — data records ({@code CoverLetterSpec} - * with header, greeting, body paragraphs, closing).
  • - *
- * - *

New code should target the layered {@code coverletter.v2} surface - * instead. See {@code docs/templates/v2-layered/}.

- * - *

Naming note: the user-facing concept is - * "cover-letter" with a hyphen, but Java packages cannot contain hyphens. - * The package name {@code coverletter} drops the hyphen for compatibility; - * file id strings and example file names retain the hyphenated form - * (e.g. {@code cover-letter-modern-professional.pdf}).

+ *

Naming note: the user-facing concept is "cover-letter" + * with a hyphen, but Java packages cannot contain hyphens. The package name + * {@code coverletter} drops the hyphen; file id strings and example file names + * retain the hyphenated form (e.g. {@code cover-letter-modern-professional.pdf}).

* * @since 1.6.0 */ -@Deprecated(since = "1.7.0", forRemoval = true) package com.demcha.compose.document.templates.coverletter; diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BlueBannerLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BlueBannerLetter.java deleted file mode 100644 index d733e0659..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BlueBannerLetter.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code BlueBanner} CV preset. - * - *

PT Serif headline + Lato body, dark INK with the soft-blue - * BANNER_BG used by - * {@link com.demcha.compose.document.templates.cv.presets.BlueBanner} - * for accent runs.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.BlueBannerLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class BlueBannerLetter { - - /** Stable template identifier. */ - public static final String ID = "blue-banner-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Blue Banner Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(20, 25, 35); - private static final DocumentColor SOFT = DocumentColor.rgb(85, 85, 85); - private static final DocumentColor BANNER_BG = DocumentColor.rgb(112, 146, 190); - - private BlueBannerLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code BlueBanner} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Blue Banner Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(22.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(7.5) - .color(SOFT) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(BANNER_BG) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java deleted file mode 100644 index 0c78c1247..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/BoxedSectionsLetter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code BoxedSections} CV preset. - * - *

PT Serif throughout, dark grey ink — matches - * {@link com.demcha.compose.document.templates.cv.presets.BoxedSections}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.BoxedSectionsLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class BoxedSectionsLetter { - - /** Stable template identifier. */ - public static final String ID = "boxed-sections-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Boxed Sections Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(34, 34, 34); - private static final DocumentColor MUTED = DocumentColor.rgb(120, 120, 120); - private static final DocumentColor RULE = DocumentColor.rgb(170, 170, 170); - - private BoxedSectionsLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code BoxedSections} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Boxed Sections Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(22.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(8.5) - .color(MUTED) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(8.5) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(RULE) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CenteredHeadlineLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CenteredHeadlineLetter.java deleted file mode 100644 index 938f5d65d..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CenteredHeadlineLetter.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code CenteredHeadline} CV preset. - * - *

Poppins headline + Lato body, dark grey ink — matches - * {@link com.demcha.compose.document.templates.cv.presets.CenteredHeadline}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.CenteredHeadlineLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class CenteredHeadlineLetter { - - /** Stable template identifier. */ - public static final String ID = "centered-headline-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Centered Headline Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(54, 54, 54); - private static final DocumentColor HEADLINE = DocumentColor.rgb(70, 70, 70); - private static final DocumentColor SOFT = DocumentColor.rgb(105, 105, 105); - private static final DocumentColor RULE = DocumentColor.rgb(188, 188, 188); - - private CenteredHeadlineLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code CenteredHeadline} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Centered Headline Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.POPPINS) - .size(24.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(HEADLINE) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.3) - .color(SOFT) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.3) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(SOFT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java deleted file mode 100644 index 452f89e8a..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ClassicSerifLetter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code ClassicSerif} CV preset. - * - *

PT Serif throughout with the bronze accent and warm INK palette - * of {@link com.demcha.compose.document.templates.cv.presets.ClassicSerif}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ClassicSerifLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class ClassicSerifLetter { - - /** Stable template identifier. */ - public static final String ID = "classic-serif-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Classic Serif Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(45, 43, 40); - private static final DocumentColor MUTED = DocumentColor.rgb(105, 101, 94); - private static final DocumentColor ACCENT = DocumentColor.rgb(126, 93, 52); - - private ClassicSerifLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code ClassicSerif} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Classic Serif Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(24.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(8.7) - .color(MUTED) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(8.7) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.PT_SERIF) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java deleted file mode 100644 index 1e3224eaa..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/CompactMonoLetter.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code CompactMono} CV preset. - * - *

IBM Plex Mono headline + Lato body, dark INK ink with the - * teal-blue ACCENT used by - * {@link com.demcha.compose.document.templates.cv.presets.CompactMono}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.CompactMonoLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class CompactMonoLetter { - - /** Stable template identifier. */ - public static final String ID = "compact-mono-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Compact Mono Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(28, 34, 42); - private static final DocumentColor MUTED = DocumentColor.rgb(84, 96, 112); - private static final DocumentColor ACCENT = DocumentColor.rgb(0, 126, 151); - - private CompactMonoLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code CompactMono} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Compact Mono Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.compact(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.IBM_PLEX_MONO) - .size(20.0) - .decoration(DocumentTextDecoration.BOLD) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.5) - .color(MUTED) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java deleted file mode 100644 index 72898fead..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EditorialBlueLetter.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code EditorialBlue} CV preset. - * - *

Helvetica throughout, deep navy ink with bright editorial blue - * accent — matches - * {@link com.demcha.compose.document.templates.cv.presets.EditorialBlue}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.EditorialBlueLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class EditorialBlueLetter { - - /** Stable template identifier. */ - public static final String ID = "editorial-blue-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Editorial Blue Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(18, 31, 72); - private static final DocumentColor BODY = DocumentColor.rgb(60, 72, 106); - private static final DocumentColor ACCENT = DocumentColor.rgb(86, 136, 255); - - private EditorialBlueLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code EditorialBlue} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Editorial Blue Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA_BOLD) - .size(22.0) - .decoration(DocumentTextDecoration.BOLD) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(9.0) - .color(BODY) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(9.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(10.0) - .color(BODY) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java deleted file mode 100644 index 105985f8c..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/EngineeringResumeLetter.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code EngineeringResume} CV preset. - * - *

Navy primary, green accent, Barlow headline + Lato body — matches - * {@link com.demcha.compose.document.templates.cv.presets.EngineeringResume}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.EngineeringResumeLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class EngineeringResumeLetter { - - /** Stable template identifier. */ - public static final String ID = "engineering-resume-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Engineering Resume Letter"; - - private static final DocumentColor NAVY = DocumentColor.rgb(13, 32, 47); - private static final DocumentColor INK = DocumentColor.rgb(32, 42, 55); - private static final DocumentColor MUTED = DocumentColor.rgb(91, 105, 119); - private static final DocumentColor GREEN = DocumentColor.rgb(27, 145, 104); - - private EngineeringResumeLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code EngineeringResume} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Engineering Resume Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.compact(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.BARLOW) - .size(24.0) - .decoration(DocumentTextDecoration.BOLD) - .color(NAVY) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.5) - .color(MUTED) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(GREEN) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java deleted file mode 100644 index 76a1ba803..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ExecutiveLetter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code Executive} CV preset. - * - *

Slate primary, bronze accent, Poppins headline + Lato body — - * matches {@link com.demcha.compose.document.templates.cv.presets.Executive}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ExecutiveLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class ExecutiveLetter { - - /** Stable template identifier. */ - public static final String ID = "executive-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Executive Letter"; - - private static final DocumentColor PRIMARY = DocumentColor.rgb(24, 35, 51); - private static final DocumentColor BODY = DocumentColor.rgb(49, 58, 72); - private static final DocumentColor ACCENT = DocumentColor.rgb(172, 112, 55); - - private ExecutiveLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code Executive} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Executive Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.POPPINS) - .size(24.0) - .decoration(DocumentTextDecoration.BOLD) - .color(PRIMARY) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.0) - .color(BODY) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.5) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.5) - .color(BODY) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java deleted file mode 100644 index f3e1359b0..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/ModernProfessionalLetter.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 "Modern Professional Letter" cover-letter preset. - * - *

Visual pair of - * {@link com.demcha.compose.document.templates.cv.presets.ModernProfessional}. - * Same right-aligned header (slate-blue name, royal-blue underlined - * contact links), same Helvetica body type. The cover letter itself - * is a single-column letter — header on top, greeting, body - * paragraphs separated by paragraph spacing, closing.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.ModernProfessionalLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class ModernProfessionalLetter { - - /** Stable template identifier. */ - public static final String ID = "modern-professional-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Modern Professional Letter"; - - /** V1 {@code BrandTheme} primary slate-blue used by the display name. */ - private static final DocumentColor NAME_COLOR = DocumentColor.rgb(44, 62, 80); - - /** V1 link accent (royal blue) used by the contact link row. */ - private static final DocumentColor LINK_COLOR = DocumentColor.rgb(65, 105, 225); - - private ModernProfessionalLetter() { - } - - /** - * Builds a fresh cover-letter template paired with the - * Modern Professional CV style. - * - * @param theme active business theme - * @return ready-to-use template - * @throws NullPointerException if {@code theme} is null - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.compact(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA_BOLD) - .size(28.0) - .decoration(DocumentTextDecoration.BOLD) - .color(NAME_COLOR) - .build(); - - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(9.0) - .color(theme.text().body().color()) - .build(); - - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(10.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(LINK_COLOR) - .build(); - - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.HELVETICA) - .size(10.0) - .color(theme.text().body().color()) - .build(); - - return CoverLetterBuilder.builder() - .id(ID) - .displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout() - .moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle) - .spacing(spacing) - .build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java deleted file mode 100644 index b37b3d18e..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/MonogramSidebarLetter.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code MonogramSidebar} CV preset. - * - *

Crimson Text headline + Lato body, deep slate ink with muted gold - * accent — matches - * {@link com.demcha.compose.document.templates.cv.presets.MonogramSidebar}. - * The cover letter is a simple single-column letter — the CV's - * monogram sidebar is intentionally not replicated.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.MonogramSidebarLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class MonogramSidebarLetter { - - /** Stable template identifier. */ - public static final String ID = "monogram-sidebar-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Monogram Sidebar Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(37, 45, 58); - private static final DocumentColor SOFT = DocumentColor.rgb(112, 119, 125); - private static final DocumentColor ACCENT = DocumentColor.rgb(158, 146, 104); - - private MonogramSidebarLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code MonogramSidebar} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Monogram Sidebar Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.CRIMSON_TEXT) - .size(26.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(7.4) - .color(SOFT) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(7.4) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.5) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java deleted file mode 100644 index 7b53d52af..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/NordicCleanLetter.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code NordicClean} CV preset. - * - *

Same INK / ACCENT palette and Barlow + Lato typography as the - * {@link com.demcha.compose.document.templates.cv.presets.NordicClean} - * CV. Single-column letter format — header on top, greeting, body - * paragraphs, closing.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.NordicCleanLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class NordicCleanLetter { - - /** Stable template identifier. */ - public static final String ID = "nordic-clean-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Nordic Clean Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(18, 39, 52); - private static final DocumentColor MUTED = DocumentColor.rgb(82, 104, 116); - private static final DocumentColor ACCENT = DocumentColor.rgb(28, 128, 135); - - private NordicCleanLetter() { - } - - /** - * Builds a fresh cover-letter template paired with the - * Nordic Clean CV style. - * - * @param theme active business theme - * @return ready-to-use template - * @throws NullPointerException if {@code theme} is null - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.BARLOW) - .size(24.0) - .decoration(DocumentTextDecoration.BOLD) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.5) - .color(MUTED) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/PanelLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/PanelLetter.java deleted file mode 100644 index c466cdb63..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/PanelLetter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code Panel} CV preset. - * - *

Deep-slate primary, teal accent, Poppins headline + Lato body — - * matches {@link com.demcha.compose.document.templates.cv.presets.Panel}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.PanelLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class PanelLetter { - - /** Stable template identifier. */ - public static final String ID = "panel-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Panel Letter"; - - private static final DocumentColor HEADER_TEXT = DocumentColor.rgb(20, 44, 66); - private static final DocumentColor BODY = DocumentColor.rgb(54, 68, 84); - private static final DocumentColor ACCENT = DocumentColor.rgb(0, 128, 128); - - private PanelLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code Panel} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Panel Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.POPPINS) - .size(22.0) - .decoration(DocumentTextDecoration.BOLD) - .color(HEADER_TEXT) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.9) - .color(BODY) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.9) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.4) - .color(BODY) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java deleted file mode 100644 index 5da97e3a7..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/SidebarPortraitLetter.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code SidebarPortrait} CV preset. - * - *

Crimson Text serif headline + Lato body in the restrained grey - * palette of - * {@link com.demcha.compose.document.templates.cv.presets.SidebarPortrait}. - * The cover letter is a simple single-column letter — the CV's - * portrait sidebar is intentionally not replicated.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.SidebarPortraitLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class SidebarPortraitLetter { - - /** Stable template identifier. */ - public static final String ID = "sidebar-portrait-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Sidebar Portrait Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(34, 34, 34); - private static final DocumentColor SOFT = DocumentColor.rgb(85, 85, 85); - private static final DocumentColor ACCENT = DocumentColor.rgb(106, 106, 106); - - private SidebarPortraitLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code SidebarPortrait} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Sidebar Portrait Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.CRIMSON_TEXT) - .size(28.0) - .decoration(DocumentTextDecoration.BOLD) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.3) - .color(SOFT) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.3) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(ACCENT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java deleted file mode 100644 index fbf27f9f7..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/TimelineMinimalLetter.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.style.DocumentColor; -import com.demcha.compose.document.style.DocumentTextDecoration; -import com.demcha.compose.document.style.DocumentTextStyle; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.components.Header; -import com.demcha.compose.document.templates.coverletter.builder.CoverLetterBuilder; -import com.demcha.compose.document.templates.coverletter.layouts.LetterFormat; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.templates.themes.Spacing; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.font.FontName; - -/** - * Templates v2 cover-letter pair for {@code TimelineMinimal} CV preset. - * - *

All-grey palette with Barlow Condensed for the headline and Lato - * body — matches - * {@link com.demcha.compose.document.templates.cv.presets.TimelineMinimal}.

- * - * @deprecated Superseded by the layered …v2… surface (the current - * standard). Kept for backward compatibility; scheduled for removal - * in a future major. See {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.presets.TimelineMinimalLetter}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public final class TimelineMinimalLetter { - - /** Stable template identifier. */ - public static final String ID = "timeline-minimal-letter"; - - /** Human-readable display name. */ - public static final String DISPLAY_NAME = "Timeline Minimal Letter"; - - private static final DocumentColor INK = DocumentColor.rgb(74, 74, 74); - private static final DocumentColor SOFT = DocumentColor.rgb(122, 122, 122); - - private TimelineMinimalLetter() { - } - - /** - * Builds the cover-letter template paired with the {@code TimelineMinimal} CV preset. - * - * @param theme the active theme supplying palette, typography, and spacing - * @return a {@code DocumentTemplate} for the "Timeline Minimal Letter" - */ - public static DocumentTemplate create(BusinessTheme theme) { - Spacing spacing = Spacing.comfortable(); - - DocumentTextStyle nameStyle = DocumentTextStyle.builder() - .fontName(FontName.BARLOW_CONDENSED) - .size(28.0) - .decoration(DocumentTextDecoration.DEFAULT) - .color(INK) - .build(); - DocumentTextStyle contactStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(8.5) - .color(SOFT) - .build(); - DocumentTextStyle linkStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(9.0) - .decoration(DocumentTextDecoration.UNDERLINE) - .color(SOFT) - .build(); - DocumentTextStyle bodyStyle = DocumentTextStyle.builder() - .fontName(FontName.LATO) - .size(10.0) - .color(INK) - .build(); - - return CoverLetterBuilder.builder() - .id(ID).displayName(DISPLAY_NAME) - .header(Header.rightAligned(theme, spacing) - .withNameStyle(nameStyle) - .withContactStyle(contactStyle) - .withLinkStyle(linkStyle)) - .layout(LetterFormat.layout().moduleGap(spacing.moduleGap())) - .bodyStyle(bodyStyle).spacing(spacing).build(); - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java deleted file mode 100644 index 0bea3e7c8..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/presets/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Superseded Gen-2 cover-letter presets — flat copy-and-tweak recipe - * classes paired one-to-one with the - * {@link com.demcha.compose.document.templates.cv.presets} CV - * preset family. - * - *

Deprecated surface. These are the older Gen-2 - * cover-letter presets. They are not the current standard. The - * current standard is the layered surface - * {@code com.demcha.compose.document.templates.coverletter.v2.presets}. This - * package is kept only for backward compatibility and is scheduled for - * removal in a future major.

- * - *

Each preset shares the typography palette and spacing rhythm - * of its paired CV preset, so a writer's CV and cover letter ship - * as a matched set with consistent visual identity.

- * - *

New code should target the layered {@code coverletter.v2} presets - * instead. See {@code docs/templates/v2-layered/}.

- * - * @since 1.6.0 - */ -@Deprecated(since = "1.7.0", forRemoval = true) -package com.demcha.compose.document.templates.coverletter.presets; diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterHeader.java b/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterHeader.java deleted file mode 100644 index ceff37f2c..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterHeader.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.spec; - -import java.util.List; -import java.util.Objects; - -/** - * Top-of-document identity block for a cover letter in Templates v2. - * - *

Mirrors {@code CvHeader} structurally because the user-facing - * concept (name, address, phone, email, links) is identical. The - * domain types are kept separate so the cover-letter and CV - * surfaces can evolve independently if needed.

- * - * @param name document subject's name (required, non-blank) - * @param address optional address line; empty string when absent - * @param phone optional phone number; empty string when absent - * @param email optional email address; empty string when absent - * @param links ordered list of {@link Link} entries (typically - * LinkedIn, GitHub); never null after construction - * @deprecated Superseded by the layered …v2… surface (the current - * standard) — the layered model - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument} - * plus the {@code coverletter.v2} presets. Kept for backward - * compatibility; scheduled for removal in a future major. See - * {@code docs/templates/v2-layered/}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public record CoverLetterHeader( - String name, - String address, - String phone, - String email, - List links) { - - /** - * Compact constructor that normalises null strings to empty and - * defensively copies the link list. - * - * @throws NullPointerException if {@code name} is null - * @throws IllegalArgumentException if {@code name} is blank - */ - public CoverLetterHeader { - Objects.requireNonNull(name, "name"); - if (name.isBlank()) { - throw new IllegalArgumentException("name must not be blank"); - } - address = address == null ? "" : address; - phone = phone == null ? "" : phone; - email = email == null ? "" : email; - links = links == null ? List.of() : List.copyOf(links); - } - - /** - * Returns the contact items (address, phone) in source order, - * skipping blank fields. - * - * @return ordered list of non-blank contact strings - */ - public List contactItems() { - java.util.List items = new java.util.ArrayList<>(2); - if (!address.isBlank()) { - items.add(address); - } - if (!phone.isBlank()) { - items.add(phone); - } - return List.copyOf(items); - } - - /** - * Returns a fresh builder. - * - * @return new builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Named hyperlink in a cover letter header (e.g. LinkedIn). - * - * @param label visible label (must not be blank) - * @param url target URL (may be empty for non-clickable label) - */ - public record Link(String label, String url) { - - /** - * Compact constructor that rejects null fields. - * - * @throws NullPointerException if {@code label} or {@code url} is null - * @throws IllegalArgumentException if {@code label} is blank - */ - public Link { - Objects.requireNonNull(label, "label"); - Objects.requireNonNull(url, "url"); - if (label.isBlank()) { - throw new IllegalArgumentException("label must not be blank"); - } - } - } - - /** - * Mutable builder for {@link CoverLetterHeader}. - */ - public static final class Builder { - private String name; - private String address = ""; - private String phone = ""; - private String email = ""; - private final java.util.List links = new java.util.ArrayList<>(); - - private Builder() { - } - - /** - * Sets the document subject's name. - * - * @param value non-blank name - * @return this builder - */ - public Builder name(String value) { - this.name = value; - return this; - } - - /** - * Sets the optional address line. - * - * @param value address; null treated as empty - * @return this builder - */ - public Builder address(String value) { - this.address = value == null ? "" : value; - return this; - } - - /** - * Sets the optional phone number. - * - * @param value phone; null treated as empty - * @return this builder - */ - public Builder phone(String value) { - this.phone = value == null ? "" : value; - return this; - } - - /** - * Sets the optional email address. - * - * @param value email; null treated as empty - * @return this builder - */ - public Builder email(String value) { - this.email = value == null ? "" : value; - return this; - } - - /** - * Appends a labelled link. - * - * @param label non-blank link label - * @param url non-null target URL (may be empty) - * @return this builder - */ - public Builder link(String label, String url) { - this.links.add(new Link(label, url)); - return this; - } - - /** - * Builds an immutable {@link CoverLetterHeader}. - * - * @return new cover letter header - */ - public CoverLetterHeader build() { - return new CoverLetterHeader(name, address, phone, email, links); - } - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java b/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java deleted file mode 100644 index ba8ae9acd..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/CoverLetterSpec.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.spec; - -import java.util.List; -import java.util.Objects; - -/** - * User-facing data record for a cover letter in Templates v2. - * - *

A cover letter is structurally simpler than a CV: a header - * identifying the writer, a greeting line ({@code "Dear Hiring - * Manager,"}), a sequence of body paragraphs, and a closing line - * ({@code "Sincerely, Artem"}). Each segment is rendered by the - * paired preset using the same typography palette as its CV - * counterpart so a writer can ship a CV and matching cover letter - * with consistent visual identity.

- * - * @param header identity block (required) - * @param greeting first body line (required, may be blank to - * suppress); typically {@code "Dear Hiring - * Manager,"} - * @param bodyParagraphs ordered list of body paragraphs; blank - * paragraphs are kept to preserve the - * writer's intended whitespace; may carry - * markdown markers ({@code **bold**}, - * {@code *italic*}) - * @param closing last body line (required, may be blank); - * typically {@code "Sincerely, Alex"} - * @deprecated Superseded by the layered …v2… surface (the current - * standard) — the layered model - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument} - * plus the {@code coverletter.v2} presets. Kept for backward - * compatibility; scheduled for removal in a future major. See - * {@code docs/templates/v2-layered/}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public record CoverLetterSpec( - CoverLetterHeader header, - String greeting, - List bodyParagraphs, - String closing) { - - /** - * Compact constructor that normalises null strings to empty and - * defensively copies the body paragraphs list. - * - * @throws NullPointerException if {@code header} or {@code bodyParagraphs} is null - */ - public CoverLetterSpec { - Objects.requireNonNull(header, "header"); - Objects.requireNonNull(bodyParagraphs, "bodyParagraphs"); - greeting = greeting == null ? "" : greeting; - closing = closing == null ? "" : closing; - bodyParagraphs = List.copyOf(bodyParagraphs); - } - - /** - * Returns a fluent builder. - * - * @return new builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Mutable builder for {@link CoverLetterSpec}. - */ - public static final class Builder { - private CoverLetterHeader header; - private String greeting = ""; - private final java.util.List bodyParagraphs = new java.util.ArrayList<>(); - private String closing = ""; - - private Builder() { - } - - /** - * Sets the document header. - * - * @param value non-null header - * @return this builder - */ - public Builder header(CoverLetterHeader value) { - this.header = value; - return this; - } - - /** - * Sets the greeting line. - * - * @param value greeting; null treated as empty - * @return this builder - */ - public Builder greeting(String value) { - this.greeting = value == null ? "" : value; - return this; - } - - /** - * Appends one body paragraph. - * - * @param value non-null paragraph text - * @return this builder - */ - public Builder paragraph(String value) { - Objects.requireNonNull(value, "paragraph"); - this.bodyParagraphs.add(value); - return this; - } - - /** - * Sets the closing line. - * - * @param value closing; null treated as empty - * @return this builder - */ - public Builder closing(String value) { - this.closing = value == null ? "" : value; - return this; - } - - /** - * Builds an immutable {@link CoverLetterSpec}. - * - * @return new spec - */ - public CoverLetterSpec build() { - return new CoverLetterSpec(header, greeting, bodyParagraphs, closing); - } - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java b/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java deleted file mode 100644 index ea846a961..000000000 --- a/src/main/java/com/demcha/compose/document/templates/coverletter/spec/package-info.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Superseded Gen-2 cover-letter specification records — user-facing data - * types. - * - *

Deprecated surface. These are the older Gen-2 - * cover-letter spec records. They are not the current standard. The - * current standard is the layered model - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument} - * in the {@code com.demcha.compose.document.templates.coverletter.v2} - * surface. This package is kept only for backward compatibility and is - * scheduled for removal in a future major.

- * - *

This package holds the immutable records a user fills with their - * cover-letter content before passing the spec to a Gen-2 preset for - * rendering:

- * - *
    - *
  • {@link com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader} - * — name, address, phone, email, links (with builder).
  • - *
  • {@link com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec} - * — header plus greeting, body paragraphs, and closing line. - * Body strings may carry markdown markers ({@code **bold**}, - * {@code *italic*}) for inline emphasis.
  • - *
- * - *

New code should target the layered {@code coverletter.v2} data model - * instead. See {@code docs/templates/v2-layered/}.

- * - * @since 1.6.0 - */ -@Deprecated(since = "1.7.0", forRemoval = true) -package com.demcha.compose.document.templates.coverletter.spec; diff --git a/src/main/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpec.java b/src/main/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpec.java deleted file mode 100644 index f4dc69a42..000000000 --- a/src/main/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpec.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.demcha.compose.document.templates.data.coverletter; - -import com.demcha.compose.document.templates.data.common.Header; - -import java.util.Objects; -import java.util.function.Consumer; - -/** - * Public compose-first cover-letter input. - * - *

Authoring role: keeps cover-letter composition document-shaped: - * one header, one body, and optional job context for personalization.

- * - * @param header contact/profile header rendered before the letter body - * @param body cover-letter body text - * @param jobDetails target role metadata used by templates - * @author Artem Demchyshyn - * @deprecated Test-only dead code; the live CV/cover-letter model is - * {@code cv.v2} / {@code coverletter.v2}. Kept for backward - * compatibility; scheduled for removal in a future major. See - * {@code docs/templates/v2-layered/} and - * {@link com.demcha.compose.document.templates.coverletter.v2.data.CoverLetterDocument}. - */ -@Deprecated(since = "1.7.0", forRemoval = true) -public record CoverLetterDocumentSpec( - Header header, - String body, - JobDetails jobDetails -) { - - /** - * Creates a normalized cover-letter spec. - */ - public CoverLetterDocumentSpec { - body = Objects.requireNonNullElse(body, ""); - } - - /** - * Creates a document spec from the common cover-letter inputs. - * - * @param header contact/profile header - * @param body cover-letter body text - * @param jobDetails target role metadata - * @return document spec - */ - public static CoverLetterDocumentSpec of(Header header, String body, JobDetails jobDetails) { - return new CoverLetterDocumentSpec(header, body, jobDetails); - } - - /** - * Starts a fluent cover-letter spec builder. - * - * @return document builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Builder for cover-letter document specs. - */ - public static final class Builder { - private Header header; - private String body; - private JobDetails jobDetails; - - private Builder() { - } - - /** - * Sets the contact/profile header. - * - * @param header header block - * @return this builder - */ - public Builder header(Header header) { - this.header = header; - return this; - } - - /** - * Configures the contact/profile header. - * - * @param spec header builder callback - * @return this builder - */ - public Builder header(Consumer spec) { - Header.Builder builder = Header.builder(); - if (spec != null) { - spec.accept(builder); - } - return header(builder.build()); - } - - /** - * Sets the cover-letter body. - * - * @param body body text - * @return this builder - */ - public Builder body(String body) { - this.body = body; - return this; - } - - /** - * Alias for {@link #body(String)}. - * - * @param body body text - * @return this builder - */ - public Builder letter(String body) { - return body(body); - } - - /** - * Sets the job details. - * - * @param jobDetails job metadata - * @return this builder - */ - public Builder jobDetails(JobDetails jobDetails) { - this.jobDetails = jobDetails; - return this; - } - - /** - * Configures the job details. - * - * @param spec job details builder callback - * @return this builder - */ - public Builder job(Consumer spec) { - JobDetails.Builder builder = JobDetails.builder(); - if (spec != null) { - spec.accept(builder); - } - return jobDetails(builder.build()); - } - - /** - * Builds the immutable cover-letter spec. - * - * @return cover-letter document spec - */ - public CoverLetterDocumentSpec build() { - return new CoverLetterDocumentSpec(header, body, jobDetails); - } - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java b/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java deleted file mode 100644 index fba48c7d3..000000000 --- a/src/main/java/com/demcha/compose/document/templates/data/coverletter/JobDetails.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.demcha.compose.document.templates.data.coverletter; - -import com.fasterxml.jackson.annotation.JsonInclude; - -/** - * Immutable job-application context passed into canonical cover-letter composition. - * - *

Pipeline role: captures the target role, company, and optional job - * posting metadata so template composers can resolve letter copy and chrome.

- * - *

Mutability: immutable record. Thread-safety: thread-safe - * when referenced through immutable component values.

- * - * @param url optional job posting URL - * @param title target role title - * @param company target company name - * @param location target job location - * @param description optional job description text - * @param seniorityLevel optional seniority label - * @param employmentType optional employment type label - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -public record JobDetails( - String url, - String title, - String company, - String location, - String description, - String seniorityLevel, - String employmentType) { - - /** - * Starts a fluent job details builder. - * - * @return job details builder - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Fluent builder for job details. - */ - public static final class Builder { - private String url; - private String title; - private String company; - private String location; - private String description; - private String seniorityLevel; - private String employmentType; - - private Builder() { - } - - /** - * Sets the job posting URL. - * - * @param url job posting URL - * @return this builder - */ - public Builder url(String url) { - this.url = url; - return this; - } - - /** - * Sets the target role title. - * - * @param title role title - * @return this builder - */ - public Builder title(String title) { - this.title = title; - return this; - } - - /** - * Sets the company name. - * - * @param company company name - * @return this builder - */ - public Builder company(String company) { - this.company = company; - return this; - } - - /** - * Sets the job location. - * - * @param location job location - * @return this builder - */ - public Builder location(String location) { - this.location = location; - return this; - } - - /** - * Sets the job description text. - * - * @param description job description text - * @return this builder - */ - public Builder description(String description) { - this.description = description; - return this; - } - - /** - * Sets the seniority label. - * - * @param seniorityLevel seniority label - * @return this builder - */ - public Builder seniorityLevel(String seniorityLevel) { - this.seniorityLevel = seniorityLevel; - return this; - } - - /** - * Sets the employment type label. - * - * @param employmentType employment type label - * @return this builder - */ - public Builder employmentType(String employmentType) { - this.employmentType = employmentType; - return this; - } - - /** - * Builds immutable job details. - * - * @return job details - */ - public JobDetails build() { - return new JobDetails( - url, - title, - company, - location, - description, - seniorityLevel, - employmentType); - } - } -} diff --git a/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java b/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java deleted file mode 100644 index 30e6a8b6a..000000000 --- a/src/main/java/com/demcha/compose/document/templates/data/coverletter/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Cover-letter document specs and supporting data records for canonical templates. - */ -package com.demcha.compose.document.templates.data.coverletter; diff --git a/src/main/java/com/demcha/compose/document/templates/data/package-info.java b/src/main/java/com/demcha/compose/document/templates/data/package-info.java index 03f4e01c3..84f1013d7 100644 --- a/src/main/java/com/demcha/compose/document/templates/data/package-info.java +++ b/src/main/java/com/demcha/compose/document/templates/data/package-info.java @@ -3,8 +3,8 @@ * {@code document.templates} layer. * *

Concrete public data types live in child packages such as - * {@code data.cv}, {@code data.invoice}, {@code data.proposal}, - * {@code data.coverletter}, and {@code data.schedule}. Shared contact/link - * types live in {@code data.common}.

+ * {@code data.cv}, {@code data.invoice}, {@code data.proposal}, and + * {@code data.schedule}. Shared contact/link types live in + * {@code data.common}.

*/ package com.demcha.compose.document.templates.data; diff --git a/src/test/java/com/demcha/compose/document/templates/TemplateTestSupport.java b/src/test/java/com/demcha/compose/document/templates/TemplateTestSupport.java index f0af670fd..e27454083 100644 --- a/src/test/java/com/demcha/compose/document/templates/TemplateTestSupport.java +++ b/src/test/java/com/demcha/compose/document/templates/TemplateTestSupport.java @@ -3,16 +3,13 @@ import com.demcha.compose.GraphCompose; import com.demcha.compose.document.api.DocumentPageSize; import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.templates.data.coverletter.CoverLetterDocumentSpec; import com.demcha.compose.document.templates.data.invoice.InvoiceData; import com.demcha.compose.document.templates.data.invoice.InvoiceDocumentSpec; -import com.demcha.compose.document.templates.data.coverletter.JobDetails; import com.demcha.compose.document.templates.data.proposal.ProposalData; import com.demcha.compose.document.templates.data.proposal.ProposalDocumentSpec; import com.demcha.compose.document.templates.data.schedule.WeeklyScheduleData; import com.demcha.compose.document.templates.data.schedule.WeeklyScheduleDocumentSpec; import com.demcha.compose.font.FontName; -import com.demcha.mock.CoverLetterMock; import com.demcha.mock.InvoiceDataFixtures; import com.demcha.mock.ProposalDataFixtures; import com.demcha.mock.WeeklyScheduleDataFixtures; @@ -50,21 +47,6 @@ public final class TemplateTestSupport { private TemplateTestSupport() { } - public static String coverLetter(String companyName) { - return CoverLetterMock.letter.replace("${companyName}", companyName); - } - - public static JobDetails jobDetails(String companyName) { - return new JobDetails( - "https://linkedin.com/jobs/view/visual-test", - "Software Engineer", - companyName, - "Remote", - "Visual verification test", - "Mid", - "Full-time"); - } - public static InvoiceData canonicalInvoiceData() { return InvoiceDataFixtures.standardInvoice(); } diff --git a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterGalleryTest.java b/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterGalleryTest.java deleted file mode 100644 index b088146b0..000000000 --- a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterGalleryTest.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.GraphCompose; -import com.demcha.compose.document.api.DocumentPageSize; -import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.theme.BusinessTheme; -import org.junit.jupiter.api.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.function.Function; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Renders every Templates v2 cover-letter preset against the same - * shared sample spec and writes the results to - * {@code target/visual-tests/clean/templates/coverletter/v2/} for - * human glance comparison. The 14 letter renders should read as a - * matched set with the sibling 14 CV preset renders in - * {@code .../templates/cv/v2/}. - */ -class CoverLetterGalleryTest { - - private static final BusinessTheme THEME = BusinessTheme.modern(); - - private static final Path OUTPUT_DIR = Path.of( - "target", "visual-tests", "clean", "templates", "coverletter", "v2"); - - private static CoverLetterSpec sampleSpec() { - return CoverLetterSpec.builder() - .header(CoverLetterHeader.builder() - .name("Artem Demchyshyn") - .address("London, UK") - .phone("+44 20 5555 1000") - .email("artem@demo.dev") - .link("LinkedIn", "https://linkedin.com/in/graphcompose") - .link("GitHub", "https://github.com/DemchaAV") - .build()) - .greeting("Dear Hiring Team at **Northwind Systems**,") - .paragraph("I am excited to share my interest in the Senior " - + "Platform Engineer role. My recent work has focused " - + "on building **reusable document-generation systems** " - + "that balance public API design, render quality, and " - + "maintainability.") - .paragraph("I enjoy translating fuzzy workflow requirements into " - + "clear template abstractions, reliable test coverage, " - + "and examples that make adoption easier for the rest " - + "of the team.") - .paragraph("I would welcome the opportunity to bring that same " - + "mix of engineering rigor and product thinking to your " - + "platform group.") - .closing("Sincerely, *Artem Demchyshyn*") - .build(); - } - - private void render(String slug, Function> factory) throws Exception { - Files.createDirectories(OUTPUT_DIR); - Path output = OUTPUT_DIR.resolve(slug + "_v2_render_file.pdf"); - Files.deleteIfExists(output); - - DocumentTemplate template = factory.apply(THEME); - try (DocumentSession session = GraphCompose.document(output) - .pageSize(DocumentPageSize.A4) - .margin(48, 48, 48, 48) - .create()) { - template.compose(session, sampleSpec()); - session.buildPdf(); - } - assertThat(output).exists(); - assertThat(Files.size(output)).isPositive(); - } - - @Test - void rendersNordicCleanLetter() throws Exception { - render("nordic_clean_letter", NordicCleanLetter::create); - } - - @Test - void rendersClassicSerifLetter() throws Exception { - render("classic_serif_letter", ClassicSerifLetter::create); - } - - @Test - void rendersCompactMonoLetter() throws Exception { - render("compact_mono_letter", CompactMonoLetter::create); - } - - @Test - void rendersExecutiveLetter() throws Exception { - render("executive_letter", ExecutiveLetter::create); - } - - @Test - void rendersEngineeringResumeLetter() throws Exception { - render("engineering_resume_letter", EngineeringResumeLetter::create); - } - - @Test - void rendersTimelineMinimalLetter() throws Exception { - render("timeline_minimal_letter", TimelineMinimalLetter::create); - } - - @Test - void rendersBoxedSectionsLetter() throws Exception { - render("boxed_sections_letter", BoxedSectionsLetter::create); - } - - @Test - void rendersCenteredHeadlineLetter() throws Exception { - render("centered_headline_letter", CenteredHeadlineLetter::create); - } - - @Test - void rendersBlueBannerLetter() throws Exception { - render("blue_banner_letter", BlueBannerLetter::create); - } - - @Test - void rendersEditorialBlueLetter() throws Exception { - render("editorial_blue_letter", EditorialBlueLetter::create); - } - - @Test - void rendersPanelLetter() throws Exception { - render("panel_letter", PanelLetter::create); - } - - @Test - void rendersSidebarPortraitLetter() throws Exception { - render("sidebar_portrait_letter", SidebarPortraitLetter::create); - } - - @Test - void rendersMonogramSidebarLetter() throws Exception { - render("monogram_sidebar_letter", MonogramSidebarLetter::create); - } - - @Test - void exposesStableIdentities() { - assertThat(NordicCleanLetter.ID).isEqualTo("nordic-clean-letter"); - assertThat(ClassicSerifLetter.ID).isEqualTo("classic-serif-letter"); - assertThat(CompactMonoLetter.ID).isEqualTo("compact-mono-letter"); - assertThat(ExecutiveLetter.ID).isEqualTo("executive-letter"); - assertThat(EngineeringResumeLetter.ID).isEqualTo("engineering-resume-letter"); - assertThat(TimelineMinimalLetter.ID).isEqualTo("timeline-minimal-letter"); - assertThat(BoxedSectionsLetter.ID).isEqualTo("boxed-sections-letter"); - assertThat(CenteredHeadlineLetter.ID).isEqualTo("centered-headline-letter"); - assertThat(BlueBannerLetter.ID).isEqualTo("blue-banner-letter"); - assertThat(EditorialBlueLetter.ID).isEqualTo("editorial-blue-letter"); - assertThat(PanelLetter.ID).isEqualTo("panel-letter"); - assertThat(SidebarPortraitLetter.ID).isEqualTo("sidebar-portrait-letter"); - assertThat(MonogramSidebarLetter.ID).isEqualTo("monogram-sidebar-letter"); - } -} diff --git a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterPilotTest.java b/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterPilotTest.java deleted file mode 100644 index 44e0a7f2b..000000000 --- a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/CoverLetterPilotTest.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.GraphCompose; -import com.demcha.compose.document.api.DocumentPageSize; -import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.theme.BusinessTheme; -import org.junit.jupiter.api.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Pilot test for the Templates v2 cover-letter pipeline. Renders the - * {@link ModernProfessionalLetter} preset to - * {@code target/visual-tests/clean/templates/coverletter/v2/} so the - * full vertical (spec → builder → layout → header component → - * markdown-aware paragraphs → session.add) can be inspected end-to-end. - */ -class CoverLetterPilotTest { - - private static final BusinessTheme THEME = BusinessTheme.modern(); - - private static final Path OUTPUT_DIR = Path.of( - "target", "visual-tests", "clean", "templates", "coverletter", "v2"); - - private static CoverLetterSpec sampleSpec() { - return CoverLetterSpec.builder() - .header(CoverLetterHeader.builder() - .name("Artem Demchyshyn") - .address("London, UK") - .phone("+44 20 5555 1000") - .email("artem@demo.dev") - .link("LinkedIn", "https://linkedin.com/in/graphcompose") - .link("GitHub", "https://github.com/DemchaAV") - .build()) - .greeting("Dear Hiring Team at **Northwind Systems**,") - .paragraph("I am excited to share my interest in the Senior " - + "Platform Engineer role. My recent work has focused " - + "on building **reusable document-generation systems** " - + "that balance public API design, render quality, and " - + "maintainability.") - .paragraph("I enjoy translating fuzzy workflow requirements into " - + "clear template abstractions, reliable test coverage, " - + "and examples that make adoption easier for the rest " - + "of the team.") - .paragraph("I would welcome the opportunity to bring that same " - + "mix of engineering rigor and product thinking to your " - + "platform group.") - .closing("Sincerely, *Artem Demchyshyn*") - .build(); - } - - @Test - void modernProfessionalLetterIdentities() { - assertThat(ModernProfessionalLetter.ID).isEqualTo("modern-professional-letter"); - assertThat(ModernProfessionalLetter.DISPLAY_NAME).isEqualTo("Modern Professional Letter"); - - DocumentTemplate template = ModernProfessionalLetter.create(THEME); - assertThat(template.id()).isEqualTo(ModernProfessionalLetter.ID); - assertThat(template.displayName()).isEqualTo(ModernProfessionalLetter.DISPLAY_NAME); - } - - @Test - void rendersModernProfessionalLetterToPdf() throws Exception { - Files.createDirectories(OUTPUT_DIR); - Path output = OUTPUT_DIR.resolve("modern_professional_letter_v2_render_file.pdf"); - Files.deleteIfExists(output); - - DocumentTemplate template = ModernProfessionalLetter.create(THEME); - try (DocumentSession session = GraphCompose.document(output) - .pageSize(DocumentPageSize.A4) - .margin(48, 48, 48, 48) - .create()) { - - template.compose(session, sampleSpec()); - session.buildPdf(); - } - - assertThat(output).exists(); - assertThat(Files.size(output)).isPositive(); - } - - @Test - void specBuilderProducesImmutableSpec() { - CoverLetterSpec spec = CoverLetterSpec.builder() - .header(CoverLetterHeader.builder().name("X").build()) - .greeting("Hi") - .paragraph("Body") - .closing("Bye") - .build(); - assertThat(spec.greeting()).isEqualTo("Hi"); - assertThat(spec.bodyParagraphs()).containsExactly("Body"); - assertThat(spec.closing()).isEqualTo("Bye"); - } - - @Test - void specRequiresNonNullHeaderAndBodyList() { - org.assertj.core.api.Assertions.assertThatThrownBy( - () -> new CoverLetterSpec(null, "Hi", List.of(), "Bye")) - .isInstanceOf(NullPointerException.class); - org.assertj.core.api.Assertions.assertThatThrownBy( - () -> new CoverLetterSpec( - CoverLetterHeader.builder().name("X").build(), - "Hi", null, "Bye")) - .isInstanceOf(NullPointerException.class); - } -} diff --git a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetLayoutSnapshotTest.java b/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetLayoutSnapshotTest.java deleted file mode 100644 index 7172e49e4..000000000 --- a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetLayoutSnapshotTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.templates.TemplateTestSupport; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.theme.BusinessTheme; -import org.apache.pdfbox.pdmodel.common.PDRectangle; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.function.Function; -import java.util.stream.Stream; - -/** - * Layout snapshot regression test for every Templates v2 cover-letter - * preset. Mirrors {@code cv.presets.PresetLayoutSnapshotTest}. - * - *

A snapshot mismatch means the preset's rendered tree drifted — - * either intentionally (re-run with - * {@code -Dgraphcompose.updateSnapshots=true}) or as a regression.

- */ -class PresetLayoutSnapshotTest { - - private static final BusinessTheme THEME = BusinessTheme.modern(); - - private static CoverLetterSpec canonicalLetterSpec() { - return CoverLetterSpec.builder() - .header(CoverLetterHeader.builder() - .name("Artem Demchyshyn") - .address("London, UK") - .phone("+44 20 5555 1000") - .email("artem@demo.dev") - .link("LinkedIn", "https://linkedin.com/in/graphcompose") - .link("GitHub", "https://github.com/DemchaAV") - .build()) - .greeting("Dear Hiring Team at **Northwind Systems**,") - .paragraph("I am excited to share my interest in the Senior " - + "Platform Engineer role. My recent work has focused " - + "on building **reusable document-generation systems**.") - .paragraph("I enjoy translating fuzzy workflow requirements into " - + "clear template abstractions and reliable test coverage.") - .paragraph("I would welcome the opportunity to bring that mix " - + "of engineering rigor and product thinking to your team.") - .closing("Sincerely, *Artem Demchyshyn*") - .build(); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("presets") - void shouldMatchLayoutSnapshot(String slug, - Function> factory) throws Exception { - DocumentTemplate template = factory.apply(THEME); - try (DocumentSession document = TemplateTestSupport.openInMemoryDocument( - PDRectangle.A4, 22, 18, 22, 22)) { - template.compose(document, canonicalLetterSpec()); - TemplateTestSupport.assertCanonicalSnapshot(document, slug, "coverletter-v2"); - } - } - - private static Stream presets() { - return Stream.of( - Arguments.of("template_v2_letter_modern_professional", - (Function>) ModernProfessionalLetter::create), - Arguments.of("template_v2_letter_nordic_clean", - (Function>) NordicCleanLetter::create), - Arguments.of("template_v2_letter_classic_serif", - (Function>) ClassicSerifLetter::create), - Arguments.of("template_v2_letter_compact_mono", - (Function>) CompactMonoLetter::create), - Arguments.of("template_v2_letter_executive", - (Function>) ExecutiveLetter::create), - Arguments.of("template_v2_letter_engineering_resume", - (Function>) EngineeringResumeLetter::create), - Arguments.of("template_v2_letter_timeline_minimal", - (Function>) TimelineMinimalLetter::create), - Arguments.of("template_v2_letter_boxed_sections", - (Function>) BoxedSectionsLetter::create), - Arguments.of("template_v2_letter_centered_headline", - (Function>) CenteredHeadlineLetter::create), - Arguments.of("template_v2_letter_blue_banner", - (Function>) BlueBannerLetter::create), - Arguments.of("template_v2_letter_editorial_blue", - (Function>) EditorialBlueLetter::create), - Arguments.of("template_v2_letter_panel", - (Function>) PanelLetter::create), - Arguments.of("template_v2_letter_sidebar_portrait", - (Function>) SidebarPortraitLetter::create), - Arguments.of("template_v2_letter_monogram_sidebar", - (Function>) MonogramSidebarLetter::create)); - } -} diff --git a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java b/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java deleted file mode 100644 index 37ec19342..000000000 --- a/src/test/java/com/demcha/compose/document/templates/coverletter/presets/PresetVisualParityTest.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.demcha.compose.document.templates.coverletter.presets; - -import com.demcha.compose.GraphCompose; -import com.demcha.compose.document.api.DocumentPageSize; -import com.demcha.compose.document.api.DocumentSession; -import com.demcha.compose.document.templates.api.DocumentTemplate; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterHeader; -import com.demcha.compose.document.templates.coverletter.spec.CoverLetterSpec; -import com.demcha.compose.document.theme.BusinessTheme; -import com.demcha.compose.testing.visual.PdfVisualRegression; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.nio.file.Path; -import java.util.function.Function; -import java.util.stream.Stream; - -/** - * Pixel-diff visual parity gate for every Templates v2 cover-letter - * preset. Mirrors {@link com.demcha.compose.document.templates.cv.presets.PresetVisualParityTest} - * but for letters. - * - *

Each preset renders a fixed canonical {@link CoverLetterSpec} on - * full A4 with the gallery-standard 48pt margin, the resulting PDF is - * rasterized via PDFBox, and the per-pixel diff against a checked-in - * baseline PNG is asserted to stay within the {@code PIXEL_DIFF_BUDGET} - * mismatched-pixel budget at {@code PER_PIXEL_TOLERANCE} per-channel - * colour tolerance. Re-run with - * {@code -Dgraphcompose.visual.approve=true} to refresh the baselines - * after a deliberate visual change.

- * - *

Baselines live under - * {@code src/test/resources/visual-baselines/coverletter-v2/}.

- */ -class PresetVisualParityTest { - - private static final BusinessTheme THEME = BusinessTheme.modern(); - - private static final Path BASELINE_ROOT = Path.of( - "src", "test", "resources", "visual-baselines", "coverletter-v2"); - - // Calibrated for cross-platform PDFBox font + colour rendering - // drift between Windows-recorded baselines and Linux CI. Budget - // sized to cover the v1.6.0 CI observation (worst preset - // modern_professional / editorial_blue at ~7k mismatched - // pixels = 1.4% of 595x841) with a comfortable margin. - private static final long PIXEL_DIFF_BUDGET = 20000L; - private static final int PER_PIXEL_TOLERANCE = 8; - private static final float MARGIN = 48f; - - @ParameterizedTest(name = "{0}") - @MethodSource("presets") - void rendersWithinPixelDiffBudget(String slug, - Function> factory) throws Exception { - DocumentTemplate template = factory.apply(THEME); - byte[] pdfBytes; - try (DocumentSession document = GraphCompose.document() - .pageSize(DocumentPageSize.A4) - .margin(MARGIN, MARGIN, MARGIN, MARGIN) - .create()) { - template.compose(document, canonicalLetterSpec()); - pdfBytes = document.toPdfBytes(); - } - - PdfVisualRegression.standard() - .baselineRoot(BASELINE_ROOT) - .perPixelTolerance(PER_PIXEL_TOLERANCE) - .mismatchedPixelBudget(PIXEL_DIFF_BUDGET) - .assertMatchesBaseline(slug, pdfBytes); - } - - private static Stream presets() { - return Stream.of( - Arguments.of("modern_professional", - (Function>) ModernProfessionalLetter::create), - Arguments.of("nordic_clean", - (Function>) NordicCleanLetter::create), - Arguments.of("classic_serif", - (Function>) ClassicSerifLetter::create), - Arguments.of("compact_mono", - (Function>) CompactMonoLetter::create), - Arguments.of("executive", - (Function>) ExecutiveLetter::create), - Arguments.of("engineering_resume", - (Function>) EngineeringResumeLetter::create), - Arguments.of("timeline_minimal", - (Function>) TimelineMinimalLetter::create), - Arguments.of("boxed_sections", - (Function>) BoxedSectionsLetter::create), - Arguments.of("centered_headline", - (Function>) CenteredHeadlineLetter::create), - Arguments.of("blue_banner", - (Function>) BlueBannerLetter::create), - Arguments.of("editorial_blue", - (Function>) EditorialBlueLetter::create), - Arguments.of("panel", - (Function>) PanelLetter::create), - Arguments.of("sidebar_portrait", - (Function>) SidebarPortraitLetter::create), - Arguments.of("monogram_sidebar", - (Function>) MonogramSidebarLetter::create)); - } - - private static CoverLetterSpec canonicalLetterSpec() { - return CoverLetterSpec.builder() - .header(CoverLetterHeader.builder() - .name("Artem Demchyshyn") - .address("London, UK") - .phone("+44 20 5555 1000") - .email("artem@demo.dev") - .link("LinkedIn", "https://linkedin.com/in/graphcompose") - .link("GitHub", "https://github.com/DemchaAV") - .build()) - .greeting("Dear Hiring Team at **Northwind Systems**,") - .paragraph("I am excited to share my interest in the Senior " - + "Platform Engineer role. My recent work has focused " - + "on building **reusable document-generation systems**.") - .paragraph("I enjoy translating fuzzy workflow requirements into " - + "clear template abstractions and reliable test coverage.") - .paragraph("I would welcome the opportunity to bring that mix " - + "of engineering rigor and product thinking to your team.") - .closing("Sincerely, *Artem Demchyshyn*") - .build(); - } -} diff --git a/src/test/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpecTest.java b/src/test/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpecTest.java deleted file mode 100644 index 910f0b1f9..000000000 --- a/src/test/java/com/demcha/compose/document/templates/data/coverletter/CoverLetterDocumentSpecTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.demcha.compose.document.templates.data.coverletter; - -import com.demcha.compose.document.templates.data.common.Header; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class CoverLetterDocumentSpecTest { - - @Test - void builderShouldCreateDocumentLevelCoverLetterSpec() { - CoverLetterDocumentSpec spec = CoverLetterDocumentSpec.builder() - .header(header -> header - .name("Artem Demchyshyn") - .email("artem@demo.dev", "artem@demo.dev")) - .letter("Dear hiring team,") - .job(job -> job - .company("Northwind Systems") - .title("Platform Engineer")) - .build(); - - assertThat(spec.header().getName()).isEqualTo("Artem Demchyshyn"); - assertThat(spec.header().getEmail().getTo()).isEqualTo("artem@demo.dev"); - assertThat(spec.body()).isEqualTo("Dear hiring team,"); - assertThat(spec.jobDetails().company()).isEqualTo("Northwind Systems"); - assertThat(spec.jobDetails().title()).isEqualTo("Platform Engineer"); - } - - @Test - void ofShouldKeepExplicitInputsTogether() { - Header header = Header.builder().name("Artem").build(); - JobDetails job = JobDetails.builder().company("Compose Ltd").build(); - - CoverLetterDocumentSpec spec = CoverLetterDocumentSpec.of(header, "Body", job); - - assertThat(spec.header()).isSameAs(header); - assertThat(spec.body()).isEqualTo("Body"); - assertThat(spec.jobDetails()).isSameAs(job); - } -} diff --git a/src/test/java/com/demcha/compose/document/templates/data/coverletter/JobDetailsBuilderTest.java b/src/test/java/com/demcha/compose/document/templates/data/coverletter/JobDetailsBuilderTest.java deleted file mode 100644 index c28701a32..000000000 --- a/src/test/java/com/demcha/compose/document/templates/data/coverletter/JobDetailsBuilderTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.demcha.compose.document.templates.data.coverletter; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class JobDetailsBuilderTest { - - @Test - void builderShouldCreateImmutableJobContext() { - JobDetails details = JobDetails.builder() - .url("https://northwind.example/jobs/platform") - .title("Senior Platform Engineer") - .company("Northwind Systems") - .location("London / Remote") - .description("Lead reusable internal platform capabilities.") - .seniorityLevel("Senior") - .employmentType("Full-time") - .build(); - - assertThat(details.url()).isEqualTo("https://northwind.example/jobs/platform"); - assertThat(details.title()).isEqualTo("Senior Platform Engineer"); - assertThat(details.company()).isEqualTo("Northwind Systems"); - assertThat(details.location()).isEqualTo("London / Remote"); - assertThat(details.description()).isEqualTo("Lead reusable internal platform capabilities."); - assertThat(details.seniorityLevel()).isEqualTo("Senior"); - assertThat(details.employmentType()).isEqualTo("Full-time"); - } -} diff --git a/src/test/java/com/demcha/mock/CoverLetterMock.java b/src/test/java/com/demcha/mock/CoverLetterMock.java deleted file mode 100644 index be7a9544a..000000000 --- a/src/test/java/com/demcha/mock/CoverLetterMock.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.demcha.mock; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -public class CoverLetterMock { - - private static final Path LETTER_PATH = Path.of("src", "test", "resources", "data", "cover_letter.txt"); - public static String letter; - - static { - try { - letter = Files.readString(LETTER_PATH); - } catch (IOException e) { - throw new RuntimeException("Failed to load cover_letter.txt",e); - } - } -} diff --git a/src/test/resources/layout-snapshots/canonical-templates/cover-letter/cover_letter_standard.json b/src/test/resources/layout-snapshots/canonical-templates/cover-letter/cover_letter_standard.json deleted file mode 100644 index 590121ae0..000000000 --- a/src/test/resources/layout-snapshots/canonical-templates/cover-letter/cover_letter_standard.json +++ /dev/null @@ -1,257 +0,0 @@ -{ - "formatVersion" : "2.0", - "canvas" : { - "pageWidth" : 595.276, - "pageHeight" : 841.89, - "innerWidth" : 570.276, - "innerHeight" : 811.89, - "margin" : { - "top" : 15.0, - "right" : 10.0, - "bottom" : 15.0, - "left" : 15.0 - } - }, - "totalPages" : 1, - "nodes" : [ { - "path" : "MainVBoxContainer[0]", - "entityName" : "MainVBoxContainer", - "entityKind" : "ContainerNode", - "parentPath" : null, - "childIndex" : 0, - "depth" : 1, - "layer" : 1, - "computedX" : 15.0, - "computedY" : 272.445, - "placementX" : 15.0, - "placementY" : 272.445, - "placementWidth" : 570.276, - "placementHeight" : 554.445, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 570.276, - "contentHeight" : 554.445, - "margin" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterHeaderName[0]", - "entityName" : "CoverLetterHeaderName", - "entityKind" : "ParagraphNode", - "parentPath" : "MainVBoxContainer[0]", - "childIndex" : 0, - "depth" : 2, - "layer" : 2, - "computedX" : 15.0, - "computedY" : 800.99, - "placementX" : 15.0, - "placementY" : 800.99, - "placementWidth" : 560.276, - "placementHeight" : 25.9, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 560.276, - "contentHeight" : 25.9, - "margin" : { - "top" : 0.0, - "right" : 10.0, - "bottom" : 5.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterHeaderInfo[1]", - "entityName" : "CoverLetterHeaderInfo", - "entityKind" : "ParagraphNode", - "parentPath" : "MainVBoxContainer[0]", - "childIndex" : 1, - "depth" : 2, - "layer" : 2, - "computedX" : 15.0, - "computedY" : 787.665, - "placementX" : 15.0, - "placementY" : 787.665, - "placementWidth" : 560.276, - "placementHeight" : 8.325, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 560.276, - "contentHeight" : 8.325, - "margin" : { - "top" : 0.0, - "right" : 10.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterHeaderLinks[2]", - "entityName" : "CoverLetterHeaderLinks", - "entityKind" : "ParagraphNode", - "parentPath" : "MainVBoxContainer[0]", - "childIndex" : 2, - "depth" : 2, - "layer" : 2, - "computedX" : 15.0, - "computedY" : 778.415, - "placementX" : 15.0, - "placementY" : 778.415, - "placementWidth" : 560.276, - "placementHeight" : 9.25, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 560.276, - "contentHeight" : 9.25, - "margin" : { - "top" : 0.0, - "right" : 10.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterBodyModule[3]", - "entityName" : "CoverLetterBodyModule", - "entityKind" : "SectionNode", - "parentPath" : "MainVBoxContainer[0]", - "childIndex" : 3, - "depth" : 2, - "layer" : 2, - "computedX" : 15.0, - "computedY" : 313.165, - "placementX" : 15.0, - "placementY" : 313.165, - "placementWidth" : 569.14, - "placementHeight" : 465.25, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 569.14, - "contentHeight" : 465.25, - "margin" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterBodyModule[3]/CoverLetterBody[0]", - "entityName" : "CoverLetterBody", - "entityKind" : "ParagraphNode", - "parentPath" : "MainVBoxContainer[0]/CoverLetterBodyModule[3]", - "childIndex" : 0, - "depth" : 3, - "layer" : 3, - "computedX" : 15.0, - "computedY" : 313.165, - "placementX" : 15.0, - "placementY" : 313.165, - "placementWidth" : 569.14, - "placementHeight" : 465.25, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 569.14, - "contentHeight" : 465.25, - "margin" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 5.0, - "bottom" : 0.0, - "left" : 20.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterClosingModule[4]", - "entityName" : "CoverLetterClosingModule", - "entityKind" : "SectionNode", - "parentPath" : "MainVBoxContainer[0]", - "childIndex" : 4, - "depth" : 2, - "layer" : 2, - "computedX" : 15.0, - "computedY" : 272.445, - "placementX" : 15.0, - "placementY" : 272.445, - "placementWidth" : 570.276, - "placementHeight" : 40.72, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 570.276, - "contentHeight" : 40.72, - "margin" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - }, { - "path" : "MainVBoxContainer[0]/CoverLetterClosingModule[4]/CoverLetterClosing[0]", - "entityName" : "CoverLetterClosing", - "entityKind" : "ParagraphNode", - "parentPath" : "MainVBoxContainer[0]/CoverLetterClosingModule[4]", - "childIndex" : 0, - "depth" : 3, - "layer" : 3, - "computedX" : 15.0, - "computedY" : 272.445, - "placementX" : 15.0, - "placementY" : 272.445, - "placementWidth" : 550.276, - "placementHeight" : 20.72, - "startPage" : 0, - "endPage" : 0, - "contentWidth" : 550.276, - "contentHeight" : 20.72, - "margin" : { - "top" : 20.0, - "right" : 20.0, - "bottom" : 0.0, - "left" : 0.0 - }, - "padding" : { - "top" : 0.0, - "right" : 0.0, - "bottom" : 0.0, - "left" : 0.0 - } - } ] -}