feat(server): скелет Go-сервера с healthz, readyz и api/v1/meta

- internal/config: конфигурация из env с валидацией и дефолтами (§5.1, §9.1)
- internal/httpx: middleware (request id, slog-логи, recover, security-заголовки),
  единый формат ошибок §8.5 и лимит тела запроса
- internal/database: SQLite WAL + busy_timeout + foreign_keys, один writer
  и пул чтения, goose-миграции embedded, PRAGMA optimize по расписанию
- internal/meta: полезная нагрузка /api/v1/meta (версия, фичи, лимиты)
- internal/server: маршруты, SPA-раздача собранного клиента, OpenAPI 3.1
- cmd/glchat: точка входа с graceful shutdown и JSON-логами
- тесты: конфиг, миграции и идемпотентность, HTTP-эндпоинты, статика, 404/405
This commit is contained in:
2026-09-19 18:20:56 +03:00
parent 9839dbeede
commit 69aa98e18c
22 changed files with 1887 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
package server
// openAPIDocument is the hand-maintained OpenAPI 3.1 contract for the endpoints
// implemented so far. Phase 1 replaces it with a schema generated from typed
// handler definitions (AGENT.md 8.1).
var openAPIDocument = []byte(`{
"openapi": "3.1.0",
"info": {
"title": "glchat API",
"version": "0.1.0",
"description": "Self-hosted communication platform. Phase 0 exposes health and metadata endpoints only.",
"license": { "name": "AGPL-3.0-or-later", "identifier": "AGPL-3.0-or-later" }
},
"servers": [{ "url": "/api/v1" }],
"paths": {
"/meta": {
"get": {
"operationId": "getMeta",
"summary": "Instance metadata, API version and feature flags",
"tags": ["Meta"],
"responses": {
"200": {
"description": "Instance metadata",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/Meta" }
}
}
}
}
}
}
},
"components": {
"schemas": {
"Meta": {
"type": "object",
"required": ["name", "version", "api_version", "base_url", "features"],
"properties": {
"name": { "type": "string" },
"version": { "type": "string" },
"commit": { "type": "string" },
"build_date": { "type": "string" },
"api_version": { "type": "string", "enum": ["v1"] },
"base_url": { "type": "string" },
"files_url": { "type": "string" },
"gateway_url": { "type": "string" },
"rtc_path": { "type": "string" },
"max_upload_size": { "type": "integer", "format": "int64" },
"features": {
"type": "object",
"properties": {
"registration_enabled": { "type": "boolean" },
"anti_bot_enabled": { "type": "boolean" },
"voice_enabled": { "type": "boolean" },
"web_push_enabled": { "type": "boolean" },
"oauth_enabled": { "type": "boolean" },
"passkeys_enabled": { "type": "boolean" }
}
}
}
},
"Error": {
"type": "object",
"required": ["error"],
"properties": {
"error": {
"type": "object",
"required": ["code", "message"],
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"details": { "type": "object", "additionalProperties": true }
}
}
}
}
}
}
}
`)