# ADR 0002: Backend Protocol = HTTPS REST + JSON (OpenAPI-First) - Status: Accepted - Date: 2026-02-14 ## Context `relationship_saver` is offline-first for MVP. Local DB remains the source of truth for core usage. Backend responsibilities are incremental: 1. account/session management 2. sync transport for local mutations and remote updates 3. recommendation/signals feed 4. future upload/download URL broker We need a transport that is cross-platform, testable in Flutter, easy to stub for local development, and contract-driven across mobile/backend teams. ## Decision Use HTTPS REST + JSON with an OpenAPI-first contract. - Client HTTP stack: `dio` - Typed models: `freezed` + `json_serializable` - Gateway boundary: `BackendGateway` (transport-agnostic interface) - Runtime implementation: `BackendGatewayRest` - Local development implementation: `BackendGatewayFake` - Auth/session support: access + refresh token with secure storage - Retry policy: only transient failures; non-idempotent retries require idempotency key - Error surface: typed `BackendException` taxonomy ## Consequences ### Positive - Strong, versioned contract artifact in `docs/api/openapi.yaml` - Fast local iteration with fake gateway, no backend dependency for core UX - Explicit behavior for refresh/retry/failure classes - Good compatibility across Android/iOS/macOS/Windows/Linux/Web ### Tradeoffs - REST polling for feed/sync may be less real-time than socket-based push - Some envelope sizes may require tuning and pagination strategy - Requires careful idempotency handling for mutation endpoints ## Evolution Plan Realtime is deferred for now but planned: 1. Keep REST as source of truth for command/query semantics. 2. Add optional SSE or WebSocket channel for push notifications/signals invalidation. 3. Continue using same DTO schema envelopes from OpenAPI where possible. 4. Add explicit capability negotiation (`/v1/capabilities`) when realtime ships. ## Rejected Alternatives - gRPC-only for MVP: stronger streaming story, but higher setup and broader tooling burden for immediate scope. - GraphQL-first: flexible querying, but sync/mutation idempotency patterns are clearer with explicit REST resources now.