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

GET /api/projects/:id/graph — Граф проекта (для агента)

Сгенерировано из матриц + кода. Правки вносить в источники (docs/matrices/, server/routes/), не здесь.

ПолеЗначение
HTTPGET /api/projects/:id/graph
AuthoptionalAuth, requireProjectAccess — гость + авторизованный, доступ к проекту (read/write)
Scope токенаread
PG-функцииapi.get_project_graph
Таблицыproject, project_node, project_edge, project_node_role
SRMSRM-343
RP (права)
Файл роутаserver/routes/projects.js
Статусdone

Аргументы запроса (best-effort из хендлера; путь-параметры опущены):

АргументГдеОбяз.Заметка
diff_fromqueryподтвердить
formatqueryподтвердить
viewqueryподтвердить

Коды ответов/ошибок (из хендлера): 304, 404, 500 (+ 200) — уточнить причины вручную

Для человека

Как открыть: отдельной кнопки «граф» в интерфейсе нет. Открыв проект со списка, вы уже на графе — это основной рабочий экран; данный метод отвечает за внутренний рендер графа и доступ агентов по токену, а не за отдельное действие пользователя.

Это «голый» граф проекта: только ноды-блоки, связи и роли, без шапки и метаданных проекта. Для человека самостоятельной страницы у него нет — всё, что он отдаёт, вы уже видите на холсте проекта. Полезен он прежде всего внешним агентам, которые читают структуру задачи без лишних данных.

Для агента

Чтение — достаточно токена со scope read (см. Конвенции). Это основной агентный read для структуры проекта. requireProjectAccess проверяет доступ владельца токена; если проект не найден или невидим — 404. Ноды всегда отдаются в топологическом порядке (server/agent/toposort.js), так что зависимости идут раньше зависимых блоков.

Query-параметры:

ПараметрЗначенияНазначение
viewsummary (по умолч.) · fullsummary — только счётчики нод/рёбер, роли и версия; full — все ноды и рёбра текстом
diff_from<updated_at>Вернуть только список нод, изменившихся после этой версии (инкрементальный опрос)
formatmdАльтернатива заголовку Accept: text/markdown (только для токена)

Пример запроса (полный граф, Markdown):

Окно терминала
curl "https://specbuilder.vnimanie.ai/api/projects/a1b2c3d4-1111-4aaa-9bbb-000000000001/graph?view=full" \
-H "Authorization: Bearer tak_..." \
-H "Accept: text/markdown"

Ответ 200 (Markdown-зеркало, view=full): ноды в топо-порядке, рёбра отсортированы (server/agent/markdown.js → serializeGraph):

# graph
version: 2026-06-20T11:42:08.512Z
## Nodes
- n1: Сбор требований
- n2: Проектирование схемы данных
## Edges
- n1 -> n2

При view=summary тело короче — nodes/edges числом и список ролей, без перечисления нод.

Ответ 200 (JSON, cookie-клиент или токен без markdown): version + view + сами массивы (server/routes/projects.js:181):

{
"version": "2026-06-20T11:42:08.512Z",
"view": "summary",
"nodes": [ { "id": "n1", "label": "Сбор требований" } ],
"edges": [ { "source_id": "n1", "target_id": "n2" } ],
"roles": [ { "id": "ba", "label": "Бизнес-аналитик" } ]
}

Инкрементальный опрос. Полный markdown-ответ несёт ETag (= версия графа, максимум по updated_at нод); повтор с If-None-Match: "<version>"304 без тела, если граф не менялся. Если граф мог измениться, передайте diff_from=<прошлая версия> — вернётся только список изменившихся нод (JSON: { "from", "to", "changed": ["n2"], "removed": null }; markdown: строки changed: n2, удаления в v1 не отслеживаются). Так агент тянет полный view=full лишь когда 304 не пришёл, а точечно — только изменившиеся блоки.

Связанные