Stage 7 · Master
Retrospective & What's Next
Mistakes & What's Next
The decisions that did not age well, the shortcuts that became real costs, and the next improvements Fieldwork actually needs.
Mistakes That Were Small Until They Weren't
The easiest mistakes to make in Fieldwork were the ones that looked locally rational. We postponed stronger secret handling because env vars were 'good enough for now'. We tolerated a few read paths with repository call-chains that looked elegant in review. We treated observability as something that could be layered in once features stabilized. None of those choices exploded immediately, which is exactly why they were dangerous. They matured quietly into operational costs.
If there is one theme to this lesson, it is that backend mistakes are often delayed-interest debt. The principal feels tiny when you write the first version. The interest shows up when traffic, incidents, or new teammates force the system to explain itself.
Several Fieldwork decisions worked functionally long before they worked operationally. That distinction matters. Production engineering is not finished when the handler returns 200; it is finished when the failure modes are acceptable too.
Where We Over-Centralized
The gateway earned its place as the auth and coarse-policy boundary, but we also let it become the obvious home for too many cross-cutting decisions. Rate limiting, edge validation, auth, and tracing belonged there. Some request shaping and response-formatting logic started to belong there only because it was convenient. That is the first step toward a gateway that becomes the most complicated service in the system.
We also centralized too much around the shared Postgres schema. It was the right early move, but by the end of the course it was clear that some read models and tenant-level reporting queries were leaning on that central schema as a crutch. The next phase should move selected read concerns toward projections instead of asking one relational shape to stay ideal for every service forever.
| Centralized area | Why it happened | Why it starts to hurt |
|---|---|---|
| API gateway behavior | It already sat in front of every route, so shared logic gravitated there | It risks becoming a bottleneck in code ownership, deploy risk, and runtime latency |
| Shared Postgres schema | Fastest way to keep auth and entity joins coherent early on | Cross-service change velocity slows when one schema absorbs every new reporting or workflow need |
Where We Under-Invested Early
The biggest under-investments were observability and operational documentation. We added structured logging early, which helped, but we waited too long to insist on route-level dashboards, DB pool metrics, event-lag visibility, and runbooks tied to actual alerts. That delay made every first failure of a subsystem feel more mysterious than it should have.
We also under-invested in idempotency discipline early. The outbox pattern was the right call, but consumers needed stricter conventions around dedupe keys, replay testing, and delivery logs sooner. Once asynchronous flows exist, replay safety stops being a nice property and becomes table stakes.
What We Would Build Next
The next step for Fieldwork is not 'add more services'. It is to sharpen the boundaries the current system already hinted at. First, we would introduce dedicated projection pipelines for heavy workspace summaries and reporting views so the write schema stops carrying every read concern. Second, we would reduce gateway surface area by moving format-specific translation closer to service edges and keeping the gateway focused on policy and traffic control. Third, we would revisit whether the shared tenant-scoped schema should stay singular or split along read/write or service seams as access patterns harden.
- Pull high-read summaries into projections before they turn the main schema into a compromise for every query shape.
- Keep the gateway focused on auth, policy, rate limits, and trace propagation; treat every extra convenience feature there with suspicion.
- Standardize idempotency and replay testing for every consumer the same way you standardize HTTP middleware for every service.
- Promote runbooks, readiness checks, and saturation metrics earlier in the build order next time.
What to Carry Into Your Own Backend
The useful lesson from Fieldwork is not 'copy this architecture'. It is narrower: make explicit decisions, tie them to real failure modes, and be willing to reverse them when the cost curve changes. Multi-tenancy, Redis, Kafka, Kubernetes, and a gateway are all optional. The discipline of saying why they exist, what alternative you refused, and what would cause you to change your mind is not optional if you want a backend that ages well.
| Carry forward | Avoid copying blindly |
|---|---|
| Evidence-driven boundary changes | Microservice count or infrastructure choices as status symbols |
| Explicit operational contracts: metrics, runbooks, readiness, idempotency | The assumption that correctness alone makes a system production-ready |
| Selective async design where side effects genuinely tolerate delay | Architecture-by-broker where every interaction becomes an event without a concrete need |
The best follow-up to this course is not feature sprawl. It is tightening boundaries, reducing accidental centralization, and making operational knowledge first-class sooner. Those are the decisions most likely to pay off in the next real system you build.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.