GET /api/v1/my/wallet/statement-exports/{jobId} — Статус выписки и ссылка на скачивание
Опрос задачи XLSX-выписки, поставленной операцией create-wallet-statement-export.md: текущий статус жизненного цикла и — для завершённой задачи — короткоживущая подписанная ссылка на скачивание файла из приватного объектного хранилища (ADR-0041).
Назначение
Пользователь-холдер после постановки выписки опрашивает её статус («готовится» → «готово») и получает
ссылку на XLSX-файл. Ссылка живёт ограниченное время (1 час) — при истечении клиент повторяет запрос и
получает новую, пока файл не удалён по retention. Feature group — my-wallet.
Metadata
| Поле | Значение |
|---|---|
| Сервис/контекст | wallet |
| API area | user |
| Feature group | my-wallet |
| Статус | draft |
| Документ | docs/06-services/wallet/api/user/get-wallet-statement-export-job.md |
Актор и доступ
| Проверка | Значение |
|---|---|
| Actor type | User (агент / партнёр — холдер счёта) |
| Auth policy / Permissions | wallet.transactions.view-own |
| Scope (RBAC) | платформа (личные данные пользователя) |
| Record-level | задача принадлежит текущему пользователю (UserId из claims); чужая задача невидима → 404 |
| Audit | выдача ссылки на скачивание — audit-запись ExportSensitive (актор, JobId, время выдачи URL) |
HTTP-контракт
| Поле | Значение |
|---|---|
| Method | GET |
| Route | /api/v1/my/wallet/statement-exports/{jobId} |
| Success status | 200 |
| Idempotency header | не применяется (read; каждая выдача ссылки генерирует новый signed URL) |
| Correlation | сквозной trace через заголовок traceparent |
Входные данные / параметры запроса
| Поле | Источник | Тип | Обязательность | Валидация / Ограничения | Безопасность |
|---|---|---|---|---|---|
UserId | identity claims (sub) | Guid | Да | Required — record-level граница | record-level |
JobId | route {jobId} | Guid | Да | Required, непустой | — |
Модель ответа WalletStatementExportJobModel
Дом модели — ../../reports/wallet-statement.md. Особенности ответа:
DownloadUrl заполняется только при Status = Completed и непросроченном файле — подписанная ссылка с
TTL 1 час; в остальных статусах DownloadUrl = null. FailureCode заполняется только при
Status = Failed.
Алгоритм
- Контекст и доступ. Операцию выполняет пользователь-холдер; scope — платформа; требуется право
wallet.transactions.view-own. - Проверка входа и существования.
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
(причины — create-wallet-statement-export.md, «Ошибки»).
Acceptance criteria
- AC-1 (готовый файл). Given задача в
Completed, файл в хранилище (retention не истёк); WhenGET; Then200,Status = Completed,DownloadUrl— подписанная ссылка с TTL 1 час; выдача зафиксирована audit-записьюExportSensitive. - AC-2 (повторная выдача ссылки). Given прежняя ссылка истекла (> 1 часа), файл ещё жив; 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 задача упала (превышен лимит 100 000 строк); 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; новые значения статуса — additive (unknown статус клиент трактует как «в процессе»).
- Logs:
JobId,UserId,Status, факт выдачи ссылки (сам URL не логируется); metrics:wallet_statement_download_url_issued_total; traces: OTel, correlation черезtraceparent. - Скачивание файла идёт напрямую из объектного хранилища по подписанной ссылке — минуя API
wallet(SLA API не зависит от размера файла, ADR-0041).
Обратные ссылки
Автоссылки: где используется этот документ.
- API (2): POST /api/v1/my/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).