KNOTTA research & development

Архитектура платформы

Высокоуровневая архитектура NG-Metrics — пять сервисов, роли, поток данных и принципы разделения ответственности.

Архитектура платформы

NG-Metrics состоит из пяти независимых сервисов, каждый со своим репозиторием, стеком и менеджером пакетов. Все они работают как Docker-контейнеры на одном хосте и связаны общей сетью ng_metrics.

Карта сервисов

СервисДиректорияСтекЯзыкМенеджер пакетов
Frontendfrontend/Next.js 15, Tailwind CSS 4, Supabase AuthTypeScriptYarn 1.22
Backend (Garden)garden/Django 5.2, DRF, PostgreSQLPython 3.13UV
Telegram-ботbot/Aiogram 3.20, FastAPI, SQLAlchemyPython 3.12UV
Supabasesupabase/PostgreSQL 17, Deno edge functionsTypeScriptSupabase CLI
Инфраструктураansible/Ansible 11.1, DockerPython 3.12Poetry

Высокоуровневая схема

Загрузка диаграммы…

Принципы разделения ответственности

Backend (Garden) — единственный владелец схемы БД и миграций. Telegram-бот зеркалирует модели через SQLAlchemy в режиме «только чтение» и никогда не создаёт миграции. Когда нужна новая модель — создаём в Django, прогоняем миграции, обновляем SQLAlchemy-модели в боте.

Supabase — инфраструктурный слой. Он предоставляет PostgreSQL (как БД для Django), Auth (как источник JWT), S3-хранилище (для файлов отчётов) и Edge Functions (как webhook-handler для Auth-событий и транзакционных писем). Бизнес-логика на стороне Supabase минимальна.

Frontend — тонкий клиент. Next.js обращается к Django REST API за данными и к Supabase Auth за токенами. Никаких прямых SQL-запросов к Supabase из фронта нет — всё проходит через Django.

Telegram-бот — изолированный транспорт. Бот не принимает решений о маршрутизации уведомлений. Он только читает Redis Stream и отправляет в Telegram. Решение «кто и через какие каналы получит уведомление» принимает Django (модуль notification).

Поток аутентификации

  1. Пользователь входит на фронтенде через Supabase Auth (email + password / OAuth / magic link).
  2. Supabase отправляет webhook → Edge Function auth-sync → POST в Django (/api/auth/...) — Django создаёт или обновляет соответствующую запись User. Связь идёт через User.supabase_uid.
  3. На каждый запрос к Django фронт прикрепляет Authorization: Bearer <jwt>.
  4. Django валидирует JWT через SupabaseAuthentication (modules/shared/auth/rest.py) — проверяет подпись, истечение, достаёт supabase_uid и подгружает User.
  5. Роль (User.role) синхронизируется в обе стороны: для смены роли вызывается Edge Function set-role, которая обновляет app_metadata.role в Supabase Auth, а Django хранит роль в своём поле.

Что читать дальше

На странице