Skip to main content

47. TSDoc backfill for the code reference

Date: 2026-06-23

Status

Proposed — plan for the comment backfill that feeds the generated code reference (ADR-0046). To be executed after approval; nothing in src/ is changed by this ADR itself.

Context

The code reference (ADR-0046) renders TypeDoc output one-to-one from the TSDoc comments in src/lib, src/server, src/db, src/types. The codebase already has good prose /** */ headers on most modules and many functions, but few carry the structured tags TypeDoc renders best — @param, @returns, @throws. Uncommented exports render as bare signatures. The goal is to lift the exported surface of the documented layers to a consistent, tag-rich baseline without touching behaviour.

Decision (proposed)

  1. Scope = the documented layers only. The same four dirs the code reference covers — src/lib, src/server, src/db (excluding the generated types.ts), src/types — and only exported symbols (functions, classes, interfaces, types, consts). Components/pages are out of scope.

  2. Comments only — zero behaviour change. The backfill adds/upgrades /** */ blocks. It MUST NOT change any statement, signature, name, import, or control flow. The post-condition is a no-op diff for the compiler: tsc --noEmit, biome check, pnpm guardrails, and the full vitest suite all stay green and unchanged in count.

  3. Accuracy over coverage. Each comment is written from the actual code (the agent reads the function body, callers, and types), not guessed from the name. A wrong comment is worse than none. Document the why/contract (units, invariants, error conditions, money/cents, week-anchor side), not a restatement of the signature. Honour the house security rules (never document a way to log full SSNs/bank/tax IDs; note masking where relevant).

  4. Tag conventions. @param name - … for each parameter, @returns …, @throws … for thrown errors, @example for non-obvious call shapes. For Result<T,E>-returning functions, describe the ok/error branches rather than @throws. Keep the existing prose lead sentence; add tags under it.

  5. Execute as a batched, verified workflow. Run a Workflow that pipelines over the in-scope files one directory at a time, smallest first (dbtypeslibserver):

    • per file: an agent reads it and rewrites only the doc comments on exported symbols;
    • after each directory batch: run tsc + biome + guardrails + vitest; a batch that changes any non-comment line or fails verification is rejected and redone;
    • an adversarial pass spot-checks a sample of comments against the code for accuracy. One PR per directory keeps each diff reviewable (comment-only diffs are easy to scan, but server alone is ~108 files).
  6. Lock it in going forward (optional, separate). Consider a lint rule requiring a doc comment on exported symbols in the scoped dirs (e.g. an ESLint/Biome rule or a guardrails check), so the reference doesn't decay. Proposed as a follow-up, not part of the backfill.

Execution checklist

  1. Branch docs/tsdoc-backfill-<dir> per directory (or one umbrella branch with per-dir commits).
  2. Workflow: pipeline(files, addDocComments) with the comment-only + verify guardrails above.
  3. After each dir: full verify; diff-audit that only comment lines changed (git diff should touch only /** … */ ranges).
  4. Adversarial accuracy spot-check (sample N functions: does the comment match the code?).
  5. Rebuild the docs site (website && npm run build) to confirm the reference now renders the tags.
  6. Open the PR(s); merge per the usual flow.

Risks / mitigations

  • Comment inaccuracy → agents read the code; adversarial spot-check; accuracy-over-coverage rule.
  • Accidental code edits → per-batch diff-audit that only comment ranges changed; full test suite.
  • Huge diff → one PR per directory; comment-only diffs review fast.
  • Churn vs. value → start with the highest-traffic public APIs (lib/invoice, lib/pay, lib/dates, server/services/invoice, server/services/payroll); stop where returns diminish.

Consequences

  • A richer, more navigable code reference; a one-time large (but comment-only) change to src/.
  • A light ongoing expectation that new exported symbols ship with a doc comment.