Stage M5 and Stage M6

This commit is contained in:
Nông Đức Huy
2026-08-13 23:20:23 +07:00
parent 7688657d3c
commit 624a6402bf
77 changed files with 4879 additions and 176 deletions
+28 -16
View File
@@ -1,23 +1,35 @@
import { Module } from '@nestjs/common';
import { ProductsModule } from '@/modules/products/products.module';
import { PostgresSearchProvider } from './postgres-search.provider';
import { SearchIndexSubscriber } from './search-index.subscriber';
import { SearchIndexerService } from './search-indexer.service';
import { SearchController } from './search.controller';
import { SEARCH_PROVIDER } from './search.provider';
import { SearchService } from './search.service';
/**
* SearchModule — boundary declared, implementation pending.
* SearchModule — owns `search_documents`, a pure projection of the catalog.
*
* Owns (exclusively): Nothing. Read-only projection over the catalog.
* The projection can be rebuilt from scratch at any moment, which is what makes
* losing it survivable and makes this module a genuine EXTRACTION CANDIDATE:
* nothing else reads its table, and it returns ids rather than product payloads
* so it never learns what a product looks like.
*
* Starts as PostgreSQL full-text + trigram, which is genuinely enough below ~50k products. Behind a SearchProvider interface so swapping in OpenSearch is a provider change, not a rewrite of every listing page.
*
* EXTRACTION CANDIDATE: designed so it could become its own service. It must
* therefore never read another module’s tables directly, and it communicates
* outward through domain events.
*
* Anatomy once implemented (see ../README.md):
* search.module.ts wiring only
* search.controller.ts HTTP surface, no logic
* search.service.ts business rules
* search.repository.ts the only file that touches Prisma
* dto/ request/response shapes
* public/ what other modules may import
* `SEARCH_PROVIDER` is the seam from ADR-0012 — swapping PostgreSQL for
* OpenSearch replaces one binding here.
*/
@Module({})
@Module({
imports: [ProductsModule],
controllers: [SearchController],
providers: [
SearchService,
SearchIndexerService,
SearchIndexSubscriber,
PostgresSearchProvider,
{ provide: SEARCH_PROVIDER, useExisting: PostgresSearchProvider },
],
exports: [SearchService, SearchIndexerService],
})
export class SearchModule {}