This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Gnexus Synapse — централизованный хаб уведомлений экосистемы Gnexus. Любой сервис шлёт событие «что случилось» в Synapse, Synapse решает, кому, куда и каким каналом доставить: Telegram, Email, Push, внутренний лог, plus system-to-system доставка в Navi и другие сервисы. Цель — убрать из каждого сервиса (bugtrail, gntodo, smart-home, Navi-инстансы, gnexus-auth) собственные реализации уведомлений.
Стек: Python + FastAPI, SQLAlchemy + Alembic, Celery + Redis, PostgreSQL, Docker + docker-compose. Frontend админки — SPA на Vue 3 + Gnexus UI Kit.
Инфраструктурное решение: база берём с собой в докер — Postgres поднимается контейнером из docker-compose, отдельного продового сервера БД нет (на 100%). Тоже касается Redis. Скорость ответа приёма (202) — ключевой контракт Ingestion: тяжёлая работа только в воркерах.
Открытые вопросы — фиксировать выбранный вариант здесь и в описании задачи gntodo, после решения убрать из списка:
gnexus-auth — Laravel (PHP), токены opaque, не JWT: валидация только «call home» через GET /oauth/userinfo с Authorization: Bearer <token> (локальной проверки/JWKS нет; зато отзыв токена и блокировка пользователя видны сразу).
gnexus-gauth (репо gnexus-auth-client-py, зависимость только httpx): полный OAuth2 Authorization Code + PKCE, exchange/refresh/revoke, fetch_user() → AuthenticatedUser. Для SPA у gnexus-auth есть свой JS-клиент (packages/auth-client/, доки 18–20).superadmin > admin > user (глобальные), плюс клиентские (per-сервис slug'и, пока не используем). Доступ к админке = system_role in ("admin", "superadmin") — аналог SystemRole::canAccessAdminArea() на сервере auth.sub, email, system_role, profile, client.roles/permissions (scopes: openid email profile roles permissions). Access-токен живёт ~30 мин, есть refresh-ротация с детекцией переиспользования.app/api/auth_routes.py, клиент gnexus-gauth): GET /auth/login (state+PKCE в Redis, redirect на authorize) → GET /auth/callback (обмен кода, проверка роли до выдачи токена: не-админу access-токен сразу revoke) → SPA получает токены в URL-фрагменте #. Тихое обновление — POST /auth/refresh, логаут — POST /auth/revoke (revoke access-токена)..env, в UI авторизация никак не конфигурируется.GAUTH_VERIFY_TLS=false по умолчанию; в проде с нормальным сертификатом — true.store_login), а вебхук auth.logout/auth.global_logout/session.revoked отзывает их все. SPA-poll /api/v1/admin/me каждые 45 c: 401 → уход на /login. Выход из Synapse (POST /auth/logout) тоже отзывает входы пользователя; завершение самой SSO-сессии (RP-initiated logout) — TODO в gnexus-auth, зафиксировано в #32.http://gnexus-auth.local (в контейнерах — extra_hosts: host-gateway в compose), API на localhost:8012.Authorization: Bearer — cookie не годятся (сессия gnexus-auth не выходит за пределы auth-сервера); SPA-клиент хранит access/refresh сам (docs 18–20 описывают клиентскую сторону).Фронтенд-зависимость: npm install git+https://git.gnexus.space/git/root/gnexus-ui-kit.git — не в npm-registry, но dist/ и Vue-адаптер (src/vue/, экспорт gnexus-ui-kit/vue, peer-dep Vue ^3.4) закоммичены в репо кита, установка из git работает. Принцип: минимум своего, максимум из кита.
Правила (полный гайд — node_modules/gnexus-ui-kit/docs/ai-guide.md; в репо кита — docs/ai-guide.md и docs/catalog.json):
node_modules/gnexus-ui-kit/docs/catalog.json (need → component → props → useWhen). Если компонент для нужды есть — использовать его (GnButton, GnModal, GnStatusCard, GnMetricCard, GnNavigationShell для каркаса приложения, ...). В vanilla HTML — классы кита, не самодельные аналоги.icon="ph-house" в Vue, <i class="ph ph-house"></i> в HTML.primary, secondary, accent, success, warning, danger, error, info; не выдумывать свои.$color-*/$surface-* или CSS custom properties var(--gn-color-secondary), var(--gn-space-4), ...), никогда сырые hex. Отступы — шкала $space-1…$space-12, никакого произвольного пиксельного padding.focus_ring на :focus-visible у интерактивных элементов; hover — через hover_touch.docs/ai-guide.md → «Building a custom component in the GNexus style» (hard_panel, uppercase-заголовки, IBM Plex Mono — не переопределять font-family).admin и выше. Пользователя с ролью ниже — отсекать явной ошибкой (403 «недостаточно прав»), как на уровне API, так и в UI (гейт после логина). Своих паролей Synapse не хранит..env + репозиторий gnexus-creds, никогда не в этом репозитории.Self-hosted, open-source, бюджет-first, без платных SaaS. Простые прямые решения без оверинжиниринга. Веб-интерфейс при необходимости — PWA на Gnexus UI Kit.
API принимает событие → очередь → маршрутизация → доставка минимум в 2 канала (Telegram + внутренний лог) → лог доставки в БД; Navi получает уведомление system-to-system; docker-compose поднимает всё одной командой; README с quickstart.