diff --git a/v2/swagger.yaml b/v2/swagger.yaml index 7571e4c..163908a 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,371 @@ 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 + enum: [created_at, "-created_at", status_id, "-status_id", balance, "-balance", name, "-name"] + description: | + Префикс `-` для DESC. По умолчанию `-created_at`. + - 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 } + description: Ключ закэшированной выборки сотрудников (создаётся через core user-list-cache). + - name: reg_status_id + in: query + schema: { type: string } + description: | + Comma-separated значения `RegStatus` (статус участия). Без параметра — + показываются все валидные для отображения статусы. + - 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-вид — видны транзакции всех юзеров) + description: | + Под `wallets-transactions` отдаёт все транзакции тенанта (учётная админ-выборка). + Без права — только транзакции по своему кошельку. + 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 + enum: + - created_at + - "-created_at" + - wallet_transaction_type + - "-wallet_transaction_type" + - wallet_operation_type + - "-wallet_operation_type" + - amount + - "-amount" + description: | + Префикс `-` для DESC. По умолчанию `-created_at`. + - name: wallet_id + in: query + schema: { type: string, format: uuid } + description: Транзакции конкретного кошелька (отправитель ИЛИ получатель). + - name: sender_wallet_id + in: query + schema: { type: string, format: uuid } + - name: recipient_wallet_id + in: query + schema: { type: string, format: uuid } + - name: sender_user_id + in: query + schema: { type: string, format: uuid } + description: Транзакции, где этот юзер — отправитель ИЛИ администратор начисления. + - name: recipient_user_id + in: query + schema: { type: string, format: uuid } + - name: sender_user_list_key + in: query + schema: { type: string, format: uuid } + description: Выборка сотрудников-отправителей (см. core user-list-cache). + - name: recipient_user_list_key + in: query + schema: { type: string, format: uuid } + - name: wallet_user_list_key + in: query + schema: { type: string, format: uuid } + description: | + Выборка сотрудников: транзакция учитывается, если кто-то из них — + отправитель, получатель ИЛИ администратор начисления. Полезно для поиска + операций, где одна из сторон NULL (покупка в магазине, авто-начисления). + - name: department_id + in: query + schema: { type: string, format: uuid } + - name: wallet_transaction_type + in: query + schema: + $ref: '#/components/schemas/walletTransactionType' + - name: wallet_operation_type + in: query + schema: + $ref: '#/components/schemas/walletOperationType' + - name: entity_id + in: query + schema: { type: integer } + - name: reference_id + in: query + schema: { type: string, format: uuid } + - name: created_at + in: query + schema: { type: string } + description: 'Диапазон в формате `from|to` (ISO дата/время).' + 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: @@ -11415,7 +11786,8 @@ components: * `6` - Автоматическое начисление валюты * `7` - Подарок (автоматическое начисление) * `8` - Подарок (процент от баланса) - enum: [1, 2, 3, 4, 5, 6, 7, 8] + * `9` - Отмена покупки + enum: [1, 2, 3, 4, 5, 6, 7, 8, 9] example: 3 walletTransaction: @@ -11648,6 +12020,206 @@ 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: + $ref: '#/components/schemas/walletTransactionType' + wallet_operation_type: + $ref: '#/components/schemas/walletOperationType' + 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, description: 'Локализованная дата для отображения.' } + 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, description: 'Человекочитаемое название операции.' } + + 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: Ключ выборки сотрудников (создаётся через core user-list-cache). + wallet_transaction_type: + $ref: '#/components/schemas/walletTransactionType' + amount: + type: integer + minimum: 1 + description: Сумма в единицах корп. валюты. На каждого сотрудника выборки. + 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