2.3 KiB
2.3 KiB
Architecture overview
Guiding constraints
- The recommendation decision is the hot path. Every architectural choice should shorten the distance between a new signal and a better tip.
- Services are small and independently deployable, but we do not multiply services for its own sake. Split by team-of-ownership and by data lifecycle.
- Python for ML, TypeScript for applications, shared contracts regenerated from a single source of truth.
Services
| Service | Language | Responsibility | Owns data |
|---|---|---|---|
gateway |
TS (Node) | BFF for web/mobile; auth-checking; request fan-out | — |
auth |
TS | OAuth (Google, Apple), sessions, token issuance | identities, sessions |
profile |
TS | user profile, preferences, consents | profiles |
integrations |
TS | third-party connectors, token vault, signal fetch | credentials, cursors |
events |
TS | event-bus ingress, normalization, durable log | signal store |
recommender |
TS | orchestration: candidates → policy → tip; feedback sink | tip history |
ml/serving |
Python | online scoring for policies/models | — (stateless) |
ml/pipelines |
Python | batch feature + training pipelines | feature store, models |
notifier |
TS | push/email delivery, quiet hours, dedupe | delivery log |
Data boundaries
Each service owns its schema; no cross-service DB access. When recommender needs profile data, it calls profile (read model), not its DB.
Event flow
connector (integrations) ──emit──▶ events ──▶ feature pipelines (ml)
│
└──▶ recommender (context assembly)
User reactions (done / snooze / dismiss) are events too. They close the loop as rewards for bandit/RL policies.
Why these choices
- NATS JetStream over Kafka for Phase 1: lighter, single-binary, fits the "one VM" deployment. Swap to Kafka in Phase 4.
- Postgres everywhere for OLTP. Per-service schemas, not per-service instances in dev.
- FastAPI + Pydantic for ML serving — fast, typed, swappable runtime (ONNX, Triton) behind it.
- Feast for feature store when we get there; homegrown adapter until then (Phase 1 seam).
- MLflow for model registry; artifacts in MinIO/S3.
- Auth.js or Ory for identity — we will not write crypto.