Skip to content

Docs Structure Convention

Single source of truth for how every backend package's developer docs are structured. Mirror skeleton lives at content/{en,vi}/developer/packages/_template/ (excluded from the published site — copy from source). Every package — current or future — follows this exact shape.

1. Goals

GoalWhy it matters
UniformityA reader who knows one package's docs knows them all. No discovery cost.
CompactnessTables/diagrams over prose. A senior dev should orient in <2 min.
Visual-firstMermaid (erDiagram, stateDiagram-v2, flowchart, sequenceDiagram, C4Container) + tables. Prose only when no chart fits.
Diátaxis-cleanOne quadrant per page (reference / explanation / how-to / tutorial). No mixing.
Spec-as-sourceAPI reference renders from /doc/openapi.json, not hand-written.
Co-located opsPer-package operations + runbook (you-build-it-you-run-it).

2. Folder Layout

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

ⓜ mandatory · ⊕ optional

No api-rest.md — REST reference is rendered live from each service's /doc/openapi.json (Scalar viewer at /doc, gateway portal explorer). Hand-maintained REST tables drift quickly. Link to the live spec from index.md instead.

3. Diátaxis Quadrant Map

PageQuadrantAudience
index.mdReference (identity card)Onboarding dev, integrator
architecture.mdExplanationSenior dev, SRE, architect
domain-model.mdReferenceImplementer
Live /doc/openapi.jsonReferenceAPI consumer
api-events.mdReferenceEvent subscriber/producer
integration.mdExplanation + referenceSister-team dev
<feature>.mdReference + small explanationFeature owner
configuration.mdReferenceOperator, deployer
operations.mdHow-to + referenceSRE, on-call
decisions/NNNN.mdExplanationAnyone asking "why?"
changelog.mdReferenceAPI consumer, integrator

Rule: never bleed quadrants. If a reference page grows a "Why we did this" section >2 paragraphs, move it to an ADR and link.

4. File-Split Rules

RuleThreshold
Promote topic to its own file≥150 lines OR ≥10 endpoints/events/tables OR ≥1 mermaid diagram OR referenced from ≥1 other page
Promote folder to a sub-tree≥3 sibling pages on the same theme
Inline in index.md<40 lines AND <5 items
One ADR per fileAlways — never batch decisions
REST + Async always separateDifferent audiences, different rendering

5. Per-Page Templates

Skeleton files live at content/{en,vi}/developer/packages/_template/ (source only). Section count and order are fixed.

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 (one block per table) · 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

Single table: ID · Status · Date · Title · Supersedes.

decisions/NNNN-<slug>.md — MADR

Context · Decision · Consequences · Alternatives Considered · References.

6. Authoring Style Rules

RuleEnforcement
Visual-firstTables/mermaid for any list ≥3 items. Prose only when neither fits.
Compact proseMax 4 lines per paragraph. Bullet > paragraph when possible.
FrontmatterAlways title, description, outline: deep.
Code blocksOnly for: directory trees · env examples · JSON payloads · TS interfaces.
Cross-linkInternal links use /en/developer/... absolute path.
English-only in identifiersVietnamese OK only in user-facing localized strings.
No emojisUnless explicitly part of UI being documented.

7. ADR (MADR) Rules

RuleDetail
NumberingZero-padded 4-digit, sequential, never reused
Status valuesProposed · Accepted · Deprecated · Superseded by NNNN
DateDecision date (not file-creation date)
UpdateAppend-only — supersede via new ADR; flip old status
Cross-service ADRsLive in developer/decisions/, not per-package
Per-service ADRsdeveloper/packages/<svc>/decisions/

8. API Reference — OpenAPI Integration

AspectConvention
Source of truthEach service exposes /doc/openapi.json at runtime
Wiki renderingNo api-rest.md pageindex.md Surface Summary table links directly to the live spec
Live explorationGateway portal at packages/gateway/portal consumes /doc/openapi.json and renders interactive UI
Hand-written referenceForbidden — never duplicate field-level schema in markdown

9. Operations vs Runbook Split

ScopeLives in
Per-service deployment, observability, security, alert classes<svc>/operations.md
Cross-service incidents, system-wide procedures, war-room playbooksrunbook/ central tree
<svc>/operations.md links to runbook/ for cross-service workAlways

10. EN ↔ VI Parallel

RuleDetail
MirrorEvery EN file has a VI counterpart at the same relative path
Line parityEN/VI line counts within ±5%
Translation orderEN ships first → VI follows in batch
Mermaid labelsTranslate node labels; keep state/event identifiers in English
Frontmatter title & descriptionTranslated
Code/identifier namesNever translated

11. Sidebar Convention

Every package's sidebar entry MUST nest its sub-pages into three Diátaxis groups + a Decisions link, in this order:

Package Name
├─ Concepts          (collapsed by default)
│  ├─ Architecture
│  ├─ Domain Model
│  └─ Integration
├─ Reference         (collapsed)
│  ├─ API Events
│  ├─ Configuration
│  └─ Operations
├─ Features          (collapsed)
│  ├─ <feature-1>
│  ├─ <feature-2>
│  └─ ...
└─ Decisions

Rules:

  • Group order: Concepts → Reference → Features → Decisions (always).
  • Collapsed by default — keeps initial sidebar compact (3 visible items + Decisions).
  • Concepts includes pages that explain why/how the system is shaped (architecture, domain, cross-service integration).
  • Reference includes pages that are lookup-only (REST endpoints, events, env vars, ops/runbook).
  • Features includes per-feature deep-dive pages (one per non-trivial domain feature).
  • Decisions is a flat link to decisions/index.md; ADR list is rendered inside that page.
  • If a group has zero pages (e.g. a tiny service with no feature pages), omit the group rather than show an empty section.

VitePress shape (.vitepress/locales/{en,vi}.ts):

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. Bootstrapping a New Package

bash
# 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
StepOwner
Copy skeletonAuthor of the new package
Fill mandatory 8 + decisions/index.md + at least 1 ADRSame
Add per-feature pages as features are addedPer feature owner
Sidebar registration PRAuthor
Code review approvalDoc convention checker (CI lint optional)

13. Anti-patterns (do not do)

Anti-patternWhy bad
Hand-writing full OpenAPI reference in markdownDrifts from code on every PR — link to live /doc/openapi.json instead
Adding api-rest.md to a packageForbidden — REST surface lives in OpenAPI spec only
Mixing reference + explanation in same pageDiátaxis violation; unscannable
Multi-decision ADR filesBreaks stable URLs and supersession
Operational docs in a separate SRE wikiSplits ownership, decays fast
C4 Code-level diagramsSource code is the source — diagram rots
Long prose paragraphs (>4 lines)Visual-first principle
Vietnamese identifiers in code samplesBreaks English-only rule
Skipping the _template/ skeletonCauses structural drift

| Flat sidebar with 10+ items at one level | Hard to scan; group into Concepts/Reference/Features per §11 |

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.