feat: backend service
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
# Configuration and Contract Examples
|
||||
|
||||
Example values that complement `../README.md` §4 and the OpenAPI
|
||||
contract.
|
||||
|
||||
## Local `.env`
|
||||
|
||||
```dotenv
|
||||
# HTTP and gRPC listeners
|
||||
BACKEND_HTTP_LISTEN_ADDR=:8080
|
||||
BACKEND_GRPC_PUSH_LISTEN_ADDR=:8081
|
||||
|
||||
# Postgres
|
||||
BACKEND_POSTGRES_DSN=postgres://galaxy:galaxy@localhost:5432/galaxy_backend?sslmode=disable&search_path=backend
|
||||
|
||||
# SMTP relay (mailpit by default for dev)
|
||||
BACKEND_SMTP_HOST=localhost
|
||||
BACKEND_SMTP_PORT=1025
|
||||
BACKEND_SMTP_FROM=galaxy-backend@galaxy.test
|
||||
BACKEND_SMTP_TLS_MODE=none
|
||||
|
||||
# Docker
|
||||
BACKEND_DOCKER_HOST=unix:///var/run/docker.sock
|
||||
BACKEND_DOCKER_NETWORK=galaxy-dev
|
||||
|
||||
# Game engine
|
||||
BACKEND_GAME_STATE_ROOT=/var/lib/galaxy-game
|
||||
|
||||
# Admin bootstrap
|
||||
BACKEND_ADMIN_BOOTSTRAP_USER=bootstrap
|
||||
BACKEND_ADMIN_BOOTSTRAP_PASSWORD=change-me-immediately
|
||||
|
||||
# GeoLite2
|
||||
BACKEND_GEOIP_DB_PATH=/var/lib/galaxy/geoip.mmdb
|
||||
|
||||
# Telemetry (stdout for dev)
|
||||
BACKEND_OTEL_TRACES_EXPORTER=stdout
|
||||
BACKEND_OTEL_METRICS_EXPORTER=stdout
|
||||
```
|
||||
|
||||
The above is enough for `go run ./backend/cmd/backend` to boot
|
||||
locally. Required-but-empty admin variables can be set to `bootstrap`
|
||||
and any non-empty password; rotate immediately after first sign-in.
|
||||
|
||||
## Public REST examples
|
||||
|
||||
### `POST /api/v1/public/auth/send-email-code`
|
||||
|
||||
```http
|
||||
POST /api/v1/public/auth/send-email-code HTTP/1.1
|
||||
Host: backend.internal
|
||||
Content-Type: application/json
|
||||
Accept-Language: en-US
|
||||
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
The `Accept-Language` header is captured as `preferred_language` for
|
||||
the new account; the body schema rejects unknown fields, so locale
|
||||
must travel through the header.
|
||||
|
||||
### `POST /api/v1/public/auth/confirm-email-code`
|
||||
|
||||
```http
|
||||
POST /api/v1/public/auth/confirm-email-code HTTP/1.1
|
||||
Host: backend.internal
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
## Internal REST examples (gateway-only)
|
||||
|
||||
```http
|
||||
GET /api/v1/internal/sessions/5e7ae3e6-3f4f-4d59-9b9b-2f2c3d2e0a91 HTTP/1.1
|
||||
Host: backend.internal
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
```http
|
||||
POST /api/v1/internal/sessions/5e7ae3e6-.../revoke HTTP/1.1
|
||||
Host: backend.internal
|
||||
```
|
||||
|
||||
## Admin REST examples
|
||||
|
||||
```http
|
||||
GET /api/v1/admin/mail/deliveries?page=1&page_size=10 HTTP/1.1
|
||||
Host: backend.internal
|
||||
Authorization: Basic <base64 of bootstrap:secret>
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
Resend on a `sent` row returns `409 Conflict`:
|
||||
|
||||
```http
|
||||
POST /api/v1/admin/mail/deliveries/{id}/resend HTTP/1.1
|
||||
Authorization: Basic ...
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 409 Conflict
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
## Standard error envelope
|
||||
|
||||
Every error response across the four route groups uses:
|
||||
|
||||
```json
|
||||
{"error": {"code": "<machine_readable>", "message": "<human_readable>"}}
|
||||
```
|
||||
|
||||
The closed set of `code` values lives in
|
||||
`components/schemas/ErrorBody` of `../openapi.yaml`.
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
Resend on a `sent` row returns `409 Conflict`:
|
||||
|
||||
```http
|
||||
POST /api/v1/admin/mail/deliveries/{id}/resend HTTP/1.1
|
||||
Authorization: Basic ...
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 409 Conflict
|
||||
Content-Type: application/json
|
||||
|
||||
{"error": {"code": "conflict", "message": "delivery already sent"}}
|
||||
```
|
||||
|
||||
## Standard error envelope
|
||||
|
||||
Every error response across the four route groups uses:
|
||||
|
||||
```json
|
||||
{"error": {"code": "<machine_readable>", "message": "<human_readable>"}}
|
||||
```
|
||||
|
||||
The closed set of `code` values lives in
|
||||
`components/schemas/ErrorBody` of `../openapi.yaml`.
|
||||
Reference in New Issue
Block a user