Bối cảnh nghiệp vụ
Module này cho phép người dùng tạo cộng đồng nhỏ gọi là circle, mời thành viên, xử lý yêu cầu tham gia, đăng bài trong nhóm và dùng cơ chế HP/EXP để phản ánh chất lượng đóng góp.
Ví dụ thực tế: client gọi endpoint của circle, 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-CIRCLE-001 | Chỉ member mới được đăng bài circle | Tạo post/reply | Không có CircleMember thì Forbidden | User ngoài circle bị chặn | circle.service.ts |
| BR-CIRCLE-002 | Giới hạn 5 bài/giờ/user/circle | Tạo bài circle | Redis counter quá 5 thì throw RATE_LIMIT_EXCEEDED | Spam bài bị từ chối | circle.service.ts |
| BR-CIRCLE-003 | Quản trị circle dựa trên role permission | Manage members/logs/join requests | Kiểm tra CIRCLE_ROLE_PERMISSIONS | Member thường không xem manage | circle.service.ts |
| BR-CIRCLE-004 | Admin chỉ invite role MEMBER | Admin gửi email invitation | Admin invite role khác MEMBER thì Forbidden | Owner có quyền rộng hơn admin | circle.service.ts |
| BR-CIRCLE-005 | Invitation có resend limit | Mời lại người cũ | User flow limit 5, admin email flow limit 3 | Không spam email mời | circle.service.ts |
| BR-CIRCLE-006 | Bài circle đi qua AI quality pipeline | Sau create post circle | Tạo CirclePostQualityLog pending rồi enqueue evaluation_queue | HP/EXP cập nhật sau | circle.service.ts + evaluate.worker.ts |
| BR-CIRCLE-007 | Sacrifice cần karma đủ và không restriction | POST /sacrifice | Kiểm tra karma/restriction rồi update energy | Thiếu karma bị lỗi | circle.service.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 | Có với route protected | 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 |
|---|---|---|---|
| Chỉ member mới được đăng bài circle | Tạo post/reply | Không có CircleMember thì Forbidden | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Giới hạn 5 bài/giờ/user/circle | Tạo bài circle | Redis counter quá 5 thì throw RATE_LIMIT_EXCEEDED | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Quản trị circle dựa trên role permission | Manage members/logs/join requests | Kiểm tra CIRCLE_ROLE_PERMISSIONS | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Admin chỉ invite role MEMBER | Admin gửi email invitation | Admin invite role khác MEMBER thì Forbidden | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
| Invitation có resend limit | Mời lại người cũ | User flow limit 5, admin email flow limit 3 | Ngăn dữ liệu sai đi sâu vào DB hoặc worker. |
Edge Cases — Trường hợp ngoại lệ
Tên file đang là circle-enery.service.ts, không phải energy.
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.
getCircleEnergy(), CPR và getUserQuantityPostInCircle còn mock/blank.
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.
Một số nhánh throw Error thường nên có thể thành 500.
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.
Invitation resend limit khác nhau giữa flow user và admin email.
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.
Private circle trả list rỗng nếu user không là member.
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 invitation, ACCEPTED membership, REJECTED/CANCELLED, PENDING quality, MASTERPIECE..TOXIC.
| 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 invitation | create/enqueue | ACCEPTED membership | System hoặc user theo route | Theo rule service |
| ACCEPTED membership | process/update | REJECTED/CANCELLED | System hoặc user theo route | Theo rule service |
| REJECTED/CANCELLED | process/update | PENDING quality | System hoặc user theo route | Theo rule service |
| PENDING quality | process/update | MASTERPIECE..TOXIC | 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 circle từ đâu? | Bắt đầu ở src/modules/circle/circle.routes.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. |