Перейти к содержимому

Архитектура ​

Принятая архитектура · 1 октября 2026, вариант 2

Agentfy содержит harness; API Store Deputy предоставляет единый MCP; OpenCart-модуль — защищённый REST/JSON API. Store Deputy проверяет подключения, контекст сотрудника/покупателя, права, согласования и аудит, не создавая второй harness. Connect → вход/регистрация → безопасное подключение → автоматическое создание агента в Agentfy с MCP Store Deputy → возврат в модуль. В app: команды, агенты, аккаунт, биллинг и чат с каждым агентом.

Это заменяет предыдущее решение того же дня про MCP непосредственно в модуле. Код и прототипы ниже ещё не реализуют новую интеграцию. Сессии покупателей и настоящая корзина OpenCart имеют отдельную проверяемую привязку; cookie остаётся в магазине. См. решение о едином MCP: границы, этапы и оставшаяся работа над контрактом.

Состояние · 1 октября 2026. Код есть у трёх частей из пяти — у API, приложения и первого наброска сайта, — и работают они только на машине разработчика. Сайт документации опубликован. Админ-панель не создана. Ни один настоящий магазин не подключён: всё, что описано как сделанное, проверялось только на двух локальных тестовых магазинах.

Store Deputy состоит из пяти частей в одном репозитории — API, приложение, админ-панель, сайт и документация — и небольшого модуля, который ставится в магазин. Эти пять частей основатель назвал 1 октября 2026 года. Код следует CleanSlice — архитектурному стандарту, который проект использует для приложений на NestJS и Nuxt. CleanSlice охватывает API, приложение и админ-панель; маркетинговый сайт, сайт документации и код на PHP он не описывает, и на соответствующих страницах это сказано.

Части ​

ЧастьДля чегоКто пользуетсяНа чёмСостояние
APIЗнает людей, команды, роли и подключённые магазины. Единственная часть, которая обращается к магазинуПриложение; позже — админ-панель и агентыNestJS, Prisma, PostgreSQLОснова сделана; работает локально
ПриложениеЗдесь человек входит и подтверждает подключение магазинаВладельцы магазинов и их командыNuxt, Vue 3, Pinia, TailwindВход, регистрация и подключение сделаны; работает локально
Админ-панельПанель для тех, кто управляет самим Store DeputyОператоры платформыNuxt, если строить так, как описывает CleanSliceНе создана; объём не определён
СайтМаркетинговый сайт: то, что владелец магазина читает, прежде чем решить попробовать продуктПокупателиNuxt, Vue 3, TailwindСделан первый набросок: одна страница; работает локально
ДокументацияВнутренняя: исследования, решения, спецификации и прототипы дизайнаКоманда и агенты, работающие над продуктомVitePressОпубликована
Модуль магазинаУстанавливается в OpenCart. Выполняет подписанные запросы API и даёт владельцу кнопки Connect, Pause и DisconnectВладелец магазина; APIPHP 7.3+, OpenCart 3.0.3.5+Подключение сделано; запускалось только на локальных тестовых магазинах

Модуль магазина описан в REST 1.0 и здесь не повторяется.

Как части общаются ​

покупатель ─▶ сайт              маркетинговая страница
владелец ───▶ приложение ───┐   вход, регистрация, подключение
оператор ───▶ админ-панель ─┤   не создана
                            ▼
                           API ─────── PostgreSQL
                            │
                            │  Bridge Protocol v1: подписанные запросы
                            ▼
                  модуль в магазине (OpenCart 3)
  • Браузерные части общаются только с API. Клиент API в приложении генерируется из описания маршрутов, которое даёт сам API, а не пишется вручную.
  • К магазину обращается только API — по REST 1.0. Приложение никогда не вызывает магазин.
  • Подключение магазина проходит через три части. Владелец нажимает Connect в модуле магазина и попадает в приложение с одноразовым кодом. Приложение просит API подключить магазин. API отправляет модулю подписанный запрос, и владелец возвращается на страницу модуля, с которой начал.

Чего CleanSlice требует от кода ​

CleanSlice соединяет две идеи. Код сгруппирован по функциям, а внутри каждой функции разделён по ответственности.

  • Слайс — это одна функция в одной папке. Всё, что нужно функции, лежит вместе. Добавить функцию — значит добавить папку; понять функцию — значит прочитать одну папку.
  • Три слоя внутри слайса. Представление принимает ввод и оформляет вывод: контроллеры и формы запросов в API, страницы и компоненты в браузерном приложении. Домен содержит правила и контракты для всего внешнего. Данные выполняют эти контракты, обращаясь к базе или к другому сервису.
  • Правила не зависят от инфраструктуры. Доменный слой описывает, что ему нужно, в виде контракта — шлюза (gateway). Слой данных его реализует. Правило вроде «подключить магазин может только владелец или админ» читается и проверяется без базы данных и сети.
  • Служебные слайсы и слайсы функций. Служебные (setup) несут общую инфраструктуру: подключение к базе, формат ошибок, тему, клиент API. Слайсы функций несут сам продукт.
  • Связанные слайсы лежат в общей папке-пространстве имён. Вход, команды и членство собраны в user/. Сама родительская папка кода не содержит.
  • Слайсы встречаются через домен. Слайс может использовать правила и типы другого слайса, но не его слой данных.
  • Имена. Папки слайсов — в единственном числе (user, store); маршруты — во множественном (/teams).
  • Фиксированный стек. NestJS и Prisma для API; Nuxt, Vue 3, Pinia и Tailwind для браузерных приложений.
  • Четыре согласуемые фазы. Общий план, детальный план, реализация, обзор — каждая согласуется до начала следующей; сначала API, потом приложение.

Когда источники расходятся, порядок в этом репозитории такой: CleanSlice, затем руководство для агентов в репозитории, затем существующий код.

Где репозиторий отступает от CleanSlice ​

CleanSliceЗдесьПочему
Схемы баз данных из слайсов сшивает пакет prisma-importИх сшивает небольшой собственный скриптЗаписанная причина: пакет последний раз публиковался в феврале 2024 года под Prisma 4
Ошибки форматирует перехватчик (interceptor)Их форматирует глобальный фильтр исключенийПерехватчик не видит ошибку, брошенную проверкой входа, поэтому ответ «не вошёл» пришёл бы в другом формате
Стандарт NestJS показывает контроллер, вызывающий шлюз; страница о слоях — контроллер, вызывающий сервисВезде контроллер → сервис → шлюзПравила ролей — это бизнес-правила, их место в сервисе
В эталонном приложении есть служебный слайс внедрения зависимостейВ приложении его нетПока не нужен. Сам CleanSlice оставляет его для слайсов, которым нужны подменные или офлайн-реализации
Компоненты интерфейса генерирует shadcn-vueПять компонентов написаны вручную в том же стилеРешение от 29 сентября 2026 года. Вернуться к shadcn-vue, когда понадобятся диалоги, меню или таблицы
В каждой папке компонентов есть Provider.vueВ папке общей шапки страницы его нетЗамечено 1 октября 2026 года; как решение не записано

Локальные адреса ​

Всё ниже — машина разработчика. Публичного адреса у продукта нет.

ЧастьПортПримечание
Приложение4140
Админ-панель4141Зарезервирован; ничего не запущено
API4142Интерактивное описание маршрутов — по адресу /api
Тестовые магазины4143, 4144OpenCart 3.0.3.5 и 3.0.5.1
База данных API4145PostgreSQL в Docker
Документация4146Предпросмотр продакшн-сборки — на 4147
Локальный дашборд4152Ссылки, состояние сервисов и логи для разработчика; не часть продукта
Сайт4148
  • API — какие слайсы есть и как один запрос проходит через слои.
  • Приложение — что человек может сделать сегодня и как приложение устроено.
  • Админ-панель — что зарезервировано и что нужно решить до начала работы.
  • Сайт — маркетинговый сайт: что на нём, как он устроен и что решить дальше.
  • Документация — как устроен этот сайт и почему CleanSlice на него не распространяется.
  • План реализации — целевой дизайн работы с каталогом, одобрений и задач; ничего из этого ещё не сделано.