API
Принятая архитектура · 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 — единственный сервис, который знает, кто этот человек, в какой он команде, что позволяет его роль и какие магазины команда подключила. Все остальные части спрашивают его. Больше никто к магазину не обращается.
Что он делает сегодня
- Аккаунты. Регистрация, вход, продление сессии, выход. Выход действует сразу: каждый запрос сверяется с живой сессией, а не только с токеном, который он несёт.
- Команды и роли. Магазины принадлежат команде. Её участники — владельцы (owner), админы (admin) и участники (member). Приглашают владельцы и админы; менять роли, убирать другого владельца и удалять команду может только владелец. Команду нельзя оставить без владельца.
- Магазины. Подключить магазин по одноразовому коду из его модуля, получить список магазинов команды, посмотреть один, отключить. Секрет, общий с магазином, хранится зашифрованным.
- Служебные проверки. Проверка «сервис жив» и интерактивное описание всех маршрутов.
| Область | Маршруты |
|---|---|
| Вход | /auth/register, /auth/login, /auth/refresh, /auth/logout, /auth/me |
| Свой профиль | /users/me |
| Команды | /teams, /teams/:teamId |
| Членство | /teams/:teamId/members, /teams/:teamId/members/:memberId |
| Магазины | /teams/:teamId/stores, /teams/:teamId/stores/connect, /teams/:teamId/stores/:storeId |
| Состояние | /health |
Регистрация, вход, продление сессии и проверка состояния открыты. Любой другой маршрут требует вошедшего человека.
Как устроен код
Весь код лежит в слайсах. Есть две группы слайсов функций и одна группа служебных.
api/src/slices/
setup/ общая инфраструктура, без бизнес-правил
prisma/ подключение к базе данных
error/ единый формат любой ошибки
response/ каждый успешный ответ — { data, success: true }
crypto/ шифрует сохранённые секреты подключений
core/ пометка для маршрутов, которым вход не нужен
health/ проверка состояния
user/ кто действует — папка-пространство имён, без кода
user/ человек
auth/ вход, сессии и проверка на каждом маршруте
team/ команда, которой принадлежат магазины
userTeam/ членство и роли
store/
store/ подключённый магазин и клиент для его модуляСлайс функции каждый раз имеет одну и ту же форму. Для примера — слайс магазина:
store/store/
store.module.ts связывает каждый контракт с его реализацией
store.controller.ts представление: маршруты, ввод, вывод
store.prisma таблицы этого слайса
dtos/ представление: формы запросов и ответов
domain/ правила и контракты
store.service.ts кто может подключать, какие адреса допустимы
store.gateway.ts контракт: сохранение и чтение магазинов
bridge.gateway.ts контракт: разговор с модулем магазина
store.types.ts
errors/ по файлу на каждую ошибку
data/ реализации
store.gateway.ts PostgreSQL через Prisma
store.mapper.ts строки базы в доменные типы
bridge.gateway.ts превращает ответы модуля в доменные результаты
repositories/bridge/ HTTP-клиент Bridge Protocol v1К базе данных шлюз обращается напрямую через Prisma; отдельного класса-репозитория для неё нет. С внешним сервисом иначе: модуль магазина обёрнут в репозиторий с собственными типами, чтобы формат протокола не попадал в правила.
Один запрос, слой за слоем
Владелец подтверждает подключение магазина. Вот что происходит с этим запросом.
- Проверка входа. До любого слайса проверка, зарегистрированная для всех маршрутов, устанавливает, кто обращается и что его сессия ещё жива.
- Контроллер. Принимает запрос, проверяет его форму и передаёт сервису. Правил в нём нет.
- Сервис — правила. Обращающийся должен быть владельцем или админом команды. Магазин должен быть доступен по HTTPS; обычный HTTP принимается только для локального адреса в разработке и тестах. Адрес, на который вернётся владелец, должен принадлежать тому же магазину, который подключается.
- Контракт моста. Сервис просит: «создай пару с этим магазином». Слой данных подписывает запрос и отправляет его. Ответ без действительной подписи считается «магазин недоступен», даже если магазин вернул статус успеха.
- Контракт магазина. Сервис просит: «сохрани этот магазин». Слой данных шифрует секрет и записывает строку. Прежнее подключение того же магазина помечается как отключённое.
- Контроллер. Возвращает магазин и адрес, на который нужно отправить владельца обратно.
Сервис не импортирует ни клиент базы данных, ни HTTP-клиент. Он знает два контракта и ничего о том, как они выполняются.
Правила для каждого слайса
- Папки слайсов — в единственном числе; маршруты — во множественном.
- Контракт — абстрактный класс в
domain/. Реализация лежит вdata/, а модуль слайса связывает одно с другим. - Слайс использует другой слайс через его домен. Слайс магазина спрашивает сервис членства, разрешена ли роль обращающегося; в чужой слой данных он не заглядывает.
- У каждого маршрута есть имя операции. Из него берутся названия методов сгенерированного клиента в приложении.
- Каждый маршрут требует входа, если явно не помечен как открытый.
- Каждый слайс владеет схемой своих таблиц. Скрипт собирает их в одну схему перед запуском инструментов базы данных.
- Импорты между слайсами идут через короткие псевдонимы —
#setup/…,#user/…,#store/…, — а не через длинные относительные пути.
Места, где этот API сознательно отходит от CleanSlice, перечислены в обзоре.
Как это проверяется
Сквозные сценарии выполняются на настоящем PostgreSQL в Docker, а не на заглушках. Сценариям магазинов нужны ещё и два запущенных локальных тестовых магазина. Последние записанные результаты — в плане репозитория, от 29 сентября 2026 года. Для этой страницы их заново не запускали.
Ещё не сделано
- Инструменты для агентов и любая связь с Agentfy.
- Чтение каталога магазина.
- Предложения цен, одобрения, задачи и журнал операций, описанные в плане реализации.
- Подтверждение email и сброс пароля.
- Ограничение числа попыток входа и регистрации.
- Ротация ключа, которым подписываются запросы подключения.
- Что-либо для операторов платформы. У каждого человека есть поле платформенной роли, но его ничто не выдаёт и ничто не проверяет. См. Админ-панель.
- Развёртывание. Хостинг не выбран.