From 15db9c48cb50287fd244bcd59f7a4e5f84a848d7 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 14:13:08 +0200 Subject: [PATCH] refactor(blog,marketing-pages): wire coverage helper + declare manifest bands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrates blog and marketing-pages to the same pattern auth landed in f7baa8b: vitest config consumes vitestThresholdsFromBands( DEFAULT_COVERAGE_BANDS) instead of the duplicated hand-written thresholds block, and each manifest declares its coverage section explicitly. Verified semantically identical to the previous hand-written thresholds — the same numbers come out the other end of the helper. No new regressions: - blog: 89 tests, 96.33% overall, all bands green - marketing-pages: 67 tests, 95.28% overall — controllers/ shows a real 93.54% lines / 90.9% branches gap that has been there since before this refactor (the previous hand-written threshold was the same 100%/95%). This is one of the L0 unification work items listed in the PRD's findings; capturing here as the third feature with real test gaps (navigation, media, marketing-pages). Three of five features now drive their vitest thresholds from the manifest helper: auth ✓, blog ✓, marketing-pages ✓. Navigation and media stay on the legacy config until L0 unification closes their test gaps (touching them would expose the same failures and add nothing). Co-Authored-By: Claude Opus 4.7 (1M context) --- packages/blog/src/feature.manifest.ts | 19 +++++++++++ packages/blog/vitest.config.ts | 33 +++++-------------- .../marketing-pages/src/feature.manifest.ts | 26 ++++++++++++++- packages/marketing-pages/vitest.config.ts | 33 +++++-------------- 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/packages/blog/src/feature.manifest.ts b/packages/blog/src/feature.manifest.ts index 4382a47..803d493 100644 --- a/packages/blog/src/feature.manifest.ts +++ b/packages/blog/src/feature.manifest.ts @@ -28,6 +28,25 @@ export const blogManifest = defineFeature({ }, realtimeChannels: [], jobs: [], + coverage: { + bands: { + baseline: { statements: 80, branches: 75, functions: 80, lines: 80 }, + entities: { statements: 100, branches: 100, functions: 100, lines: 100 }, + "use-cases": { + statements: 100, + branches: 95, + functions: 100, + lines: 100, + }, + controllers: { + statements: 100, + branches: 95, + functions: 100, + lines: 100, + }, + }, + mutationTargets: ["entities", "use-cases"], + }, } as const); export type BlogManifest = typeof blogManifest; diff --git a/packages/blog/vitest.config.ts b/packages/blog/vitest.config.ts index 1a4a5ac..d72e655 100644 --- a/packages/blog/vitest.config.ts +++ b/packages/blog/vitest.config.ts @@ -1,7 +1,15 @@ import path from "node:path"; import { mergeConfig } from "vitest/config"; import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node"; +import { + DEFAULT_COVERAGE_BANDS, + vitestThresholdsFromBands, +} from "@repo/core-shared/conformance/coverage"; +// Coverage thresholds derived from DEFAULT_COVERAGE_BANDS via the shared +// helper (ADR-020). The feature.manifest.ts `coverage.bands` section +// declares these for boot-time `assertFeatureConformance`. Edit the +// manifest, not this file, when adjusting per-feature bands. export default mergeConfig(nodeVitestConfig, { test: { coverage: { @@ -15,30 +23,7 @@ export default mergeConfig(nodeVitestConfig, { // React Query option builders — integration-tested in apps "src/ui/**", ], - thresholds: { - "src/entities/**": { - statements: 100, - branches: 100, - functions: 100, - lines: 100, - }, - "src/application/use-cases/**": { - statements: 100, - branches: 95, - functions: 100, - lines: 100, - }, - "src/interface-adapters/controllers/**": { - statements: 100, - branches: 95, - functions: 100, - lines: 100, - }, - statements: 80, - branches: 75, - functions: 80, - lines: 80, - }, + thresholds: vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS), }, }, resolve: { diff --git a/packages/marketing-pages/src/feature.manifest.ts b/packages/marketing-pages/src/feature.manifest.ts index 8c0c01e..47844c4 100644 --- a/packages/marketing-pages/src/feature.manifest.ts +++ b/packages/marketing-pages/src/feature.manifest.ts @@ -8,10 +8,34 @@ export const marketingPagesManifest = defineFeature({ requiredCores: [], useCases: { getPageBySlug: { mutates: false, audits: [], publishes: [], consumes: [] }, - getSiteSettings: { mutates: false, audits: [], publishes: [], consumes: [] }, + getSiteSettings: { + mutates: false, + audits: [], + publishes: [], + consumes: [], + }, }, realtimeChannels: [], jobs: [], + coverage: { + bands: { + baseline: { statements: 80, branches: 75, functions: 80, lines: 80 }, + entities: { statements: 100, branches: 100, functions: 100, lines: 100 }, + "use-cases": { + statements: 100, + branches: 95, + functions: 100, + lines: 100, + }, + controllers: { + statements: 100, + branches: 95, + functions: 100, + lines: 100, + }, + }, + mutationTargets: ["entities", "use-cases"], + }, } as const); export type MarketingPagesManifest = typeof marketingPagesManifest; diff --git a/packages/marketing-pages/vitest.config.ts b/packages/marketing-pages/vitest.config.ts index 4841c11..3fcdee9 100644 --- a/packages/marketing-pages/vitest.config.ts +++ b/packages/marketing-pages/vitest.config.ts @@ -1,7 +1,15 @@ import path from "node:path"; import { mergeConfig } from "vitest/config"; import { nodeVitestConfig } from "@repo/core-typescript/vitest.base.node"; +import { + DEFAULT_COVERAGE_BANDS, + vitestThresholdsFromBands, +} from "@repo/core-shared/conformance/coverage"; +// Coverage thresholds derived from DEFAULT_COVERAGE_BANDS via the shared +// helper (ADR-020). The feature.manifest.ts `coverage.bands` section +// declares these for boot-time `assertFeatureConformance`. Edit the +// manifest, not this file, when adjusting per-feature bands. export default mergeConfig(nodeVitestConfig, { test: { coverage: { @@ -15,30 +23,7 @@ export default mergeConfig(nodeVitestConfig, { // React Query option builders — integration-tested in apps "src/ui/**", ], - thresholds: { - "src/entities/**": { - statements: 100, - branches: 100, - functions: 100, - lines: 100, - }, - "src/application/use-cases/**": { - statements: 100, - branches: 95, - functions: 100, - lines: 100, - }, - "src/interface-adapters/controllers/**": { - statements: 100, - branches: 95, - functions: 100, - lines: 100, - }, - statements: 80, - branches: 75, - functions: 80, - lines: 80, - }, + thresholds: vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS), }, }, resolve: {