# services/ Backend modules. Each owns a contract and ships its own `README.md`. In **Phase 0** these are internal packages inside a single Node process (ADR-0003); they extract to their own processes as pressure justifies. | Dir | Role | Phase-0 shape | Extracts when | |---|---|---|---| | `gateway/` | BFF for clients; auth check; fan-out | in-proc router | never (stays as the edge) | | `auth/` | Google OAuth (Apple in M1), sessions, JWT | Auth.js behind OIDC shape | mobile native ships (M3) | | `profile/` | user profile, preferences, consents | in-proc module | team ownership diverges | | `integrations/` | connectors + encrypted token vault | in-proc module | credential blast-radius isolation | | `recommender/` | `POST /recommend` — policy-driven tip selection | in-proc; calls `ml/serving` from M1 | scaling hotspot | | `events/` | event bus + signal log | in-proc emitter; bridges to NATS JetStream when `NATS_URL` set (ADR-0010) | always a library + broker, not a service | | `notifier/` | push/email delivery + quiet hours | in-proc; **web push in M1** | SLA divergence or mobile push scale | Contracts that cross module lines (HTTP or events) come from `packages/shared-types/`. In-module imports across modules are forbidden by import lint.