Skip to content

Шари-слайси

Ця сторінка — звід правил: 8 груп, одне правило залежностей і ментальні моделі, які вирішують, куди йде новий код. Повний список усіх підслайсів — у Розборі слайсів; чому api взагалі влаштований так — в Огляді.

8 груп

Усередині api/src/slices/ кожен вертикальний слайс CleanSlice належить одній із 8 груп, упорядкованих від фундаменту до вершини:

#ГрупаОдна задача
L0infraадаптери до зовнішніх систем (БД · кеш · blob · вектор) — чисті I/O-драйвери, без домену
L0setupпламбінг фреймворку та експозиції (core = REST, mcp = MCP) — без власної здатності
L1systemспільні сервіси, кожен щось робить: заміряє, обмежує, сповіщає, інферить, зберігає файли
L2userідентичність і тенантність — тенант = команда
L3adminопс і аудит; читає дані інших груп через Prisma, нічого згори не імпортує
L4runtimeефемерний конвеєр виконання: черга → под → потік подій
L5agentдомен агента і мозок (orchestrator)
L6billingверхній стік — гроші; його не імпортує ніхто

Одне правило

Залежності йдуть лише вниз. Без циклів. Група може імпортувати лише групи нижче себе.

infra   ← ніхто
setup   ← (максимум) infra
system  ← infra · setup
user    ← system · setup · infra
admin   ← user (+ читає решту через Prisma)
runtime ← system · setup · infra            (жодних ребер в agent)
agent   ← runtime · system · user · …       (мозок тягнеться вниз до всіх)
billing ← system · user · notification      (ВЕРШИНА: billing не імпортує ніхто)

Інваріант примушується в CI (boundary-перевірка валить збірку на імпорті вгору — див. Реалізацію). Усе інше на цій сторінці відповідає на одне питання: в яку групу йде мій новий слайс?

В яку групу? — ментальні моделі

infra vs setup vs system:

  • infra = адаптери до зовнішніх систем (БД, кеш, blob, вектор). Чисті I/O-драйвери.
  • setup = пламбінг фреймворку/експозиції без власної здатності — експонує функціональність інших слайсів. core = REST-експозиція, mcp = MCP-експозиція.
  • system = спільні L1-сервіси, кожен з яких щось робить (записує / обмежує / сповіщає / інферить / зберігає).

system vs runtime:

  • system = стан і здатність (що істинно / фундаментально). Персистентно, низько.
  • runtime = механізм і дія (як виконується задача): черга → ефемерний под → стрим.

Тест на членство в system: L1-лист (залежності лише від infra/setup), який використовують кілька верхніх шарів. Тримайте критерій суворим, інакше system знову обросте в жирний смітник.

Ухвалені рішення (не переглядати без причини)

  • orchestrator — це мозок → живе в agent, не в runtime. Runtime = чисті механізми; мозок читає стан домену агента й ганяє механізми, тому сидить вище них.
  • billing — чистий стік → вершина (L6). Billing не імпортує ніхто; setting читає team.planId (який billing пише) замість імпорту billing (інверсія залежності).
  • llm і file — у system, не в runtime — фундаментальні здатності, які використовують багато шарів, а не частина конвеєра виконання. («Емітить usage» — не критерій сусідства.)
  • mcp лишається в setup, не в system — це транспорт, що експонує тули інших слайсів (близнюк REST у core), без власної здатності.
  • admin лишається внизу (L3), читаючи дані інших слайсів напряму через Prisma (без імпортів feature-модулів), — щоб не тягнути agent/runtime-залежності в низький шар.
Як ми до цього прийшли (перейменування 1.x → 2.0)

platform перейменовано в system. Стару жирну групу «account» розпущено: user, admin, billing стали власними групами; usage/setting/notification/llm/file — спільні L1-сервіси. publicApi розпущено (rate-limit → core, доставка вебхуків → notification, ключі вже в user/apiKey). runtime/artifacts влився в system/file.

Дивіться також

  • Розбір слайсів — усі підслайси кожної групи, по таблиці на групу.
  • Огляд — чому api — один образ із двома ролями.
  • Реалізація — build-prompt, що прошиває групи + CI boundary-перевірку.
  • Конвенції — правила CleanSlice всередині слайса (domain/data/dtos, шлюзи).