0 / 91
Week 13 · Day 90 of 91

Documentation and developer handoff

Capstone Completion and Professional Handoff

Objective

Make the project understandable and runnable by someone else.

The final phase is commissioning and handoff: validate under expected conditions, document limitations, and leave the next engineer a maintainable system.

  • README
  • architecture decision notes
  • API and schema documentation
  • known limitations

Why this matters

Everything you have built so far runs on knowledge that lives in your head. Today you move it into the repository, because a project only one person can run is a project with a single point of failure — and in three months that person will not remember either.

The bar for today is exact and testable: a developer who has never seen this project can clone it and get it running using only the repository documentation. Not with a phone call to you.

Write for the reader who was not there

Picture them precisely: a competent developer, a fresh machine, no context, no access to you. They know how to program. They do not know that your migrations must run before the seed script, or that port 5432 conflicts with the Postgres they already have.

That picture rules out the two failure modes of beginner documentation. The first is writing for yourself — "set up the database as usual" — where every step you found obvious is missing. The second is writing a tutorial that explains what Express is. Your reader knows Express. What they do not know is this project.

The handover pack, not the datasheet

When a board leaves your bench you do not hand over the op-amp datasheet — they can find that. You hand over the schematic, the bring-up procedure, the test points with expected values, and the known issues list ("R14 runs hot above 40 °C; do not populate C9 on rev B"). Documentation is the handover pack: project-specific facts nobody can look up.

The README: clone to running

The README's one job is getting someone from nothing to a running app. Structure it in this order — it is the order they need it in.

  1. What this is. Two sentences: the problem and who it is for. Not marketing.
  2. Prerequisites, with versions. "Node 20 or later, Docker Desktop, PostgreSQL 16 (or use the Compose file)." Say how to check: node --version.
  3. Setup, as copy-pasteable commands. Every command in a code block, in order, no prose steps hiding an action.
  4. Environment variables, as a table. Name, what it is for, required or optional, example value. Never the real value.
  5. How to run it, and what they should see when it works — a URL and a confirmation line.
  6. How to run the tests and the checks.
  7. Troubleshooting: the three things that actually go wrong.
## Setup

    git clone <repo-url>
    cd capstone
    cp .env.example .env      # fill in the values described below
    docker compose up -d db   # starts PostgreSQL on port 5432
    npm install
    npm run migrate
    npm run seed              # optional demo data
    npm run dev               # http://localhost:5173

| Variable | Purpose | Required |
|---|---|---|
| `DATABASE_URL` | PostgreSQL connection string | yes |
| `SESSION_SECRET` | Signs session cookies; any long random string | yes |
| `AI_API_KEY` | Enables the summary feature; app runs without it | no |

That last row does real work: it tells the reader the AI feature is optional, which is exactly the degradation you built on Day 87.

Documentation is a common way secrets escape

Never paste a real key, password, or connection string into a README, an example, or a troubleshooting note — documentation gets copied, screenshotted, and published far more freely than code. Ship .env.example with empty values and confirm .env is ignored: git check-ignore .env prints .env when it is.

Architecture notes: write down why

Your code shows what it does. Git shows when it changed. Neither records why you chose this over the alternative — and that is the thing a future maintainer most needs, because without it they will either preserve a decision that no longer applies or undo one that still matters.

A decision note is short. Four headings:

## Sessions in a signed cookie, not JWTs in localStorage

**Context.** Single server, one user type, needs logout to take effect immediately.

**Decision.** Server-side sessions, id in an httpOnly cookie.

**Alternatives.** JWT in localStorage — no server state, but readable by any XSS and
cannot be revoked before expiry.

**Consequences.** Sessions are in memory, so a restart logs everyone out. Moving to more
than one instance requires a shared session store first.

The consequences section is what makes this useful. It names a real constraint the next person will hit — and it is honest, which is the tone the whole document needs.

The note taped inside the panel

Every good machine has a note inside the cover: "valve replaced with a metric part 2019 — do not order the imperial one from the manual." It exists because someone made a decision the manual contradicts. Decision notes are that tape, kept where the next person will look.

API and schema documentation

Two tables and one worked example carry most of the value.

Endpoints: method, path, what it does, who may call it. Then one complete example — a real request body and the real response, copied from a run, not written from memory.

Schema: each table with one line on what it holds, then the relationships in plain sentences — "each maintenance_record belongs to one equipment row via equipment_id; deleting equipment is blocked while records exist." State where the migrations live and how to apply them, so the reader knows the schema file is generated by history, not edited by hand.

Known limitations

This is the section beginners leave out and professionals read first. Known limitations are concrete unsupported cases and operational risks — not future marketing ideas, and never credentials.

Concrete means specific enough to act on:

  • "The records list loads all rows; above roughly 2000 records the page becomes slow. Pagination is designed but not built."
  • "The AI summary feature calls a paid provider. Each call costs money; there is a per-user daily cap of 20 and no organisation-wide cap."
  • "Sessions are in process memory. A deploy signs everyone out, and running two instances will break login."
  • "Backups are manual (docs/release-checklist.md, step 3). No automated schedule exists."
  • "Timestamps are stored in UTC and displayed in the browser's timezone. There is no per-user timezone setting."

Vague means useless: "some performance issues", "security could be improved". Writing your real limits down is not admitting weakness — it is the difference between a maintainer who is prepared and one who is ambushed.

Walkthrough

The only honest test of a README is following it literally, so simulate a stranger:

cd /tmp
git clone ~/fullstack-journey/capstone handoff-test
cd handoff-test

Now open only README.md and do exactly what it says — no memory, no improvising. Every time you have to think, stop and write down what was missing. Typical findings: .env.example does not exist, the migrate command is named differently in package.json, the seed step must come after migrate and does not say so, a port is already in use with no note about it.

Fix the README, then delete the clone and repeat until the run is clean.

`rm -rf` deletes immediately and permanently

When you remove the throwaway clone, read the path twice: rm -rf /tmp/handoff-test removes that folder and everything under it with no recovery. Never run it on a path you have not just printed with pwd. The clone lives in /tmp precisely so a mistake costs nothing.

Checkpoint

You have completed one clone-to-running pass with zero improvisation, and every gap you hit is now a line in the README.

Your turn

  1. Write or rewrite README.md with all seven sections above.
  2. Create .env.example with every variable name and empty values. Verify .env is git-ignored.
  3. Write docs/architecture.md: a diagram in text (browser → API → database), then three decision notes in the four-heading format. At least one must be a decision you now doubt.
  4. Write docs/api.md and docs/schema.md with the tables and one real worked example each.
  5. Write docs/limitations.md: at least five concrete limitations, including the AI feature's cost and failure behaviour and anything your Day 88 measurements exposed.
  6. Do the clone test. Fix what breaks. Repeat until it runs clean.
  7. Commit the documentation with the code, in one commit.

Reviewer mode — after the clone test passes

Today's mode is reviewer: bring finished work, ask for defects. A useful review produces specific, actionable findings with evidence — a line in the README — not praise, not a rewrite.

"Follow my README literally and report every missing prerequisite, ambiguous command, and hidden assumption."

Paste the README and package.json scripts. Check each finding against the file yourself.

Common pitfalls

  • Documenting the framework instead of the project. They can read the Express docs. They cannot guess your seed order.
  • Never testing the instructions. A README that has not been followed on a clean checkout is a draft. The clone test is the test.
  • Docs in a separate place. Keep them in the repo, changed in the same commit as the code, or they rot within weeks.
  • Skipping limitations to look competent. The opposite lands: an honest limits list is the clearest signal that you understand your own system.

Verify it yourself

Open today's reference, the Pro Git book, and find the section on ignoring files in Chapter 2.

  1. Confirm the pattern rules for .gitignore and check yours actually covers .env, node_modules, and any local database dump. Test one with git check-ignore -v <path>.
  2. Find Pro Git's guidance on commit messages in the chapter on contributing to a project. Compare it to your last ten commits with git log --oneline -10. Note one habit to change.

Record both in your notes. Your commit history is documentation too — it is the only record of why each change happened, and it is the one you cannot rewrite later.

The hour

  1. 0–5 min Recall

    Without notes, state yesterday’s main idea and one unresolved question.

  2. 5–20 min Learn

    Read only the listed concept notes and official reference sections needed today.

  3. 20–48 min Build

    Write setup, architecture, data model, testing, deployment, AI-feature risks, and troubleshooting sections.

  4. 48–55 min Explain and verify

    Run the result, inspect evidence, and explain the data/control flow in your own words.

  5. 55–60 min Quiz and commit

    Complete the quiz, record one lesson, and commit the verified change when applicable.

What to hand in

Deliverable

A new developer can run the app using only repository documentation.

Working with AI today

AI as skeptical reviewer

Provide existing work and ask for concrete defects, risks, missing tests, and unsupported assumptions—not praise.

Follow my README literally and report every missing prerequisite, ambiguous command, and hidden assumption.

References

End-of-day quiz

Q1 What should known limitations contain?
Q2 Which result best proves today’s work is complete?
Q3 What should an AI code review primarily produce?

Explain-back gate

Pass the quiz above to unlock completion.

Quiz + explain-back checks required.