| 2026-10-03 |

feat: многопользовательский режим — личный лог по каналу user
...
- Конвенция payload.user_id (sub gnexus-auth): контракт v1 цел, получателей
в конверте нет — дописка в docs/05-ingestion-api.md.
- Канал user в CHANNELS: правило с действием user направляет событие в личный
лог пользователя; без payload.user_id — skipped-delivery с причиной (аудит).
- deliveries.recipient_user_id + ix_deliveries_recipient; миграция 0004
пересоздаёт ck_channel на всех трёх таблицах (deliveries, routing_rule_actions,
channel_targets).
- Routing: _throttled по recipient для user-канала; s2s без цели — прежний
ретрай-цикл.
- Правила: действие user валидно без цели, user + target_id — 422; TargetIn
по-прежнему отвергает user.
- GET /api/v1/me (любой аутентифицированный) и GET /api/v1/me/events (личный
лог строго по своему sub, дедуп по событию).
- OAuth-колбэк: токен выдаётся любому аутентифицированному, роль решает только
раздел; adмин-API остаётся под 403.
- SPA: роль-гейт в router (user -> /my-events, прямой заход в админ-маршруты
редиректит), нав от роли, MyEventsView («Мои события»), getSession-кэш.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
9 hours ago
|
Admin API (#32): CRUD конфигурации и поток под гейтом ролей
...
/api/v1/admin (require_admin): sources (+keys create/revoke), types,
targets, rules (POST/PATCH actions с заменой, toggle enabled), events и
deliveries списки с фильтрами. Конфликты — 409 с человекочитаемой
причиной; защита источника с событиями от удаления. Создание ключа
возвращает токен ровно один раз.
Проверено: TestClient с подменой require_admin против живой БД —
полный цикл create/dup-409/bad-target-422/patch/list/delete/revoke.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
14 hours ago
|
Ingestion (#31): приём событий по контракту docs/05
...
- POST /api/v1/events: Bearer-ключ -> source, анти-спуфинг (401/403/422),
дедуп по dedup_key в окне (DEDUP_WINDOW_SECONDS, дефолт 24ч), 202 мгновенно
- POST /api/v1/events/batch: честная частичная валидация по индексам,
202 при хоть одном принятом, dispatch строго после коммита
- GET /api/v1/events/{id}: статус + доставки, только своему источнику
- synapse.ingest: Routing Engine MVP — первое подошедшее правило по weight,
internal_log исполняется сразу (Jinja-рендер), каналы — #29/#28
- app/cli.py: create-source/create-key/add-type/add-target/add-rule для dev
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
| 2026-10-02 |
SPA-fallback вместо StaticFiles(html=True): /oauth/callback и прочие SPA-роуты отдают index.html
...
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
SSO через gnexus-auth-client-py: OAuth-поток на сервере, без ввода токенов в UI
...
- /auth/login: state+PKCE в Redis (переживает рестарты), redirect на authorize
- /auth/callback: обмен кода, проверка system_role до выдачи токена,
не-админу access-токен сразу revoke; токены в URL-фрагменте
- /auth/refresh и /auth/revoke; SPA: кнопка входа, /oauth/callback,
тихий refresh по 401, логаут
- креды только из env (GAUTH_*), GAUTH_VERIFY_TLS для self-signed в LAN
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|
Каркас #33: FastAPI + Celery + Postgres в докере, Vue 3 SPA на gnexus-ui-kit
...
- FastAPI: healthz/readyz, Swagger на /api/docs, раздача SPA-статики из того же контейнера
- Гейт админки по ролям gnexus-auth (opaque-токены, userinfo, admin/superadmin, 401/403)
- Celery-воркер (redis broker) с каркасной задачей synapse.ping
- Alembic настроен на DATABASE_URL из .env, миграций пока нет (#34)
- docker-compose: api, worker, postgres, redis — одна команда, миграции при старте
- frontend: Vue 3 + Vite + gnexus-ui-kit (git-зависимость), вход-заглушка dev, дашборд, denied-экран
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
1 day ago
|