ADR-006: Live Data Layer для Reality Bridge
ADR-006: Live Data Layer для Reality Bridge
Дата: 2026-06-17 Статус: draft
Контекст
SprosOS строится как конституционно-управляемая система. Текущий фронтенд (63 страницы, System Console, offer flow) работает на localStorage и mock-данных. Для подключения реальных данных (1С, Яндекс.Метрика, сайт) нужен минимальный, но production-sane persistence-слой.
Проблемы текущей модели
- localStorage не переживает деплой, очистку браузера, смену пользователя
- Данные 1С (каталог: группы, товары, цены, остатки) не помещаются в localStorage
- Метрика (трафик по дням × страницам) — табличные данные большого объёма
- Sync logs и connector health требуют персистентности
- Product Binding (MetaProduct ↔ CatalogProduct ↔ SitePage) — реляционные связи
Решение
Выбор: PostgreSQL (via Neon/Supabase) + API Routes (Next.js)
PostgreSQL — прагматичный минимальный выбор:
- Реляционная модель идеально подходит для Reality Bridge сущностей
- Neon/Supabase дают serverless PostgreSQL без администрирования
- pgvector — опция для будущего semantic слоя
- Знакомый стек (уже есть в docker-compose проекта)
Альтернативы, которые рассматривались
| Вариант | Pros | Cons | Решение |
|---|---|---|---|
| SQLite | Нет сервера, файл | Не подходит для cloud-deploy, race conditions | ❌ |
| Supabase | Hosted Postgres + API + Auth | Vendor lock, costs | ✅ fallback |
| Neon | Serverless Postgres, branch per PR | Vendor lock | ✅ fallback |
| Firebase | Serverless | Не реляционная | ❌ |
| Локальный JSON/файлы | Просто | Нет запросов, нет sync, нет ACL | ❌ |
Решение: PostgreSQL, развёрнутый как Docker-контейнер на сервере (мастерхост? другой VPS?) или через Neon/Supabase для быстрого старта.
Архитектура
┌─────────────────────────────────────────────────────┐
│ Next.js App │
│ ┌─────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ UI Layer │ │ API Routes │ │ System │ │
│ │ (pages) │◄─┤ /api/v1/ │◄─┤ Console │ │
│ └─────────────┘ └──────┬───────┘ └───────────┘ │
│ │ │
└──────────────────────────┼──────────────────────────┘
│ fetch / server action
┌──────────────────────────▼──────────────────────────┐
│ PostgreSQL (Docker/Neon) │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Catalog │ │ Metrika │ │ Sync Logs │ │
│ │ Groups │ │ Metrics │ │ Connector Health │ │
│ │ Products │ │ Goals │ │ Bindings │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
└──────────────────────────────────────────────────────┘
Сущности (первая миграция)
См. docs/registries/entity-registry.yaml — Reality Layer секция:
CatalogGroup— группа товаров из 1СCatalogProduct— товар/SKUCatalogSyncRun— лог синхронизацииSitePage— страница сайтаSitePageLink— связка продукт↔страницаMetrikaCounter— счётчикTrafficMetricDaily— трафик по днямGoalMetricDaily— цели по днямMetrikaSyncRun— лог синхронизации МетрикиMetaProductBinding— связка MetaProduct ↔ Catalog ↔ Site ↔ MetrikaConnectorStatus— статус коннектора
Sync-модель
1С ──(n8n)──► CatalogSyncRun ──► CatalogGroup/CatalogProduct
│
Метрика ──(api)──► MetrikaSyncRun ──► TrafficMetricDaily / GoalMetricDaily
│
Сайт ──(parse)──► SitePage / SitePageLink ──► MetaProductBinding
- Каждый sync — отдельная запись с
started_at,finished_at,status,records_count - ConnectorHealth —
last_sync,last_error,uptime
Separation: live vs mock
- Mock-данные остаются в
src/data/mock*.ts— для разработки и UI preview - Live-данные в PostgreSQL — source of truth для прода
- UI сначала пытается читать из live-данных, fallback на mock если не подключено
- В System Console — переключатель
Data Source: Mock / Live
API маршруты (первые)
GET /api/v1/catalog/groups — все группы товаров
GET /api/v1/catalog/products — товары с фильтрами
GET /api/v1/catalog/sync/runs — история синхронизации
GET /api/v1/metrika/metrics — метрики по страницам/дням
GET /api/v1/metrika/sync/runs — история синхронизации
GET /api/v1/binding/meta-products — связки MetaProduct ↔ реальность
GET /api/v1/system/connectors — статусы всех коннекторов
Почему не Supabase сразу
- Supabase — хороший выбор для hosted, но добавляет vendor lock
- На данном этапе Docker-контейнер на сервере даёт больше гибкости
- Миграция на Supabase — всегда опция, если Docker-хостинг неудобен
Исполнение
- Создать миграцию с Reality Layer таблицами (Alembic / Prisma / raw SQL)
- Развернуть PostgreSQL (Docker или Neon)
- Создать API routes
/api/v1/catalog/*,/api/v1/metrika/*,/api/v1/system/connectors - Обновить UI — заменить чтение из localStorage на чтение из API
- Добавить fallback на mock в админке
- Добавить в System Console: переключатель источника, статусы
Решение
✅ PostgreSQL как базовый live data layer.
✅ n8n как оркестратор sync для 1С (или прямой Python worker).
✅ API Routes в Next.js для чтения данных.
✅ Mock-данные сохраняются как development fallback.
✅ Адресация — connector registry → API → DB.
Связанные документы
docs/reports/REPORT-LIVE-CONNECTORS-AUDIT.md— что вообще естьdocs/registries/entity-registry.yaml— entity definitionsdocs/registries/connector-registry.yaml— connector definitionsdocs/dna/product-dna.yaml— продуктовая DNA