refactor: architecture revision — modular monolith, auth-commit, event protobuf, privacy-from-day-0
- ADR-0003: modular monolith for Phase 0 with documented extraction triggers - ADR-0004: Auth.js + OIDC-shaped boundary; dedicated provider when mobile ships - ADR-0005: protobuf for events, OpenAPI for HTTP, schema-registry CI gate - New architecture docs: data-model, metrics (magic proxies), privacy (Phase-0 feature) - Prime directives updated: privacy-as-feature, modular-by-package-deployable-by-stage - Roadmap revised: Apple OAuth deferred to M1; web push in M1; k3s intermediate; tip-kind-aware UI - PLAN updated: Phase-0 deletion endpoint, metrics baseline, compose profiles, import-boundary lint - License decision in README (ARR with OSS plan in Phase 5)
This commit is contained in:
28
docs/adr/0005-event-schemas-protobuf.md
Normal file
28
docs/adr/0005-event-schemas-protobuf.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# ADR-0005: Protocol Buffers for event schemas, OpenAPI for HTTP
|
||||
|
||||
## Status
|
||||
Accepted — 2026-04-13
|
||||
|
||||
## Context
|
||||
Two contract surfaces exist:
|
||||
1. **HTTP** — synchronous, client ↔ server, human-readable debugging matters. OpenAPI is the default and generates decent TS clients.
|
||||
2. **Events** — durable, fan-out to ML consumers, schema evolution critical. Feature pipelines trained on old schemas will silently misbehave when producers change a field.
|
||||
|
||||
Using OpenAPI for both means:
|
||||
- Python pydantic generation is awkward and hand-maintained in practice.
|
||||
- No wire-format discipline (JSON is loose).
|
||||
- No central schema registry, so schema drift is undetected until a model regresses.
|
||||
|
||||
## Decision
|
||||
- **HTTP** contracts: OpenAPI 3.1 in `packages/shared-types/http/`. Generate TS clients; hand-write Python pydantic models for ML consumers (few, and they're shallow).
|
||||
- **Event** contracts: Protocol Buffers in `packages/shared-types/events/`. Generate TS and Python. All events carry an envelope: `{event_id, occurred_at, schema_version, producer, payload}`.
|
||||
- **Schema registry:** lightweight self-hosted (buf.build Schema Registry OSS or a tiny registry in `events/`). CI check blocks breaking changes without a version bump.
|
||||
- **Evolution rules:** additive only within a major version; `reserved` for removed fields; new `schema_version` for breaking changes; consumers advertise the versions they accept.
|
||||
|
||||
## Consequences
|
||||
- One extra build step in `shared-types` (buf or protoc).
|
||||
- Breaking event changes cost something — good; they should.
|
||||
- ML pipelines can replay old events against new code with confidence.
|
||||
|
||||
## Non-consequences
|
||||
- No gRPC. HTTP stays HTTP/JSON. Protobuf is only the wire format on the event bus.
|
||||
Reference in New Issue
Block a user