From b7b136be0c27cb0752e0e25bbae2875b3f110dca Mon Sep 17 00:00:00 2001 From: Anton Pomorzin Date: Wed, 6 May 2026 11:40:39 +0500 Subject: [PATCH] =?UTF-8?q?H-3656:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20Wallet=20admin=20API=20=D0=B2=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Новые эндпоинты: - GET /admin/wallet[/view] — кошельки сотрудников (read-only) - POST /admin/wallet/export-excel - GET /admin/wallet-transaction[/view] — транзакции, admin-вид - POST /admin/wallet-transaction/create — массовое начисление/списание по форме - POST /admin/wallet-transaction/create-from-excel — проведение по результату парсинга - POST /admin/wallet-transaction/excel-processing — парсинг xlsx (file_id + mappings) - POST /admin/wallet-transaction/export-excel - GET /file-processing[/view] — статусы FileProcessing для поллинга Permission: wallets-transactions, требует enableWallet=true у тенанта. Co-Authored-By: Claude Opus 4.7 (1M context) --- v2/swagger.yaml | 520 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 520 insertions(+) diff --git a/v2/swagger.yaml b/v2/swagger.yaml index 7571e4c..72d501f 100644 --- a/v2/swagger.yaml +++ b/v2/swagger.yaml @@ -61,6 +61,12 @@ tags: description: Methods for working with workflow. - name: kedo description: Методы для работы с КЭДО. + - name: admin-wallet + description: Админский API кошельков сотрудников (read-only). Permission `wallets-transactions`, требует `enableWallet=true` у тенанта. + - name: admin-wallet-transaction + description: Админский API транзакций кошелька — проведение начислений/списаний (form/excel) и просмотр. + - name: file-processing + description: Статусы асинхронных обработок файлов (excel-импорт/экспорт, архивы). Видны только записи текущего пользователя. paths: /mobile/bind/{id}/{token}: @@ -6894,6 +6900,316 @@ paths: example: - field: entityId message: Необходимо заполнить «Entity Id». + + /admin/wallet: + get: + tags: [admin-wallet] + summary: Список кошельков сотрудников + operationId: adminWalletIndex + parameters: + - name: page + in: query + schema: { type: integer, minimum: 1, default: 1 } + - name: per-page + in: query + schema: { type: integer, minimum: 1, maximum: 100, default: 20 } + - name: sort + in: query + schema: { type: string } + description: Префикс "-" для DESC. Пример "-balance". + - name: user_id + in: query + schema: { type: string, format: uuid } + - name: status_id + in: query + schema: { type: integer, enum: [1, 2] } + description: 1=Active, 2=Disabled + - name: department_id + in: query + schema: { type: string, format: uuid } + - name: user_list_key + in: query + schema: { type: string, format: uuid } + - name: reg_status_id + in: query + schema: { type: string } + - name: created_at + in: query + schema: { type: string } + description: Диапазон, формат "from|to" (ISO). + responses: + 200: + description: Список кошельков + content: + application/json: + schema: + $ref: '#/components/schemas/WalletList' + + /admin/wallet/view: + get: + tags: [admin-wallet] + summary: Один кошелёк + operationId: adminWalletView + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + responses: + 200: + description: Кошелёк + content: + application/json: + schema: + $ref: '#/components/schemas/Wallet' + + /admin/wallet/export-excel: + post: + tags: [admin-wallet] + summary: Поставить задачу на excel-экспорт списка кошельков + description: | + Файл готовится асинхронно — статус смотреть через `/file-processing/view`. + operationId: adminWalletExportExcel + requestBody: + required: false + content: + application/x-www-form-urlencoded: + schema: + type: object + additionalProperties: true + description: Параметры фильтра — те же что у `GET /admin/wallet`. + responses: + 200: + description: Задача поставлена + content: + application/json: + schema: + type: object + properties: + success: { type: boolean } + + /admin/wallet-transaction: + get: + tags: [admin-wallet-transaction] + summary: Список транзакций (admin-вид — видны транзакции всех юзеров) + operationId: adminWalletTransactionIndex + parameters: + - name: page + in: query + schema: { type: integer, minimum: 1, default: 1 } + - name: per-page + in: query + schema: { type: integer, minimum: 1, maximum: 100, default: 20 } + - name: sort + in: query + schema: { type: string } + - name: wallet_id + in: query + schema: { type: string, format: uuid } + - name: sender_user_id + in: query + schema: { type: string, format: uuid } + - name: recipient_user_id + in: query + schema: { type: string, format: uuid } + - name: wallet_transaction_type + in: query + schema: { type: integer, enum: [1, 2] } + description: 1=Credit, 2=Debit + - name: wallet_operation_type + in: query + schema: { type: integer } + - name: created_at + in: query + schema: { type: string } + responses: + 200: + description: Список транзакций + content: + application/json: + schema: + $ref: '#/components/schemas/WalletTransactionList' + + /admin/wallet-transaction/view: + get: + tags: [admin-wallet-transaction] + summary: Одна транзакция + operationId: adminWalletTransactionView + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + responses: + 200: + description: Транзакция + content: + application/json: + schema: + $ref: '#/components/schemas/WalletTransaction' + + /admin/wallet-transaction/create: + post: + tags: [admin-wallet-transaction] + summary: Провести начисление/списание по форме + description: | + Массовая операция через `usersListKey` (ключ закэшированной выборки сотрудников). + Запускается асинхронно через launcher. + + Soft-error состояния возвращаются в `message.type=warning`: + - "Укажите сотрудников" — выборка пустая + - "Невозможно провести транзакцию, у некоторых сотрудников недостаточно средств..." — debit, не хватает баланса (имена в тексте) + operationId: adminWalletTransactionCreate + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/WalletTransactionFormBody' + responses: + 200: + description: HttpJsonResult + content: + application/json: + schema: + $ref: '#/components/schemas/WalletAdminHttpJsonResult' + + /admin/wallet-transaction/create-from-excel: + post: + tags: [admin-wallet-transaction] + summary: Провести транзакции по результатам excel-обработки + description: | + Принимает `file_processing_id` от `/excel-processing`. Запускает launcher, + который читает `validRows` из FileProcessing.result и проводит транзакции. + + Soft-error состояния: + - "Обработка файла не найдена" — file_processing_id не существует + - "Файл ещё обрабатывается, подождите" — статус не терминальный + - "Ошибка при обработке файла" — статус FATAL/ERROR + - "Нет валидных данных для начисления" — validCount == 0 + operationId: adminWalletTransactionCreateFromExcel + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + required: [file_processing_id] + properties: + file_processing_id: + type: string + format: uuid + responses: + 200: + description: HttpJsonResult + content: + application/json: + schema: + $ref: '#/components/schemas/WalletAdminHttpJsonResult' + + /admin/wallet-transaction/excel-processing: + post: + tags: [admin-wallet-transaction] + summary: Запустить парсинг xlsx с маппингом колонок + description: | + Создаёт FileProcessing с типом PROCESS_WALLET_EXCEL, ставит задачу на парсинг. + Воркер читает xlsx, валидирует строки, складывает в `result.validRows`/`result.invalidRows` + `result.summary`. + + Возвращает `fileProcessingId` для поллинга через `/file-processing/view`. + operationId: adminWalletTransactionExcelProcessing + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/WalletExcelFormBody' + responses: + 200: + description: Задача поставлена + content: + application/json: + schema: + allOf: + - $ref: '#/components/schemas/WalletAdminHttpJsonResult' + - type: object + properties: + data: + type: object + properties: + fileProcessingId: + type: string + format: uuid + + /admin/wallet-transaction/export-excel: + post: + tags: [admin-wallet-transaction] + summary: Поставить задачу на excel-экспорт списка транзакций + operationId: adminWalletTransactionExportExcel + requestBody: + required: false + content: + application/x-www-form-urlencoded: + schema: + type: object + additionalProperties: true + description: Параметры фильтра — те же что у `GET /admin/wallet-transaction`. + responses: + 200: + description: Задача поставлена + content: + application/json: + schema: + type: object + properties: + success: { type: boolean } + + /file-processing: + get: + tags: [file-processing] + summary: Список асинхронных обработок файлов текущего пользователя + description: Видны только записи, привязанные к файлам с `user_id` = текущий пользователь. + operationId: fileProcessingIndex + parameters: + - name: page + in: query + schema: { type: integer, minimum: 1, default: 1 } + - name: per-page + in: query + schema: { type: integer, minimum: 1, maximum: 10, default: 10 } + - name: file_processing_status_id + in: query + schema: { type: string } + description: Comma-separated FileProcessingStatus + - name: file_processing_type_id + in: query + schema: { type: string } + description: Comma-separated FileProcessingType + responses: + 200: + description: Список + content: + application/json: + schema: + $ref: '#/components/schemas/FileProcessingList' + + /file-processing/view: + get: + tags: [file-processing] + summary: Одна обработка + operationId: fileProcessingView + parameters: + - name: id + in: query + required: true + schema: { type: string, format: uuid } + responses: + 200: + description: Обработка + content: + application/json: + schema: + $ref: '#/components/schemas/FileProcessing' + components: securitySchemes: SessionAuth: @@ -11648,6 +11964,210 @@ components: format: uri example: "https://accounts.google.com/o/oauth2/v2/auth?..." + WalletAdminHttpJsonResult: + type: object + properties: + success: { type: boolean } + data: + oneOf: + - type: object + - type: array + - type: 'null' + errors: + type: array + items: + $ref: '#/components/schemas/WalletAdminFieldError' + message: + oneOf: + - $ref: '#/components/schemas/WalletAdminMessage' + - type: 'null' + + WalletAdminFieldError: + type: object + properties: + attribute: { type: string, example: "amount" } + text: { type: string, example: "Необходимо заполнить «Сумма»." } + + WalletAdminMessage: + type: object + properties: + type: + type: string + enum: [success, info, warning, error] + text: { type: string } + + Wallet: + type: object + properties: + id: { type: string, format: uuid } + created_at: { type: string } + status_id: { type: integer, enum: [1, 2] } + user_id: { type: string, format: uuid } + balance: { type: integer, description: "В единицах корп. валюты" } + createdAt: { type: string, description: "Локализованная дата" } + statusName: { type: string } + sumGiftCredits: { type: integer, description: "Подарочный остаток (auto-credit)" } + user: + $ref: '#/components/schemas/WalletAdminUserShort' + + WalletAdminUserShort: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string } + department: + type: object + properties: + id: { type: string, format: uuid } + name: { type: string } + + WalletList: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Wallet' + _meta: + $ref: '#/components/schemas/_meta' + + WalletTransaction: + type: object + properties: + id: { type: string, format: uuid } + created_at: { type: string } + wallet_transaction_type: + type: integer + enum: [1, 2] + description: 1=Credit, 2=Debit + wallet_operation_type: + type: integer + description: Подтип операции (Credit, Debit, AutoCredit, BalancePercentGift, Gift и т.д.) + sender_wallet_id: { type: string, format: uuid, nullable: true } + recipient_wallet_id: { type: string, format: uuid, nullable: true } + amount: { type: integer } + entity_id: { type: integer, nullable: true } + reference_id: { type: string, format: uuid, nullable: true } + comment: { type: string, nullable: true } + createdAt: { type: string } + senderUserId: { type: string, format: uuid, nullable: true } + senderName: { type: string, nullable: true } + recipientUserId: { type: string, format: uuid, nullable: true } + recipientName: { type: string, nullable: true } + walletOperationTypeName: { type: string } + + WalletTransactionList: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/WalletTransaction' + _meta: + $ref: '#/components/schemas/_meta' + + WalletTransactionFormBody: + type: object + required: + - usersListKey + - wallet_transaction_type + - amount + - comment + properties: + usersListKey: + type: string + format: uuid + description: Ключ выборки сотрудников (создаётся через `POST /core/user-list-cache/set-user-list`) + wallet_transaction_type: + type: integer + enum: [1, 2] + description: 1=Credit (начисление), 2=Debit (списание) + amount: + type: integer + minimum: 1 + comment: + type: string + maxLength: 400 + + WalletExcelFormBody: + type: object + required: [file_id, mappings] + properties: + file_id: + type: string + format: uuid + description: ID предварительно загруженного xlsx-файла + mappings: + type: array + description: | + Соответствие колонок xlsx и полей транзакции. + items: + type: object + required: [colIndex, attribute] + properties: + colIndex: + type: integer + description: Индекс колонки в xlsx (с 0) + attribute: + type: string + enum: + - id + - org_num + - full_name + - last_name + - first_name + - middle_name + - amount + - transaction_type + - comment + example: + - { colIndex: 0, attribute: id } + - { colIndex: 1, attribute: amount } + - { colIndex: 2, attribute: transaction_type } + - { colIndex: 3, attribute: comment } + + FileProcessing: + type: object + properties: + id: { type: string, format: uuid } + file_id: { type: string, format: uuid } + file_processing_type_id: + type: integer + description: | + Тип обработки. Релевантные: + - 3 — PROCESS_EXCEL_REPORT (excel-экспорт) + - 10 — PROCESS_WALLET_EXCEL (парсинг wallet-excel) + file_processing_status_id: + type: integer + description: | + 1 — NEW, 2 — QUEUED, 3 — STARTED, 4 — FINISHED, 5 — ERROR, 6 — FATAL + arguments: + type: array + result: + type: object + description: | + Результат. Для wallet-excel содержит: + ``` + { + "summary": { "totalRows": 4, "validCount": 1, "invalidCount": 3 }, + "validRows": [...], + "invalidRows": [{ "row": 2, "errors": {...} }, ...] + } + ``` + created_at: { type: string } + started_at: { type: string, nullable: true } + finished_at: { type: string, nullable: true } + + FileProcessingList: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/FileProcessing' + _meta: + $ref: '#/components/schemas/_meta' + parameters: boardDateTypeParam: in: query