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

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; отдельного класса-репозитория для неё нет. С внешним сервисом иначе: модуль магазина обёрнут в репозиторий с собственными типами, чтобы формат протокола не попадал в правила.

Один запрос, слой за слоем ​

Владелец подтверждает подключение магазина. Вот что происходит с этим запросом.

  1. Проверка входа. До любого слайса проверка, зарегистрированная для всех маршрутов, устанавливает, кто обращается и что его сессия ещё жива.
  2. Контроллер. Принимает запрос, проверяет его форму и передаёт сервису. Правил в нём нет.
  3. Сервис — правила. Обращающийся должен быть владельцем или админом команды. Магазин должен быть доступен по HTTPS; обычный HTTP принимается только для локального адреса в разработке и тестах. Адрес, на который вернётся владелец, должен принадлежать тому же магазину, который подключается.
  4. Контракт моста. Сервис просит: «создай пару с этим магазином». Слой данных подписывает запрос и отправляет его. Ответ без действительной подписи считается «магазин недоступен», даже если магазин вернул статус успеха.
  5. Контракт магазина. Сервис просит: «сохрани этот магазин». Слой данных шифрует секрет и записывает строку. Прежнее подключение того же магазина помечается как отключённое.
  6. Контроллер. Возвращает магазин и адрес, на который нужно отправить владельца обратно.

Сервис не импортирует ни клиент базы данных, ни HTTP-клиент. Он знает два контракта и ничего о том, как они выполняются.

Правила для каждого слайса ​

  • Папки слайсов — в единственном числе; маршруты — во множественном.
  • Контракт — абстрактный класс в domain/. Реализация лежит в data/, а модуль слайса связывает одно с другим.
  • Слайс использует другой слайс через его домен. Слайс магазина спрашивает сервис членства, разрешена ли роль обращающегося; в чужой слой данных он не заглядывает.
  • У каждого маршрута есть имя операции. Из него берутся названия методов сгенерированного клиента в приложении.
  • Каждый маршрут требует входа, если явно не помечен как открытый.
  • Каждый слайс владеет схемой своих таблиц. Скрипт собирает их в одну схему перед запуском инструментов базы данных.
  • Импорты между слайсами идут через короткие псевдонимы — #setup/…, #user/…, #store/…, — а не через длинные относительные пути.

Места, где этот API сознательно отходит от CleanSlice, перечислены в обзоре.

Как это проверяется ​

Сквозные сценарии выполняются на настоящем PostgreSQL в Docker, а не на заглушках. Сценариям магазинов нужны ещё и два запущенных локальных тестовых магазина. Последние записанные результаты — в плане репозитория, от 29 сентября 2026 года. Для этой страницы их заново не запускали.

Ещё не сделано ​

  • Инструменты для агентов и любая связь с Agentfy.
  • Чтение каталога магазина.
  • Предложения цен, одобрения, задачи и журнал операций, описанные в плане реализации.
  • Подтверждение email и сброс пароля.
  • Ограничение числа попыток входа и регистрации.
  • Ротация ключа, которым подписываются запросы подключения.
  • Что-либо для операторов платформы. У каждого человека есть поле платформенной роли, но его ничто не выдаёт и ничто не проверяет. См. Админ-панель.
  • Развёртывание. Хостинг не выбран.

Протокол модуля ↔ API: REST 1.0