---
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. |
