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.
1. Structure
Section titled “1. Structure”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 here12 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.
2. Assessment
Section titled “2. Assessment”Practical work dominates. Same weightings in every module.
| Component | Weight | Form |
|---|---|---|
| Coursework — labs | 45% | One per week, submitted as a branch |
| Project | 35% | Real artefact: merged, deployed, or measured |
| Check-off viva | 10% | 20 min oral, unannounced, on her own code |
| Examination | 10% | 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.
3. Modules
Section titled “3. Modules”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.
FTM301 · The FTM Backend — 8 credits
Section titled “FTM301 · The FTM Backend — 8 credits”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.
FTM302 · The FTM Domain — 4 credits
Section titled “FTM302 · The FTM Domain — 4 credits”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.
4. What the cut preserved
Section titled “4. What the cut preserved”| Dropped module | Whose practical content survived | Where |
|---|---|---|
| CS102 Discrete Structures | invariants, constraints, complexity | CS202 §5–9, FTM302 |
| CS201 Data Structures | hash tables, B-trees, traversal | CS202 §5–6 |
| CS203 Computer Systems | bootcamp, processes, fds, sockets, OOM | CS101 §0, FTM402 §8–9 |
| CS401 Distributed Systems | idempotency, retries, timeouts, queues, cache invalidation | FTM301 §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.
6. Codebase coverage
Section titled “6. Codebase coverage”| Area | Module | Proof |
|---|---|---|
backend/, 15 apps | FTM301 | Trace any URL unaided |
| Enquiry → payout, search, geo | FTM302 | Domain law tests merged |
frontend/, dashboard, mobile/, Astro | FTM401 | Verified per surface |
deployment/, flake.nix, terraform/ | FTM402 | Deploy and roll back |
worker/, push/, services/ | FTM301, FTM402 | Idempotent job |
e2e/, CI, pytest infra | CS301 | Suite merged to master |
| Postgres, Redis, S3, CDN | CS202, FTM401 | Schema report, perf review |
| Observability, security | FTM402 | Incident timeline, findings |
Not covered, by design: ftm_bot/band_bot internals, geolibre plugins,
YouTrack/BookStack/Hoppscotch tooling. Say if any should become a module.
7. Method
Section titled “7. Method”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.
8. Authoring cost
Section titled “8. Authoring cost”| Item | Hours |
|---|---|
| 8 module specs to teaching-ready (lecture map, lab briefs) | 24 |
| 32 labs | 32 |
| 8 practical papers + marking guides | 20 |
| Viva rubrics, transcript, capstone scaffold | 6 |
| Total | ~82 h |
Author Semester 1 only (~18 h), start her, write Semester 2 while she is in Semester 1.
9. Risks
Section titled “9. Risks”- 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.
10. Decisions needed
Section titled “10. Decisions needed”- Hours per week — 9 (14 months) or fewer and longer?
- Semester 1 only first (~18 h), or all 8 modules up front (~82 h)?
- Capstone ticket now, or at the start of Semester 3?