docs(mana-sync): document billing middleware, new env vars, project structure

- Add MANA_CREDITS_URL and MANA_SERVICE_KEY to configuration table
- Document billing gate on sync endpoints (402 behavior, 5min cache, fail-open)
- Add billing/check.go to project structure
- Add stream endpoint to API table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-10 22:38:23 +02:00
parent ed76f53b00
commit 56d7f9a4de

View file

@ -127,13 +127,16 @@ Result: title="Buy eggs", completed=true (merged — different fields)
| Endpoint | Method | Auth | Description | | Endpoint | Method | Auth | Description |
|----------|--------|------|-------------| |----------|--------|------|-------------|
| `POST /sync/{appId}` | POST | JWT | Push changes, get server delta | | `POST /sync/{appId}` | POST | JWT + Billing | Push changes, get server delta |
| `GET /sync/{appId}/pull` | GET | JWT | Pull changes for a collection | | `GET /sync/{appId}/pull` | GET | JWT + Billing | Pull changes for a collection |
| `GET /sync/{appId}/stream` | GET | JWT + Billing | SSE stream for real-time changes |
| `GET /ws` | WS | JWT (in-band) | Unified real-time sync (all apps, one connection) | | `GET /ws` | WS | JWT (in-band) | Unified real-time sync (all apps, one connection) |
| `GET /ws/{appId}` | WS | JWT (in-band) | Legacy per-app sync notifications | | `GET /ws/{appId}` | WS | JWT (in-band) | Legacy per-app sync notifications |
| `GET /health` | GET | No | Health check with connection stats | | `GET /health` | GET | No | Health check with connection stats |
| `GET /metrics` | GET | No | Prometheus metrics | | `GET /metrics` | GET | No | Prometheus metrics |
**Billing gate**: Push, pull, and stream endpoints are wrapped by a billing middleware that checks the user's sync subscription status via `mana-credits`. Returns **402 Payment Required** if sync is not active. Status is cached for 5 minutes per user. Fail-open: if mana-credits is unreachable, sync is allowed.
## Database Schema ## Database Schema
Single table for all sync data: Single table for all sync data:
@ -163,6 +166,8 @@ Indexes: `(user_id, app_id, created_at)`, `(table_name, record_id, created_at)`,
| `DATABASE_URL` | `postgresql://...localhost:5432/mana_sync` | PostgreSQL connection | | `DATABASE_URL` | `postgresql://...localhost:5432/mana_sync` | PostgreSQL connection |
| `JWKS_URL` | `http://localhost:3001/api/auth/jwks` | mana-auth JWKS endpoint | | `JWKS_URL` | `http://localhost:3001/api/auth/jwks` | mana-auth JWKS endpoint |
| `CORS_ORIGINS` | `http://localhost:5173,...` | Comma-separated allowed origins | | `CORS_ORIGINS` | `http://localhost:5173,...` | Comma-separated allowed origins |
| `MANA_CREDITS_URL` | `http://localhost:3061` | mana-credits service URL for billing checks |
| `MANA_SERVICE_KEY` | `dev-service-key` | Service-to-service auth key |
## Testing ## Testing
@ -181,6 +186,7 @@ services/mana-sync/
├── internal/ ├── internal/
│ ├── auth/jwt.go — EdDSA JWT validation via JWKS │ ├── auth/jwt.go — EdDSA JWT validation via JWKS
│ ├── auth/jwt_test.go — Token extraction, validator tests │ ├── auth/jwt_test.go — Token extraction, validator tests
│ ├── billing/check.go — Sync billing status checker (cached, fail-open)
│ ├── config/config.go — Environment variable loading │ ├── config/config.go — Environment variable loading
│ ├── config/config_test.go — Config defaults and env override tests │ ├── config/config_test.go — Config defaults and env override tests
│ ├── store/postgres.go — PostgreSQL schema, queries │ ├── store/postgres.go — PostgreSQL schema, queries
@ -195,6 +201,7 @@ services/mana-sync/
## Security ## Security
- JWT validated via EdDSA JWKS (same as NestJS backends) - JWT validated via EdDSA JWKS (same as NestJS backends)
- Sync endpoints gated by billing check (402 if subscription inactive)
- WebSocket connections must authenticate within 10 seconds - WebSocket connections must authenticate within 10 seconds
- Request body limited to 10 MB - Request body limited to 10 MB
- Operation types validated (insert/update/delete only) - Operation types validated (insert/update/delete only)