Skip to content

aakosarev/transaction-system

Repository files navigation

Система транзакций:

Задание: ТЗ

Описание работы:

От клиента на сервер приходит http-запрос на транзакцию (пополнение / списание {перевод между счетами - не реализовано в силу сроков}).

Предполагается, что транзакция может исполняться продолжительное время, поэтому запросы необходимо обрабатывать асинхронно:

  1. Осуществляется валидация входных данных http-запроса. При успешной валидации данные о запрашиваемой транзакции кладутся в БД со статусом open и после этого клиент получает http-код ответа 202 Accepted (запрос принят на обработку). При неуспешной валидации клиенту отдаётся http-код ответа 422. Eсли не удалось добавить данные о транзакции в БД и при прочих ошибках сервера клиенту отдается http-код ответа 500 Internal server error.

  2. В фоне для каждого пользователя в своей горутине данные о транзакциях извлекаются из БД в порядке добавления и выполняются. При успешном выаполнении транзакции её статус изменяется на closed, в противном случае на rejected (На этом моменте можно при помощи отдельного микросервиса оповещать клиента условно по электронной почте о принятии/отклонении транзакции.

  3. Если сервер падает - данные о транзакциях пользователей из БД не исчезают; при поднятии сервера автоматически запускается их дальнейшая обработка.

Используемые библиотеки:

  1. Для роутинга: https://github.com/julienschmidt/httprouter
  2. Для чтения конфига: https://github.com/ilyakaznacheev/cleanenv
  3. Для работы с Postgres: https://github.com/jackc/pgx
  4. Для работы с миграциями: github.com/golang-migrate/migrate/v4
  5. Для валидации данных запросов: github.com/go-playground/validator/v10

О хранении денег:

Хранение и работа с деньгами в БД осуществляю в типа bigint, т.к.:

  • Нет плавающей точки — меньше неточностей
  • Можно производить стандартные математические операции и не бояться, что потеряются где-то копейки
  • В международном стандарте денежных единиц видно, что число знаков после запятой у них может быть разное. А значит для простоты разработки все стоит хранить в минимальной дробной денежной единице валюты, осущеставляя конвертацию при выводе

Миграции:

Up

Down

Разворачивание проекта локально:

git clone https://github.com/aakosarev/transaction-system

docker-compose up

АПИ:

POST http://localhost:8181/user/new

Request Body:

{
  "name":"Test Name"
}

Response Status Code 200:

{
  "user_id": "7d710c24-f737-4284-96b9-41d75a9d83ca"
}

GET http://localhost:8181/user/{uuid}

Response Status Code 200:

{
  "id": "7d710c24-f737-4284-96b9-41d75a9d83ca",
  "name": "test_2",
  "balance": 0
}

POST http://localhost:8181/user/transaction

Request Body:

{
  "user_id":"7d710c24-f737-4284-96b9-41d75a9d83ca",
  "amount":200,
  "transaction_type":"replenishment"
}

replenishment - пополнение; write-off - списание;

Response Status Code 202:

{
  "message": "The transaction is queued"
}

Пример таблицы транзакций:

  • При постановки транзакции в очередь в столбце tr_status будет значение open
  • После успешного выполнения транзакции в столбце tr_status будет значение closed
  • При отклонении транзакции в столбце tr_status будет значение rejected

About

transaction system [REST + Postgres]

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages