Skip to content

Search

@nx/search là một package dạng thư viện, không phải ứng dụng IGNIS độc lập. Nó ship bốn IGNIS component mà một host service (hiện là commerce) đăng ký, cộng với một SearchableControllerMixin mà consumer nối lên các REST controller của riêng họ. Nó giữ ~8 Typesense collection đồng bộ với PostgreSQL qua một pipeline CDC Debezium → Kafka và phục vụ tìm kiếm keyword + ngữ nghĩa tùy chọn.

1. Tham chiếu nhanh

Thuộc tínhGiá trị
Package@nx/search
CodeLIB-SEARCH
LoạiThư viện / component package (tiêu thụ bởi commerce)
RuntimeBun (>=1.3.8) — chạy bên trong process host
Base ClassN/A — không có lớp Application; export các lớp con BaseComponent
Vị trípackages/search
Base Path/search (mount dưới base path của host service)
Dev PortN/A — package thư viện, không có port riêng
Container PortN/A — chạy trong container host (commerce)
Snowflake IDN/A — host service sở hữu cấp phát ID
Search EngineTypesense ^3.0.3 (nodes dạng protocol:host:port)
Sync SourceDebezium → Kafka CDC (schema public, pricing, inventory)
Consumed bycommerce
Binding Namespace@nx/search

Bản chất thư viện: không có application.ts, index.ts → bootstrapApplication(), port riêng, hay DB schema riêng. Ứng dụng host đăng ký bốn component theo thứ tự dependency; tất cả collection, service, CDC consumer, và SearchController generic được nối vào IGNIS container của host. Xem ADR-0001.

2. Mục đích & Phạm vi

Bao gồmKhông bao gồm
Tìm kiếm full-text keyword trên 8 Typesense collectionSở hữu các bảng nguồn (commerce/pricing/inventory sở hữu chúng)
Tìm kiếm ngữ nghĩa / hybrid tùy chọn qua auto-embeddingHosting model embedding (config Typesense/Google bên ngoài)
CDC consumer: Debezium → Kafka → Typesense syncBản thân Debezium connector (do infra sở hữu)
Cascade fan-out từ bảng join/related tới doc principalWrite API để mutate document trực tiếp từ client
Dịch where/order/fields/include kiểu Ignis → TypesensePattern operator (like/ilike/regexp) — dùng text search
SearchableControllerMixin cho /search + /search/count theo từng entityTenant scope policy (host override resolveSearchScope)
Phát hiện schema drift (migration thủ công khi phân kỳ)Auto-rebuild collection đã phân kỳ (thủ công, tránh mất dữ liệu)

3. Tech Stack

Bên ngoài:

Thư việnMục đích
@venizia/ignisIoC container, BaseComponent, BaseRestController, DI
@venizia/ignis-helpersLogger, applicationEnvironment, HTTP helpers
typesenseTypesense client — collection CRUD, search, import
@platformatic/kafkaCDC Kafka consumer + DLQ producer
avscGiải mã Avro các payload CDC Debezium
@hono/zod-openapiSchema Zod request/response cho route search
zodValidate schema
lodashTiện ích

Nội bộ:

PackageMục đích
@nx/coreCdcTables, ConfigurationRepository, EnvironmentKeys, SystemConfigurations, base class, DI

4. Cấu trúc Project

packages/search/
├── src/
│   ├── index.ts                    # Barrel — re-export components, services, helpers
│   ├── component.ts                # ApplicationSearchComponent
│   ├── components/
│   │   ├── embedding-configuration.component.ts
│   │   ├── typesense-search-engine.component.ts
│   │   └── cdc.component.ts
│   ├── common/                     # keys, environments, constants, kafka-topics,
│   │                               # search.types, relations, pipeline-config types
│   ├── configurations/             # 8 collection configs + schema-fragments.ts
│   ├── controllers/                # SearchController + searchable.mixin + definitions
│   ├── datasources/                # (re-export)
│   ├── helpers/                    # typesense, converter, registry, include, migration
│   ├── mappers/                    # DB row → Typesense doc (theo từng entity + *-info)
│   ├── services/
│   │   ├── search/                 # SearchService, SearchIndexingService
│   │   ├── cdc/                    # kafka, cdc, cascade, enrichment, circuit-breaker
│   │   └── search-configuration.service.ts
│   ├── migrations/processes/       # backfill processes
│   └── utilities/                  # error-classifier, with-retry, errors
├── scripts/                        # data-feeder, migrate-add-*, check_sync_status.sh
└── package.json

Khôngapplication.ts / migrate.ts / models/ / repositories riêng — đây là thư viện, không phải service.

5. Architecture

@nx/search chạy bên trong host service (commerce). Sơ đồ thể hiện nó được nhúng.

Chi tiết: xem Architecture.

6. Snapshot Domain

Không có schema PostgreSQL riêng — "domain" là tập các Typesense collection, mỗi cái là một projection denormalized của các bảng nguồn.

Schema collection đầy đủ + cascade source: xem Domain Model.

7. Tổng quan bề mặt

REST controllers@nx/search expose hai endpoint; phần lớn consumer dùng mixin thay vì controller generic. Schema đầy đủ render trực tiếp từ /doc/openapi.json của host service (commerce), không phải từ thư viện này.

NguồnBase pathEndpoints
SearchController (generic)/search/{collectionName}2 (GET, GET …/count)
SearchableControllerMixin (theo từng entity, trên controller consumer)<entity>/search2 mỗi controller
PermissionAction
search:searchTìm kiếm document
search:search-countĐếm document khớp

Async topics (tham chiếu đầy đủ trong API Events):

HướngSố lượng
Inbound (Kafka CDC)18 topic trên 3 schema
Outbound (Kafka)1 — DLQ (nx.seller.cdc.dlq)
WebSocket out0
BullMQ jobs in/out0

8. Components

Đăng ký bởi host theo thứ tự này:

Thứ tựComponentFileMục đích
1ApplicationSearchComponentsrc/component.tsParse Typesense nodes + 8 collection config từ env, bind SEARCH_COMPONENT_OPTIONS, đăng ký ConfigurationRepository + SearchConfigurationService
2ApplicationEmbeddingConfigurationComponentsrc/components/embedding-configuration.component.tsLoad config model embedding tùy chọn + config pipeline từ DB; bind EMBEDDING_MODEL_CONFIG + SEARCH_PIPELINE_CONFIG
3TypesenseSearchEngineComponentsrc/components/typesense-search-engine.component.tsBuild TypesenseHelper, đăng ký collection vào CollectionRegistry (nối embed.from), đăng ký service + SearchController, chạy schema-drift check
4ApplicationCdcComponentsrc/components/cdc.component.tsKhởi động CDCKafkaService trên ALL_CDC_TOPICS, với DLQ + circuit breaker tùy chọn

9. Services

ServiceFileMô tả ngắn
SearchServicesrc/services/search/search.service.tsPhía query: filter Ignis → Typesense, resolve include, trả về { count, data }
SearchIndexingServicesrc/services/search/search-indexing.service.tsPhía write: upsert/delete single + batch, metric throughput, getHealth()
CDCServicesrc/services/cdc/cdc.service.tshandleBatch() — route các dòng CDC tới mapper, upsert/delete
CDCCascadeServicesrc/services/cdc/cdc-cascade.service.tsFan-out thay đổi bảng join/related để tính lại doc principal
CDCEnrichmentServicesrc/services/cdc/cdc-enrichment.service.tsHydrate doc với dữ liệu cross-collection
CDCCircuitBreakerServicesrc/services/cdc/cdc-circuit-breaker.service.tsProbe Typesense health, pause consume khi down (opt-in)
CDCKafkaServicesrc/services/cdc/cdc-kafka.service.tsKafka consumer, batching, route DLQ
SearchConfigurationServicesrc/services/search-configuration.service.tsĐọc config embedding + pipeline từ bảng Configuration

10. Repositories

RepositoryBảngNguồnMethod tùy chỉnh
ConfigurationRepositorycore.Configuration@nx/core— (đăng ký, không sở hữu; đọc config embedding/pipeline)

Search không sở hữu bảng nào; nó không có repository riêng.

11. Entry Points

FileMục đích
src/index.tsBarrel export — host import component từ đây
src/component.tsApplicationSearchComponent (entry component)
scripts/migrate-add-references.tsBackfill trường relation/reference trong Typesense (migrate:references)
scripts/migrate-add-denorm-fields.tsBackfill trường denormalized (migrate:denorm)
scripts/data-feeder/index.tsFeed dữ liệu giả qua Commerce API (feed-data)

Không có bootstrapApplication() / bootstrapMigration() — những cái đó thuộc về host service.

12. Configuration

Typesense nodes/API key, env CDC + circuit-breaker, config embedding + pipeline lưu trong DB: xem Configuration.

13. Operations

Chạy bên trong commerce — không deploy độc lập. Schema migration, CDC lag, chẩn đoán sync: xem Operations.

14. Trang liên quan

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.