Backend API Spec (Living)
Operating Links (Implementation-Ready)
- Project OS: 05_PROJECT_OPERATING_SYSTEM.md
- Engineering Rules: 06_ENGINEERING_RULES.md
- Execution Playbook: 07_EXECUTION_PLAYBOOK.md
- Task Packet Template: TASK_PACKET_TEMPLATE.md
References
- Quyết định kiến trúc: 01_DECISION_LOG.md
- Nguồn Endpoint: backend_api_manifest.md
- Nguồn Entity: backend_entity_manifest.md
- Dòng chảy dữ liệu: API_TRACEABILITY.md
Delivery Rule for Any API Change
Mỗi thay đổi API bắt buộc đi qua 5 bước:
- Tạo task packet có
Feature Key. - Đối chiếu DEC liên quan + manifest hiện trạng.
- Implement + test ở module tương ứng.
- Cập nhật traceability.
- Regenerate
_generated/backend_api_manifest.md.
Reality Check Queue (from generated manifest)
- Manifest hiện tại đang đánh dấu nhiều endpoint tenant-scope có nguy cơ thiếu bảo vệ quyền.
- Queue kiểm tra được theo dõi tại
03_TRACEABILITY/WORKITEM_BOARD.md(WI-SEC-001). - Trong mọi task chạm controller, phải re-check
@UseGuards(PermissionsGuard)+@Permissions(...)theo DEC-003.
1. Invariants (Luật bất biến)
- Datetime/Timezone Standard: Mọi định dạng thời gian tuân thủ nghiêm ngặt DEC-004 (Timezone) (Sử dụng ISO 8601 UTC string).
- Dữ liệu luôn tenant-scoped trừ các entity global (MDM).
1.A Auth & Tenant Context (SoT)
- API Endpoints Invariants:
POST /login(Portal): Nhận xác thực Zalo/Password, trả về JWT không chứatenantId.POST /switch-tenant: NhậntenantIdyêu cầu, cấp phát/đổi phiên và trả về JWT mới ngậmtenantId.GET /me: Trả về global profile của User (có thể gọi lúc chưa có tenant).- Mọi API nghiệp vụ khác (vd:
/api/v2/catalog,/api/v2/ecommerce) → Reject cứng nếu request JWT vào thiếu mảngtenantId.
- Guard Stack Order & Semantics (Reality Sync): Trình tự global block là:
JwtAuthGuard➡TenantGuard.PermissionsGuardchỉ chạy khi được gắn explicitly.@Public(): Bỏ quaJwtAuthGuard(cho phép anonymous), nhưng không bỏ quaTenantGuard. API@Public()vẫn sẽ đòitenantIdtrừ khi có@SkipTenantCheck().@SkipTenantCheck(): Bỏ quaTenantGuard(dùng cho System Admin cross-tenant hoặc Auth flow). Vẫn yêu cầu JWT hợp lệ trừ khi có@Public().- SECURITY RULE (P0): Mọi API tenant-scoped (không có
@SkipTenantCheck()) bắt buộc phải gắn@UseGuards(PermissionsGuard)và@Permissions(...). Nếu không, bất kể role nào có tenant token đều có thể gọi được quyền cao nhất.
1.B Domain Specific Invariants
- Order State Machine (Ecommerce/Procurement): Tuân thủ quy tắc chuyển trạng thái nghiêm ngặt tại DEC-007.
- Cấm
CANCELLEDkhi đơn đã ở trạng tháiSHIPPING. - Cấm
COMPLETEDnếupaymentStatus !== 'PAID'.
- Cấm
- Tenant Settings Ownership: Cấu hình tenant được quản lý tập trung và tách biệt tại DEC-008.
- Khuyến khích sử dụng
TenantService.getSettings()để đảm bảo layer fallback hoạt động đúng.
- Khuyến khích sử dụng
2. Global Standards (DoD Enforcement)
- API Prefix: Mọi API nội bộ dùng route
api/v2(Ví dụ:/api/v2/catalog/products). - Error Format: Chuẩn hoá HttpExceptions của NestJS (tự động mapping bởi
GlobalExceptionFilter). - Pagination: Mọi endpoint danh sách (
GET /) hỗ trợpage,limit,sort,filter. - Validation: Strict validation dùng
class-validator(DTOs), reject payload thừa (whitelist: true). DTOs tuyệt đối KHÔNG chứa các Audit fields (createdById,createdAt...) để tránh client mutate. - Audit Logging: Các action tạo/sửa/xoá được bắt lại bởi
AuditLogInterceptorvà lưu vào schemaAuditLogvớicreatedById. - Audit Stamping (GOV-AUDIT):
- Mọi entity bắt buộc có
createdAt,updatedAt,createdById,updatedById. - Nếu soft-delete: thêm
isDeleted,deletedAt,deletedById. - Việc gán
createdById/updatedByIdthực hiện ở Service Layer dựa trênRequestContext.userId(tác nhân gọi), KHÔNG gán/nhận ở Controller/DTO.
- Mọi entity bắt buộc có
- IDs: UUID v4 hoặc ObjectId tuỳ module (đa số chuẩn hoá Mongoose ObjectId cho V2).
- Population & Relationship (D-008):
- Khóa ngoại DB luôn lưu hậu tố:
<name>Id(ví dụcreatedById) hoặc<name>Ids. TUYỆT ĐỐI không dùngcreatedBy: ObjectId. - Include Policy: API không tự động load relations. Client muốn lấy thêm dữ liệu phụ phải truyền
?include=<relation_name>. - Depth Limit: Max Depth = 1. KHÔNG được nối chain sâu (ví dụ chặn
include=category.parent). - Projection: Relation trả về dạng Summary (VD:
{_id, name}). Không trả full object làm phình to payload.
- Khóa ngoại DB luôn lưu hậu tố:
3. Module Registry (Control Plane)
Quy tắc: Mọi module phải khai báo rõ nguồn Canonical (từ
docs_delivery_v2), Code Truth, và Gaps trước khi code. KHÔNG copy/paste requirement vào đây. Tại đây chỉ giữ "Card chỉ đường".
MODULE: IAM (Identity & Access)
Canonical (CKB - docs_delivery_v2):
- Overview:
baseline/imported_sources/docs_delivery_v2/03_MODULES/IAM/00_OVERVIEW.md - Requirements:
baseline/imported_sources/docs_delivery_v2/03_MODULES/IAM/10_REQUIREMENTS.md - Data Model:
baseline/imported_sources/docs_delivery_v2/03_MODULES/IAM/20_DATA_MODEL.md - API Contract:
baseline/imported_sources/docs_delivery_v2/03_MODULES/IAM/30_API_CONTRACT.md - RBAC:
baseline/imported_sources/docs_delivery_v2/03_MODULES/IAM/50_RBAC.md
Code Truth (_generated + code_v2):
- Endpoints:
_generated/backend_api_manifest.md(search:/iam/auth) - Entities:
_generated/backend_entity_manifest.md(search:User,Identity) - Permissions:
_generated/permission_manifest.md
Delta / Gaps:
- Missing: None (Synced)
- Mismatch: None (Synced)
MODULE: TENANT (Multi-Tenancy)
Canonical (CKB): 03_MODULES/TENANT/*Code Truth: _generated/backend_api_manifest.md (search: /iam/tenants), Entities: Tenant, Membership, TenantSettings (DEC-008) Delta / Gaps: None (Synced)
MODULE: ADMIN (System Admin)
Canonical (CKB): 03_MODULES/ADMIN/*Code Truth: _generated/backend_api_manifest.md (search: /admin) Delta / Gaps: None (Synced)
MODULE: PLUGIN
Canonical (CKB): 03_MODULES/PLUGIN/*Code Truth: _generated/backend_api_manifest.md (search: /plugins) Delta / Gaps: None (Synced)
MODULE: CATALOG
Canonical (CKB): 03_MODULES/CATALOG/*Code Truth: _generated/backend_api_manifest.md (search: /catalog), Entities: Product, CategoryDelta / Gaps: None (Synced)
MODULE: ORDER (Cart & Checkout)
Canonical (CKB): 03_MODULES/ORDER/*Code Truth: _generated/backend_api_manifest.md (search: /ecommerce/orders), Invariants: DEC-007 (State Machine)Delta / Gaps: None (Synced)
MODULE: INVENTORY
Canonical (CKB): 03_MODULES/INVENTORY/*Code Truth: _generated/backend_api_manifest.md (search: /supply-chain/inventory) Delta / Gaps: None (Synced)
MODULE: PROCUREMENT
Canonical (CKB): 03_MODULES/PROCUREMENT/*Code Truth: _generated/backend_api_manifest.md (search: /procurement) Delta / Gaps: None (Synced)
MODULE: CRM (Unified CRM)
Canonical (CKB): 03_MODULES/CRM/*Code Truth: _generated/backend_api_manifest.md (search: /crm) Delta / Gaps: None (Synced)
MODULE: PARTNER (Vendors & Customers)
Canonical (CKB): 03_MODULES/PARTNER/*Code Truth: _generated/backend_api_manifest.md (search: /crm/partners) Delta / Gaps: None (Synced)
MODULE: INBOX
Canonical (CKB): 03_MODULES/INBOX/*Code Truth: _generated/backend_api_manifest.md (search: /inbox) Delta / Gaps: None (Synced)
MODULE: AFFILIATE (Loyalty)
Canonical (CKB): 03_MODULES/AFFILIATE/*Code Truth: _generated/backend_api_manifest.md (search: /affiliate) Delta / Gaps: None (Synced)
MODULE: CMS (Content & Blog)
Canonical (CKB): 03_MODULES/CMS/*Code Truth: _generated/backend_api_manifest.md (search: /content/cms) Delta / Gaps: None (Synced)
MODULE: ESN (Internal Comms)
Canonical (CKB): 03_MODULES/ESN/*Code Truth: _generated/backend_api_manifest.md (search: /content/comms) Delta / Gaps: None (Synced)
MODULE: VOUCHER (Marketing)
Canonical (CKB): 03_MODULES/VOUCHER/*Code Truth: _generated/backend_api_manifest.md (search: /marketing/vouchers) Delta / Gaps: None (Synced)
MODULE: AI (Studio & KB)
Canonical (CKB): 03_MODULES/AI/*Code Truth: _generated/backend_api_manifest.md (search: /ai) Delta / Gaps: None (Synced)
MODULE: ZALO (Integration & Messaging)
Canonical (CKB): 03_MODULES/ZALO/*Code Truth: _generated/backend_api_manifest.md (search: /zalo) Delta / Gaps: None (Synced)
MODULE: SHIPPING
Canonical (CKB): 03_MODULES/SHIPPING/*Code Truth: _generated/backend_api_manifest.md (search: /shipping) Delta / Gaps: None (Synced)
MODULE: BILLING
Canonical (CKB): 03_MODULES/BILLING/*Code Truth: _generated/backend_api_manifest.md (search: /billing) Delta / Gaps: None (Synced)
MODULE: MDM (Master Data)
Canonical (CKB): 03_MODULES/MDM/*Code Truth: _generated/backend_api_manifest.md (search: /mdm) Delta / Gaps: None (Synced)
MODULE: NOTIFY (Notification Hub)
Canonical (CKB): 03_MODULES/NOTIFY/*Code Truth: _generated/backend_api_manifest.md (search: /notify) Delta / Gaps: None (Synced)
MODULE: AUDIT (Audit Logs)
Canonical (CKB): 03_MODULES/IAM/* (Shared with IAM) Code Truth: _generated/backend_api_manifest.md (search: /audit) Delta / Gaps: None (Synced)
MODULE: CART (Shopping Cart)
Canonical (CKB): 03_MODULES/ORDER/* (Shared with ORDER) Code Truth: _generated/backend_api_manifest.md (search: /cart) Delta / Gaps: None (Synced)
MODULE: VENDOR (Supplier Mgmt)
Canonical (CKB): 03_MODULES/CRM/* (Shared with CRM/PARTNER) Code Truth: _generated/backend_api_manifest.md (search: /crm/vendors) Delta / Gaps: TBD