---
id: design-doc-inline-edit
title: "POST /api/projects/:id/doc-content/:nodeId/inline-edit — Точечная правка блока (SSE)"
domain: design-doc
kind: api-method
http: "POST /api/projects/:id/doc-content/:nodeId/inline-edit"
---

# POST /api/projects/:id/doc-content/:nodeId/inline-edit — Точечная правка блока (SSE) {#design-doc-inline-edit}

## Сводка

| Поле | Значение |
|---|---|
| **HTTP** | `POST /api/projects/:id/doc-content/:nodeId/inline-edit` |
| **Auth** | `optionalAuth, requireProjectAccess` — гость + авторизованный, доступ к проекту (read/write) |
| **Scope токена** | `read_write` |
| **PG-функции** | `api.upsert_block_doc_content` |
| **Таблицы** | `block_doc_content`, `block_doc_content_history` |
| **SRM** | SRM-199 |
| **RP (права)** | RP-112 |
| **Файл роута** | `server/routes/projects.js` |
| **Статус** | done |

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

| Аргумент | Где | Обяз. | Заметка |
|---|---|---|---|
| `contentItemId` | body | | _подтвердить_ |
| `fullContent` | body | | _подтвердить_ |
| `instruction` | body | | _подтвердить_ |
| `selectedText` | body | | _подтвердить_ |
| `mode` | query | | _подтвердить_ |

**Коды ответов/ошибок** (из хендлера): `202`, `400`, `403`, `429`, `500` (+ `200`) — _уточнить причины вручную_

Запись — токен со scope `read_write` (см. [Конвенции](../../../shared/conventions.md#conventions)); под ролью владельца, write-доступ к проекту обязателен. Ответ — **поток `text/event-stream` (SSE)**.

**Тело запроса (JSON):**

| Поле | Тип | Обяз. | Назначение |
|---|---|---|---|
| `selectedText` | string | да | Выделенный фрагмент, ≤ 5000 символов |
| `instruction` | string | да | Что сделать с фрагментом, ≤ 1000 символов |
| `fullContent` | string | да | Текущий полный текст блока, ≤ 50 000 символов |
| `contentItemId` | number | нет | Если правится не сам блок, а его артефакт — id этого артефакта |

Любое из обязательных полей пропущено → `400` (поток не открывается). Невалидный `contentItemId` → событие `error` в потоке.

**Пример запроса** (`-N` — потоковый ответ):

```bash
curl -N -X POST "https://specbuilder.vnimanie.ai/api/projects/a1b2c3d4-.../doc-content/node-7/inline-edit" \
  -H "Authorization: Bearer tak_..." \
  -H "Content-Type: application/json" \
  -d '{"selectedText":"Данные берём из CRM.","instruction":"Уточни, какие именно поля","fullContent":"## Сбор данных\n\nДанные берём из CRM.\n..."}'
```

**Пример потока** (события — из `server/services/docGenerator.js`):

```
event: generating
data: {"nodeId":"node-7","label":"Сбор данных","phase":"inline-edit"}

event: chunk
data: {"nodeId":"node-7","text":"## Сбор данных\n\nИз CRM берём поля..."}

event: saved
data: {"nodeId":"node-7","version":5,"tokenEstimate":560}

event: done
data: {"nodeId":"node-7","phase":"inline-edit"}
```

Возвращается **весь обновлённый блок** (не дифф) — собираете его из `chunk`-событий. `saved` означает, что результат записан, а прежняя версия ушла в историю с типом правки `llm_inline` — отсюда работает откат. `done` закрывает поток. Обрыв соединения прерывает генерацию (`AbortController`). Поток — SSE, не JSON и не Markdown.

<!-- gen:start:related -->
## Связанные
- [Конвенции](../../../shared/conventions.md#conventions) · [Роли](../../../shared/roles.md#roles) · [Ошибки](../../../shared/errors.md#errors) · [Глоссарий](../../../shared/glossary.md#glossary)
<!-- gen:end:related -->

---

Human view: https://docs.vnimanie.ai/specbuilder/v1/domains/design-doc/api/inline-edit/