From 43d88be4bd9e2101bfe129cf7059f413a25bc188 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 13 May 2026 17:55:43 +0000 Subject: [PATCH] refactor(blog): migrate binders to wireUseCase for all 3 use cases Replace inline withSpan + withCapture blocks for getArticles, getArticleBySlug, and createArticle in both bind-production and bind-dev-seed with wireUseCase calls. Co-Authored-By: Claude Sonnet 4.6 --- packages/blog/src/di/bind-dev-seed.ts | 103 +++++++++++----------- packages/blog/src/di/bind-production.ts | 110 +++++++++++------------- 2 files changed, 98 insertions(+), 115 deletions(-) diff --git a/packages/blog/src/di/bind-dev-seed.ts b/packages/blog/src/di/bind-dev-seed.ts index dff69d1..ae91e01 100644 --- a/packages/blog/src/di/bind-dev-seed.ts +++ b/packages/blog/src/di/bind-dev-seed.ts @@ -6,7 +6,10 @@ import { type ILogger, } from "@repo/core-shared/instrumentation"; import type { BindContext } from "@repo/core-shared/di"; -import { assertFeatureConformance } from "@repo/core-shared/conformance"; +import { + assertFeatureConformance, + wireUseCase, +} from "@repo/core-shared/conformance"; import { blogManifest } from "../feature.manifest.js"; import { blogContainer } from "./container.js"; import { BLOG_SYMBOLS } from "./symbols.js"; @@ -58,54 +61,48 @@ export async function bindDevSeedBlog(ctx: BindContext): Promise { .bind(BLOG_SYMBOLS.IArticlesRepository) .toConstantValue(repo); - // Wrap use cases + controllers identically to bind-production - const wrappedGetArticles = withSpan( + // Use cases + const wrappedGetArticles = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.IGetArticlesUseCase, + factory: getArticlesUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "getArticles", tracer, - { name: "blog.getArticles", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.getArticles" }, - getArticlesUseCase(repo), - ), - ); - const wrappedGetArticleBySlug = withSpan( + logger, + }); + const wrappedGetArticleBySlug = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.IGetArticleBySlugUseCase, + factory: getArticleBySlugUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "getArticleBySlug", tracer, - { name: "blog.getArticleBySlug", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.getArticleBySlug" }, - getArticleBySlugUseCase(repo), - ), - ); - const wrappedCreateArticle = withSpan( + logger, + }); + const wrappedCreateArticle = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.ICreateArticleUseCase, + factory: createArticleUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "createArticle", tracer, - { name: "blog.createArticle", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.createArticle" }, - createArticleUseCase(repo), - ), - ); + logger, + }); for (const sym of [ - BLOG_SYMBOLS.IGetArticlesUseCase, - BLOG_SYMBOLS.IGetArticleBySlugUseCase, - BLOG_SYMBOLS.ICreateArticleUseCase, BLOG_SYMBOLS.IGetArticlesController, BLOG_SYMBOLS.IGetArticleBySlugController, BLOG_SYMBOLS.ICreateArticleController, ]) { if (blogContainer.isBound(sym)) blogContainer.unbind(sym); } - blogContainer - .bind(BLOG_SYMBOLS.IGetArticlesUseCase) - .toConstantValue(wrappedGetArticles); - blogContainer - .bind(BLOG_SYMBOLS.IGetArticleBySlugUseCase) - .toConstantValue(wrappedGetArticleBySlug); - blogContainer - .bind(BLOG_SYMBOLS.ICreateArticleUseCase) - .toConstantValue(wrappedCreateArticle); blogContainer .bind(BLOG_SYMBOLS.IGetArticlesController) @@ -120,23 +117,21 @@ export async function bindDevSeedBlog(ctx: BindContext): Promise { ), ), ); - blogContainer - .bind(BLOG_SYMBOLS.IGetArticleBySlugController) - .toConstantValue( - withSpan( - tracer, - { name: "blog.getArticleBySlug", op: "controller" }, - withCapture( - logger, - { - feature: "blog", - layer: "controller", - name: "blog.getArticleBySlug", - }, - getArticleBySlugController(wrappedGetArticleBySlug), - ), + blogContainer.bind(BLOG_SYMBOLS.IGetArticleBySlugController).toConstantValue( + withSpan( + tracer, + { name: "blog.getArticleBySlug", op: "controller" }, + withCapture( + logger, + { + feature: "blog", + layer: "controller", + name: "blog.getArticleBySlug", + }, + getArticleBySlugController(wrappedGetArticleBySlug), ), - ); + ), + ); blogContainer .bind(BLOG_SYMBOLS.ICreateArticleController) .toConstantValue( diff --git a/packages/blog/src/di/bind-production.ts b/packages/blog/src/di/bind-production.ts index d9b3134..76bed7c 100644 --- a/packages/blog/src/di/bind-production.ts +++ b/packages/blog/src/di/bind-production.ts @@ -6,7 +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 { + assertFeatureConformance, + wireUseCase, +} from "@repo/core-shared/conformance"; import { blogContainer } from "./container"; import { BLOG_SYMBOLS } from "./symbols"; import { blogManifest } from "../feature.manifest"; @@ -43,53 +46,40 @@ export function bindProductionBlog(ctx: BindProductionContext): void { const repo = new ArticlesRepository(config, tracer, logger); blogContainer.bind(BLOG_SYMBOLS.IArticlesRepository).toConstantValue(repo); - // Use cases — wrapped with span + capture at bind time - const wrappedGetArticles = withSpan( + // Use cases + const wrappedGetArticles = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.IGetArticlesUseCase, + factory: getArticlesUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "getArticles", tracer, - { name: "blog.getArticles", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.getArticles" }, - getArticlesUseCase(repo), - ), - ); - const wrappedGetArticleBySlug = withSpan( + logger, + }); + const wrappedGetArticleBySlug = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.IGetArticleBySlugUseCase, + factory: getArticleBySlugUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "getArticleBySlug", tracer, - { name: "blog.getArticleBySlug", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.getArticleBySlug" }, - getArticleBySlugUseCase(repo), - ), - ); - const wrappedCreateArticle = withSpan( + logger, + }); + const wrappedCreateArticle = wireUseCase({ + container: blogContainer, + symbol: BLOG_SYMBOLS.ICreateArticleUseCase, + factory: createArticleUseCase, + deps: [repo], + feature: "blog", + layer: "use-case", + name: "createArticle", tracer, - { name: "blog.createArticle", op: "use-case" }, - withCapture( - logger, - { feature: "blog", layer: "use-case", name: "blog.createArticle" }, - createArticleUseCase(repo), - ), - ); - - if (blogContainer.isBound(BLOG_SYMBOLS.IGetArticlesUseCase)) { - blogContainer.unbind(BLOG_SYMBOLS.IGetArticlesUseCase); - } - if (blogContainer.isBound(BLOG_SYMBOLS.IGetArticleBySlugUseCase)) { - blogContainer.unbind(BLOG_SYMBOLS.IGetArticleBySlugUseCase); - } - if (blogContainer.isBound(BLOG_SYMBOLS.ICreateArticleUseCase)) { - blogContainer.unbind(BLOG_SYMBOLS.ICreateArticleUseCase); - } - blogContainer - .bind(BLOG_SYMBOLS.IGetArticlesUseCase) - .toConstantValue(wrappedGetArticles); - blogContainer - .bind(BLOG_SYMBOLS.IGetArticleBySlugUseCase) - .toConstantValue(wrappedGetArticleBySlug); - blogContainer - .bind(BLOG_SYMBOLS.ICreateArticleUseCase) - .toConstantValue(wrappedCreateArticle); + logger, + }); // Controllers — wrapped with span at bind time if (blogContainer.isBound(BLOG_SYMBOLS.IGetArticlesController)) { @@ -114,23 +104,21 @@ export function bindProductionBlog(ctx: BindProductionContext): void { ), ), ); - blogContainer - .bind(BLOG_SYMBOLS.IGetArticleBySlugController) - .toConstantValue( - withSpan( - tracer, - { name: "blog.getArticleBySlug", op: "controller" }, - withCapture( - logger, - { - feature: "blog", - layer: "controller", - name: "blog.getArticleBySlug", - }, - getArticleBySlugController(wrappedGetArticleBySlug), - ), + blogContainer.bind(BLOG_SYMBOLS.IGetArticleBySlugController).toConstantValue( + withSpan( + tracer, + { name: "blog.getArticleBySlug", op: "controller" }, + withCapture( + logger, + { + feature: "blog", + layer: "controller", + name: "blog.getArticleBySlug", + }, + getArticleBySlugController(wrappedGetArticleBySlug), ), - ); + ), + ); blogContainer .bind(BLOG_SYMBOLS.ICreateArticleController) .toConstantValue(