import { Global, Module } from "@nestjs/common"; import { PrismaService } from "./prisma.service.js"; import { RedisService } from "./redis.service.js"; import { EventBus } from "./event-bus.js"; import { AuditService } from "./audit.service.js"; import { EmailService } from "./email.service.js"; import { CacheService } from "./cache.js"; import { PermissionCacheBridge } from "./permission-cache-bridge.js"; /** * Global core services (TASK-0100 S0 — repo-wide DI fix). * * **Why this module exists.** Nest resolves plain `private readonly` ctor * injection against the *module's own scope*: a provider is injectable only if * it is declared (or imported/exported) in the same module, or provided by a * `@Global()` module. The five shared services used to be declared in the * root `AppModule` — which NO feature module imports — so: * * - under the **tsc-compiled** runtime (metadata emitted), boot threw * `Nest can't resolve dependencies of ...` for every feature service; * - under **tsx / vitest** (esbuild: `design:paramtypes` is NEVER emitted — * esbuild has no decorator-metadata support), boot "succeeded" and every * plain-injected dependency resolved to `undefined`, surfacing as 500s at * request time (e.g. login: `this.auth` undefined). * * **Fix (two halves, both required):** * 1. this `@Global()` module — makes the five services visible to every * feature module without per-module imports (verified empirically: the * plain-injection shape fails to boot without a global module, boots with * one, under both tsc and tsx); * 2. explicit `@Inject(Token)` on every DI ctor param across the app — * explicit tokens resolve under every transform (tsx, vitest, tsc) * regardless of emitted metadata, so the app boots identically in dev, * test and build runtimes. */ @Global() @Module({ providers: [PrismaService, RedisService, EventBus, AuditService, EmailService, CacheService, PermissionCacheBridge], exports: [PrismaService, RedisService, EventBus, AuditService, EmailService, CacheService] }) export class CoreModule {}