Stack: Docs as code · Project: TicketFlow Status: Published — opening the soft-skills module Prerequisite: Lesson 47 — Debugging in production
Objectives
- Tell documentation types apart (tutorial, how-to, reference, explanation — Diátaxis) and pick the format by reader.
- Write ADRs recording the course's decisions (you already made 10+ in the exercises): context, decision, consequences, review.
- Keep documentation alive with docs-as-code: in the repo, in the PR, with expiry and tests wherever possible.
1. The four formats and their reader
The Diátaxis matrix (the map avoiding the "doc of everything"): tutorial (teaches a beginner: the course itself, the repo's onboarding — "do this step by step, you will learn"), how-to (solves the problem of someone who already knows: "how to add an endpoint with problem+json" — recipe, not class), reference (the dry lookup: 15's API, 45's events table, 27's settings — exactness, zero narration), explanation (the why: ADRs, 47's postmortems, this lesson). The classic mistake: the README mixing all four (500 lines nobody navigates). The test: which reader's question does this doc answer? — "how do I start?" (tutorial), "how do I do X?" (how-to), "what does this field mean?" (reference), "why is it this way?" (explanation). Each question deserves ITS doc, linked.
docs/
onboarding.md # tutorial: day 1 in the repo
howtos/ # how-to: one recipe per file
nuevo-endpoint.md
rotar-secreto.md # 27's checklist
reference/ # reference: API (15), events (45), runbooks (47)
adr/ # explanation: the decisions, §2
postmortems/ # explanation: 472. The ADR: the minimum unit of technical memory
The ADR (Architecture Decision Record) records ONE costly-to-reverse decision. The course's format (the one the exercises have been asking for):
# ADR-0011 — Event broker: Redis Streams
Date: 2027-09-20 · Status: accepted · Decider: backend · Supersede: —
## Context
~150k events/day; team of 1; Redis already operated (12); 32's saga demands per-aggregate ordering.
## Decision
Outbox (25) → Redis Streams with consumer groups; Celery-Redis for tasks (commands).
## Consequences
+ Zero new infra, PEL for reclaims, basic replay.
− Short retention; massive replay demands a per-day export.
## Review
Re-evaluate if volume ×10 or the saga demands weekly retention (the written trigger: the ADR with
an implicit expiry date lives; the one without a trigger dies in the drawer).The format's 5 keys: ONE decision per ADR (the 3-decision ADR decides none well); context with NUMBERS (the justifying volume); consequences with + and − (the honesty: every decision loses something); the review trigger (the living ADR reopens when the world changed, not when someone argues for taste); and the Supersede: (ADR-0018 replacing 0011 links it: the decision history is a chain, not an edited file — ADRs are NOT corrected, they are replaced).
3. The ADRs this course already made (the index)
The course's review produces the decision index (each with its lesson):
| ADR | Decision | Lesson |
|---|---|---|
| 0001 | Public UUID + internal IDs | 13 |
| 0002 | RFC 7807 as error format | 13/26 |
| 0003 | Short JWT + rotated refresh + blacklist | 18 |
| 0004 | Argon2id + TOTP | 20 |
| 0005 | State machines in the model, flows in services | 00b/24 |
| 0006 | Outbox for reliable events | 25 |
| 0007 | Blue-green + expand-contract in releases | 11/41 |
| 0008 | Run locks with PG advisory | 31 |
| 0009 | Orchestrated saga for checkout | 32 |
| 0010 | Redis Streams as event broker | 30 |
| 0011 | Container PaaS, not K8s | 43 |
| 0012 | Infra as code with remote state | 44 |
The index (the docs/adr/README.md file) is the system's why-map: the new teammate reads 12 one-page ADRs and understands the system in an hour (vs 3 months of folklore). And the documented-decision test: when someone asks "why Redis and not Kafka?", the answer is a link, not an anecdote.
4. Docs-as-code: in the repo, in the PR, with expiry
Documentation outside the repo (wiki, Google Doc, the mind) diverges within weeks. The project's rules: (1) docs live in the repo's docs/ (markdown, reviewed in PR like code — 44 proved it with infra, here with text); (2) the per-PR doc: if the PR changes the contract (13/14), the API reference regenerates (15's drf-spectacular: the doc NOT updated by hand is the only one that survives); (3) docs with date and owner (Last reviewed: 2027-09-28, buffy) and 31's runner: the quarterly doc review (the doc unreviewed for 6 months gets flagged "possibly rotten" — explicit expiry beats silence); (4) what is testable gets tested: the doc saying "listings carry no total" is ALREADY a contract test (39) — the doc that can be code, IS code.
<!-- the doc-linked-to-code pattern -->
The availability that decides the purchase is NEVER cached (see ADR-0006 and the test
test_disponibilidad_no_cacheada_en_checkout) — if this test dies, this doc lies.5. Documentation as a craft skill
What documentation buys (measured in this course): onboarding (the ADR index: 1 h vs 3 months), the incident (47's runbook: MTTR −40%), future-you (the 4-month-old postmortem explains today's system), and decision review (the ADR's trigger avoids both fashion and fossil). The effort rule: document the decision when you MAKE it (10 min in the PR) — the post-hoc doc never gets written. And the final honesty: rotten documentation is WORSE than absent documentation (the reader trusts and errs); hence expiry (§4) and the reference generated from code (15) are the only two guarantees of truth.
Self-assessment
- Diátaxis's 4 formats: which question does each answer, and what is the everything-README's mistake?
- Which 5 keys does the course's ADR carry, and why are ADRs replaced (Supersede) rather than edited?
- The course's ADR index: what does the index buy that the loose lessons do not?
- What does docs-as-code mean in this project, and which two mechanisms keep documentation from rotting?
- Why does documenting the decision WHEN MAKING it (10 min) beat "I'll document it once it's stable"?
Continue with the exercises. The solutions only after trying it yourself.