# FlatRender V2 — Service Contracts This directory defines all inter-service contracts. Services are loosely coupled — they communicate via REST APIs (synchronous) and RabbitMQ events (asynchronous). The browser connects to the Gateway over HTTPS + WebSocket. ## Layout ``` contracts/ ├── common/ # Reusable OpenAPI components (Error, Pagination, ...) │ └── types.yaml ├── events/ # RabbitMQ event schemas (JSON Schema) │ ├── README.md # Event catalog with routing keys │ ├── render.yaml │ ├── node.yaml │ ├── identity.yaml │ ├── file.yaml │ ├── tenant.yaml │ └── notification.yaml ├── websocket/ # WebSocket message protocol │ └── render-progress.md └── rest/ # Per-service OpenAPI 3.0 specs ├── identity.openapi.yaml # internal ├── content.openapi.yaml # internal ├── studio.openapi.yaml # internal ├── render.openapi.yaml # internal ├── file.openapi.yaml # internal ├── notification.openapi.yaml # internal ├── node-agent.openapi.yaml # called by render orchestrator ├── gateway-public.openapi.yaml # what frontend uses └── reseller-api.openapi.yaml # B2B API (api-key auth) ``` ## Authentication | Surface | Auth | Carries | |----------------------|---------------------------------|------------------------| | Gateway public API | JWT (Bearer) | user_id, tenant_id | | Reseller API | API key (X-API-Key + signature) | tenant_id, scopes | | Internal service API | Service token (mTLS in prod) | service_name | | Node Agent API | Shared secret (HMAC) | orchestrator_signature | | WebSocket | JWT in query param `?token=...` | user_id, job_id | ## Versioning - REST: URL prefix `/v1/...` - Events: routing key suffix `.v1` - WebSocket: protocol negotiation header ## Conventions - All IDs are UUID v4 - All timestamps ISO 8601 with timezone (`2026-05-27T10:15:00Z`) - All money fields are `_minor` integers (rial / cent) - All durations are seconds (numeric) - All file sizes are bytes (integer) - Pagination: `?page=1&page_size=20` returning `PaginatedResponse` - Errors: `{ "error": { "code", "message", "details", "trace_id" } }` - Tenant context: `X-Tenant-Id` header on internal calls (JWT carries it on public)