Skip to content

Тестовое задание в avito на golang-разработчика.

License

Notifications You must be signed in to change notification settings

vprud/avito-test-work

Repository files navigation

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

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

Проблема:

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

Задача:

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

Решение:

Для обеспечения корректности данных операции над баланасом пользователя выполняются в транзакциях со строгой изоляцией Serializable. С таким уровнем изоляции каждая транзакция будет исполнятся будто последовательно, что обеспечивает корректность значений при параллельных запросах на обновление баланса.

Архитектура проекта была вдохнавлена go-clean-template. В слое entity находится модель данных, в слое usecase описаны пути работы с моделью данных, в repo работа с хранилищем данных.

АPI микросервиса предоставляет следующий функционал:

  1. Создание нового аккаунта
  2. Получение полей аккаунта
  3. Обновление баланса аккаунта
  4. Перевод средств между аккаунтами
  5. Получение истории транзакций аккаунта с возможностью сортировки и пагинации

После успешного запуска проекта интерактивная документация API доступна по ссылке.

Развёртывание:

Запуск сервера и СУБД:

make run

Запуск юнит-тестов:

make unit-test

Запуск интеграционных тестов:

make integration-test

Генерация swagger документации:

make run-swag

Остановка сервера и СУБД, удаление контейнеров и сети:

make down

Конфигурирование:

Через переменные окружения можно настроить реквизиты доступа к СУБД. Чтобы их задать, необходимо создать и заполнить .env файл. Пример его заполнения в файле .env.example. Для быстрой демонстрации проекта в docker-compose.yml прописаны значения переменных окружения по умолчанию.

Для конфигурирования не конфиденциальных переменных достаточно прописать их в config/config.yml. При изменении портов необходимо изменить обновить информацию в коде интеграционных тестов. Код инициализации СУБД находится в файле init/init.sql.

Примеры:

Создание аккаунта

curl -X POST "http://0.0.0.0:8080/v1/account/"
"data": {
  "id": 1,
  "balance": 0,
  "created_dt": "2022-07-11T18:37:27.126846Z"
}

Получить аккаунт по ID

curl -X GET "http://0.0.0.0:8080/v1/account/1"
"data": {
    "id": 1,
    "balance": 56,
    "created_dt": "2022-07-11T18:37:27.126846Z"
}

Обновить баланс, начислить 56 рублей

curl -X PUT "http://0.0.0.0:8080/v1/account/1?amount=56"
"data": {
    "id": 1,
    "balance": 56,
    "created_dt": "2022-07-11T18:37:27.126846Z"
}

Обновить баланс, снять 16 рублей

curl -X PUT "http://0.0.0.0:8080/v1/account/1?amount=-16"
"data": {
    "id": 1,
    "balance": 40,
    "created_dt": "2022-07-11T18:37:27.126846Z"
}

Перевести 10 рублей от аккаунта 1 аккаунту 2 (должен был быть создан заранее)

curl -X PUT "http://0.0.0.0:8080/v1/account/amount/1/transfer/2?amount=10"
"data": {
    "accrualAccount": {
        "id": 2,
        "balance": 10,
        "created_dt": "2022-07-11T18:46:41.585732Z"
    },
    "redeemAccount": {
        "id": 1,
        "balance": 30,
        "created_dt": "2022-07-11T18:37:27.126846Z"
    }
}

Получить историю транзакций аккаунта 1 c сортировкой по убыванию даты операции (по умолчанию)

curl -X GET "http://0.0.0.0:8080/v1/account/history/1?limit=15&offset=0"
"data": [
    {
        "id": 1,
        "trans_dt": "2022-07-11T18:50:21.906308Z",
        "account_id": 1,
        "doc_num": -999,
        "type": "accrual",
        "amount": 56
    },
    {
        "id": 2,
        "trans_dt": "2022-07-11T18:50:25.121921Z",
        "account_id": 1,
        "doc_num": -999,
        "type": "redeem",
        "amount": -16
    },
    {
        "id": 3,
        "trans_dt": "2022-07-11T18:50:27.348807Z",
        "account_id": 1,
        "doc_num": 2,
        "type": "redeem",
        "amount": -10
    }
]

Получить историю транзакций аккаунта 1 c сортировкой по возрастанию суммы операции

curl -X GET "http://0.0.0.0:8080/v1/account/history/1?limit=15&offset=0&sort=amount&isDecreasing=false"
"data": [
    {
        "id": 1,
        "trans_dt": "2022-07-11T18:50:21.906308Z",
        "account_id": 1,
        "doc_num": -999,
        "type": "accrual",
        "amount": 56
    },
    {
        "id": 3,
        "trans_dt": "2022-07-11T18:50:27.348807Z",
        "account_id": 1,
        "doc_num": 2,
        "type": "redeem",
        "amount": -10
    },
    {
        "id": 2,
        "trans_dt": "2022-07-11T18:50:25.121921Z",
      "account_id": 1,
        "doc_num": -999,
        "type": "redeem",
        "amount": -16
    }
]

About

Тестовое задание в avito на golang-разработчика.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published