--- id: api-rag-session-job title: Получение статуса и событий задачи индексации doc_type: api_method domain: rag status: draft owner: system-analyst source_of_truth: code related_docs: - arch-rag-package - entity-rag-session - entity-rag-index-job related_code: - src/app/modules/rag/module.py - src/app/modules/rag/job_store.py - src/app/schemas/rag_sessions.py entities: - RagSession - IndexJob tags: - rag - api - job-status - sse --- # Получение статуса и событий задачи индексации ## Summary - Purpose: отдать текущее состояние job и поток событий её выполнения в рамках конкретной `RagSession`. - Actor: внешний клиент модуля RAG. - Trigger: polling или live-monitoring после запуска snapshot/change indexing. - Endpoint: `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}` и `GET /api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events` - Main entities: `RagSession`, `IndexJob`. - Main logic: чтение job по id, проверка принадлежности сессии, возврат status payload или SSE stream. - Main errors: `not_found` при отсутствии job или несовпадении `rag_session_id`. - Source of truth: `src/app/modules/rag/module.py`, `src/app/modules/rag/job_store.py`. ## Назначение Документ описывает два связанных метода наблюдения: синхронный status endpoint и потоковый SSE endpoint. Оба работают поверх одной сущности `IndexJob`. ## Контекст Create и changes endpoints возвращают только стартовый статус задачи, поэтому клиенту нужны отдельные методы для отслеживания выполнения. SSE-поток даёт live progress, а status endpoint нужен для простого polling. ## Технический use case ### Основной сценарий 1. Клиент вызывает status endpoint или открывает SSE stream по `index_job_id`. 2. Endpoint читает job из `IndexJobStore`. 3. Если job отсутствует или принадлежит другой `rag_session_id`, возвращается `not_found`. 4. Status endpoint отдаёт снимок counters и error payload. 5. SSE endpoint подписывается на `EventBus` c `replay=True` и транслирует `index_status`, `index_progress`, `terminal`. ### Альтернативные ветки - При отсутствии новых событий SSE endpoint каждые 10 секунд отправляет `: keepalive`. - После события `terminal` поток завершается и отписывается от EventBus. ## Функциональные требования ### Request validation - `rag_session_id` и `index_job_id` обязательны как path parameters. - Job должна существовать и принадлежать переданной сессии. ### Processing rules - Status endpoint не подписывается на события и читает только текущее состояние job. - SSE endpoint использует `replay=True`, чтобы клиент получил уже опубликованные события. - Оба метода защищают от доступа к job другой сессии. ### State changes - Методы не меняют состояние job. ### Side effects - SSE endpoint создаёт временную подписку на EventBus. - При завершении или разрыве соединения выполняется `unsubscribe`. ## Contract ### Endpoint - Method: `GET` - Path: `/api/rag/sessions/{rag_session_id}/jobs/{index_job_id}` и `/api/rag/sessions/{rag_session_id}/jobs/{index_job_id}/events` - Auth: определяется внешним слоем приложения. - Idempotent: да. - Timeout: status endpoint короткий; SSE stream долгоживущий. - Retry: polling можно повторять безопасно; SSE можно переподключать. ### Request | Field | Type | Required | Constraints | Description | |------|------|----------|-------------|-------------| | `rag_session_id` | `string` | yes | path param | идентификатор сессии | | `index_job_id` | `string` | yes | path param | идентификатор задачи | ### Response | Field | Type | Description | |------|------|-------------| | `rag_session_id` | `string` | идентификатор сессии, только для status endpoint | | `index_job_id` | `string` | идентификатор задачи | | `status` | `IndexJobStatus` | текущее состояние job | | `indexed_files` | `integer` | число успешно обработанных файлов | | `failed_files` | `integer` | число файлов с ошибками | | `cache_hit_files` | `integer` | число cache hit | | `cache_miss_files` | `integer` | число cache miss | | `error` | `object \| null` | ошибка, если job завершилась с `error` | ### External contract refs - OpenAPI: status endpoint использует `response_model=RagSessionJobResponse`; SSE endpoint отдаёт `text/event-stream`. - Schema: `RagSessionJobResponse`. - DTO / serializer: `src/app/schemas/rag_sessions.py`. - Additional refs: `entity-rag-index-job`. ## Errors | error_id | http_code | when | client_behavior | retry | |----------|-----------|------|-----------------|-------| | `not_found` | `404` | job отсутствует или не принадлежит переданной сессии | проверить id или создать новую задачу | no | ## Нефункциональные требования ### Security - Проверка `job.rag_session_id == rag_session_id` обязательна для обоих методов. ### Observability - Logs: отдельные логи чтения статуса не реализованы. - Metrics: отсутствуют. - Traces: отсутствуют. - Audit: история job хранится в `rag_index_jobs`, поток событий в памяти EventBus. ### Reliability - SSE heartbeat удерживает соединение активным. - `finally` блок гарантирует `unsubscribe`. ### Performance - Status endpoint работает как лёгкий запрос к БД. - SSE stream масштабируется числом активных подписчиков и объёмом событий. ## Связанные блоки логики - `logic-rag-indexing` ## Связанные сущности - `RagSession` - `IndexJob` ## Связанный код ### Files - `src/app/modules/rag/module.py` - `src/app/modules/rag/job_store.py` - `src/app/schemas/rag_sessions.py` ### Symbols - `RagModule.public_router.rag_session_job` - `RagModule.public_router.rag_session_job_events` - `IndexJobStore.get` ## Связанные документы - `arch-rag-package` - `entity-rag-session` - `entity-rag-index-job` ## История изменений | Date | Source | Changes | |------|--------|---------| | 2026-03-13 | code | Задокументированы status и SSE endpoints для наблюдения за indexing job. |