Skip to content

DenisKhanov/Gophermart

Repository files navigation

Накопительная система лояльности Gophermart

Система предназначена для расчета бонусных начислений и ведения накопительного бонусного счета пользователя и состоит из следующих сервисов:

  • Сервис лояльности Gophermart
  • Сервис начисления баллов лояльности Accrual/Mockaccrual (запросы к нему выполняются через предоставленное им REST API и реализация сокрыта)

Краткий сценарий использования:

  1. Пользователь регистрируется в системе лояльности Gophermart.
  2. Совершая покупки пользователь загружает в систему Gophermart номера заказов.
  3. Система Gophermart направляет номера заказов в систему начисления баллов лояльности Accrual.
  4. Accrual производит расчет баллов лояльности.
  5. Accrual может вернуть ответ без баллов лояльности со статусом PROCESSING.
  6. Полученные ответы от Accrual обрабатываются в зависимости от статуса ответа.
  7. У каждого пользователя ведётся баланс его баллов лояльности.
  8. Пользователь при наличии баллов лояльности может потратить их на покупки (списав на определенный заказ)

Схема связей таблиц в базе данных. schema.png

Для взаимодействия с сервисами предоставляется HTTP API.

Используемые технологии:

  • Docker/Docker compose

  • PostgreSQL/pgx

  • Gin

  • Middleware

  • JWT auth

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

Запуск возможен с использованием cli флагов и env переменных

  • SERVER_ADDRESS (-a):Адрес сервера: По умолчанию — localhost:8090.

  • LOG_LEVEL (-l):Уровень логирования: По умолчанию установлен на info.

  • ACCRUAL_SYSTEM_ADDRESS (-b): Адрес внешнего сервиса расчета бонусных баллов: По умолчанию — http://localhost:8080/api/orders/.

  • DATABASE_URI (-d):Данные для подключения к базе данных: По умолчанию установлен на пусто.

  • FILE_STORAGE_PATH (-f):Путь сохранения файла локального хранения данных: По умолчанию установлен на /tmp/gopher-mart-db.json.

Особенности проекта в т.ч. сложности, которые предстояло решить в процессе написания кода.

Проект прежде всего учебный, поэтому считаю возможным уточнить некоторые решенные нюансы:

  • Система accrual была представлена "черным ящиком", внутреннее устройство неизвестно (известны только форматы ответов).

  • Основной проблемой было то, что время ответа сервиса было рандомным и чтобы пользователь не повис в ожидании ответа, нужно было разработать механику ответов клиенту. Для этого запрос к сервису осуществлялся асинхронно

  • Потребовалось отслеживать какие номера заказов отправлялись в accrual систему, чтобы избежать отправки дублирующих запросов. Для этого в таблице orders были добавлены поля для отслеживания состояния (готовность к отправке в accrual и т.д.)

В рамках одного запросы происходит выборка заказов, у которых НЕ окончательный статус и имеется статус true для возможности отправки в accrual. В свою очередь при получении ответа от accrual происходит обновление заказа в соответствии с полученным статусом:

Т.е. если у заказа статус не являются окончательным - флаг возможности отправки в accrual снова меняется на true, таким образом заказ будет повторно обработан. В итоге gophermart не отправляет в accrual уже отправленные заказы.

  • Для таблицы balance первоначально были созданы неименованные constraint: current >= 0 и withdrawn >= 0.

Однако был обнаружен баг, при котором общая проверка CheckViolation одинаково понимала и нарушение для баланса и для списаний. Соответственно указанные constraints были заменены на именованные, при этом добавлена проверка конкретно для constraint баланса:

  • В проекте старался обработать все возможные ошибки и залогировать их выводя в cli, а также сохраняя в во временный файл при помощи конфигурации logrus и lumberjack. Убедился, насколько это упростило отладку приложения.

  • Так как в проекте предполагаются финансовые операции был использован пакет shopspring/decimal

TODO

  • Интеграционные тесты (testcontainers)
  • Godoc

About

Мой выпускной проект YandexPracticum

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages