Course plan
Product brief: Field Notes
Small teams use Field Notes to organize projects and tasks. Tasks have a title, description, status (TODO, IN_PROGRESS, DONE), assignee, and timestamps. A user belongs to a team; only team members can access its projects. Changes should appear in connected clients without polling.
Teaching sequence
| Ch. | Learner-visible result | Main concepts | Checkpoint |
|---|---|---|---|
| 1 | Go program runs | install, module, packages, format/build/run | Explain go.mod, main, and gofmt |
| 2 | Task validation helper | variables, types, functions, loops, errors | Handle invalid title |
| 3 | Tasks represented as data | structs, slices, maps, JSON | Filter tasks by status |
| 4 | In-memory repository | methods, pointers, interfaces, packages | Swap storage behind an interface |
| 5 | Tested domain rules | errors, test package, vet, race detector | Save/read and missing-task tests |
| 6 | Concurrent work can stop | goroutines, channels, mutex, context | Explain request cancellation |
| 7 | Flutter starter app and toolchain | RPC lifecycle, HTTP/2, generation prerequisites | Verify all tools |
| 8 | Shared API contract | proto messages, enums, field tags, codegen | Generate Go and Dart stubs |
| 9 | Go gRPC server | registration, unary handler, status codes | Invoke with grpcurl |
| 10 | Flutter fetches remote task | channel, generated Dart stub, async UI | Show task and connection error |
| 11 | Flutter creates task | validation, status mapping, error UX | Blank title is rejected |
| 12 | PostgreSQL stores tasks | SQL, migrations, repository adapter | Data survives server restart |
| 13 | Bounded task listing | deadlines, context, cursor pagination | Fetch next page and cancel stale call |
| 14 | Live task updates | server stream, fan-out, reconnect | Second client sees event |
| 15 | Team data is protected | metadata, token validation, authz, TLS | Cross-team request is denied |
| 16 | Repeatable changes | tests, code generation, compatibility | Clean regeneration and build |
| 17 | Deployable service | logs, health, shutdown, container, TLS | Readiness probe passes |
| 18 | Reviewed capstone | UX, runbook, threat model, tradeoffs | Meet capstone rubric |
Recommended pacing
Each chapter is intended for 1–3 hours. For a cohort, use one session for reading and demonstration, then a lab session. Ask learners to commit after each working checkpoint. Pair Go and Flutter learners when possible; rotate who owns the API and client so both sides understand the contract.
Instructor rhythm
- Start with a user story and a failing end-to-end path.
- Make the smallest contract change that supports it.
- Regenerate code and inspect the generated API briefly.
- Implement the Go path, then connect it from Flutter.
- Add failure-path handling before adding the next feature.
- End with a checkpoint, reflection, and a small independent variation.
Scope boundaries
The required path uses a single Go service and PostgreSQL. Keep microservices, offline-first conflict resolution, bidirectional streaming, Kubernetes, and event brokers as optional extensions. Do not introduce them before the core client/server contract is stable.