POST /api/projects/:id/doc-content/:nodeId/artifacts/:contentItemId/generate — Сгенерировать артефакт (SSE)
Сгенерировано из матриц + кода. Правки вносить в источники (
docs/matrices/,server/routes/), не здесь.
| Поле | Значение |
|---|---|
| HTTP | POST /api/projects/:id/doc-content/:nodeId/artifacts/:contentItemId/generate |
| Auth | optionalAuth, requireProjectAccess — гость + авторизованный, доступ к проекту (read/write) |
| Scope токена | read_write |
| PG-функции | api.get_artifact_doc_content, api.upsert_artifact_doc_content |
| Таблицы | artifact_doc_content, project_node, content_item |
| SRM | SRM-210 |
| RP (права) | RP-118 |
| Файл роута | server/routes/projects.js |
| Статус | done |
Аргументы запроса (best-effort из хендлера; путь-параметры опущены):
| Аргумент | Где | Обяз. | Заметка |
|---|---|---|---|
mode | query | подтвердить | |
quality | query | подтвердить |
Коды ответов/ошибок (из хендлера): 403 (+ 200) — уточнить причины вручную
Для человека
Как открыть: откройте проект → вид «Дизайн-документ» → блок → разверните нужный артефакт → нажмите «Оглавление» (набросок плана) или «Полный текст» (развёрнутая версия). Текст выводится потоком, по мере написания.
Пишет содержимое одного артефакта блока. Есть два режима: «оглавление» — короткий план-каркас, и «полный текст» — развёрнутый материал. В контекст идут метаданные проекта, описание блока, уже написанные соседние артефакты этого блока (для связности) и, если у артефакта уже был план, он разворачивается в полный текст. Готовый артефакт можно затем дописать вручную через редактирование.
Текст отдаётся потоком и дописывается в реальном времени. По завершении новая версия сохраняется, а прежний текст артефакта уходит в историю — то есть генерацию всегда можно откатить. Есть и более тщательный режим качества (дольше, но аккуратнее).
Кто может. Генерировать артефакт может только владелец проекта (RP-118). Менеджер спейса, наблюдатель и администратор организации за владельца документ не генерируют; гость — только если проект его собственный.
Для агента
Запись + генерация — нужен токен со scope read_write (см. Конвенции). Кроме доступа к проекту хендлер требует уровень write (иначе 403); под гостевым доступом генерация разрешена только владельцу проекта. Проверка прав происходит до открытия потока: при отказе вернётся обычный JSON 403, поток не начнётся.
Это SSE-эндпоинт: ответ — поток text/event-stream, а не один JSON. Тела запроса нет — режим задаётся query-параметрами.
Путь-параметры:
| Параметр | Назначение |
|---|---|
:id | UUID проекта |
:nodeId | id блока (ноды) |
:contentItemId | id артефакта (из списка артефактов) |
Query-параметры:
| Параметр | Значения | По умолч. | Назначение |
|---|---|---|---|
mode | outline | full | full | Оглавление-каркас или развёрнутый текст |
quality | fast | pro | fast | pro — более тщательный режим (несколько черновиков + доработка), дольше |
Пример запроса (флаг -N отключает буферизацию, иначе события придут пачкой в конце):
curl -N -X POST "https://specbuilder.vnimanie.ai/api/projects/{id}/doc-content/{nodeId}/artifacts/51/generate?mode=full&quality=fast" \ -H "Authorization: Bearer tak_..." \ -H "Accept: text/event-stream"Поток событий (event: + data: JSON на каждое):
event: generatingdata: {"nodeId":"n3","contentItemId":51,"label":"Модель данных","phase":"artifact"}
event: chunkdata: {"nodeId":"n3","text":"## Таблицы\n"}
event: chunkdata: {"nodeId":"n3","text":"- events\n- aggregates\n"}
event: saveddata: {"nodeId":"n3","contentItemId":51,"version":3,"tokenEstimate":420}
event: donedata: {"nodeId":"n3","contentItemId":51,"phase":"artifact"}Порядок: generating (старт, с phase: artifact или artifact-outline) → серия chunk с приращениями текста → saved (записана новая версия, в version — её номер) → done. В режиме quality=pro между стартом и текстом приходят события quality_phase (этапы черновиков и доработки). При сбое генерации — warning (если часть текста уже есть) или error. Если клиент разрывает соединение, сервер прерывает генерацию (AbortController).
Формат. Это поток событий, не JSON-ресурс и не Markdown-зеркало; Accept: text/markdown / ?format=md и ETag/304 к нему неприменимы. Текст артефакта собирается из последовательных chunk и фиксируется событием saved; после завершения итоговый результат читается как обычно через артефакты блока. Блок affordances в поток не входит (server/agent/affordances.js).