Skip to content

FTM BSc (part-time) — Programme syllabus

Practical-first. Theory is named where it bites and deferred otherwise. 8 modules, 52 credits, 520 hours, 4 semesters × 15 weeks, ~9 h/week.

Dropped from the previous draft: CS102 Discrete Structures, CS201 Data Structures, CS203 Computer Systems, CS401 Distributed Systems — 4 modules, 20 credits, ~200 hours. Their practical content is reassigned (§3), not lost.


S1 CS101 Programming & Abstraction (8)
CS103 The Web: HTTP, Networks, Browsers (4)
S2 CS202 Databases, SQL & Indexes (8)
CS301 Software Construction & Testing (8)
S3 FTM301 The FTM Backend (8)
FTM302 The FTM Domain (4)
S4 FTM401 The FTM Client Surfaces (4)
FTM402 Infrastructure, Deploy, Ops (8)
└─ capstone ships here

12 teaching weeks + 1 reading + 2 exam weeks per semester. 1 credit = 10 notional hours. 520 hours at 9 h/week ≈ 58 weeks.

Prereqs: CS101 → CS103, CS202, CS301 → FTM301 → FTM302, FTM401; FTM402 needs FTM301 + CS202. All of a semester must pass before the next starts.

Practical work dominates. Same weightings in every module.

ComponentWeightForm
Coursework — labs45%One per week, submitted as a branch
Project35%Real artefact: merged, deployed, or measured
Check-off viva10%20 min oral, unannounced, on her own code
Examination10%One practical paper, open-book, exam week

Pass 50, Merit 60, Distinction 70. Exam and project must each be passed independently. Labs may be resubmitted twice; a viva may not be resat.


CS101 · Programming & Abstraction — 8 credits

Section titled “CS101 · Programming & Abstraction — 8 credits”

Ancestry: CS50x structure, MIT 6.100A Python sequence.

Objectives. Read any function in backend/ and state its contract, inputs, and mutations. Write a function, class and test from a spec. Diagnose a failure from the traceback. See why a value-vs-reference mistake corrupts a queryset.

Units. 0: bootcamp — shell, Git, pdb, nix develop .#backend, running backend/ locally (from 15-213’s bootcamp). 1–2 types, control flow, functions. 3–4 strings, lists, dicts, sets. 5 modules, imports, venvs, uv. 6–7 classes, dataclasses, exceptions, tracebacks. 8 comprehensions, generators, decorators, context managers. 9 type hints, mypy, pytest basics. 10–11 reading a real module end to end (payments/wise.py). 12 reading week.

Labs. L1 hit one endpoint from a local run. L2 write contracts for three backend/shared/ functions. L3 journal-export parser with tests. L4 four seeded defects, failing test first.

Project. CLI reporting worker/job failures from a journal export. Tested, reviewed.

Theory deferred: complexity → CS202; induction → FTM302 (money rules as invariants).


CS103 · The Web: HTTP, Networks & Browsers — 4 credits

Section titled “CS103 · The Web: HTTP, Networks & Browsers — 4 credits”

Ancestry: Stanford CS142 architecture, MDN as reference.

Objectives. Trace a request end to end and name the log line proving each hop. Use curl as the primary instrument, cookies and CSRF included. Tell 401/403/404/422 apart in a system with three auth mechanisms. Know what a CDN may and may not cache.

Units. 1 DNS/TCP/TLS as failure modes. 2–3 HTTP methods, headers, cookies, sessions, CSRF, status semantics. 4 caching: Cache-Control, Vary, surrogate keys, purge. 5–6 browser: DOM, events, fetch, storage. 7–8 JS: scope, closures, this, async/await. 9 CORS, CSP, same-origin. 10–11 nginx → Next.js → Django in FTM’s actual routing.

Labs. L1 curl a staging endpoint four ways, explain each status. L2 capture a dashboard Unpoly interaction and write the whole chain. L3 trace a staging request across hops with evidence.

Project. One-page static client for a read-only FTM API endpoint, correct caching and error states, no framework.


CS202 · Databases, SQL & Indexes — 8 credits

Section titled “CS202 · Databases, SQL & Indexes — 8 credits”

Ancestry: UW CSE 414 (application-facing) + CMU 15-445 (only the index, planning, and transaction lectures).

Objectives. Design a schema that cannot hold a wrong state. Write any query she can describe in English. Read a plan and fix the slow one. State what a transaction isolates and what race it still permits. Operate the Postgres instance: roles, permissions, backups.

Units. 1 relational model, keys, constraints. 2–4 SQL: joins, aggregates, subqueries, CTEs, window functions. 5 the two data structures that matter — hash tables and B-trees; why an index is one. 6 indexes: B-tree, GIN, GiST, partial, composite order. 7 EXPLAIN (ANALYZE, BUFFERS) and query planning. 8–9 transactions, isolation, locking, MVCC, deadlock, lost updates. 10 schema evolution and migrations on live tables. 11 Postgres operation: roles (ftm, hermes, ftm_ai_reader), peer auth, RLS, replication lag, backups.

Labs. L1 ten analytical queries against staging, with plans. L2 find and fix one missing index on a real slow query. L3 reproduce a lost update in payments/, fix with the right constraint. L4 prove what each Postgres role can and cannot do.

Project. Schema report: three missing constraints, two missing indexes, one rewritten query, all measured.

Theory deferred: relational algebra, storage internals, recovery logs. Take 15-445 lectures 3–6 and 22–23 if she ever owns database performance work.


CS301 · Software Construction, Testing & Refactoring — 8 credits

Section titled “CS301 · Software Construction, Testing & Refactoring — 8 credits”

Ancestry: MIT 6.031 readings 01–28, minus the concurrency and parser readings.

Objectives. Write the spec before the body. Tell testing, debugging and proving apart. Refactor without changing behaviour. Review a PR usefully. Decide what level a test belongs at and say what it cannot catch.

Units. 1 static checking, types. 2–3 specifications and designing them. 4–5 testing: black box, glass box, coverage, boundaries. 6 code review. 7 mutability, aliasing, immutability. 8 ADTs, abstraction functions, rep invariants. 9 equality and hashing. 10 debugging methodology. 11 refactoring and legacy seams; the PR as the unit of work.

Labs. L1 write specs for four undocumented backend/ functions, check against reality. L2 review a real merged PR as if open, before reading the discussion. L3 refactor one long view with tests green throughout. L4 turn a real QA card’s AC1…ACn into executable tests.

Project. Test suite pinning three FTM invariants (fee arithmetic, booked state immutable, one band per enquiry) plus a mutation check proving they fail when the logic breaks. Merged to master.

Theory deferred: concurrency (6.031 readings 19–22) → FTM301’s worker work. Parsers and little languages: skip, not used here.


No external equivalent. Closest published analogue: Berkeley CS169.

Objectives. URL → view → template → model → task, unaided. Add an endpoint or page end to end with permissions and tests. Say who can read what. Say where background work runs, and how it fails.

Units. 1 layout, settings, env vars, backend-env.nix. 2 URLs, views, middleware. 3 templates, inheritance, forms. 4 admin, custom pages, get_urls(). 5–6 auth: sessions, magic links, BandAPIAccess hashed tokens, band-access permissions, RLS. 7 Django Ninja in bands/api_v2/, versioning discipline. 8 ORM in anger: N+1, select_related, transactions. 9–10 tasks: huey, the arq worker, Redis, retries, idempotency and timeouts (CS401’s practical residue). 11 uploads: presigned S3 POST, S3→S3 copy. 12 mail: template → Postmark → inbound webhook.

Labs. L1 trace six URLs to views and back, on paper then verified. L2 add a read-only admin page with a permission test. L3 migration on staging, then made safe for a live table. L4 queue a job, break it, read the journal. L5 make one job safe under duplicate delivery.

Project. The capstone’s backend: field, migration, view, permission, tests.

Theory deferred: processes, fds, sockets, OOM → FTM402. Concurrency → this module’s worker labs only.


Written from the code and the KB. Nowhere else teaches it.

Objectives. Narrate a booking from first enquiry to band payout, naming the model and guard at each step. Apply the money rules: 18% booking fee, no VAT, FTM is agent not principal, band sees only its band fee, owed = band net fee − band paid amount, Invoice.band_paid_amount is the only ledger. Say how a search result is ordered and why. Name what is never shown to a band.

Units. 1–2 enquiry lifecycle and soft auth. 3 quotes, replies, invoice coupling. 4 BOOKED and its guards. 5–6 money, Wise, recipient accounts, payouts, batch finality. 7–8 search: FTS, embeddings, blended scoring, rank tiers, local-first, the single-booking inflation trap. 9–10 geography: regions, OSM import, synthetic regions, place IDs, venue vs region. 11 adjacent domains: forms, venue intelligence, reviews, channels. 12 disclosure rules.

Labs. L1 draw the state machine, list every guard and where it is enforced. L2 account for every message in one real prod enquiry thread. L3 find a reachable state violating a stated rule. L4 compute owed for five scenarios, reconcile against the ledger.

Project. Domain law tests: fee arithmetic, band-visible field set, payout owed — as executable specs the team keeps.

Theory deferred: induction and invariants (6.042J) — read after the first money defect, not before.


FTM401 · The FTM Client Surfaces — 4 credits

Section titled “FTM401 · The FTM Client Surfaces — 4 credits”

Ancestry: CS142 for architecture; frameworks learned from the codebase.

Objectives. Given a screen, name the surface, service and file. Change a public page without breaking cacheability. Work with the dashboard’s Unpoly/Alpine conventions. Know what mobile gets from api_v2 and what it does not.

Units. 1 four surfaces and ownership. 2–3 Next.js 16 App Router: server vs client components, routing, data fetching. 4 ISR, Fastly, surrogate keys, pages that cannot be cached. 5–6 Unpoly overlays, Alpine components. 7 React Query and the mobile app’s api_v2 consumption. 8 Astro: blog, help, SEO satellites. 9 images, Core Web Vitals. 10 accessibility as a review criterion. 11 cache invalidation and stampede (CS401’s practical residue).

Labs. L1 eight URLs → surface, service, file. L2 add a cached page, prove the header. L3 change a dashboard drawer, verify in a PR preview. L4 perf-review a recent PR with numbers.

Project. The capstone’s UI, correct surface, verified in a preview.


FTM402 · Infrastructure, Deployment, Security & Ops — 8 credits

Section titled “FTM402 · Infrastructure, Deployment, Security & Ops — 8 credits”

Ancestry: NixOS/Colmena from the repository, security scoped from MIT 6.858, operations from the incident write-ups.

Objectives. Use every devShell. Write a NixOS option without guessing. Deploy to staging and prod, and roll back. Explain how a PR gets its own environment. Find the log line for any request. Triage an incident from signal to cause. Name the auth boundary a request crossed and the one it should have.

Units. 1–2 Nix language, flakes, uv2nix, _pnpmDepsHash. 3 NixOS modules, systemd, users, firewall. 4 secrets: agenix; root-only DDL lives in postStart. 5 hosts and topology: staging, prod, containers, previews. 6 Colmena, restartIfChanged, rollback. 7 nginx routing and the main-site catch-all trap. 8–9 the OS layer that bites: processes, file descriptors, sockets, connection pools, OOM (CS203’s practical residue). 10 observability: Alloy → Loki → Grafana, LogQL, alert hygiene. 11 security: surface, headers, auth boundaries, webhook signatures, S3 exposure. 12 incidents: timeline, postmortem, what “fixed” means.

Labs. L1 build the backend devShell cold. L2 deploy change verified with nix eval. L3 answer five questions from Loki alone. L4 write an alert that fires and one that stays quiet. L5 reproduce a historical incident from logs, write the timeline. L6 induce connection-pool exhaustion on staging, read the traceback.

Project (capstone). Ship the ticket: preview → staging → prod, instrumented with a log line proving it works, QA brief written for someone else to run, card closed.


Dropped moduleWhose practical content survivedWhere
CS102 Discrete Structuresinvariants, constraints, complexityCS202 §5–9, FTM302
CS201 Data Structureshash tables, B-trees, traversalCS202 §5–6
CS203 Computer Systemsbootcamp, processes, fds, sockets, OOMCS101 §0, FTM402 §8–9
CS401 Distributed Systemsidempotency, retries, timeouts, queues, cache invalidationFTM301 §9–10, FTM401 §11

Nothing practical was lost. What was lost is theory with no immediate bite.

5. Standalone theory, if she ever wants it

Section titled “5. Standalone theory, if she ever wants it”

One line each, no exams, no credits. Read when the trigger fires.

  • MIT 6.042J — induction, invariants, sets. Trigger: second money defect.
  • MIT 6.006 — algorithms, dynamic programming. Trigger: a ranking or search change that needs a complexity argument.
  • CMU 15-445 lectures 3–6, 22–23 — storage, buffer pool, recovery. Trigger: owning Postgres performance.
  • MIT 6.5840 — replication, consensus. Trigger: a second writer.
  • CMU 15-213 labs — C, malloc, caches. Trigger: native extensions, if ever.
AreaModuleProof
backend/, 15 appsFTM301Trace any URL unaided
Enquiry → payout, search, geoFTM302Domain law tests merged
frontend/, dashboard, mobile/, AstroFTM401Verified per surface
deployment/, flake.nix, terraform/FTM402Deploy and roll back
worker/, push/, services/FTM301, FTM402Idempotent job
e2e/, CI, pytest infraCS301Suite merged to master
Postgres, Redis, S3, CDNCS202, FTM401Schema report, perf review
Observability, securityFTM402Incident timeline, findings

Not covered, by design: ftm_bot/band_bot internals, geolibre plugins, YouTrack/BookStack/Hoppscotch tooling. Say if any should become a module.

Lectures are the published courses — watch the named weeks, skip where the lab replaces them. One 2-hour supervised block per module per week, which is also when the viva runs. Everything submitted as a branch; no lab counts until it is one. One paragraph before each lecture week (the 6.5840 habit) — it is what stops passive watching.

ItemHours
8 module specs to teaching-ready (lecture map, lab briefs)24
32 labs32
8 practical papers + marking guides20
Viva rubrics, transcript, capstone scaffold6
Total~82 h

Author Semester 1 only (~18 h), start her, write Semester 2 while she is in Semester 1.

  • 520 hours at 9 h/week is 58 weeks. At 6 h/week it is 20 months. Pick the number before she starts.
  • Semester 2 (CS202 + CS301, 160 h) is still the heaviest. If she flags in week 6, cut CS202’s units 10–11 to reading and let the labs carry it.
  • A practical-only assessment can be gamed by copying a working diff. The viva is the defence; do not drop it.
  • Exam week competes with QA deadlines. Protect it.
  • Capstone must be a real, low-blast-radius ticket that Freeman approves. Nothing in payments state transitions.
  1. Hours per week — 9 (14 months) or fewer and longer?
  2. Semester 1 only first (~18 h), or all 8 modules up front (~82 h)?
  3. Capstone ticket now, or at the start of Semester 3?