Bối cảnh nghiệp vụ
Module jobs gom toàn bộ pipeline bất đồng bộ: email, Bloom filter, vector search, full-text search, like sync, notification debounce, AI evaluation, giảm HP circle và tự gỡ ban.
Ví dụ thực tế: client gọi endpoint của jobs, server kiểm tra token nếu route yêu cầu, validate dữ liệu, gọi service đúng domain, rồi ghi DB/cache hoặc enqueue job theo đúng nhánh trong code.
Luồng chính — Happy Path
Request vào route. Bước này chuyển dữ liệu sang lớp tiếp theo theo pattern hiện có.
Middleware auth/validate chạy. Bước này chuyển dữ liệu sang lớp tiếp theo theo pattern hiện có.
Controller gọi service. Bước này chuyển dữ liệu sang lớp tiếp theo theo pattern hiện có.
Service áp dụng rule nghiệp vụ. Đây là bước quan trọng nhất vì service quyết định request có được ghi dữ liệu, enqueue job hoặc bị trả lỗi.
Repository/worker/provider thực thi. Bước này chuyển dữ liệu sang lớp tiếp theo theo pattern hiện có.
Response trả về client. Bước này chuyển dữ liệu sang lớp tiếp theo theo pattern hiện có.
Business Rules — Quy tắc nghiệp vụ
| Rule ID | Tên rule | Điều kiện kích hoạt | Hành động | Ví dụ minh họa | File kiểm tra |
|---|---|---|---|---|---|
| BR-JOBS-001 | Request đi qua route/controller/service | Client gọi endpoint | Controller đọc request rồi service xử lý nghiệp vụ chính | Trace rõ từ route đến service | workers/index.ts |
| BR-JOBS-002 | Auth theo route thật | Endpoint có authorization | JWT được kiểm tra trước controller | Thiếu token bị chặn | workers/index.ts |
| BR-JOBS-003 | Validate bằng Zod nếu route có validate() | Request body/params/query | Sai schema trả 400 | Client sửa field sai | workers/index.ts |
| BR-JOBS-004 | Repository là nơi chạm DB | Service cần dữ liệu | Service gọi repository/Prisma, controller không tự query | Dễ trace lỗi DB | workers/like.worker.ts |
[CẦN XÁC NHẬN], phần code hiện tại là stub, TODO hoặc trả dữ liệu mock.Validations — Kiểm tra dữ liệu đầu vào
Input Validation
| Field | Kiểu | Required | Rule | Lỗi nếu vi phạm | Ví dụ hợp lệ | Ví dụ không hợp lệ |
|---|---|---|---|---|---|---|
| Authorization | header | Tùy route | Bearer access token nếu cần | 401 | Bearer eyJ... | missing |
| params | string | Tùy endpoint | Không rỗng theo DTO route | 400 | publicId/code | |
| query.take | number | Không | int dương, thường max 100 nếu DTO có | 400 | 20 | 1000 |
| body | object | Tùy endpoint | Theo DTO tương ứng | 400 | {"content":"Hello"} | {} thiếu field |
Business Validation
| Điều kiện kiểm tra | Khi nào chạy | Lỗi trả về | Lý do rule này tồn tại |
|---|---|---|---|
| Request đi qua route/controller/service | Client gọi endpoint | Controller đọc request rồi service xử lý nghiệp vụ chính | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Auth theo route thật | Endpoint có authorization | JWT được kiểm tra trước controller | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Validate bằng Zod nếu route có validate() | Request body/params/query | Sai schema trả 400 | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Repository là nơi chạm DB | Service cần dữ liệu | Service gọi repository/Prisma, controller không tự query | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
Edge Cases — Trường hợp ngoại lệ
Email worker dùng template invitation-email.ejs nhưng repo có invitation-memeber.ejs; cần xác nhận.
Nếu không hiểu điểm này, QA có thể viết thiếu case hoặc frontend có thể hiển thị trạng thái sai.
Queue retry policy chưa cấu hình rõ ở nhiều producer.
Nếu không hiểu điểm này, QA có thể viết thiếu case hoặc frontend có thể hiển thị trạng thái sai.
Redis là cache, queue transport, Bloom và debounce store.
Nếu không hiểu điểm này, QA có thể viết thiếu case hoặc frontend có thể hiển thị trạng thái sai.
Error Handling — Xử lý lỗi
| Tình huống lỗi | Nguyên nhân | HTTP Status | Error Code | Message trả về | Cách recover |
|---|---|---|---|---|---|
| Unauthorized | Thiếu/sai token ở route protected | 401 | UNAUTHORIZED | Token invalid | Login lại hoặc refresh token. |
| Validation failed | Zod schema không pass | 400 | VALIDATION_FAILED | Validation failed | Client sửa field sai. |
| Resource not found | Repository không tìm thấy record | 404 | NOT_FOUND | Resource not found | Refresh dữ liệu. |
| Forbidden | User không có quyền hoặc role không đúng | 403 | FORBIDDEN | Forbidden | Ẩn action trong UI. |
| External dependency fail | Redis/DB/provider lỗi | 500 | INTERNAL_SERVER_ERROR | Internal server error | On-call kiểm tra provider/log. |
State Machine / Vòng đời
Một entity/job trong module này có thể đi qua các trạng thái sau: PENDING, PROCESSING, SUCCESS, FAILED.
| Từ trạng thái | Hành động/Event | Đến trạng thái | Ai được phép | Điều kiện thêm |
|---|---|---|---|---|
| PENDING | create/enqueue | PROCESSING | System hoặc user theo route | Theo rule service |
| PROCESSING | process/update | SUCCESS | System hoặc user theo route | Theo rule service |
| SUCCESS | process/update | FAILED | System hoặc user theo route | Theo rule service |
| FAILED | process/update | terminal | System hoặc user theo route | Theo rule service |
Side Effects — Tác dụng phụ
| Hành động | Khi nào xảy ra | Đồng bộ hay bất đồng bộ | Nếu thất bại thì sao? |
|---|---|---|---|
| DB read/write | Khi service cần dữ liệu bền vững | Đồng bộ | Request fail nếu DB fail. |
| Cache/queue/realtime | Nếu module gọi Redis/Pusher/jobs | Tùy flow | Có thể delay hoặc fail riêng. |
| External API | Nếu module gọi service ngoài | Bất đồng bộ hoặc đồng bộ | Phụ thuộc cấu hình provider. |
FAQ — Câu hỏi thường gặp
| Câu hỏi | Trả lời |
|---|---|
| Tôi bắt đầu đọc module jobs từ đâu? | Bắt đầu ở workers/index.ts, sau đó đi sang controller và service. |
| Lỗi validation nằm ở đâu? | Ở DTO Zod và middleware validate(). Route nào không gọi validate() thì không có lớp check này. |
| Side effect có chạy trong cùng request không? | Tùy flow. Nếu có producer/worker thì side effect chạy bất đồng bộ sau response. |
| Có chỗ nào chưa hoàn chỉnh không? | Xem phần Gotchas và các dòng [CẦN XÁC NHẬN]. |
| QA nên test gì trước? | Happy path, thiếu token, sai DTO, resource không tồn tại, và side effect fail/defer. |