Outreach Service
@nx/outreachthu thập yêu cầu từ form liên hệ và đăng ký newsletter từ trang marketing công khai. Khi người dùng gửi, service phát một WebSocket event theo thời gian thực tới các phòng quan sát của admin. Đây là service lá, không dùng Kafka và chỉ phụ thuộc nội bộ vào@nx/core.
1. Tham chiếu nhanh
| Thuộc tính | Giá trị |
|---|---|
| Package | @nx/outreach |
| Code | SVC-00110-OUTREACH |
| Loại | Microservice |
| Runtime | Bun |
| Base Class | VerifierApplication |
| Vị trí | packages/outreach |
| Base Path | /v1/api/outreach |
| Dev Port | 31110 |
| Container Port | 3000 (external 31110) |
| Snowflake ID | 10 |
| DB Schema | outreach (2 bảng: Inquiry, Subscriber) |
| Binding Namespace | @nx/outreach |
| Owner | outreach-team |
2. Mục đích & Phạm vi
| Bao gồm | Không bao gồm |
|---|---|
| Thu thập yêu cầu liên hệ / bán hàng / demo / đối tác | Gửi email / SMTP (không có thành phần mail) |
| Đăng ký / huỷ đăng ký newsletter (idempotent) | Phát Kafka event (không có) |
| Thống kê subscriber cho admin dashboard | Tự động hoá luồng CRM (thủ công qua trường CRUD) |
| Thông báo WebSocket theo thời gian thực khi có yêu cầu mới | Phân tách theo merchant đa-tenant (bảng dùng chung toàn cục) |
3. Tech Stack
Bên ngoài:
| Thư viện | Mục đích |
|---|---|
@venizia/ignis | IoC container, DI, BaseService, ControllerFactory, VerifierApplication |
@venizia/ignis-helpers | WebSocketEmitter, HTTP, env helpers |
hono | Framework cho HTTP server (qua IGNIS) |
@hono/zod-openapi | Schema của route → spec OpenAPI |
@scalar/hono-api-reference | Trình xem tương tác /doc |
drizzle-orm | Truy cập DB qua PostgresCoreDataSource |
pg | PostgreSQL driver |
Nội bộ:
| Package | Mục đích |
|---|---|
@nx/core | Toàn bộ schema/repository (Inquiry, Subscriber), VerifierApplication, BaseSocketEventService, Redis factory, bộ nạp migration, repository cho permission/role/policy |
@nx/corelà phụ thuộc nội bộ duy nhất. Không có client tới service nào khác.
4. Cấu trúc Project
packages/outreach/
├── src/
│ ├── application.ts # Application extends VerifierApplication
│ ├── index.ts # Entry → bootstrapApplication()
│ ├── migrate.ts # Migration entry → bootstrapMigration()
│ ├── common/ # RestPaths, constants, keys
│ ├── components/
│ │ └── websocket/ # ApplicationWebSocketComponent + OutreachSocketEventService
│ ├── controllers/
│ │ ├── inquiry/ # InquiryController (+ /submit)
│ │ ├── subscriber/ # SubscriberController (+ subscribe/unsubscribe/statistics)
│ │ └── permissions.ts # OutreachPermissions (permission CRUD cho cả hai entity)
│ ├── datasources/ # PostgresCoreDataSource binding
│ ├── errors/ # SubscriberErrors, WorkerErrors
│ ├── migrations/processes/ # 0001 seed-permissions, 0002 seed-role-permissions
│ ├── repositories/ # SubscriberRepository (custom getStatistics) + re-exports
│ └── services/ # SubscriberService
├── package.json
└── tsconfig.json5. Architecture
Chi tiết: xem Architecture.
6. Tổng quan Domain
Không có khóa ngoại giữa các entity - cả hai là bảng thu thập độc lập. ERD đầy đủ + bảng theo từng entity: xem Domain Model.
7. Tổng quan giao diện
REST controllers (tham chiếu đầy đủ được render trực tiếp từ /v1/api/outreach/doc/openapi.json):
| Controller | Base path | Endpoints |
|---|---|---|
InquiryController | /inquiries | 7 (CRUD + /submit) |
SubscriberController | /subscribers | 9 (CRUD + /subscribe, /unsubscribe, /statistics) |
Async topics (tham chiếu đầy đủ trong API Events):
| Hướng | Số lượng |
|---|---|
| Inbound (Kafka) | 0 (không có) |
| Outbound (Kafka) | 0 (không có) |
| WebSocket out | 1 (INQUIRY_SUBMITTED) |
| BullMQ jobs in | 0 |
| BullMQ jobs out | 0 |
8. Components
| Component | File | Mục đích |
|---|---|---|
ApplicationWebSocketComponent | src/components/websocket/component.ts | Tạo WebSocketEmitter dựa trên Redis (single/cluster), bind nó, đăng ký OutreachSocketEventService |
9. Services
| Service | File | Mô tả ngắn |
|---|---|---|
SubscriberService | src/services/subscriber.service.ts | Đăng ký idempotent, huỷ đăng ký theo token, tổng hợp thống kê |
OutreachSocketEventService | src/components/websocket/socket-event.service.ts | Phát INQUIRY_SUBMITTED tới các phòng quan sát (được bind bởi component, không qua configureServices) |
10. Repositories
| Repository | Bảng | Nguồn | Method tuỳ chỉnh |
|---|---|---|---|
InquiryRepository | outreach.Inquiry | @nx/core (re-export) | - |
SubscriberRepository | outreach.Subscriber | kế thừa repo của core | getStatistics() - tổng hợp trong một truy vấn (total / monthlyNew / by-status) |
11. Entry Points
| File | Mục đích |
|---|---|
src/index.ts | Service entry → bootstrapApplication() |
src/migrate.ts | Migration entry → bootstrapMigration() |
src/application.ts | Lớp Application kế thừa VerifierApplication |
12. Configuration
Biến môi trường + feature flag + dữ liệu seed: xem Configuration.
13. Operations
Deployment + observability + security + runbook: xem Operations.
14. Trang liên quan
- Architecture
- Domain Model
- API Events
- Integration
- Configuration
- Operations
- Decisions
- REST endpoints - OpenAPI trực tiếp tại
/v1/api/outreach/doc/openapi.json