# spark-server Spark IM modular monolith. Architecture: [docs/architecture-v3.md](docs/architecture-v3.md). - Go 1.26 - Gin HTTP on `127.0.0.1:8080`. JSON envelope `{"code","msg","data"}`. Docs: `GET /docs`, spec: `GET /openapi.yaml`. - Probes: `GET /healthz` liveness; `GET /readyz` readiness (HTTP 503 when MySQL/Redis/task pool/accepting are not ready). `env: prod` (or `SPARK_ENV=prod`) rejects empty MySQL DSN, empty Redis, and the default JWT secret. - Logs: zap to console and/or rotating file (`log.console` / `log.file`). GORM SQL goes through the same zap. `trace_id` / `request_id` follow context (`X-Request-ID` / `X-Trace-ID`). - gnet TCP on `127.0.0.1:9000` (EventLoop + TaskPool). gnet v2.10 has no built-in TLS; Nginx terminates IM TLS and forwards PROXY+plaintext. Sample: `deploy/nginx/`. - TCP Frame body is JSON `{code,msg,data}`. AUTH body: `{"token","device_id","app_version","language"}`. - Public entry is Nginx `:443` only (SNI split) ```bash make start make migrate make lint ``` `make start` runs `cmd/server` against `configs/config.yaml` (override with `make start CONFIG=path/to.yaml`). `make run` builds `bin/spark-server` first, then starts that binary. Agent conventions live in `.cursor/rules` and `.cursor/skills/spark-im-v3`. Lint conventions live in `.golangci.yaml`.