Project+apps

Документация АПИ Project+apps

API Project+apps принимает управленческий слой целиком: core-объекты портфеля, канон и summary-сущности. Сырые события, установки, отзывы, логи и выгрузки рекламных кабинетов сюда не отправляются.

Local URL: http://127.0.0.1:8010 Public URL: https://apps.farmchel.org Заголовок: X-Project-Apps-Token Формат: JSON Уровень: summary

Подключение

Для локальной разработки используем http://127.0.0.1:8010. Публичный прод-контур живёт на https://apps.farmchel.org. MCP и API должны подключаться к тому контуру, в котором реально запущено приложение.

Accept: application/json
Content-Type: application/json
X-Project-Apps-Token: <выданный токен>
API-агенты подключаются только через токен. Без заголовка X-Project-Apps-Token или с неверным токеном API возвращает 403.
MCP вынесен в отдельную страницу: Документация MCP.
Жёсткий режим «только чтение в MCP»: PROJECT_APPS_MCP_WRITE_ENABLED=false — write-tools не регистрируются, запись только через этот API.
Перенос продуктов с legacy-направления: php artisan project-apps:reconcile-legacy-directions --dry-run (карта slug → slug в config/project_apps.phplegacy_direction_slug_map или env PROJECT_APPS_LEGACY_DIRECTION_MAP=old:fitness).
Короткий рабочий протокол для внешнего ИИ-агента вынесен отдельно: Контракт для агента.
Если агентный MCP-коннектор не умеет передавать arguments в tool call, запись в Project+apps нужно делать через этот API, а не через MCP write-tools.

Контракт для агентов

Правильная модель интеграции для внешних агентов: MCP для чтения, API для записи.

Если агент может только вызвать MCP tool по имени, но не умеет передавать payload, такой клиент должен использовать MCP только для чтения и HTTP API для записи.
Внешних ingest-endpoints для competitors, competitor reviews, keyword positions и store truth сейчас нет. Этот market/store слой уже живёт в системе, но ведётся через admin до появления отдельного публичного write-контракта.

Модель портфеля

Project+apps выражает мобильный контур по слоям: направление → продукт → приложение.

Внутри admin это развёрнуто в полноценный штаб: Портфель (направления, продукты, приложения), Управление (канон, решения, задачи), Рынок и рост (конкуренты, отзывы, ключи и позиции, store truth) и Summary (signals, insights, economics).
Спорные Android-хвосты вроде 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.
HTTP API в текущем контракте пишет core-слой: продукты, приложения, решения, задачи, signals, insights, economics и canon. Market/store-слой уже живёт в системе, но пока ведётся через admin-UI, а не через отдельные внешние ingest endpoints.

Генерация 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_сгенерированный_токен

Эндпоинты

Метод Local / Public URL Назначение
GET http://127.0.0.1:8010/api/project-apps/summary
https://apps.farmchel.org/api/project-apps/summary
Верхняя сводка портфеля без сырой первички: здоровье, продукты, тренды, риски, точки роста и блок внимания.
GET http://127.0.0.1:8010/api/project-apps/directions
https://apps.farmchel.org/api/project-apps/directions
Прочитать допустимые направления, их slug и портфельный слой перед созданием продуктов и спорных приложений.
GET http://127.0.0.1:8010/api/project-apps/products
https://apps.farmchel.org/api/project-apps/products
Найти существующие продукты по slug, имени, направлению и статусу; фильтр is_favorite (boolean) ограничивает выборку избранными.
GET http://127.0.0.1:8010/api/project-apps/apps
https://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/signals
https://apps.farmchel.org/api/project-apps/signals
Приём точки роста, проблемы или риска из нижней системы.
POST http://127.0.0.1:8010/api/project-apps/insights
https://apps.farmchel.org/api/project-apps/insights
Приём продуктового вывода: что стало понятно и какое действие рекомендуется.
POST http://127.0.0.1:8010/api/project-apps/economics
https://apps.farmchel.org/api/project-apps/economics
Приём экономической summary-сводки по продукту или направлению за период.
POST http://127.0.0.1:8010/api/project-apps/products
https://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/apps
https://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/decisions
https://apps.farmchel.org/api/project-apps/decisions
Записать жёсткое решение: что решили, почему, кто владелец и когда пересмотр.
POST http://127.0.0.1:8010/api/project-apps/tasks
https://apps.farmchel.org/api/project-apps/tasks
Создать рабочую задачу, вытекающую из решения, продукта, направления или приложения.
GET http://127.0.0.1:8010/api/project-apps/canon-rules
https://apps.farmchel.org/api/project-apps/canon-rules
Прочитать канон Project+apps: постоянные правила о продуктах, заморозке и структуре портфеля.
POST http://127.0.0.1:8010/api/project-apps/canon-rules
https://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.

Коды ответов

422 ожидаем не только на пустых полях, но и на конфликте модели: например, если агент пытается отправить product_binding_status=confirmed без продукта или дублирует технический store identity внутри одной платформы.

Как агенту узнать допустимые направления

GET http://127.0.0.1:8010/api/project-apps/directions
X-Project-Apps-Token: <выданный токен>
Текущие направления этого контура: utilities, documents-qr, parental-family-safety, fitness, wellness-habit-change, wellness-mental.
В JSON-ответе также есть 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-параметры

В теле ответа у каждого продукта есть поле 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 двух вариаций и вынести решение по продуктовой гипотезе."
}

Обязательные поля

Пример инсайта

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": "Не масштабировать без подтверждения магазина приложений."
}
Economics, insights и signals — это summary-слой. Сырые CSV, event logs, store dumps, списки отзывов и рекламные таблицы в этот API не отправляются.

Создать продукт

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."
}

Обязательные поля

Фокус продукта

Обновить продукт

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"
    }
  ]
}

Типы решений

Создать приложение

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": "Пока неясно, это отдельный продукт или приложение существующего продукта."
}

Создать задачу

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"
}

Статусы задачи

Создать каноническое правило

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"
    }
  ]
}

Что не отправлять