LaHainee / avito-tech-task

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Тествое задание в Avito на позицию стажера бэкенд-разработчика

Микросервис для работы с балансом пользователей.

Проблема:

В нашей компании есть много различных микросервисов. Многие из них так или иначе хотят взаимодействовать с балансом пользователя. На архитектурном комитете приняли решение централизовать работу с балансом пользователя в отдельный сервис.

Задача:

Необходимо реализовать микросервис для работы с балансом пользователей (зачисление средств, списание средств, перевод средств от пользователя к пользователю, а также метод получения баланса пользователя). Сервис должен предоставлять HTTP API и принимать/отдавать запросы/ответы в формате JSON.

Дополнительные задачи:

  • Реализовать метод получения списка транзакций с комментариями откуда и зачем были начислены/списаны средства с баланса. Необходимо предусмотреть пагинацию и сортировку по сумме и дате.
  • Добавить к методу получения баланса доп. параметр. Пример: ?currency=USD. Если этот параметр присутствует, то мы должны конвертировать баланс пользователя с рубля на указанную валюту. Данные по текущему курсу валют можно взять отсюда https://exchangeratesapi.io/ или из любого другого открытого источника.

Описание

  • Сервис разработан на языке Golang с использованием чистой архитектуры
  • В качестве базы данных используется PostgresSQL
  • Для всех слоев: delivery, usecase, repository написаны тесты. Для слоя repository использовался pgxmock, для слоев delivery и usecase использовались моки интерфейсов, моки сгенерированы с помощью gomock
  • API сервиса задокументировано с использованием Swagger
  • Реализован docker-compose состоящий из двух контейнеров: приложение и база данных
  • Для удобства взаимодействия с проектом реализован Makefile
  • Настроен CI: линтер и тесты

В сервисе реализованы оба дополнительных задания. Для получения актуального курса валют выполняется GET запрос к публичному API ЦБ РФ. Согласно документации API, при его бесплатном использовании, данные обновляются раз в сутки. В следствие чего в сервисе реализована отдельная горутина, которая раз в сутки выполняет GET запрос для получения актуального курса валют. Для избежания утечки горутин функция принимает канал отмены, таким образом, при завершении работы сервиса, горутина успешно завершит свою работу. Актуальный курс валют сохраняется в хэш-карту, все операции чтения и записи происходят с использованием sync.RWMutex - являются потокобезопасными.

Запуск

Запуск сервиса c использованием Docker

make run

Запуск тестов

make run-tests

Запуск линтера

make lint

Описание API

1. Получение баланса пользователя

GET /api/v1/balance/{user_id}?currency={currency}

Параметры запроса:

  • user_id - id пользователя в сервисе
  • currency - опциональный параметр - валюта, в которой необходимо получить балланс, по умолчанию - российский рубль

Ответ:

200-ОК

{
    "user_id": 1,
    "balance": 2500
}

Коды ответа:

  • 200 - ОК
  • 400 - некорректные параметры запроса
  • 404 - пользователь не найден
  • 422 - неподдерживаемая валюта для перевода
  • 500 - внутренняя ошибка сервера

2. Обновление балланса пользователя

POST /api/v1/balance/{user_id}

Параметры запроса:

  • user_id - id пользователя в сервисе

Тело запроса:

{
    "operation_type": 1,
    "amount": 2500
}
  • operation_type - тип операции (1 - пополнение балланса, 2 - списание денег с балланса)
  • amount - сумма списания/пополнения

Ответ:

200-ОК

{
    "user_id": 1,
    "balance": 2500
}

Коды ответа:

  • 200 - ОК
  • 400 - некорректные параметры или тело запроса
  • 422 - недостаточно средств для совершения операции, неподдерживаемый тип операции, некорректный ID пользователя, не задана сумма списания/пополнения
  • 500 - внутренняя ошибка сервера

3. Перевод средств

POST /api/v1/transfer

Тело запроса:

{
    "sender_id": 1,
    "receiver_id": 2,
    "amount": 2500
}
  • sender_id - ID отправителя
  • receiver_id - ID получателя
  • amount - сумма денег для перевода

Ответ:

200-ОК

{
    "sender": {
        "user_id": 1,
        "balance": 3500
    },
    "receiver": {
        "user_id": 2,
        "balance": 5500
    }
}

Коды ответа:

  • 200 - ОК
  • 400 - некорректное тело запроса
  • 404 - отправитель или получатель не найдены
  • 422 - недостаточно денег для совершения перевода
  • 500 - внутренняя ошибка сервера

4. Получения транзакций

POST /api/v1/transactions/{user_id}

Параметры запроса:

  • user_id - id пользователя в сервисе

Тело запроса:

{
    "limit": 10,
    "operation_type": "add",
    "since": "2022-01-18T21:27:20.969985Z",
    "order_amount": true,
    "order_date": true
}
  • limit - ограничение количества транзакций для вывода
  • operation_type - тип операции для выборки - пополнение/снятие/перевод
  • since - ограничение по дате и времени - начиная с какой даты будут получены транзакции
  • order_amount - сортировать транзакции по сумме
  • order_date - сортировать транзакции по дате

Ответ:

200-ОК

[
    {
        "operation_type": "add",
        "amount": 100000,
        "created": "2022-01-18T21:27:20.969985Z"
    },
    {
        "operation_type": "add",
        "amount": 100000,
        "created": "2022-01-18T21:27:21.432568Z"
    },
]

Коды ответа:

  • 200 - ОК
  • 400 - некорректные параметры или тело запроса
  • 404 - пользователь не найден
  • 422 - некорретное значение поля limit в теле запроса
  • 500 - внутренняя ошибка сервера

About


Languages

Language:Go 99.2%Language:Makefile 0.5%Language:Dockerfile 0.3%