Архитектура работающего сервиса
Срез 01.11.2026: размещение и доступность компонентов проверены по SSH и HTTP. Здесь показаны работающие процессы и настроенные связи; планы развития — в модулях. Проверка гостевого BFF и владельцы сведений помогают перейти от схемы к каноническому описанию и нужному репозиторию.
| Где | Что работает | Граница |
|---|---|---|
| gateway | Caddy и BFF | HTTPS, HTML и /api/trpc; Go и БД отсюда вынесены |
| VPS2 | Go API, PostgreSQL 18, Redis 8 | Go доступен BFF по приватной сети; БД и Redis не публикуют host-порты |
| auxiliary | Caddy, hooks, Telegram proxy | Служебные интеграции отдельно от пользовательского запроса |
| S3 / CDN | Релизные JS/CSS, статика и продуктовые бакеты | Наличие и конфигурация подтверждены; пользовательский CRUD не проверен |
| GitHub Pages | Документация и OpenWiki | Отдельная публикация знаний, не часть запроса приложения |
Свидетельства проверки. На gateway запущены только Caddy/BFF; на VPS2 контейнеры Go/PostgreSQL/Redis healthy, pg_isready и Redis ping успешны. GET /health Go с gateway — 200. Публичный /login с Accept: text/html — 200; GET /api/trpc/users.me без X-CSRF — 403, с X-CSRF: 1 без сессии — 401.
| Компонент | Проверенная выложенная версия | Подтверждение |
|---|---|---|
| BFF | baf512e9 | Revision и digest живого контейнера, SSH 01.11.2026 |
| Go API | 6e1a0d81 | Успешный CI/CD, затем образ sha-6e1a0d8, healthy и HTTP 200 по SSH |
Digest BFF:
sha256:26205cff0bdfd9c1d74e9f23557d8c931c724b9573ee49ce1b6eec3748c233f3Границы проверки
Авторизованные сценарии — вход, работа с блокнотами, refresh/logout — не проверены этим срезом. RUNTIME_ENABLED=true в живом Go подтверждает включённый механизм, но создание, исполнение и удаление runtime-VPS не проверены. Восстановление продукта из backup также не проверено; backup auxiliary не доказывает backup PostgreSQL. SHA исходников подтверждает реализацию, а наблюдение на выложенной версии — только явно названный сценарий. Более свежий main сам по себе не обновляет это свидетельство.
Схемы хранятся в diagrams/, рендерятся eraser-diagrams. Масштаб — кнопками, Ctrl/⌘ + колесо или щипком; схему можно двигать. Ссылка «HTML» открывает её целиком.
Доступ к серверам
Три постоянные VPS имеют разные роли и маршруты подключения:
| Машина | Роль | Домен | Подключение |
|---|---|---|---|
| VPS1 | gateway | cellestial.ru | Прямой вход по SSH |
| VPS2 | backend | Публичного домена нет | По приватной сети через VPS1 (gateway) |
| VPS3 | auxiliary | hooks.cellestial.ru | Прямой вход по SSH |
Для входа используется пользователь deploy и личный авторизованный SSH-ключ участника. Доступ к репозиториям сам по себе не выдаёт доступ к серверам.
Актуальные IP-адреса, подготовка ключа, команды подключения и особенности Happ/VPN собраны в скилле cellestial-ops в приватном репозитории команды; для чтения нужен GitHub-доступ участника. Успешный вход по SSH подтверждает доступ к машине, а работоспособность приложения проверяется отдельным сценарием.
Размещение компонентов
Где работает сервис и как идёт запрос? Браузер обращается к Caddy/BFF на gateway, а BFF — к Go на VPS2. PostgreSQL и Redis находятся рядом с Go; auxiliary обслуживает интеграции отдельно. JS/CSS выбранного выпуска и общая статика приходят с CDN. Связь Go с S3 описывает конфигурацию, а не проверенный сценарий сохранения блокнота.
Источники: Compose и разделение сервисов, Caddy и маршруты BFF, upstream BFF.
Проверки CI
Кто что проверяет и публикует? Frontend CI проверяет код, а main publish с включённым флагом создаёт BFF image, S3-ассеты выбранного SHA и запись release-artifacts. Backend CI проверяет Go/runtime-agent/kernel images; публикация образов выполняется при push/main или workflow_dispatch независимо от PRODUCTION_ENABLED, который ограничивает production deploy. Публикация артефактов отделена от production CD. Course-sync копирует main командных frontend/backend в учебные репозитории при включённом COURSE_SYNC_ENABLED. В infra общие checks предшествуют двум отдельным путям: preview в PR и apply при push/main или ручном запуске на main. Docs собирает Pages и экспортирует существующие wiki. Frontend-packages публикует библиотеки/Vite plugin через npm OIDC, static загружает собственную статику в S3.
Источники: frontend checks/publish, backend jobs и course-sync, npm publishing, static Check/Upload, Pages: подготовка, экспорт и deploy, infra preview/apply.
Выкатка CD
Как выпуск становится работающим релизом? Frontend CD запускается вручную через workflow_dispatch: выбирает выпуск, проверяет BFF digest и связанные ассеты, вызывает Ansible и проверяет фактический результат. Rollback выбирает существующий выпуск из истории GitHub Deployments без пересборки. Сам main CI frontend не выкладывает. Backend CD после успешного main CI при PRODUCTION_ENABLED=true вызывает Ansible и обновляет Go на приватной VPS2 через SSH gateway; после backend #64 этот маршрут проверен успешной выкладкой и SSH-сверкой работающего образа. Миграции PostgreSQL выполняет Go при запуске. Откат BFF не откатывает БД. Infra Pulumi/Ansible управляет ресурсами и конфигурацией отдельно от этих выпусков.
Источники: ручной frontend CD, rollback, backend CD и known_hosts для jump, выбор backend-хоста, миграции при старте Go.
Фронтенд
Где менять frontend и его зависимости? Репозиторий frontend содержит apps/client, apps/bff и packages/schemas. Клиент использует командные React/router/zustand. Их исходники и Vite BFF HTML plugin принадлежат отдельному репозиторию frontend-packages, который публикует npm-пакеты; frontend потребляет версии этих пакетов. BFF отдаёт HTML с bootstrap и обслуживает tRPC, ведёт сессию и вызывает Go. HTML-шаблон входит в образ BFF, а JS/CSS выпуска загружаются через CDN. Это описание реализации; успешные авторизованные сценарии не подтверждены срезом.
Источники: зависимости клиента и Vite plugin, маршруты HTML/tRPC, серверная сессия, публикация библиотек.
Контракт и генерация
Какие контракты связывают стороны? Браузер работает с BFF через tRPC; BFF вызывает Go по HTTP-контракту OpenAPI из Apidog. Go использует oapi-codegen, а Orval создаёт fetch-client и Zod-схемы для BFF. Эти генераторы читают экспортированный snapshot, а не обращаются к Apidog при каждом пользовательском запросе. Backend Contract drift заново генерирует контракт и сравнивает его с репозиторием; отдельный frontend drift workflow в проверенном срезе отсутствует. Генерация, совпадение типов и drift не доказывают выкладку или работу пользовательского сценария.
Источники: Orval: клиент и Zod, CSRF и контекст tRPC, вызов Go, backend drift.
Инфраструктура
Кто управляет инфраструктурой и служебными потоками? Pulumi описывает облачные ресурсы, state хранится в отдельном проекте; Ansible настраивает серверы и Compose. Три постоянные VPS имеют разные роли. На auxiliary hooks использует SQLite/outbox и отправляет уведомления через Telegram proxy; Restic обслуживает данные auxiliary. Runtime включён в Go, его пользовательский сценарий остаётся непроверенным. Docs/Pages экспортирует существующие wiki, генерацию владелец запускает вручную.
Источники: распределение Ansible plays, auxiliary Compose, backup auxiliary, включение runtime, проект и бакет state, ресурсы и backup bucket, OpenStack runtime adapter, очередь и Telegram proxy.