feat(13-03): wire SourceRegistry + TenderDedupService into TendersModule
Register SourceRegistry and TenderDedupService as providers. onModuleInit registers DoeOpenDataAdapter with the registry before the scheduler's first tick — the DI-boot-time enforcement point for the INGEST-07 denylist gate (D-06). This is Wave 2's sole writer of tenders.module.ts; 13-04 (NetServer) and 13-05 (cosinex) add their own registry.register(...) calls additively in later waves. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,9 @@ import { ModuleRegistryService } from '../module-registry/module-registry.servic
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { SettingsModule } from '../settings/settings.module';
|
||||
import { DoeOpenDataAdapter } from './adapters/doe-opendata.adapter';
|
||||
import { SourceRegistry } from './source-registry';
|
||||
import { seedTendersModule } from './tenders.seed';
|
||||
import { TenderDedupService } from './tender-dedup.service';
|
||||
import { TenderDigestScheduler } from './tender-digest.scheduler';
|
||||
import { TenderIngestionService } from './tender-ingestion.service';
|
||||
import { TenderMailService } from './tender-mail.service';
|
||||
@@ -61,13 +63,27 @@ import { TendersController } from './tenders.controller';
|
||||
*
|
||||
* Seeds itself into the module registry on application startup via
|
||||
* OnModuleInit lifecycle hook — same pattern as DkvModule.
|
||||
*
|
||||
* Phase 13, Plan 03 (SCHEMA-03): adds `SourceRegistry` (fan-out lookup +
|
||||
* INGEST-07 denylist gate, Plan 13-02) and `TenderDedupService`
|
||||
* (three-tier cross-source dedup resolver, Plan 13-03 Task 1) as
|
||||
* providers. `onModuleInit` registers every known source adapter with the
|
||||
* registry via `SourceRegistry.register()` BEFORE the scheduler's first
|
||||
* tick can run — this is the DI-boot-time hook where the denylist gate
|
||||
* (D-06) structurally applies. `DoeOpenDataAdapter` is registered here;
|
||||
* this is deliberately the ONE place that grows an additional
|
||||
* `registry.register(...)` call as 13-04 (NetServer) and 13-05 (cosinex)
|
||||
* add their adapters in later waves — this plan is Wave 2's sole writer
|
||||
* of tenders.module.ts, so those additions are purely additive follow-ups.
|
||||
*/
|
||||
@Module({
|
||||
imports: [ModuleRegistryModule, SettingsModule],
|
||||
controllers: [TendersController],
|
||||
providers: [
|
||||
DoeOpenDataAdapter,
|
||||
SourceRegistry,
|
||||
TenderNormalizerService,
|
||||
TenderDedupService,
|
||||
TenderIngestionService,
|
||||
TenderSchedulerService,
|
||||
TenderTriageService,
|
||||
@@ -84,9 +100,27 @@ export class TendersModule implements OnModuleInit {
|
||||
constructor(
|
||||
private readonly moduleRegistryService: ModuleRegistryService,
|
||||
private readonly prisma: PrismaService,
|
||||
private readonly sourceRegistry: SourceRegistry,
|
||||
private readonly doeAdapter: DoeOpenDataAdapter,
|
||||
) {}
|
||||
|
||||
async onModuleInit(): Promise<void> {
|
||||
try {
|
||||
// D-06/INGEST-07: registration itself is the denylist-gate enforcement
|
||||
// point — SourceRegistry.register() throws for any adapter serving a
|
||||
// denylisted portal. DoeOpenDataAdapter is legitimate; this call is
|
||||
// additive-only for 13-04/13-05's future adapters.
|
||||
this.sourceRegistry.register(this.doeAdapter);
|
||||
this.logger.log(
|
||||
`Registered source adapters: ${this.sourceRegistry
|
||||
.activeAdapters()
|
||||
.map((a) => a.sourceType)
|
||||
.join(', ')}`,
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error('Failed to register tender source adapters', error);
|
||||
}
|
||||
|
||||
try {
|
||||
await seedTendersModule(this.moduleRegistryService);
|
||||
this.logger.log('Ausschreibungs-Radar module seeded in registry');
|
||||
|
||||
Reference in New Issue
Block a user