Документация АПИ Project+apps
API Project+apps принимает управленческий слой целиком: core-объекты портфеля, канон и summary-сущности. Сырые события, установки, отзывы, логи и выгрузки рекламных кабинетов сюда не отправляются.
Подключение
Для локальной разработки используем http://127.0.0.1:8010. Публичный прод-контур живёт на https://apps.farmchel.org. MCP и API должны подключаться к тому контуру, в котором реально запущено приложение.
Accept: application/json
Content-Type: application/json
X-Project-Apps-Token: <выданный токен>
X-Project-Apps-Token или с неверным токеном API возвращает 403.PROJECT_APPS_MCP_WRITE_ENABLED=false — write-tools не регистрируются, запись только через этот API.php artisan project-apps:reconcile-legacy-directions --dry-run (карта slug → slug в config/project_apps.php → legacy_direction_slug_map или env PROJECT_APPS_LEGACY_DIRECTION_MAP=old:fitness).arguments в tool call, запись в Project+apps нужно делать через этот API, а не через MCP write-tools.Контракт для агентов
Правильная модель интеграции для внешних агентов: MCP для чтения, API для записи.
- Через MCP агент читает контекст системы, канон, карту портфеля и ищет существующие продукты.
- Через API агент создаёт и обновляет продукты, приложения, решения, задачи и канонические правила.
- Через API агент также пишет summary-слой:
signals,insights,economics. - Перед записью агент должен сначала читать
/api/project-apps/directionsили ресурсproject-apps://portfolio, чтобы использовать только допустимыеdirection_slug. - Перед записью агент должен проверить через MCP или API, существует ли объект, чтобы не создавать дубль.
- Для продуктов опорный идентификатор —
slug. - Для приложений опорный идентификатор —
slug,bundle_id,package_idиstore_url. - Для одной и той же
platformне допускаются два приложения с одинаковым непустымbundle_idилиpackage_id— сервер вернёт422.
Модель портфеля
Project+apps выражает мобильный контур по слоям: направление → продукт → приложение.
- Направление — управленческий контур и общий рынок/тезис.
- Продукт — самостоятельный продуктовый смысл со своим фокусом, решениями и economics.
- Приложение — реализация продукта или временный хвост направления, если продукт ещё не подтверждён.
Quit Alcohol / Quit Smoking можно хранить как app-кандидаты на уровне направления через product_binding_status, не создавая грязный псевдопродукт раньше времени.Канонический перечень направлений Farmchel
Эталонные direction_slug для мобильного портфеля (строки в БД могут включать и демо-направления вроде watches или sales-support):
utilities, documents, documents-qr, parental-family-safety, fitness, fitness-cognitive, wellness-habit-change, wellness-mental, lifestyle-content, wellness-lifestyle, security-privacy
POST /products или спорным POST /apps всё равно вызывайте GET /directions: в ответе есть и фактические записи, и поле reference.canonical_direction_slugs.Генерация API-токенов
Токен выдаётся каждому API-агенту, который пишет управленческий слой в Project+apps. Реальные токены нельзя хранить в git, README, задачах, скриншотах или публичной документации.
/admin/api-agent-tokens. Полный секрет показывается только один раз сразу после создания.1. Сгенерировать токен
php artisan project-apps:token metrika-agent
Команда выведет безопасное значение вида pa_... и готовую строку для окружения.
2. Подключить одного агента
PROJECT_APPS_INGEST_TOKEN=pa_сгенерированный_токен
3. Подключить несколько агентов
PROJECT_APPS_INGEST_TOKENS=pa_токен_метрики,pa_токен_финансов,pa_токен_store
4. Передавать токен в каждом запросе
X-Project-Apps-Token: pa_сгенерированный_токен
- Для каждого внешнего API-агента лучше выдавать отдельный токен.
- При компрометации удалите старый токен из
PROJECT_APPS_INGEST_TOKENS, сгенерируйте новый и перезапустите приложение. - После изменения токенов очистите конфиг, если он кешировался:
php artisan config:clear. - MCP endpoint остаётся отдельным каналом чтения контекста; входящие API-записи от агентов принимаются только через токен.
Эндпоинты
| Метод | Local / Public URL | Назначение |
|---|---|---|
GET |
http://127.0.0.1:8010/api/project-apps/summaryhttps://apps.farmchel.org/api/project-apps/summary |
Верхняя сводка портфеля без сырой первички: здоровье, продукты, тренды, риски, точки роста и блок внимания. |
GET |
http://127.0.0.1:8010/api/project-apps/directionshttps://apps.farmchel.org/api/project-apps/directions |
Прочитать допустимые направления, их slug и портфельный слой перед созданием продуктов и спорных приложений. |
GET |
http://127.0.0.1:8010/api/project-apps/productshttps://apps.farmchel.org/api/project-apps/products |
Найти существующие продукты по slug, имени, направлению и статусу; фильтр is_favorite (boolean) ограничивает выборку избранными. |
GET |
http://127.0.0.1:8010/api/project-apps/appshttps://apps.farmchel.org/api/project-apps/apps |
Найти существующие приложения по slug, product_slug, package_id, bundle_id, store_url и привязке. |
POST |
http://127.0.0.1:8010/api/project-apps/signalshttps://apps.farmchel.org/api/project-apps/signals |
Приём точки роста, проблемы или риска из нижней системы. |
POST |
http://127.0.0.1:8010/api/project-apps/insightshttps://apps.farmchel.org/api/project-apps/insights |
Приём продуктового вывода: что стало понятно и какое действие рекомендуется. |
POST |
http://127.0.0.1:8010/api/project-apps/economicshttps://apps.farmchel.org/api/project-apps/economics |
Приём экономической summary-сводки по продукту или направлению за период. |
POST |
http://127.0.0.1:8010/api/project-apps/productshttps://apps.farmchel.org/api/project-apps/products |
Создать продукт как рабочий объект: портфельный статус, фокус, монетизация, здоровье и следующий шаг. |
PATCH |
http://127.0.0.1:8010/api/project-apps/products/{product}https://apps.farmchel.org/api/project-apps/products/{product} |
Обновить продукт: статус, фокус, денежность, риск, шанс роста и паспорт здоровья. |
POST |
http://127.0.0.1:8010/api/project-apps/appshttps://apps.farmchel.org/api/project-apps/apps |
Создать приложение как реализацию продукта: платформа, store links, bundle ID, package ID и статус реализации. |
PATCH |
http://127.0.0.1:8010/api/project-apps/apps/{mobileApp}https://apps.farmchel.org/api/project-apps/apps/{mobileApp} |
Обновить приложение: реализацию продукта, платформу, store links и идентификаторы публикации. |
POST |
http://127.0.0.1:8010/api/project-apps/decisionshttps://apps.farmchel.org/api/project-apps/decisions |
Записать жёсткое решение: что решили, почему, кто владелец и когда пересмотр. |
POST |
http://127.0.0.1:8010/api/project-apps/taskshttps://apps.farmchel.org/api/project-apps/tasks |
Создать рабочую задачу, вытекающую из решения, продукта, направления или приложения. |
GET |
http://127.0.0.1:8010/api/project-apps/canon-ruleshttps://apps.farmchel.org/api/project-apps/canon-rules |
Прочитать канон Project+apps: постоянные правила о продуктах, заморозке и структуре портфеля. |
POST |
http://127.0.0.1:8010/api/project-apps/canon-ruleshttps://apps.farmchel.org/api/project-apps/canon-rules |
Создать каноническое правило: что считать продуктом, что заморожено и какие правила структуры постоянны. |
PATCH |
http://127.0.0.1:8010/api/project-apps/canon-rules/{canonRule}https://apps.farmchel.org/api/project-apps/canon-rules/{canonRule} |
Обновить каноническое правило внутри apps. |
Коды ответов
200— read endpoint или update endpoint успешно отработал.201— сигнал, инсайт, экономика, продукт, приложение, решение, задача или каноническое правило созданы.403— неверный или отсутствующийX-Project-Apps-Token.422— payload не прошёл валидацию.503— токен API не настроен на стороне сервера: не заполненыPROJECT_APPS_INGEST_TOKENилиPROJECT_APPS_INGEST_TOKENS.
422 ожидаем не только на пустых полях, но и на конфликте модели: например, если агент пытается отправить product_binding_status=confirmed без продукта или дублирует технический store identity внутри одной платформы.Как агенту узнать допустимые направления
GET http://127.0.0.1:8010/api/project-apps/directions
X-Project-Apps-Token: <выданный токен>
reference.canonical_direction_slugs — эталонный список slug для мобильного контура Farmchel.Список продуктов (поиск перед записью)
GET http://127.0.0.1:8010/api/project-apps/products?direction_slug=fitness&portfolio_status=core&is_favorite=1&limit=25
X-Project-Apps-Token: <выданный токен>
Основные query-параметры
slug— точный slug продукта.direction_slug— фильтр по направлению.name— подстрока в названии.portfolio_status—core,next,rebuild,freeze.is_favorite—1/0или boolean: только избранные в админке.limit— максимум записей (по умолчанию до 25).
is_favorite — состояние «звезды» в админке.Получить сводку портфеля
GET http://127.0.0.1:8010/api/project-apps/summary
X-Project-Apps-Token: <выданный токен>
Фрагмент ответа
{
"message": "Сводка Project+apps без сырой первички.",
"portfolio": {
"health": "Требует внимания",
"directions_count": 4,
"products_count": 9,
"apps_count": 7,
"critical_problems": 1,
"key_growth_points": 2
},
"need_attention": [
{
"title": "Раскрыть внутреннюю карту часов",
"severity": "high",
"recommended_action": "Уточнить приложения, выплаты и store-подтверждение."
}
],
"canon": [
{
"title": "Что считать отдельным продуктом",
"type": "Критерий продукта"
}
]
}
Пример сигнала
POST http://127.0.0.1:8010/api/project-apps/signals
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"signal_type": "problem",
"source_layer": "metrika",
"severity": "high",
"status": "open",
"title": "Удержание второй вариации ниже ожидания",
"body": "В сводке поведения видно, что пользователи быстрее бросают тренировочный сценарий.",
"recommended_action": "Сравнить onboarding двух вариаций и вынести решение по продуктовой гипотезе."
}
Обязательные поля
signal_type:growth,problem,riskилиopportunity.source_layer: источник summary-сигнала, напримерmetrika,store,acquisition,finance.severity:low,medium,highилиcritical.titleи хотя бы одно изbody/recommended_action: управленческий смысл, а не сырой лог.
Пример инсайта
POST http://127.0.0.1:8010/api/project-apps/insights
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"source_layer": "metrika",
"confidence_level": "medium",
"impact_level": "high",
"title": "Вторая вариация отжиманий слабее удерживает пользователя",
"body": "После onboarding пользователи чаще обрывают тренировочный сценарий. Поведенческая summary показывает разницу между вариациями без передачи сырых событий.",
"discovered_at": "2026-04-08"
}
Пример экономической сводки
POST http://127.0.0.1:8010/api/project-apps/economics
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"economics_status": "unconfirmed",
"confidence_level": "medium",
"title": "Отжимания: сводка экономики за период",
"period_start": "2026-04-01",
"period_end": "2026-04-08",
"acquisition_summary": "Стоимость установки требует проверки по качеству трафика.",
"behavior_summary": "Поведение отличается между вариациями.",
"store_confirmation_summary": "Нужны рейтинг, отзывы и выплаты.",
"roi_summary": "Рентабельность пока не подтверждена.",
"conclusion": "Не масштабировать без подтверждения магазина приложений."
}
Создать продукт
POST http://127.0.0.1:8010/api/project-apps/products
X-Project-Apps-Token: <выданный токен>
{
"direction_slug": "fitness",
"name": "Бег",
"portfolio_status": "next",
"product_focus": "assess-development",
"summary": "Кандидат в новый фитнес-продукт.",
"is_revenue_generating": false,
"is_favorite": true,
"monetization_model": "Пока не подтверждена",
"health_state": "На проверке",
"risk_summary": "Не собрана app map и economics.",
"growth_chance": "Есть соседний спрос внутри фитнес-контура.",
"next_step": "Проверить app map и economics."
}
Обязательные поля
direction_idилиdirection_slug.name.portfolio_status:core,next,rebuild,freeze.
Фокус продукта
increase-monetization— усиливать монетизацию.rewrite— переписывать.assess-development— оценивать разработку.scale— масштабировать.leave-as-is— не трогать.
Обновить продукт
PATCH http://127.0.0.1:8010/api/project-apps/products/{product}
X-Project-Apps-Token: <выданный токен>
{
"portfolio_status": "core",
"product_focus": "scale",
"is_revenue_generating": true,
"is_favorite": true,
"monetization_model": "Подписка",
"health_state": "Стабильный рост",
"health_summary": "Экономика подтверждена, продукт можно усиливать.",
"next_step": "Подтвердить план роста и store map."
}
Записать решение
POST http://127.0.0.1:8010/api/project-apps/decisions
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"title": "Масштабировать после подтверждения stores",
"decision_type": "scale",
"owner": "Growth",
"decision": "Не масштабировать без store truth.",
"rationale": "Требуются точные названия и подтверждение выплат.",
"review_at": "2026-04-30",
"tasks": [
{
"title": "Проверить store truth по Отжиманиям",
"owner": "Growth",
"priority": "high"
}
]
}
Типы решений
focusscalestopretestpositioninginvestment
Создать приложение
POST http://127.0.0.1:8010/api/project-apps/apps
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"name": "Отжимания Android",
"platform": "Android",
"implementation_status": "building",
"store_url": "https://play.google.com/store/apps/details?id=org.farmchel.pushups.android",
"bundle_id": "org.farmchel.pushups.android",
"package_id": "org.farmchel.pushups.android"
}
Спорный хвост без подтверждённого продукта
{
"direction_slug": "fitness",
"name": "Quit Alcohol Android",
"platform": "Android",
"implementation_status": "building",
"product_binding_status": "product-candidate",
"product_candidate_name": "Quit Alcohol",
"package_id": "org.farmchel.quit.alcohol",
"portfolio_note": "Пока неясно, это отдельный продукт или приложение существующего продукта."
}
confirmed— приложение уже связано с подтверждённым продуктом.needs-product— приложение точно живёт в направлении, но продукт ещё не оформлен.product-candidate— приложение может оказаться отдельным продуктом после проверки.
Создать задачу
POST http://127.0.0.1:8010/api/project-apps/tasks
X-Project-Apps-Token: <выданный токен>
{
"product_slug": "push-ups",
"product_decision_id": 12,
"title": "Собрать store links по Отжиманиям",
"owner": "Operations",
"status": "open",
"priority": "high",
"due_at": "2026-04-20"
}
Статусы задачи
openin-progressblockeddone
Создать каноническое правило
POST http://127.0.0.1:8010/api/project-apps/canon-rules
X-Project-Apps-Token: <выданный токен>
{
"title": "Один продукт может иметь несколько приложений",
"rule_type": "product-definition",
"body": "Продукт не равен одному приложению, если смысл общий и решения принимаются на уровне продукта."
}
rule_type: product-definition, portfolio-structure, freeze-policy, direction-policy, summary-contract, portfolio-governance. Устаревшее значение structure-canon при записи нормализуется в portfolio-structure.direction_id / direction_slug и product_id / product_slug — область правила (портфель, направление или продукт). Продукт должен принадлежать указанному направлению, если заданы оба уровня.Прочитать канон
GET http://127.0.0.1:8010/api/project-apps/canon-rules?status=active
X-Project-Apps-Token: <выданный токен>
{
"message": "Канонические правила Project+apps.",
"rules": [
{
"title": "Что считать отдельным продуктом",
"rule_type": "product-definition",
"status": "active"
}
]
}
Что не отправлять
- Сырые события аналитики и клики пользователей.
- Сырые установки, показы, поисковые таблицы и рекламные выгрузки.
- Сырые отзывы, store dumps и технические логи.
- Данные, по которым нельзя сразу принять продуктовый вывод или решение.