| 2026-10-03 |
feat: валидация payload.user_id и ретеншн (ttl_seconds, RETENTION_DAYS)
...
- Routing: _user_recipient() — субьектом user-канала принимается непустая
строка/число; массив/объект/bool → skipped-доставка с причиной (аудит),
а не «delivered в никуда».
- ttl_seconds стал действующим: воркер не маршрутизирует истёкшее событие
(новый статус expired, миграция 0005 пересоздаёт ck_event_status).
- Beat-задача synapse.expire_events (ежечасно): удаление событий с
истёкшим ttl и старше RETENTION_DAYS (дефолт 30; 0 — окно отключено),
deliveries каскадом.
- ui.js: бейдж expired; docs/05: «Ретеншн», формат значения payload.user_id.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
8 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
|
Правки второй волны: редактирование цели, вёрстка, тултипы, ссылки
...
- Цель: PATCH /admin/targets/{id} (частичное обновление, канал не
меняется; 409 на дубль имени в канале) + редактирование на странице
цели: название/описание/config-JSON с валидацией, switch вкл/выкл.
- Тултипы заголовков таблиц: панель кита раскрывается ВНИЗ поверх
таблицы — иначе обрезается overflow у .table-wrapper.
- Правила: колонка «Условия» из таблицы убрана (только на странице
правила); вёрстка действий на странице правила починена — голова
(номер/канал/цель) и тело (шаблон) в отдельные строки.
- Доставки: кнопка обновления выровнена по вертикали с контролами
фильтров.
- Источники/цели: у строк убрана кнопка просмотра; slug/название —
кликабельная ссылка на страницу, удаление — единственная кнопка.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
13 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
|