Skip to content

Module 1 — Planning & design

Estimated: 1 week · Syllabus · ← Module 0 · Next → Module 2

  • Requirements before solutions. The most expensive mistakes are building the wrong thing well. Separate what (requirements) from how (design) from implementation (code).

  • Design docs. Structure: problem statement, goals/non-goals, proposed approach, alternatives considered, risks/open questions. Non-goals are as important as goals — they bound scope.

  • Decomposition. Break systems into modules with clear responsibilities. Two lenses:

    • Coupling — how much modules depend on each other (minimize).
    • Cohesion — how related the contents of one module are (maximize).

    Low coupling + high cohesion is the central heuristic of good structure. The theory underneath: a system’s parts should be changeable independently.

  • Vertical slices vs. horizontal layers. Deliver thin end-to-end slices that each work, rather than complete layers that don’t do anything until the last one lands. Slices give feedback early.

  • Abstraction & information hiding (David Parnas). A module should expose a stable interface and hide its implementation, so internal changes don’t ripple outward. This is the theoretical root of “separation of concerns.”

  • Architecture Decision Records (ADRs). One short markdown file per significant, hard-to-reverse decision: context, decision, consequences. They preserve the why.

Read Parnas’s “On the Criteria To Be Used in Decomposing Systems into Modules” (1972) — short, foundational, still correct. The key insight: decompose around what’s likely to change, hiding each volatile decision inside one module, not around processing steps.

  • Write the design doc for Project B (FeeForge). Goals: create a proposal, define a fee model, compute the fee, draft narrative sections via the API. Non-goals (v1): no multi-user/teams, no billing/invoicing, no PDF export, no auth beyond a single user. Alternatives to argue between: Next.js full-stack vs. separate frontend + FastAPI backend; Prisma vs. Drizzle. Decompose it: fee-calculation domain (pure, no I/O), persistence, API/LLM integration, UI — note where the coupling boundaries fall (the fee engine should know nothing about React or Postgres).
  • Write a one-paragraph problem statement + goals/non-goals for Project A (3D viewer). The interesting design question to name now: what is the linking model — the stable identifier scheme that ties a rendered element to its analysis counterpart and its markups? That’s the module most likely to change, so per Parnas it deserves its own boundary.

☐ Two design docs + your first ADR (e.g., “ADR-001: Next.js full-stack over a split frontend/backend for v1,” with context and consequences).

(working notes go here)