Architecture
@nx/searchlà một thư viện; nó không có runtime độc lập. Mọi sơ đồ thể hiện nó được nhúng trong process host (commerce).
1. System Context (C4 L1)
2. Container View (C4 L2)
3. Component View (C4 L3) — Phân lớp nội bộ
| Layer | Trách nhiệm |
|---|---|
Mixin / SearchController | Bề mặt HTTP, cổng auth + permission, merge scope |
SearchService | Filter Ignis → tham số Typesense, resolve include, định hình response |
TypesenseConverter | where/order/fields → filter_by/sort_by/include_fields |
| CDC services | Consume, batch, route, cascade, enrich, index |
| Mappers | DB row (snake/camel) → Typesense doc; null cho soft-deleted |
CollectionRegistry | Registry singleton của 8 config (+ nối embed.from) |
| Helpers | Typesense client, so sánh schema-drift, parse include |
4. Chỉ mục State Machine
Phần tử runtime có state duy nhất là CDC circuit breaker (opt-in).
| Element | Trạng thái | Sơ đồ |
|---|---|---|
| CDC circuit breaker | CLOSED, OPEN | → jump |
CDC Circuit Breaker
| Từ | Sự kiện | Đến | Guards |
|---|---|---|---|
CLOSED | health probe fail | OPEN | APP_ENV_CDC_CIRCUIT_BREAKER_ENABLED=true |
OPEN | probe phục hồi | CLOSED | quiet window trôi qua (Typesense 30s / Google 90s) |
OPEN | — | OPEN | giới hạn ở maxOpenMs (30 phút) |
Khi
OPEN, consumer pause (auto-commit off, nên offset không tiến) — message được đọc lại sau khi phục hồi.
5. Kịch bản Runtime
5.1 Query path (consumer → Typesense)
| Bước | Chi tiết |
|---|---|
| 2 | resolveSearchScope() inject where tenant/merchant; mặc định null (mở) trừ khi host override |
| 5 | Nếu set disableSemanticSearch, trường embedding bị bỏ khỏi query_by (keyword nghiêm ngặt) |
| 7 | Quan hệ include resolve qua Typesense native join (reference) hoặc lookup hydration |
5.2 CDC sync (Debezium → Typesense)
| Bước | Chi tiết |
|---|---|
| 3 | Batch tinh chỉnh bởi CDCBatchingConfig (200 max, 2000ms flush) + maxBytes 5MB |
| 5 | Mapper trả về null cho soft-deleted → trigger Typesense delete |
| 6 | Cascade source: ProductCategory, MetaLink, FareSet/Fare, ProductBundler, hầu hết bảng inventory |
| 8 | Auto-commit off — offset tiến chỉ sau khi batch thành công (at-least-once) |
5.3 Schema-drift check khi bootstrap
Phân kỳ được log, không bao giờ auto-apply — auto-rebuild sẽ drop document. Dùng các script backfill cho thay đổi additive.
6. Mối quan tâm xuyên suốt
| Mối quan tâm | Cách thư viện này xử lý |
|---|---|
| AuthN | Kế thừa từ host — SearchController + mixin nhận JWT hoặc Basic (AuthenticateStrategy.JWT, .BASIC) |
| AuthZ | Permission search:search / search:search-count; mixin yêu cầu config authorize từ consumer |
| Multi-tenancy | resolveSearchScope() inject một scope where, and-merge với filter của caller (host override theo từng entity) |
| i18n | { en, vi } flatten thành trường Typesense name.en / name.vi; locale tương lai bắt bởi wildcard field |
| Logging | Key-value có cấu trúc (key: %s) qua IGNIS logger |
| Idempotency | Guard LSN/version (source_lsn, deleted_at) loại bỏ event CDC sai thứ tự |
| Soft-delete | Mapper trả về null cho deletedAt != null → document bị xóa khỏi Typesense |
| Resilience | Circuit breaker (opt-in) + DLQ cho message độc + utility retry |
| IDs | Document id = id dòng nguồn; thư viện không cấp Snowflake ID nào |