import { withSpan, withCapture, INSTRUMENTATION_SYMBOLS, type ITracer, type ILogger, } from "@repo/core-shared/instrumentation"; import type { BindProductionContext } from "@repo/core-shared/di"; import { assertFeatureConformance, wireUseCase, } from "@repo/core-shared/conformance"; import { marketingPagesContainer } from "./container"; import { MARKETING_PAGES_SYMBOLS } from "./symbols"; import { marketingPagesManifest } from "../feature.manifest"; import { PagesRepository } from "../infrastructure/repositories/pages.repository"; import { SiteSettingsRepository } from "../infrastructure/repositories/site-settings.repository"; import { getSiteSettingsUseCase } from "../application/use-cases/get-site-settings.use-case"; import { getPageBySlugUseCase } from "../application/use-cases/get-page-by-slug.use-case"; import { getSiteSettingsController } from "../interface-adapters/controllers/get-site-settings.controller"; import { getPageBySlugController } from "../interface-adapters/controllers/get-page-by-slug.controller"; import { userSignedUpEvent } from "@repo/auth"; import { onAuthUserSignedUpHandler } from "../events/handlers/on-auth-user-signed-up.handler"; import { sendWelcomeEmailJob } from "../jobs/send-welcome-email.job"; import { RecordingMailerService } from "../infrastructure/services/recording-mailer.service"; import type { IMailerService } from "../application/services/mailer.service.interface"; export function bindProductionMarketingPages(ctx: BindProductionContext): void { const { config, tracer, logger, bus, queue, realtime, realtimeRegistry } = ctx; // Bind shared instrumentation into feature container if (marketingPagesContainer.isBound(INSTRUMENTATION_SYMBOLS.TRACER)) { marketingPagesContainer.unbind(INSTRUMENTATION_SYMBOLS.TRACER); } if (marketingPagesContainer.isBound(INSTRUMENTATION_SYMBOLS.LOGGER)) { marketingPagesContainer.unbind(INSTRUMENTATION_SYMBOLS.LOGGER); } marketingPagesContainer .bind(INSTRUMENTATION_SYMBOLS.TRACER) .toConstantValue(tracer); marketingPagesContainer .bind(INSTRUMENTATION_SYMBOLS.LOGGER) .toConstantValue(logger); // Real repositories if ( marketingPagesContainer.isBound(MARKETING_PAGES_SYMBOLS.IPagesRepository) ) { marketingPagesContainer.unbind(MARKETING_PAGES_SYMBOLS.IPagesRepository); } const pagesRepo = new PagesRepository(config, tracer, logger); marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.IPagesRepository) .toConstantValue(pagesRepo); if ( marketingPagesContainer.isBound( MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository, ) ) { marketingPagesContainer.unbind( MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository, ); } const siteSettingsRepo = new SiteSettingsRepository(config, tracer, logger); marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.ISiteSettingsRepository) .toConstantValue(siteSettingsRepo); // Use cases const wrappedGetSiteSettings = wireUseCase({ container: marketingPagesContainer, symbol: MARKETING_PAGES_SYMBOLS.IGetSiteSettingsUseCase, factory: getSiteSettingsUseCase, deps: [siteSettingsRepo], feature: "marketing-pages", layer: "use-case", name: "getSiteSettings", tracer, logger, }); const wrappedGetPageBySlug = wireUseCase({ container: marketingPagesContainer, symbol: MARKETING_PAGES_SYMBOLS.IGetPageBySlugUseCase, factory: getPageBySlugUseCase, deps: [pagesRepo], feature: "marketing-pages", layer: "use-case", name: "getPageBySlug", tracer, logger, }); // Controllers — wrapped with span at bind time for (const sym of [ MARKETING_PAGES_SYMBOLS.IGetSiteSettingsController, MARKETING_PAGES_SYMBOLS.IGetPageBySlugController, ]) { if (marketingPagesContainer.isBound(sym)) marketingPagesContainer.unbind(sym); } marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.IGetSiteSettingsController) .toConstantValue( withSpan( tracer, { name: "marketing-pages.getSiteSettings", op: "controller" }, withCapture( logger, { feature: "marketing-pages", layer: "controller", name: "marketing-pages.getSiteSettings", }, getSiteSettingsController(wrappedGetSiteSettings), ), ), ); marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.IGetPageBySlugController) .toConstantValue( withSpan( tracer, { name: "marketing-pages.getPageBySlug", op: "controller" }, withCapture( logger, { feature: "marketing-pages", layer: "controller", name: "marketing-pages.getPageBySlug", }, getPageBySlugController(wrappedGetPageBySlug), ), ), ); // Bind the production mailer. Until a real SMTP/SES adapter ships, this is // a placeholder RecordingMailerService — production wiring is structurally // identical to dev-seed but the impl is the seam where a real mailer plugs in. if (marketingPagesContainer.isBound(MARKETING_PAGES_SYMBOLS.IMailerService)) { marketingPagesContainer.unbind(MARKETING_PAGES_SYMBOLS.IMailerService); } const mailer = new RecordingMailerService(); marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.IMailerService) .toConstantValue(mailer); // // onAuthUserSignedUpHandler subscription — generated, edit the handler file (not this block) for behavior. // bus is optional: when @repo/core-events is not scaffolded, ctx.bus is undefined and the handler is not bound. // queue (IJobQueue) is in core-shared and always provided; the inner if (queue) below is belt-and-suspenders. if (queue) { const wrappedAuthUserSignedUp = withSpan( tracer, { name: "marketing-pages.onAuthUserSignedUpHandler", op: "event-handler", }, withCapture( logger, { feature: "marketing-pages", layer: "event-handler", name: "marketing-pages.onAuthUserSignedUpHandler", }, onAuthUserSignedUpHandler(queue), ), ); if ( marketingPagesContainer.isBound( MARKETING_PAGES_SYMBOLS.IOnAuthUserSignedUpHandler, ) ) { marketingPagesContainer.unbind( MARKETING_PAGES_SYMBOLS.IOnAuthUserSignedUpHandler, ); } marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.IOnAuthUserSignedUpHandler) .toConstantValue(wrappedAuthUserSignedUp); bus?.subscribe( userSignedUpEvent, "marketing-pages", wrappedAuthUserSignedUp, ); } // const wrappedSendWelcomeEmail = withSpan( tracer, { name: "marketing-pages.sendWelcomeEmail", op: "job" }, withCapture( logger, { feature: "marketing-pages", layer: "job", name: "marketing-pages.sendWelcomeEmail", }, sendWelcomeEmailJob(mailer), ), ); if ( marketingPagesContainer.isBound( MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob, ) ) { marketingPagesContainer.unbind( MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob, ); } marketingPagesContainer .bind(MARKETING_PAGES_SYMBOLS.ISendWelcomeEmailJob) .toConstantValue(wrappedSendWelcomeEmail); void realtime; void realtimeRegistry; // // Boot-time conformance check. assertFeatureConformance( marketingPagesContainer, marketingPagesManifest, { getPageBySlug: MARKETING_PAGES_SYMBOLS.IGetPageBySlugUseCase, getSiteSettings: MARKETING_PAGES_SYMBOLS.IGetSiteSettingsUseCase, }, ctx, ); }