architect/standards/PLATFORM2_LAYERS.md

PLATFORM 2: Архитектура слоёв и конфигурации

Версия: 1.0
Дата: 2026-03-14
Статус: draft


Содержание

  1. Стек компонентов
  2. Три уровня платформы
  3. Типы проектов
  4. Классы конфигурации
  5. Профили: стек наследования
  6. Файлы vs БД: правило разделения
  7. Компиляция профиля

1. Стек компонентов

┌─────────────────────────────────────────────────────┐
│                    NGINX                            │  Внешний вход
└────────────────────┬────────────────────────────────┘
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
   ┌─────────┐  ┌─────────┐  ┌──────────┐
   │ Refine  │  │FastAPI  │  │Supabase  │
   │ :3000   │  │ :8080   │  │ Studio   │
   └─────────┘  └────┬────┘  └──────────┘
                     │
        ┌────────────┼────────────┐
        ▼            ▼            ▼
   ┌─────────┐  ┌─────────┐  ┌──────────┐
   │Supabase │  │  Redis  │  │  Celery  │
   │ core    │  │ :6379   │  │ worker   │
   └─────────┘  └─────────┘  └──────────┘
        │
   ┌────┴──────────────────────────┐
   │ PostgreSQL · GoTrue · PostgREST│
   │ Storage · Realtime · Kong      │
   └───────────────────────────────┘

   ┌────────────────────────────────┐
   │ PostHog  · LiteLLM · Marimo   │  Расширения
   └────────────────────────────────┘

Что даёт каждый компонент

Компонент Роль
PostgreSQL Основная БД, RLS, multi-tenancy
PostgREST Auto REST API из схемы БД
GoTrue Аутентификация (JWT, OAuth, Magic Link)
Realtime WebSocket подписки на изменения
Storage Файлы (S3-совместимо)
FastAPI Кастомная бизнес-логика, state machines
Celery + Redis Фоновые задачи, очереди
Refine React UI, CRUD, дашборды
PostHog Feature flags per tenant + аналитика
LiteLLM AI прокси (Claude, другие модели)
Marimo Python-документы с формулами
Nginx Внешний entry point, SSL, роутинг

2. Три уровня платформы

┌────────────────────────────────────────────────────────────┐
│  УРОВЕНЬ 1: ИНФРАСТРУКТУРА                                 │
│  Как запущено. Конфигурация: файлы. Меняется редко.       │
│  docker-compose · .env · nginx.conf                        │
├────────────────────────────────────────────────────────────┤
│  УРОВЕНЬ 2: ПЛАТФОРМЕННОЕ ЯДРО                             │
│  Что установлено. Конфигурация: файлы + миграции.          │
│  Core schema · Base API · Refine shell                     │
├────────────────────────────────────────────────────────────┤
│  УРОВЕНЬ 3: ПРИЛОЖЕНИЕ                                     │
│  Что делает продукт. Конфигурация: профили → код + БД.    │
│  Schema · Routes · UI · Tasks · Rules                      │
└────────────────────────────────────────────────────────────┘

Уровень 1: Инфраструктура

Каждый компонент конфигурируется через env и свой config-файл:

Компонент Конфигурация
PostgreSQL POSTGRES_PASSWORD, POSTGRES_DB в .env
Supabase supabase/config.toml — JWT, auth providers, storage
FastAPI Pydantic Settings читает .env
Celery CELERY_BROKER_URL в .env
Refine NEXT_PUBLIC_SUPABASE_URL в .env
PostHog POSTHOG_KEY в .env
Nginx /etc/nginx/sites-enabled/*.conf

Всё в файлах под git. Ничего в БД.

Уровень 2: Платформенное ядро

Создаётся один раз при установке платформы.

Backend — системные таблицы:

-- migrations/0000_platform_core.sql
tenants       -- реестр тенантов
users         -- пользователи
sessions      -- сессии
audit_log     -- лог всех изменений
ui_config     -- хранилище UI конфигурации (SDUI)
feature_store -- локальное зеркало PostHog флагов

FastAPI — базовые модули:

fastapi/core/
  auth.py       ← GoTrue интеграция, JWT валидация
  tenant.py     ← middleware: tenant_id из JWT
  health.py     ← GET /health
  ui_config.py  ← GET /api/ui-config (для Refine)

Refine — оболочка (shell):

frontend/src/core/
  App.tsx           ← роутер, провайдеры
  AuthProvider.tsx  ← GoTrue
  DataProvider.tsx  ← Supabase + FastAPI
  UIProvider.tsx    ← читает /api/ui-config → рендерит

Refine состоит из двух частей:
- Shell (код) — не меняется между приложениями
- UI Config (из БД через API) — формы, меню, поля — меняется без деплоя

Уровень 3: Приложение

Конфигурируется через профили (см. раздел 5).


3. Типы проектов

Платформа одна. Проект стартует из шаблона который включает нужные компоненты.

# project.yaml — декларация проекта
name: my-project
type: worker | app | saas

Worker — бот, скрипт, интеграция

FastAPI → Celery → Redis → [Supabase опционально]

Нет UI, нет пользователей, нет тенантов.
Примеры: синхронизация 1С↔OZON, Telegram-бот, парсер, ночной импорт.

App — корпоратив / внутренний инструмент

Nginx → Refine → FastAPI → Supabase
                    ↓
               Celery + Redis (опционально)

Один тенант, пользователи внутри компании, простой RLS.
Примеры: каталог для сотрудников, внутренняя CRM, склад.

SaaS — мультитенант

Nginx → Refine → FastAPI → Supabase (RLS + tenant_id в JWT)
                    ↓
         Celery + Redis + PostHog + LiteLLM (опц.)

Много клиентов, каждый изолирован. Полная система профилей.
Примеры: CRM для дилеров, ERP как сервис, любой клиентский продукт.

Матрица компонентов

Worker App SaaS
FastAPI
Supabase опц.
Refine UI
Celery опц.
Multi-tenancy (RLS)
PostHog опц.
Профили опц.

4. Классы конфигурации

Профиль состоит из классов. Каждый класс конфигурирует конкретный компонент стека.

Граф зависимостей

EntityClass + TaxonomyClass + EnumClass   ← ФУНДАМЕНТ
    │
    ├── PipelineClass      (зависит от EntityClass)
    ├── RoleClass          (зависит от EntityClass)
    │     ├── PermissionClass
    │     └── VisibilityClass
    │
    ├── ValidationClass    (зависит от EntityClass + PipelineClass)
    ├── AutomationClass    (зависит от EntityClass + PipelineClass + RoleClass)
    │     └── NotifyClass
    │
    ├── FormClass          (зависит от EntityClass + RoleClass)
    ├── LabelClass         (зависит от EntityClass)
    └── ReportClass        (зависит от EntityClass + RoleClass)

FeatureClass               ← независимы, управляют всем выше

Классы → компоненты стека

Класс Компонент Что генерирует
EntityClass PostgreSQL + PostgREST CREATE TABLE, колонки, PostgREST expose
TaxonomyClass PostgreSQL справочные таблицы
RoleClass GoTrue + PostgreSQL роли в БД, RLS POLICY, JWT claims
PermissionClass FastAPI guard декораторы
VisibilityClass PostgreSQL RLS POLICY per role per table
PipelineClass FastAPI + Refine state machine, /transition, kanban
ValidationClass FastAPI + Refine guard при переходе, валидация формы
AutomationClass Celery + FastAPI tasks, beat schedule, event triggers
NotifyClass Celery + elements notification tasks, templates
FormClass БД ui_config конфиг формы (поля, порядок, секции)
LabelClass БД ui_config терминология (i18n)
ReportClass БД ui_config + FastAPI dashboard виджеты, /analytics
FeatureClass PostHog feature flags per tenant

Порядок применения (из зависимостей)

1. EntityClass + TaxonomyClass + EnumClass    schema
2. PipelineClass                               uses schema
3. RoleClass                                  abstract
4. PermissionClass + VisibilityClass          role + schema
5. ValidationClass + AutomationClass          schema + pipeline
6. FormClass + LabelClass + ReportClass       schema + role  в БД
7. NotifyClass                                automation + role
8. FeatureClass                               управляет всем

5. Профили: стек наследования

Концепция

Профиль — атомарный конфигурационный слой с одной ответственностью. Профили образуют стек, который применяется последовательно между Ядром и Тенантом.

ПЛАТФОРМА (уровень 2)
    └── ЯДРО (схема + правила мутабельности)
            └── [base-crm]         базовый (обязательный)
                    └── [automotive]    отраслевой
                            └── [ru-market]    региональный (опц.)
                                    └── [1c-integration]   тематический (опц.)
                                            └── ТЕНАНТ

Тенант объявляет стек в project.yaml:

profiles:
  - base-crm          # обязательно
  - automotive        # отрасль
  - ru-market         # регион
  - 1c-integration    # тема/интеграция

Типы профилей

Тип Примеры Ответственность
Base base-crm, base-erp Базовые сущности, роли, схема
Отраслевой automotive, retail Терминология, поля, воронки
Региональный ru-market, kz-market Валюта, адреса, налоги
Тематический 1c-integration, ozon Интеграции, доп. функции

Структура файла профиля

name: automotive
version: 1.0
type: industry
extends: base-crm          # зависимость

# ШАГ 1: DATA
data:
  entities:
    - name: deal
      fields:
        - name: truck_brand
          type: taxonomy_ref
          source: brands
          mutability_down: lock    # тенант не может удалить
        - name: mileage
          type: integer
  taxonomy:
    - name: brands
      values: [Volvo, Scania, MAN, Mercedes]
      mutability_down: extend      # тенант может добавить

# ШАГ 2: ACCESS
access:
  roles:
    - name: Manager
      permissions: [deals.*, contacts.read]
      visibility:
        deals: assigned_to = current_user
    - name: Logist
      permissions: [orders.*, warehouse.*]
  policy:
    tenant_max_grant: manager      # потолок прав тенанта

# ШАГ 3: PROCESS
process:
  pipelines:
    - entity: deal
      stages: [Новый, Диагностика, КП, Договор, Закрыт]
      transitions:
        Новый → Диагностика: always
        Диагностика → КП: require(mileage)
      mutability_down: extend      # тенант может добавить стадии
  automations:
    - trigger: deal.stage → КП
      action: notify(Director, "Новое КП #{deal.id}")

# ШАГ 4: UI (→ в БД)
ui:
  labels:
    deal: Заявка
    contact: Клиент
  forms:
    - entity: deal
      sections:
        - title: Грузовик
          fields: [truck_brand, mileage]
        - title: Сделка
          fields: [amount, stage, assigned_to]

# ШАГ 5: FEATURES
features:
  - name: pdf_export
    enabled: true
    mutability_down: override      # тенант может выключить
  - name: ozon_integration
    enabled: false
    mutability_down: override

Правила наследования мутабельности

Профиль может только сужать права вниз, никогда не расширять:

extend  → можно оставить extend, override или lock
override → можно оставить override или lock
lock    → всегда lock, нельзя открыть

Правила наследования ролей


6. Файлы vs БД: правило разделения

ЧТО                              ГДЕ          ПОЧЕМУ
────────────────────────────────────────────────────────────
Инфраструктура (.env, compose)   файлы        секреты, деплой
Структура БД (таблицы, RLS)      SQL файлы    нужна миграция
FastAPI маршруты и логика        Python код   требует деплой
Celery задачи                    Python код   требует деплой
────────────────────────────────────────────────────────────
Конфигурация форм                БД           меняется без деплоя
Лейблы / терминология            БД           per-tenant
Порядок полей                    БД           per-tenant
Навигация / меню                 БД           per-tenant
Отчёты / дашборды                БД           per-tenant
────────────────────────────────────────────────────────────
Feature flags                    PostHog      runtime вкл/выкл

Правило:
- Меняется при смене структуры → файлы (git → деплой → миграция)
- Меняется при смене настроек → БД (без деплоя)
- Меняется per-tenant → БД или PostHog (runtime)

Итоговая карта хранения

files/git                    БД (ui_config)           PostHog
─────────────────────────────────────────────────────────────
docker-compose.yml
.env
nginx.conf
supabase/config.toml
─────────────────
migrations/
  0000_core.sql              tenants
  0001_entities.sql          users
  0002_rls.sql               audit_log
  0003_taxonomy.sql          taxonomy_values
─────────────────                                 ────────────
fastapi/                     ui_config.forms       feature flags
  routes/                    ui_config.labels      per tenant
  pipelines/                 ui_config.navigation
  guards/                    ui_config.reports
─────────────────
celery/
  tasks/
  schedule.py
─────────────────
frontend/src/
  core/ (shell)               shell читает БД 

7. Компиляция профиля

Применить стек профилей = скомпилировать в конфиги компонентов.

[base-crm]
    ↓ merge
[automotive]
    ↓ merge
[ru-market]
    
profile.compile()
    
┌───────────────────────────────────────┐
│ migrations/                           │
│   001_entities.sql                    │
│   002_rls_policies.sql                │
│   003_taxonomy.sql                    │
│                                       │
│ fastapi/generated/                    │
│   routes_deal.py                      │
│   pipeline_deal.py                    │
│   guards.py                           │
│                                       │
│ celery/generated/                     │
│   tasks_automation.py                 │
│                                       │
│ db_seed/                              │
│   ui_config_forms.json                │
│   ui_config_labels.json               │
│   ui_config_navigation.json           │
│                                       │
│ posthog/                              │
│   flags.json                          │
└───────────────────────────────────────┘

Принцип: Профиль — декларация. Компилятор — генерирует конфиги компонентов.
Это как Terraform для бизнес-приложений: описываешь что хочешь, система генерирует инфраструктуру.


Ссылки

Документ Путь
Архитектура стека architect/standards/PLATFORM2_ARCHITECTURE.md
Dev Setup architect/standards/PLATFORM2_DEV_SETUP.md
Стандарт профилей architect/standards/PLATFORM2_PROFILES.md (следующий)