openapi: 3.0.1 info: title: Customer - сервис для управления клиентами description: |- Область ответственности сервиса - предоставление пользователю функционала корзины и кошелька. version: 1.0.0 tags: - name: account description: аккаунт - name: currency description: доступные валюты - name: cart description: корзина - name: wallet description: кошелёк - name: history description: история paths: /account: get: tags: - account summary: Получение текущего аккаунта юзера description: Используется при заходе юзера в систему. Айдишник юзера получает из токена, который передаётся в заголовке authorization operationId: getAccount security: - Bearer: [] responses: '200': description: успешное получение content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Такого пользователя нет content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - account summary: Создать новый аккаунт description: Создаёт новый аккаунт для юзера, если такого ещё не было operationId: addAccount security: - Bearer: [] responses: '200': description: успешное создание аккаунта content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - account summary: удалить собственный аккаунт description: помечает аккаунт удалённым operationId: deleteAccount security: - Bearer: [] responses: '200': description: успешное удаление аккаунта content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' /accounts: get: tags: - account summary: списко аккаунтов с пагинацией description: получает список аккаунтов на указанной странице + общее количество аккаунтов operationId: paginationAccounts parameters: - name: page in: query description: Номер страницы, начиная с 1 required: false explode: false schema: type: integer default: 1 - name: limit in: query description: размер страницы required: false explode: false schema: type: integer default: 100 responses: '200': description: успешное получение страницы аккаунтов content: application/json: schema: type: object properties: totalPages: type: integer example: 11 accounts: type: array items: $ref: "#/components/schemas/Account" /account/{userId}: get: tags: - account summary: Получить аккаунт по ID пользователя системы единой авторизации description: Метод необходимый в основном только менеджерам, для получения данных о клиенте security: - Bearer: [] operationId: getDirectAccount parameters: - name: userId in: path description: ID аккаунта required: true schema: type: string responses: '200': description: Успешное получение аккаунта content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Нет такого пользователя content: application/json: schema: $ref: '#/components/schemas/Error' patch: tags: - account summary: Выставление статуса верификации description: Используется сервисом верификации для выставления статуса верификации, является ли юзер НКО, Юр Лицом или Физ Лицом operationId: setStatus parameters: - name: userId in: path description: ID аккаунта required: true schema: type: string requestBody: content: application/json: schema: type: object properties: status: type: string enum: ["no", "nko", "org"] responses: '200': description: Успешное выставление статуса content: application/json: schema: $ref: '#/components/schemas/Account' '404': description: Нет такого пользователя content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - account summary: Удалить аккаунт по айди description: Метод необходимый в основном только менеджерам, для удаления клиента operationId: deleteDirectAccount security: - Bearer: [] parameters: - name: userId in: path description: ID аккаунта required: true schema: type: string responses: '200': description: Успешное удаление аккаунта content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Нет такого пользователя content: application/json: schema: $ref: '#/components/schemas/Error' /currencies: get: tags: - currency summary: получить список одобренных валют operationId: getCurrencies responses: '200': description: успешное получение списка валют content: application/json: schema: type: array example: - "RUB" - "USD" - "CAD" items: type: string put: tags: - currency summary: обновляет список одобренных валют operationId: updateCurrencies security: - Bearer: [] requestBody: content: application/json: schema: type: array example: - "RUB" - "USD" - "CAD" items: type: string responses: '200': description: успешное обновление списка валют content: application/json: schema: type: array example: - "RUB" - "USD" - "CAD" items: type: string '401': description: Uanuthorized content: application/json: schema: $ref: '#/components/schemas/Error' /cart: patch: tags: - cart summary: Добавляем в корзину тариф description: Необходимо проверить, что такой тариф существует operationId: add2cart security: - Bearer: [] parameters: - name: id in: query required: true schema: type: string example: "807f1f77bcf81cd799439011" responses: '200': description: Добавлено в корзину content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Не найден такой тариф content: application/json: schema: $ref: '#/components/schemas/Error' delete: tags: - cart summary: Удаляем из корзины тариф operationId: removeFromCart security: - Bearer: [] parameters: - name: id in: query required: true schema: type: string example: "807f1f77bcf81cd799439011" responses: '200': description: Удалено из корзины content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Не найден такой тариф content: application/json: schema: $ref: '#/components/schemas/Error' /cart/pay: post: tags: - cart summary: оплатить козину operationId: payCart security: - Bearer: [] description: >- - Очевидно нужен воркер или очередь (место где можно потрогать кафку), которая будет слать запросы в конечные сервисы для добавления привилегий в аккаунт пользователя - В случае если денег в кошельке достаточно - отправить в воркер или очередь задачи на разослать конкретным сервисам добавление привилегий - Если денег недостаточно, вернуть ошибку и указать количество недостающих средств в валюте - Отправить запрос на discount сервис - Очистить корзину requestBody: content: application/json: schema: type: object required: [userId] properties: userId: type: string description: ID для того, чтобы указать сервису оплаты, какой юзер оплатил example: "807f1f77bcf81cd799439011" responses: '200': description: успешная оплата корзины content: application/json: schema: $ref: '#/components/schemas/Account' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' /wallet: patch: tags: - wallet summary: Изменить валюту кошелька operationId: changeCurrency description: >- При запросе необходимо: - Отвалидировать, что такая валюта одобрена - Получить данные из сервиса cbrf (выдам задачу на него чуть позднее) - Перевести валюту кошелька в новую валюту. Кошелёк нарочно целочисленный, чтобы не было претензий к точности с плавающей точкой, поэтому, например долларовый счёт считается в центах security: - Bearer: [] requestBody: content: application/json: schema: type: object required: [currency] properties: currency: type: string example: "USD" responses: '200': description: Успешная смена валюты кошелька content: application/json: schema: $ref: "#/components/schemas/Account" '401': description: Неавторизован content: application/json: schema: $ref: "#/components/schemas/Error" '400': description: Такая валюта не одобрена content: application/json: schema: $ref: "#/components/schemas/Error" '404': description: Пользователь не найден content: application/json: schema: $ref: "#/components/schemas/Error" post: tags: - wallet summary: Зачислить деньги на кошелёк description: "Прибавляем полученное значение к cash и при необходимости приводим к валюте кошелька" operationId: putMoney security: - Bearer: [] requestBody: content: application/json: schema: type: object required: [cash, currency, userId] properties: cash: type: integer format: int64 example: 10000 currency: type: string example: "USD" userId: type: string example: "807f1f77bcf81cd799439011" responses: '200': description: успешное внесение денег на кошелёк content: application/json: schema: $ref: "#/components/schemas/Account" '400': description: Такая валюта не одобрена content: application/json: schema: $ref: "#/components/schemas/Error" '404': description: Аккаунт не найден content: application/json: schema: $ref: "#/components/schemas/Error" get: tags: - wallet summary: Запрос на получение ссылки на оплату operationId: requestMoney description: >- - Формируем запрос к сервису оплаты, с необходимыми постбэками - Получаем ответ от сервиса оплаты с ссылкой на оплату, которую надо передать пользователю security: - Bearer: [] parameters: - name: cash in: query description: Количество денег required: true schema: type: integer default: 10000 responses: '200': description: Успешный запрос денег content: application/json: schema: type: object properties: link: type: string example: "https://google.ru" '500': description: Сервис оплаты вернул ошибку content: application/json: schema: $ref: '#/components/schemas/Error' /history: get: tags: - history summary: Получение лога событий связанных с аккаунтом operationId: getHistory security: - Bearer: [] parameters: - name: page in: query description: Номер страницы, начиная с 1 required: false explode: false schema: type: integer default: 1 - name: limit in: query description: Размер страницы required: false explode: false schema: type: integer default: 100 responses: '200': description: Успешное получение событий content: application/json: schema: type: object properties: totalPages: type: integer example: 11 records: type: array items: $ref: '#/components/schemas/History' '401': description: Неавторизован content: application/json: schema: $ref: '#/components/schemas/Error' post: tags: - history summary: Публикация лога в истории operationId: add2history requestBody: content: application/json: schema: type: object required: [userId, type, comment, rawDetails] properties: userId: type: string example: "807f1f77bcf81cd799439011" type: $ref: '#/components/schemas/HistoryType' comment: type: string example: "я это сделал потому что 42" rawDetails: type: string example: '{"tariffs":["807f1f77bcf81cd799439011","807f1f77bcf81cd799439011"]}' responses: '200': description: Успешная публикация лога content: application/json: schema: $ref: "#/components/schemas/History" '500': description: Ошибка при публикации content: application/json: schema: $ref: "#/components/schemas/Error" components: schemas: Account: type: object required: [_id, userId, cart, wallet, deleted, createdAt, updatedAt] properties: _id: type: string example: "807f1f77bcf81cd799439011" userId: type: string example: "807f1f77bcf81cd799439011" cart: type: array items: type: string example: - "807f1f77bcf81cd799439011" - "807f1f77bcf81cd799439012" wallet: $ref: "#/components/schemas/Wallet" status: type: string enum: ["no", "org", "nko"] deleted: type: boolean example: false createdAt: type: string format: "date-time" updatedAt: type: string format: "date-time" deletedAt: type: string format: "date-time" Wallet: type: object required: [currency, cash, money] properties: currency: description: Текущий курс валюты type: string example: "RUB" cash: description: Сумма money переведённая на текущий курс type: integer format: int64 example: 10701 spent: type: integer format: int64 description: общая сумма потраченных денег за всё время существования аккаунта money: type: integer format: int64 description: >- Деньги на счету в копейках. Чтобы при перессчётах не возникало денег изниоткуда. фиксируемся к одной валюте, она будет внутренней, никому её не покажем example: 10701 History: type: object required: [id, userId, type, deleted, createdAt, updatedAt, comment, subject] properties: id: type: string example: "807f1f77bcf81cd799439011" userId: type: string example: "807f1f77bcf81cd799439011" type: $ref: '#/components/schemas/HistoryType' deleted: type: boolean example: false createdAt: type: string format: "date-time" updatedAt: type: string format: "date-time" deletedAt: type: string format: "date-time" comment: type: string example: "я это сделал потому что 42" rawDetails: type: string description: >- Я пока не могу предположить, какие будут фильтры по истории, поэтому предлагаю в это поле просто класть строку с json. Ибо для каждого типа записи она своя. example: '{"tariffs":["807f1f77bcf81cd799439011","807f1f77bcf81cd799439011"]}' HistoryType: type: string enum: ["successfulPayment", "declinedPayment", "timeoutPayment", "buyCart", "subsriptionEnd"] Error: type: object required: [code, message] properties: statusCode: type: integer format: int64 example: 404 message: type: string example: user not found securitySchemes: Bearer: # arbitrary name for the security scheme type: http scheme: bearer bearerFormat: JWT description: >- Enter the token with the `Bearer: ` prefix, e.g. "Bearer abcde12345".