Архитектура
Принятая архитектура · 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 | Владелец магазина; API | PHP 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 | Зарезервирован; ничего не запущено |
| API | 4142 | Интерактивное описание маршрутов — по адресу /api |
| Тестовые магазины | 4143, 4144 | OpenCart 3.0.3.5 и 3.0.5.1 |
| База данных API | 4145 | PostgreSQL в Docker |
| Документация | 4146 | Предпросмотр продакшн-сборки — на 4147 |
| Локальный дашборд | 4152 | Ссылки, состояние сервисов и логи для разработчика; не часть продукта |
| Сайт | 4148 |
Что читать дальше
- API — какие слайсы есть и как один запрос проходит через слои.
- Приложение — что человек может сделать сегодня и как приложение устроено.
- Админ-панель — что зарезервировано и что нужно решить до начала работы.
- Сайт — маркетинговый сайт: что на нём, как он устроен и что решить дальше.
- Документация — как устроен этот сайт и почему CleanSlice на него не распространяется.
- План реализации — целевой дизайн работы с каталогом, одобрений и задач; ничего из этого ещё не сделано.