Without notes, state yesterday’s main idea and one unresolved question.
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.
- What this is. Two sentences: the problem and who it is for. Not marketing.
- Prerequisites, with versions. "Node 20 or later, Docker Desktop, PostgreSQL 16 (or use the
Compose file)." Say how to check:
node --version. - Setup, as copy-pasteable commands. Every command in a code block, in order, no prose steps hiding an action.
- Environment variables, as a table. Name, what it is for, required or optional, example value. Never the real value.
- How to run it, and what they should see when it works — a URL and a confirmation line.
- How to run the tests and the checks.
- 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
- Write or rewrite
README.mdwith all seven sections above. - Create
.env.examplewith every variable name and empty values. Verify.envis git-ignored. - 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. - Write
docs/api.mdanddocs/schema.mdwith the tables and one real worked example each. - 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. - Do the clone test. Fix what breaks. Repeat until it runs clean.
- 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.
- Confirm the pattern rules for
.gitignoreand check yours actually covers.env,node_modules, and any local database dump. Test one withgit check-ignore -v <path>. - 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
- 0–5 min Recall
- 5–20 min Learn
Read only the listed concept notes and official reference sections needed today.
- 20–48 min Build
Write setup, architecture, data model, testing, deployment, AI-feature risks, and troubleshooting sections.
- 48–55 min Explain and verify
Run the result, inspect evidence, and explain the data/control flow in your own words.
- 55–60 min Quiz and commit
Complete the quiz, record one lesson, and commit the verified change when applicable.
What to hand in
A new developer can run the app using only repository documentation.
Working with AI today
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
Explain-back gate
Pass the quiz above to unlock completion.
Quiz + explain-back checks required.