Quy ước Cấu trúc Tài liệu
Nguồn chân lý duy nhất về cách cấu trúc tài liệu nhà phát triển cho mọi package backend. Skeleton mẫu nằm tại
content/{en,vi}/developer/packages/_template/(chỉ trong source — đã loại khỏi site đã publish). Mọi package — hiện tại hay tương lai — đều tuân theo đúng hình dạng này.
1. Mục tiêu
| Mục tiêu | Vì sao quan trọng |
|---|---|
| Đồng nhất | Người đọc đã biết tài liệu của một package thì biết tất cả. Không tốn chi phí tìm hiểu. |
| Súc tích | Bảng/biểu đồ thay cho văn xuôi. Dev senior định hướng được trong <2 phút. |
| Trực quan trước | Mermaid (erDiagram, stateDiagram-v2, flowchart, sequenceDiagram, C4Container) + bảng. Văn xuôi chỉ khi không có biểu đồ phù hợp. |
| Diátaxis-clean | Một góc phần tư trên một trang (reference / explanation / how-to / tutorial). Không trộn lẫn. |
| Spec-as-source | API reference render từ /doc/openapi.json, không viết tay. |
| Vận hành cùng chỗ | Operations + runbook theo từng package (you-build-it-you-run-it). |
2. Cấu trúc Thư mục
content/{en,vi}/developer/packages/<service-name>/
├── index.md # ⓜ Identity card + service catalog
├── architecture.md # ⓜ C4 + state machines + runtime scenarios
├── domain-model.md # ⓜ ERD + entity tables
├── api-events.md # ⓜ Kafka + WS topics in/out + payloads
├── integration.md # ⓜ Sister-service + external-system contracts
├── configuration.md # ⓜ Env vars + flags + seeded data
├── operations.md # ⓜ Deploy + observability + security + runbook
├── <feature>.md ... # ⊕ Optional per-feature deep dive
├── decisions/
│ ├── index.md # ⓜ ADR catalogue
│ └── NNNN-<slug>.md # ⓜ MADR — one per decision
└── changelog.md # ⊕ Optional, only if stable contractⓜ bắt buộc · ⊕ tùy chọn
Không có
api-rest.md— REST reference được render trực tiếp từ/doc/openapi.jsoncủa mỗi service (Scalar viewer tại/doc, gateway portal explorer). Bảng REST viết tay nhanh chóng lệch khỏi mã nguồn. Hãy liên kết tới live spec từindex.md.
3. Bản đồ Diátaxis Quadrant
| Trang | Quadrant | Đối tượng |
|---|---|---|
index.md | Reference (identity card) | Dev mới onboarding, integrator |
architecture.md | Explanation | Dev senior, SRE, kiến trúc sư |
domain-model.md | Reference | Người triển khai |
Live /doc/openapi.json | Reference | API consumer |
api-events.md | Reference | Subscriber/producer sự kiện |
integration.md | Explanation + reference | Dev nhóm liên quan |
<feature>.md | Reference + chút explanation | Feature owner |
configuration.md | Reference | Operator, deployer |
operations.md | How-to + reference | SRE, on-call |
decisions/NNNN.md | Explanation | Bất kỳ ai hỏi "tại sao?" |
changelog.md | Reference | API consumer, integrator |
Quy tắc: không bao giờ pha trộn quadrant. Nếu một trang reference phát sinh phần "Vì sao chúng ta làm vậy" >2 đoạn, hãy chuyển nó vào ADR và liên kết.
4. Quy tắc Tách File
| Quy tắc | Ngưỡng |
|---|---|
| Tách chủ đề thành file riêng | ≥150 dòng HOẶC ≥10 endpoint/sự kiện/bảng HOẶC ≥1 mermaid HOẶC được tham chiếu từ ≥1 trang khác |
| Nâng folder thành sub-tree | ≥3 trang anh em cùng chủ đề |
Inline trong index.md | <40 dòng VÀ <5 mục |
| Một ADR mỗi file | Luôn — không gộp các quyết định |
| REST + Async luôn tách | Đối tượng khác nhau, cách render khác nhau |
5. Mẫu Cho Từng Trang
Skeleton nằm tại
content/{en,vi}/developer/packages/_template/(chỉ trong source). Số lượng và thứ tự section là cố định.
index.md — 14 sections
Quick Reference · Purpose & Scope · Tech Stack · Project Structure · Architecture · Domain Snapshot · Surface Summary · Components · Services · Repositories · Entry Points · Configuration · Operations · Related Pages
architecture.md — 7 sections
System Context (C4 L1) · Container View (C4 L2) · Component View (C4 L3) · State Machines Index · Runtime Scenarios · Crosscutting Concerns · Related Pages
domain-model.md — 5 sections
Full ERD · Entities (mỗi bảng một block) · Cross-entity Invariants · Soft-delete Behavior · Related Pages
api-events.md — 8 sections
Inbound Kafka · Outbound Kafka · Inbound BullMQ · Outbound BullMQ · WebSocket Emissions · Payload Schemas · Idempotency & Ordering · Related Pages
integration.md — 5 sections
Sister Services · External Systems · Critical Cross-Service Flows · Contract Stability · Related Pages
configuration.md — 5 sections
Environment Variables · Feature Flags · Seeded Data · Configuration Storage · Related Pages
operations.md — 5 sections
Deployment · Observability · Security · Runbook · Related Pages
<feature>.md — 7 sections
Overview · Entity Model · Lifecycle · Operations · REST Endpoints · Events · Related Pages
decisions/index.md
Một bảng duy nhất: ID · Status · Date · Title · Supersedes.
decisions/NNNN-<slug>.md — MADR
Context · Decision · Consequences · Alternatives Considered · References.
6. Quy tắc Phong cách Viết
| Quy tắc | Cách áp dụng |
|---|---|
| Trực quan trước | Bảng/mermaid cho mọi danh sách ≥3 mục. Văn xuôi chỉ khi không có lựa chọn nào phù hợp. |
| Văn xuôi gọn | Tối đa 4 dòng mỗi đoạn. Bullet > đoạn văn khi có thể. |
| Frontmatter | Luôn có title, description, outline: deep. |
| Code block | Chỉ dùng cho: cây thư mục · ví dụ env · JSON payload · TS interface. |
| Cross-link | Liên kết nội bộ dùng đường dẫn tuyệt đối /vi/developer/.... |
| English-only trong identifier | Tiếng Việt chỉ chấp nhận trong chuỗi i18n hướng người dùng. |
| Không emoji | Trừ khi là một phần UI đang được mô tả. |
7. Quy tắc ADR (MADR)
| Quy tắc | Chi tiết |
|---|---|
| Đánh số | 4 chữ số đệm 0, tuần tự, không bao giờ tái sử dụng |
| Giá trị status | Proposed · Accepted · Deprecated · Superseded by NNNN |
| Date | Ngày ra quyết định (không phải ngày tạo file) |
| Cập nhật | Append-only — supersede bằng ADR mới; lật status của ADR cũ |
| ADR liên service | Sống trong developer/decisions/, không đặt theo từng package |
| ADR riêng service | developer/packages/<svc>/decisions/ |
8. API Reference — Tích hợp OpenAPI
| Khía cạnh | Quy ước |
|---|---|
| Nguồn chân lý | Mỗi service expose /doc/openapi.json lúc runtime |
| Render trên wiki | Không có trang api-rest.md — bảng Surface Summary trong index.md link thẳng tới live spec |
| Khám phá trực tiếp | Gateway portal tại packages/gateway/portal tiêu thụ /doc/openapi.json và render UI tương tác |
| Reference viết tay | Cấm — không bao giờ trùng lặp schema cấp trường trong markdown |
9. Tách Operations và Runbook
| Phạm vi | Sống ở |
|---|---|
| Triển khai, observability, bảo mật, lớp alert riêng từng service | <svc>/operations.md |
| Sự cố liên service, quy trình toàn hệ thống, war-room playbook | Cây trung tâm runbook/ |
<svc>/operations.md link sang runbook/ cho công việc liên service | Luôn |
10. Song song EN ↔ VI
| Quy tắc | Chi tiết |
|---|---|
| Mirror | Mỗi file EN có file VI tương ứng tại cùng đường dẫn |
| Số dòng tương đương | EN/VI chênh lệch trong ±5% |
| Thứ tự dịch | EN ship trước → VI theo sau theo lô |
| Nhãn mermaid | Dịch nhãn node; giữ tên state/event bằng tiếng Anh |
Frontmatter title & description | Dịch |
| Tên code/identifier | Không bao giờ dịch |
11. Quy ước Sidebar
Mục sidebar của mỗi package PHẢI lồng các trang con vào 3 nhóm Diátaxis + một liên kết Decisions, theo thứ tự sau:
Package Name
├─ Concepts (collapsed by default)
│ ├─ Architecture
│ ├─ Domain Model
│ └─ Integration
├─ Reference (collapsed)
│ ├─ API Events
│ ├─ Configuration
│ └─ Operations
├─ Features (collapsed)
│ ├─ <feature-1>
│ ├─ <feature-2>
│ └─ ...
└─ DecisionsQuy tắc:
- Thứ tự nhóm: Concepts → Reference → Features → Decisions (luôn luôn).
- Mặc định collapsed — giữ sidebar ban đầu gọn (3 mục hiện + Decisions).
Conceptsgồm các trang giải thích vì sao/làm thế nào hệ thống được định hình (architecture, domain, tích hợp liên service).Referencegồm các trang chỉ để tra cứu (REST endpoint, sự kiện, env var, ops/runbook).Featuresgồm các trang đi sâu theo từng feature (mỗi feature miền không tầm thường một trang).Decisionslà một liên kết phẳng tớidecisions/index.md; danh sách ADR được render bên trong trang đó.- Nếu một nhóm không có trang nào (ví dụ service nhỏ không có feature page), bỏ luôn nhóm thay vì hiển thị section rỗng.
Hình thức trong VitePress (.vitepress/locales/{en,vi}.ts):
{
text: '<Service Name>',
link: '/en/developer/packages/<svc>/',
collapsed: true,
items: [
{ text: 'Concepts', collapsed: true, items: [/* ... */] },
{ text: 'Reference', collapsed: true, items: [/* ... */] },
{ text: 'Features', collapsed: true, items: [/* ... */] },
{ text: 'Decisions', link: '/en/developer/packages/<svc>/decisions/' },
],
}12. Khởi tạo một Package mới
# 1. Copy skeleton
cp -r content/en/developer/packages/_template \
content/en/developer/packages/<svc>
cp -r content/vi/developer/packages/_template \
content/vi/developer/packages/<svc>
# 2. Replace placeholders
# <service-name>, <Service Name>, TODO:, <n>, <NNNNN>
# 3. Register in sidebar
# .vitepress/locales/en.ts and vi.ts| Bước | Người chịu trách nhiệm |
|---|---|
| Copy skeleton | Tác giả của package mới |
| Điền 8 file bắt buộc + decisions/index.md + ít nhất 1 ADR | Cùng người |
| Thêm trang theo từng feature khi feature được thêm | Feature owner |
| PR đăng ký sidebar | Tác giả |
| Duyệt code review | Người kiểm tra quy ước tài liệu (CI lint tùy chọn) |
13. Anti-patterns (không được làm)
| Anti-pattern | Vì sao không nên |
|---|---|
| Viết tay full OpenAPI reference trong markdown | Lệch khỏi code mỗi PR — link tới live /doc/openapi.json |
Thêm api-rest.md vào package | Cấm — bề mặt REST chỉ sống trong OpenAPI spec |
| Trộn reference + explanation trong cùng trang | Vi phạm Diátaxis; không quét được |
| File ADR đa quyết định | Phá URL ổn định và supersession |
| Tài liệu vận hành để trong wiki SRE riêng | Tách quyền sở hữu, mục ruỗng nhanh |
| Sơ đồ C4 cấp Code | Mã nguồn là nguồn — sơ đồ sẽ mục |
| Đoạn văn dài (>4 dòng) | Vi phạm nguyên tắc trực quan trước |
| Identifier tiếng Việt trong code mẫu | Phá quy tắc English-only |
Bỏ qua skeleton _template/ | Gây trôi cấu trúc |
| Sidebar phẳng với 10+ mục cùng cấp | Khó quét; nhóm vào Concepts/Reference/Features theo §11 |
14. Liên quan
- Skeleton
_template/—content/{en,vi}/developer/packages/_template/ - Diátaxis framework — https://diataxis.fr/
- arc42 template — https://arc42.org/overview
- C4 model — https://c4model.com/
- MADR (Markdown ADR) — https://adr.github.io/madr/