From 9bbc068498c84d28a0631d613450771f5151832c Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 00:09:08 +0200 Subject: [PATCH] feat(blog): conformance manifest + self-asserting bind-production --- packages/blog/src/di/bind-production.ts | 14 +++++++++++ packages/blog/src/feature.manifest.ts | 33 +++++++++++++++++++++++++ packages/blog/src/index.ts | 1 + 3 files changed, 48 insertions(+) create mode 100644 packages/blog/src/feature.manifest.ts diff --git a/packages/blog/src/di/bind-production.ts b/packages/blog/src/di/bind-production.ts index 2bc52c3..dcaf9b3 100644 --- a/packages/blog/src/di/bind-production.ts +++ b/packages/blog/src/di/bind-production.ts @@ -6,8 +6,10 @@ import { type ILogger, } from "@repo/core-shared/instrumentation"; import type { BindProductionContext } from "@repo/core-shared/di"; +import { assertFeatureConformance } from "@repo/core-shared/conformance"; import { blogContainer } from "./container"; import { BLOG_SYMBOLS } from "./symbols"; +import { blogManifest } from "../feature.manifest"; import { ArticlesRepository } from "../infrastructure/repositories/articles.repository"; import { getArticlesUseCase } from "../application/use-cases/get-articles.use-case"; import { getArticleBySlugUseCase } from "../application/use-cases/get-article-by-slug.use-case"; @@ -138,4 +140,16 @@ export function bindProductionBlog(ctx: BindProductionContext): void { // // // + + // Boot-time conformance check. + assertFeatureConformance( + blogContainer, + blogManifest, + { + getArticles: BLOG_SYMBOLS.IGetArticlesUseCase, + getArticleBySlug: BLOG_SYMBOLS.IGetArticleBySlugUseCase, + createArticle: BLOG_SYMBOLS.ICreateArticleUseCase, + }, + ctx, + ); } diff --git a/packages/blog/src/feature.manifest.ts b/packages/blog/src/feature.manifest.ts new file mode 100644 index 0000000..4382a47 --- /dev/null +++ b/packages/blog/src/feature.manifest.ts @@ -0,0 +1,33 @@ +import { defineFeature } from "@repo/core-shared/conformance"; + +/** + * The blog feature's conformance manifest. + */ +export const blogManifest = defineFeature({ + name: "blog", + requiredCores: [], + useCases: { + getArticles: { + mutates: false, + audits: [], + publishes: [], + consumes: [], + }, + getArticleBySlug: { + mutates: false, + audits: [], + publishes: [], + consumes: [], + }, + createArticle: { + mutates: true, + audits: [], + publishes: [], + consumes: [], + }, + }, + realtimeChannels: [], + jobs: [], +} as const); + +export type BlogManifest = typeof blogManifest; diff --git a/packages/blog/src/index.ts b/packages/blog/src/index.ts index 26c4cb3..5ace2ab 100644 --- a/packages/blog/src/index.ts +++ b/packages/blog/src/index.ts @@ -33,3 +33,4 @@ export type { IGetArticleBySlugController } from "./interface-adapters/controlle // // +export { blogManifest, type BlogManifest } from "./feature.manifest";