feat: V2 microservices stack — backend services, gateway, JWT auth
Add full V2 architecture: identity, content, studio (.NET 10) and file, render, notification, gateway (Go) services with vendored deps, plus DB migrations, event/API contracts, and an init-db script. Wire the Next.js frontend to the gateway: server-side JWT auth routes (login/register/refresh/logout/me), gateway fetch helper, and session/ cookie/jwt helpers under src/lib. Containerize the stack via docker-compose.v2.yml and per-service Dockerfiles. Base images resolve through a Nexus mirror (Docker Hub) and MCR directly; npm/NuGet pull from Nexus groups. Self-host fonts via next/font/local to avoid Google Fonts (geo-blocked). Add CI workflow and ignore .env.v2, *.stackdump, and .NET bin/obj. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
# 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<T>`
|
||||
- Errors: `{ "error": { "code", "message", "details", "trace_id" } }`
|
||||
- Tenant context: `X-Tenant-Id` header on internal calls (JWT carries it on public)
|
||||
Reference in New Issue
Block a user