Signal Service
@nx/signallà edge real-time duy nhất của nền tảng: một WebSocket server mã hoá đầu-cuối (/stream) mà các service khác push tới qua Redis pub/sub, cộng một pipeline activity-notification do Kafka cấp giải người nhận, lưu hàngActivityNotification(trong@nx/core), và push chúng tới room theo từng người nhận. Nó không sở hữu schema riêng — chỉ seed migration cho permission của nó.
1. Tham chiếu nhanh
| Thuộc tính | Giá trị |
|---|---|
| Package | @nx/signal |
| Code | SVC-00090-SIGNAL |
| Type | Microservice |
| Runtime | Bun |
| Base Class | VerifierApplication |
| Location | packages/signal |
| Base Path | /v1/api/signal |
| WebSocket Path | /stream (requireEncryption: true) |
| Dev Port | 31090 |
| Container Port | 3000 (ngoài 31090) |
| Snowflake ID | 9 |
| DB Schema | không có riêng — tái dùng bảng @nx/core (ActivityNotification) |
| Binding Namespace | @nx/signal |
2. Mục đích & Phạm vi
| Bao gồm | Loại trừ |
|---|---|
WebSocket server mã hoá (/stream, ECDH P-256 + AES-256-GCM) | Lưu kết nối WebSocket (in-memory theo từng instance, mất khi restart) |
| Fan-out xuyên instance / xuyên service qua Redis pub/sub | Sản xuất sự kiện domain (signal chỉ consume + push) |
| REST quản lý client (list, get, broadcast, room/client send, disconnect) | Soạn nội dung notification cho loại sự kiện tuỳ ý (hiện chỉ PAYMENT_SUCCESS) |
| Pipeline activity-notification Kafka (resolve → persist → push) | Sở hữu schema ActivityNotification (tập trung trong @nx/core) |
| REST notification phạm vi người nhận (list, count, mark-read) | Kênh Email / SMS / push-notification |
| Xác minh JWT qua JWKS từ xa (Identity) | Phát hành token (uỷ thác cho @nx/identity) |
3. Tech Stack
External:
| Library | Mục đích |
|---|---|
@venizia/ignis | IoC container, DI, BaseComponent, WebSocketComponent, JWKSVerifierTokenService |
@venizia/ignis-helpers | ECDH, WebSocketServerHelper, WebSocketEmitter, KafkaConsumerHelper |
@platformatic/kafka | (De)serializer Kafka + types SASL cho notification consumer |
hono | Framework HTTP server (qua IGNIS) |
@hono/zod-openapi | Sinh OpenAPI từ Zod schema |
zod | Validate schema request/response |
drizzle-orm / pg | Truy cập DB qua PostgresCoreDataSource (lưu notification + authz) |
Internal:
| Package | Mục đích |
|---|---|
@nx/core | VerifierApplication, createAppConfig, bootstrapApplication, repository/model tập trung (ActivityNotification), KafkaTopics, WebSocketTopics/WebSocketRooms, RedisConnectionFactory, BaseSocketEventService |
4. Cấu trúc dự án
packages/signal/
├── src/
│ ├── application.ts # subclass VerifierApplication
│ ├── index.ts # bootstrapApplication()
│ ├── migrate.ts # bootstrapMigration()
│ ├── common/ # BindingKeys, RestPaths, WebSocketClientInfoSchema
│ ├── components/
│ │ ├── signal.component.ts # Component orchestrator cấp cao
│ │ ├── websocket.component.ts # NxWebSocketComponent (ECDH + Redis + handlers)
│ │ └── notification/ # NotificationKafkaComponent + socket-event service
│ ├── controllers/
│ │ ├── websocket-clients/ # WebSocketClientController (+ permissions)
│ │ └── activity-notifications/ # ActivityNotificationController
│ ├── datasources/ # binding PostgresCoreDataSource
│ ├── errors/ # WorkerErrors
│ ├── migrations/processes/ # 2 seed migration (permissions, role-permissions)
│ ├── models/requests/ # zod query schema
│ ├── services/ # SignalEventService, ActivityNotification(Worker)Service
│ └── utilities/ # content-decorator (markdown → content/html)
├── package.json
└── tsconfig.json5. Kiến trúc
Chi tiết: xem Architecture.
6. Ảnh chụp Domain
Signal không sở hữu bảng nào. Nó đọc/ghi bảng tập trung ActivityNotification từ @nx/core.
ERD đầy đủ + bảng entity: xem Domain Model.
7. Tổng quan bề mặt
REST controllers — tham chiếu đầy đủ render trực tiếp từ /v1/api/signal/doc/openapi.json (Scalar viewer tại /doc, portal gateway):
| Controller | Base path | Ghi chú |
|---|---|---|
WebSocketClientController | /socket/websocket/clients | status (public) + list / get / broadcast / room-send / client-send / disconnect (auth + permission WebSocketClient.*) |
ActivityNotificationController | /notifications | JWT, phạm vi người nhận: list / count / mark-read / mark-all-read |
Bề mặt async — tham chiếu đầy đủ trong API Events:
| Hướng | Kênh | Số lượng |
|---|---|---|
| Inbound | Kafka | 1 (SIGNAL_ACTIVITY_NOTIFICATION) |
| Outbound | Kafka | 0 |
| Outbound | WebSocket | 1 topic (observation/signal/notification/created) + broadcast/room/client send tuỳ biến |
8. Components
| Component | File | Mục đích |
|---|---|---|
SignalComponent | src/components/signal.component.ts | Orchestrator — đăng ký SignalEventService + ActivityNotificationService, WebSocketClientController + ActivityNotificationController, và hai sub-component bên dưới |
NxWebSocketComponent | src/components/websocket.component.ts | Redis, mã hoá ECDH, options /stream, 6 binding handler, IGNIS WebSocketComponent, WebSocketEmitter |
NotificationKafkaComponent | src/components/notification/component.ts | Bind notification service, khởi động consumer SIGNAL_ACTIVITY_NOTIFICATION (autocommit off, fallbackMode: latest, shutdown graceful) |
9. Services
| Service | File | Một dòng |
|---|---|---|
SignalEventService | services/signal-event.service.ts | Façade trên WS server/emitter (broadcast, room/client send, introspection, disconnect) |
ActivityNotificationService | services/activity-notification.service.ts | Read/update phạm vi người nhận trên ActivityNotificationRepository (list, count, mark-read, mark-all) |
ActivityNotificationWorkerService | services/activity-notification-worker.service.ts | Handler Kafka — giải người nhận, dựng nội dung, lưu hàng, push WS |
NotificationSocketEventService | components/notification/socket-event.service.ts | Subclass BaseSocketEventService; emit tới room theo từng người nhận |
10. Repositories
Tất cả re-export từ
@nx/core; signal không sở hữu schema. Đăng ký trongpreConfigure()(+ rebind bởiNotificationKafkaComponent).
| Repository | Table | Source | Method tuỳ chỉnh |
|---|---|---|---|
ActivityNotificationRepository | ActivityNotification | @nx/core | — (SoftDeletableRepository thuần) |
PolicyDefinitionRepository | PolicyDefinition | @nx/core | findUserIdsInOrganizer, findUserIdsInMerchant (giải người nhận) |
PermissionRepository | Permission | @nx/core | — (seed migration) |
RoleRepository | Role | @nx/core | — (seed migration) |
11. Entry Points
| File | Mục đích |
|---|---|
src/index.ts | Entry service → bootstrapApplication() |
src/migrate.ts | Entry migration → bootstrapMigration() (seed permissions + role-permissions) |
src/application.ts | Application extends VerifierApplication |
12. Configuration
Env vars + dữ liệu seed: xem Configuration.
13. Operations
Triển khai + observability + bảo mật + runbook: xem Operations.
14. Trang liên quan
Khái niệm — vì sao/như thế nào:
- Architecture
- Domain Model
- Integration — Redis pub/sub từ service anh em + JWKS identity
Tham chiếu — tra cứu:
- API Events
- Configuration
- Operations
- REST endpoints — OpenAPI trực tiếp tại
/v1/api/signal/doc/openapi.json
Tính năng — đào sâu:
- Encryption — ECDH P-256, HKDF, AES-256-GCM, handshake
- Components & Services — tham chiếu component cấp source
- REST API — endpoint quản lý WebSocket client
- Client Integration Guide — kết nối từ web / Tauri / cross-service
Decisions: