System design reference for Sleek Coach: a FastAPI backend (apps/api), a React Native mobile app (apps/mobile), and Terraform-managed AWS infrastructure (infra/), built around an AI coach with tool calling, safety policies, and streaming chat.
Historical product and design documents are preserved in docs/archive/: PRD, TDD.
flowchart TB
subgraph Mobile["Mobile App (React Native/Expo)"]
UI[UI Components]
TQ[TanStack Query]
ZS[Zustand Stores]
MMKV[(MMKV)]
end
subgraph Backend["Backend (FastAPI)"]
API[API Routes]
Auth[Auth Module]
Coach[AI Coach]
Services[Business Logic]
end
subgraph AI["AI Layer"]
Orch[Orchestrator]
Tools[Tool Registry]
Policies[Safety Policies]
Factory[Provider Factory]
LLM[OpenAI / Anthropic]
end
subgraph Storage["Storage"]
PG[(PostgreSQL)]
Redis[(Redis)]
S3[(S3/MinIO)]
end
subgraph Infra["Infrastructure (AWS)"]
ALB[Application Load Balancer]
ECS[ECS Fargate]
RDS[RDS PostgreSQL]
S3Bucket[S3 Buckets]
end
UI --> TQ
TQ --> ZS
ZS --> MMKV
TQ -->|HTTPS| ALB
ALB --> ECS
ECS --> API
API --> Auth
API --> Coach
API --> Services
Coach --> Orch
Orch --> Tools
Orch --> Policies
Orch --> Factory
Factory --> LLM
Services --> PG
Services --> Redis
Services --> S3
ECS --> RDS
ECS --> S3Bucket
The mobile app talks HTTPS/JSON to the API; coach chat additionally streams over Server-Sent Events. The API is stateless: PostgreSQL is the source of truth, Redis caches coach tool results, and S3 stores progress photos accessed only through presigned URLs.
apps/mobile)Expo SDK 54 on React Native 0.81 with the New Architecture. The app requires a development build (npx expo run:ios); Expo Go is not supported.
| Concern | Library |
|---|---|
| UI kit | React Native Paper (Material Design 3) |
| Server state | TanStack Query 5 |
| Client state | Zustand 5, persisted with MMKV |
| Coach streaming | react-native-sse (SSE client) |
| Navigation | React Navigation 7 (native stack + bottom tabs) |
| Forms and validation | react-hook-form + zod |
| Charts | victory-native on React Native Skia |
| Token storage | expo-secure-store (hardware-backed) |
Layout under apps/mobile/src/:
components/: reusable UI grouped by domain (coach, checkin, nutrition, progress, ui, …)screens/: one directory per navigator area (auth, onboarding, home, coach, progress, settings, legal)services/api/: one service module per backend domain plus a shared client.ts; coachService.ts bridges the SSE stream into an async generatorservices/hooks/: TanStack Query hooks wrapping the servicesstores/: Zustand stores (authStore, chatStore, syncStore, …)navigation/, theme/, lib/, schemas/, constants/: navigators, design tokens, query client and MMKV storage, zod schemas, configUI work must follow DESIGN_CONVENTIONS.md.
apps/api)FastAPI on Python 3.12 with SQLModel (SQLAlchemy + Pydantic) over PostgreSQL, Redis for caching, and S3-compatible object storage (MinIO in development). Each domain module follows the same layering: router.py owns HTTP concerns, service.py owns business logic, models.py owns SQLModel tables, schemas.py owns request/response shapes.
| Module | Responsibility |
|---|---|
auth |
Registration, login, JWT access/refresh tokens with rotation, password change |
users |
Profile, goals, diet preferences, privacy consents, GDPR export, account deletion |
checkins |
Daily weight and wellness check-ins, trends, offline batch sync |
nutrition |
Daily macro logging, range aggregates, TDEE/macro target calculation |
photos |
Progress photos via presigned S3 upload/download URLs |
coach_ai |
The AI coach: orchestrator, providers, tools, policies (see below) |
integrations |
MyFitnessPal export import |
legal |
Serves the legal documents in docs/legal/ at runtime |
Shared plumbing lives in config.py (pydantic-settings), database.py, dependencies.py (Redis), middleware/ (security headers, request ID, performance timing, rate limiter), storage/ (S3 client), exceptions.py, and core/. All routers mount under /api/v1; /health serves load balancer checks. Endpoint details: API.md; schema: DATABASE.md.
The coach (apps/api/app/coach_ai/) is an orchestrated tool-calling loop around a pluggable LLM provider. A factory constructs the provider from settings.llm_provider (openai or anthropic) and a per-tier model config; six internal tools fetch user data with Redis caching; a safety policy engine checks every input and output and returns structured disclaimers; chat streams over SSE with a typed event contract. Sessions expire after idle timeout and conversation history is capped.
Full architecture: AI_COACH.md. Normative rules for changing the layer: AI_CONVENTIONS.md.
infra/)Terraform-managed AWS, with staging and production environments. A public ALB fronts ECS Fargate tasks in private subnets, which use RDS PostgreSQL, ElastiCache Redis, and S3; secrets live in AWS Secrets Manager, and container images in ECR. Production runs Multi-AZ RDS and multiple tasks; staging is a single-instance, lower-cost copy. Module and environment details: infra/README.md.
| Surface | Target |
|---|---|
| Check-in creation | < 300 ms |
| Check-in list | < 200 ms |
| Coach chat (first token) | < 2 s |
| Coach insights | < 1 s |
| Mobile app startup | < 3 s |
Every response carries an X-Response-Time header, and requests slower than 500 ms are logged with path, duration, status, and request ID (app/middleware/performance.py). Monitoring, profiling, and troubleshooting procedures: RUNBOOK.md.