| 2026-10-03 |

feat: раздел Настройки (.env-оверрайды UI) и PWA с web-push каналом
...
Настройки: реестр app/settings_registry.py + хранение оверрайдов в
app_settings (settings_store, без кэша). Дефолт из .env, перебивается из
админки без перезапуска. Секреты (VAPID private, тг-токен, SMTP-пароль)
— write-only: записываются через UI, никогда не возвращаются API.
Эндпоинты GET/PUT /api/v1/admin/settings.
Web-push: канал push (целенаправлен как user — адресат из payload.user_id),
таблица push_subscriptions, самопользовательская подписка браузера через
/me/push* (upsert по endpoint, чужой 404). Воркер send_push: pywebpush
(DER base64url ключи), 404/410 — подписка удаляется, ретраи как у s2s.
PWA: manifest + sw.js (pass-through, push/notificationclick), иконки из
gnexus-mark.svg, /settings с личным пуш-блоком и админ-конфигами.
Миграция 0006 (ck_channel ×3 +push, app_settings, push_subscriptions).
Верификация: 47 бэкенд-проверок + mecheck/retcheck + 17 puppeteer — ALL OK.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
6 hours ago
|

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
8 hours ago
|
Админка по правкам владельца: детали, тултипы, читаемость
...
- Навигация: иконки ph-pulse/ph-shapes не было в шрифте Phosphor
из кита -> activity/squares-four; пункт топбара подписан префиксно
(детали не теряют текущий раздел).
- Удаления в таблицах — btn-icon вместо полнокровных кнопок.
- Источники: таблица только slug/название/создан; ключи, типы и
описание — на странице источника, токен показывается один раз.
- Цели: страница цели, config как код с подсветкой (CodeBlock).
- Правила: страница правила — условия по одному ключу с подписями
и подсветкой, действия целиком, шаблон; «W» -> «Вес» и тултипы
кита во всех спорных местах (вес, шумодав, условия, статусы).
- Время везде HH:MM:SS, D месяца (год, если не текущий).
- Доставки: фильтры вынесены из шапки, с подписями Статус/Канал.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
Админка SPA (#32): разделы Источники/Типы/Цели/Правила/Доставки
...
Маршруты + навигация в App.vue; ui.js — варианты статусов, формат
времени, JSON-обрезка. Токен ключа показывается один раз (модаль с
GnCopyButton), шумодав и switch вкл/выкл правила, s2s-target config в
JSON, фильтры доставок по статусу/каналу. Компоненты — из кита.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 hours ago
|
| 2026-10-02 |
SPA на каркасе gnexus-ui-kit: GnNavigationShell + GnPageHeader
...
- App.vue: каркас GnNavigationShell (topbar+drawer+footer), bare-страницы
входа/отсечения/коллбэка через route.meta.bare
- router.js: meta.bare для /login /denied /oauth/callback
- DashboardView: GnPageHeader + GnMetricCard/GnStatusCard, контент в #content
- frontend/public/assets/imgs/gnexus-mark.svg: логотип по контракту кита (/assets)
По канону vue-адаптера кита: только именованные импорты, иконки ph-*,
варианты primary/secondary/error/info, scoped-стили только на var(--gn-*).
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
|