--- id: api-rag-session-changes title: Применение изменений к RAG-сессии doc_type: api_method domain: rag status: draft owner: system-analyst source_of_truth: code related_docs: - arch-rag-package - logic-rag-indexing - entity-rag-session - entity-rag-index-job related_code: - src/app/modules/rag/module.py - src/app/schemas/rag_sessions.py - src/app/schemas/indexing.py entities: - RagSession - IndexJob tags: - rag - api - changes - incremental-indexing --- # Применение изменений к RAG-сессии ## Summary - Purpose: поставить incremental indexing для уже существующей `RagSession`. - Actor: внешний клиент модуля RAG. - Trigger: частичное обновление индекса после изменения файлов. - Endpoint: `POST /api/rag/sessions/{rag_session_id}/changes` - Main entities: `RagSession`, `IndexJob`. - Main logic: проверка существования сессии, создание change job, асинхронная обработка `upsert`/`delete`. - Main errors: `not_found` для отсутствующей сессии, `422` для некорректного payload. - Source of truth: `src/app/modules/rag/module.py`, `src/app/schemas/rag_sessions.py`. ## Назначение Метод позволяет обновить индекс без полной переиндексации проекта. Он принимает только изменённые файлы и операции удаления. ## Контекст Endpoint относится к новому API с явной работой через `rag_session_id`. В отличие от legacy `/api/index/changes`, он не создаёт сессию молча и требует, чтобы она уже существовала. ## Технический use case ### Основной сценарий 1. Клиент передаёт `rag_session_id` в path и список `changed_files` в body. 2. Endpoint проверяет наличие сессии через `RagSessionStore.get`. 3. При успехе `IndexingOrchestrator.enqueue_changes` создаёт новую job и запускает фоновое применение изменений. 4. API возвращает `index_job_id` и стартовый статус. ### Альтернативные ветки - Если `rag_session_id` не найдена, endpoint бросает `AppError("not_found", ...)`. - Для `op=delete` в последующей логике происходит удаление документов по пути без повторной генерации embeddings. ## Функциональные требования ### Request validation - Path parameter `rag_session_id` обязателен. - `changed_files` обязателен и состоит из элементов `ChangedFile`. - Для каждого элемента обязательны `op` и `path`. - `op` допускает только `upsert` или `delete`. ### Processing rules - Сессия должна существовать до постановки change job. - Каждый вызов создаёт новый `IndexJob`. - Фактическое применение изменений выполняется асинхронно. ### State changes - В `rag_index_jobs` появляется новая задача. - Сам индекс меняется позже, внутри `RagService.index_changes`. ### Side effects - Публикация job events. - Удаление документов по `delete_paths` и upsert новых документов в фоне. ## Contract ### Endpoint - Method: `POST` - Path: `/api/rag/sessions/{rag_session_id}/changes` - Auth: определяется внешним слоем приложения. - Idempotent: нет, повторный вызов создаёт новую job. - Timeout: короткий, endpoint не дожидается завершения индексации. - Retry: только если клиент готов к созданию дополнительной job. ### Request | Field | Type | Required | Constraints | Description | |------|------|----------|-------------|-------------| | `rag_session_id` | `string` | yes | path param, non-empty | идентификатор существующей RAG-сессии | | `changed_files` | `array` | yes | схема каждого элемента обязательна | изменения файлов | | `changed_files[].op` | `enum` | yes | `upsert` or `delete` | тип операции | | `changed_files[].path` | `string` | yes | `min_length=1` | путь файла | | `changed_files[].content` | `string \| null` | no | нужен для `upsert` | содержимое файла | | `changed_files[].content_hash` | `string \| null` | no | повышает cache reuse | hash содержимого | ### Response | Field | Type | Description | |------|------|-------------| | `index_job_id` | `string` | идентификатор фоновой задачи | | `status` | `string` | стартовый статус задачи | ### External contract refs - OpenAPI: формируется FastAPI по `response_model=IndexJobQueuedResponse`. - Schema: `RagSessionChangesRequest`, `ChangedFile`, `IndexJobQueuedResponse`. - DTO / serializer: `src/app/schemas/rag_sessions.py`, `src/app/schemas/indexing.py`. - Additional refs: `logic-rag-indexing`. ## Errors | error_id | http_code | when | client_behavior | retry | |----------|-----------|------|-----------------|-------| | `not_found` | `404` | `rag_session_id` отсутствует | создать новую сессию или исправить id | no | | `validation_error` | `422` | нарушена схема request | исправить payload | no | ## Нефункциональные требования ### Security - Метод доверяет внешнему слою авторизации. ### Observability - Logs: прямое логирование endpoint отсутствует. - Metrics: нет отдельной метрики на уровне метода. - Traces: отсутствуют. - Audit: каждая операция материализуется в `IndexJob`. ### Reliability - Проверка существования сессии защищает от случайной записи в неинициализированный scope. - Ошибки индексации доступны через job status и SSE events. ### Performance - Быстрый ответ за счёт фонового выполнения. ## Связанные блоки логики - `logic-rag-indexing` ## Связанные сущности - `RagSession` - `IndexJob` ## Связанный код ### Files - `src/app/modules/rag/module.py` - `src/app/schemas/rag_sessions.py` - `src/app/schemas/indexing.py` ### Symbols - `RagModule.public_router.rag_session_changes` - `RagSessionStore.get` - `IndexingOrchestrator.enqueue_changes` ## Связанные документы - `arch-rag-package` - `logic-rag-indexing` - `entity-rag-session` - `entity-rag-index-job` ## История изменений | Date | Source | Changes | |------|--------|---------| | 2026-03-13 | code | Задокументирован публичный endpoint incremental indexing для существующей сессии. |