GET /api/projects/:id/graph — Граф проекта (для агента)
Сгенерировано из матриц + кода. Правки вносить в источники (
docs/matrices/,server/routes/), не здесь.
| Поле | Значение |
|---|---|
| HTTP | GET /api/projects/:id/graph |
| Auth | optionalAuth, requireProjectAccess — гость + авторизованный, доступ к проекту (read/write) |
| Scope токена | read |
| PG-функции | api.get_project_graph |
| Таблицы | project, project_node, project_edge, project_node_role |
| SRM | SRM-343 |
| RP (права) | — |
| Файл роута | server/routes/projects.js |
| Статус | done |
Аргументы запроса (best-effort из хендлера; путь-параметры опущены):
| Аргумент | Где | Обяз. | Заметка |
|---|---|---|---|
diff_from | query | подтвердить | |
format | query | подтвердить | |
view | query | подтвердить |
Коды ответов/ошибок (из хендлера): 304, 404, 500 (+ 200) — уточнить причины вручную
Для человека
Как открыть: отдельной кнопки «граф» в интерфейсе нет. Открыв проект со списка, вы уже на графе — это основной рабочий экран; данный метод отвечает за внутренний рендер графа и доступ агентов по токену, а не за отдельное действие пользователя.
Это «голый» граф проекта: только ноды-блоки, связи и роли, без шапки и метаданных проекта. Для человека самостоятельной страницы у него нет — всё, что он отдаёт, вы уже видите на холсте проекта. Полезен он прежде всего внешним агентам, которые читают структуру задачи без лишних данных.
Для агента
Чтение — достаточно токена со scope read (см. Конвенции). Это основной агентный read для структуры проекта. requireProjectAccess проверяет доступ владельца токена; если проект не найден или невидим — 404. Ноды всегда отдаются в топологическом порядке (server/agent/toposort.js), так что зависимости идут раньше зависимых блоков.
Query-параметры:
| Параметр | Значения | Назначение |
|---|---|---|
view | summary (по умолч.) · full | summary — только счётчики нод/рёбер, роли и версия; full — все ноды и рёбра текстом |
diff_from | <updated_at> | Вернуть только список нод, изменившихся после этой версии (инкрементальный опрос) |
format | md | Альтернатива заголовку 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):
# graphversion: 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 не пришёл, а точечно — только изменившиеся блоки.