feature: API-ключи клиентов и журнал использования в Postgres (#4, #17)

- Postgres в compose; пакет db (SQLAlchemy async): clients, windows, requests.
- Все эндпоинты, кроме /health, — только с ключом в X-API-Key, иначе 401; без
  выпущенных ключей доступа нет. В базе — только sha256 ключа.
- Задача и окно сессии привязаны к клиенту: чужой ключ их не видит.
- Воркер пишет журнал: окно (открыто, последнее обращение, закрыто) и задачу
  (в очереди, начало, конец, итог, данные без секретов). Сбой записи не роняет задачу.
- python -m db.cli create|list|revoke|stats; make key-create/key-list/key-revoke/stats.
- smoke и loadtest с ключом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
protokeyandClaude Opus 5.5 committed 2026-10-13 21:48:48 +04:00
1 parent 9dc2c0b619
commit 1a4bd8d672
34 files changed
+857 -81

No files matched your search

+20
View File
@@ -3,6 +3,7 @@
x-backend-env: &backend-env
RABBITMQ_URL: amqp://robotex:${RABBITMQ_PASSWORD:-robotex}@rabbitmq:5672/
REDIS_URL: redis://redis:6379/0
DATABASE_URL: postgresql+asyncpg://robotex:${POSTGRES_PASSWORD:-robotex}@postgres:5432/robotex
services:
api:
@@ -20,6 +21,7 @@ services:
depends_on:
rabbitmq: {condition: service_healthy}
redis: {condition: service_healthy}
postgres: {condition: service_healthy}
worker:
build: .
@@ -43,6 +45,7 @@ services:
depends_on:
rabbitmq: {condition: service_healthy}
redis: {condition: service_healthy}
postgres: {condition: service_healthy}
rabbitmq:
image: rabbitmq:4.1-alpine
@@ -60,6 +63,22 @@ services:
timeout: 10s
retries: 10
# клиенты и API-ключи, журнал окон и запросов
postgres:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: robotex
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-robotex}
POSTGRES_DB: robotex
volumes:
- postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "robotex", "-d", "robotex"]
interval: 5s
timeout: 5s
retries: 10
redis:
image: redis:8.2-alpine
restart: unless-stopped
@@ -83,3 +102,4 @@ volumes:
extra:
rabbitmq:
redis:
postgres: