GET /api/v1/agency/wallet/statement-exports/{jobId} — Статус выписки и ссылка на скачивание
Опрос задачи XLSX-выписки, поставленной операцией create-wallet-statement-export.md: текущий статус жизненного цикла и — для завершённой задачи — короткоживущая подписанная ссылка на скачивание файла из приватного объектного хранилища (ADR-0041).
Назначение
Руководитель агентства после постановки выписки опрашивает её статус («готовится» → «готово») и получает
ссылку на XLSX-файл. Ссылка живёт ограниченное время (1 час) — при истечении клиент повторяет запрос и
получает новую, пока файл не удалён по retention. Feature group — agency-wallet.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | wallet |
| API area | agency |
| Feature group | agency-wallet |
| Статус | draft |
| Документ | docs/06-services/wallet/api/agency/get-wallet-statement-export-job.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (руководитель агентства) |
| Auth policy / Permissions | wallet.team.view |
| Scope (RBAC) | организация (только своё агентство) |
| Record-level | задача поставлена актором в периметре его компании (AgencyCompanyId из claims); чужая задача невидима → 404 |
| Audit | выдача ссылки на скачивание — audit-запись ExportSensitive (актор, JobId, время выдачи URL) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/agency/wallet/statement-exports/{jobId} |
| Success status | 200 |
| Idempotency header | не применяется (read; каждая выдача ссылки генерирует новый signed URL) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
AgencyCompanyId | identity claims (tenant_id) | Guid | Да | Required — граница периметра | tenant isolation |
ActorUserId | identity claims (sub) | Guid | Да | Required — audit выдачи ссылки | audit |
JobId | route {jobId} | Guid | Да | Required, непустой | — |
Модель ответа WalletStatementExportJobModel
Дом модели — ../../reports/wallet-statement.md. DownloadUrl
заполняется только при Status = Completed и непросроченном файле — подписанная ссылка с TTL 1 час;
в остальных статусах null. FailureCode — только при Status = Failed.
Алгоритм
- Контекст и доступ. Операцию выполняет руководитель агентства; scope — организация
(
AgencyCompanyIdиз claims); требуется правоwallet.team.view. - Проверка входа и существования.
JobIdнепустой; задача существует в периметре компании актора — иначеWALLET_STATEMENT_JOB_NOT_FOUND(чужая задача не раскрывается). - Проекция статуса. Возвращается текущее состояние задачи (
Queued/Running/Completed/Failed/Expired). ДляCompleted: если retention файла (7 дней) не истёк — генерируется подписанная ссылка с TTL 1 час,DownloadUrlзаполняется, пишется audit-запись выдачи; если файл удалён по retention — задача отдаётся какExpired,DownloadUrl = null. - Результат.
WalletStatementExportJobModel→200. Клиент приQueued/Runningповторяет опрос (5–10 с); приExpired— ставит новую выписку; приFailed— читаетFailureCodeи сужает период.
Ошибки и failure modes
Общие коды (ValidationError, FORBIDDEN, UNAUTHORIZED) — дом ../README.md «Общие
ошибки». Дельта операции:
| Код | HTTP status | Условие | Сообщение | Retry |
|---|---|---|---|---|
WALLET_STATEMENT_JOB_NOT_FOUND | 404 | Задача не существует или вне периметра компании актора | «Выписка не найдена» | no retry |
Статус Failed самой задачи — не HTTP-ошибка: ответ 200 с Status = Failed и FailureCode.
Acceptance criteria
- AC-1 (готовый файл). Given задача в
Completed, файл в хранилище; WhenGET; Then200,Status = Completed,DownloadUrl— ссылка с TTL 1 час; выдача зафиксирована audit-записью. - AC-2 (повторная выдача ссылки). Given прежняя ссылка истекла, файл жив; When повторный
GET; Then200с новой ссылкой (новый signed URL + новая audit-запись). - AC-3 (в процессе). Given задача
Queued/Running; WhenGET; Then200, соответствующий статус,DownloadUrl = null. - AC-4 (retention истёк). Given прошло > 7 дней; When
GET; Then200,Status = Expired,DownloadUrl = null. - AC-5 (неуспех генерации). Given задача упала; When
GET; Then200,Status = Failed,FailureCode = WALLET_STATEMENT_ROW_LIMIT_EXCEEDED,DownloadUrl = null. - AC-6 (чужой периметр). Given
JobIdзадачи другого агентства; WhenGET; ThenWALLET_STATEMENT_JOB_NOT_FOUND(404) — без раскрытия существования.
Совместимость и наблюдаемость
- Новые optional-поля модели задачи и значения статуса — additive (unknown статус клиент трактует как «в процессе»).
- Logs:
JobId,AgencyCompanyId,Status, факт выдачи ссылки (URL не логируется); metrics:wallet_statement_download_url_issued_total; traces: OTel, correlation черезtraceparent. - Скачивание файла — напрямую из объектного хранилища по подписанной ссылке (SLA API не зависит от размера файла, ADR-0041).
Обратные ссылки
Автоссылки: где используется этот документ.
- API (2): POST /api/v1/agency/wallet/statement-exports — Постановка выписки по счёту агентства/агента (XLSX), Wallet API — реестр операций и общие контрактные модели
- Отчёты (1): Отчет/Export: Выписка по счёту кошелька (wallet-statement)
- registries (1): Реестр API-методов PIN
Связанные документы
- Постановка выписки, лимиты и жизненный цикл задачи: create-wallet-statement-export.md.
- Контракт отчёта и модель задачи: ../../reports/wallet-statement.md.
- Общие модели и ошибки: ../README.md.
- ADR-0041 (signed URL, TTL, retention).