Skip to content

grabr/challenge-2022

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Задача: сервис переводов денег другим пользователям с конвертацией

Описание

Нужно дописать Rails-приложение для переводов денег между пользователями, с автоматической конвертацией валют.

В приложении две модели:

  • User (может посылать и принимать переводы), с такими аттрибутами:
    • balance_cents: баланс в центах
    • balance_currency: валюта баланса (ARS|BRL|MXN)
    • pending_balance_cents: баланс с учетом неокончившихся переводов.
    • external_id: ID пользователя во внешнем сервисе (об этом ниже)
  • Transfer (перевод), с аттрибутами:
    • sender_id: ID отправителя (User)
    • receiver_id: ID получателя (User)
    • amount_cents: размер перевода (в валюте отправителя)
    • rate: курс обмена (в валюту получателя)
    • external_id: ID перевода во внешнем сервисе
    • status:
      • pending: перевод создан и отправлен во внешний сервис
      • succeeded: перевод завершился успешно
      • failed: перевод завершился с ошибкой (т.е. фактически перевода не произошло)

Есть внешний сервис (т.е. мы отправляем туда HTTP-запросы):

  • Gateway (lib/gateway.rb):
    • .create_transfer(from_id:, to_id:, amount_cents:):
    • создает перевод во внешнем сервисе, где from_id и to_idexternal_id юзеров
    • возращает:
      • transfer_id – ID созданного трансфера во внешнем сервисе
      • rate - рейт, по которому происходит конвертация между валютой отправителя и валютой получателя
    • через некоторое время после запроса отправляет вебхук со статусом перевода (succeeded или failed)

Есть 2 контроллера:

  • TransfersController:
    • Вызывается пользователями сервиса для отправки переводов
    • Принимает параметры:
      • to_id – ID юзера, которому делаем перевод
      • amount_cents – Сумма перевода в центах (считаем, что в валюте отправителя)
    • В контроллере есть аутентификация, поэтому можем обращаться к current_user (который будет отправителем перевода)
  • WebhooksController:
    • Принимает вебхуки о статусах переводов от Gateway
    • Параметры:
      • transfer_id – ID перевода в gateway (наш external_id)
      • status – статус перевода (succeeded или failed)

Задача

  • Заимплементить контроллеры с условиями:
    • TransfersController:
      • Transfer не может быть создан, если баланс отправителя меньше суммы в запросе (подсказка: для этого можно использовать pending_balance_cents)
      • Нужно создать трансфер во внешнем сервисе Gateway
      • Нужно создать Transfer в базе со статусом pending, external_id и rate из предыдущего пункта
      • Если на каком-то из шагов произошла ошибка, нужно вернуть статус 400 с текстом этой ошибки
    • WebhooksController:
      • Нужно обработать статус трансфера и в зависимости от него обновить балансы пользователей (учитывая rate)
      • Если мы вынуждены по какой-либо причине упасть, и хотим, чтобы вебхук пришел еше раз, нужно вернуть статус 400
  • Нужно учитывать, что сервис – высоконагруженный, то есть одновременно приходит много запросов
  • Баланс пользователей не может опускаться ниже нуля ни при каких условиях
  • Важно не только написать "работающий" production-ready код, но и удобно его организовать: можно писать сервисы, использовать гемы (допустим, есть все, какие нужно) и тд.

Нужные файлы

  • app/controllers/v1/transfers_controller.rb – эндпойнт создания трансферов
  • app/controllers/webhooks_controller.rb – сюда приходят вебхуки
  • app/models/transfer.rb – трансфер
  • app/models/user.rb - юзер
  • lib/gateway.rb – клиент, общающийся с внешним сервисом

About

Live-coding challenge for backend developers

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages