Skip to content

Latest commit

 

History

History
510 lines (350 loc) · 23.6 KB

SPECIFICATION.md

File metadata and controls

510 lines (350 loc) · 23.6 KB

Техническое задание (для команд)

Накопительная система лояльности «Гофермарт»


Отличия от ТЗ для индивидуальной работы выделены линиями.


Общие требования

Система представляет собой HTTP API со следующими требованиями к бизнес-логике:

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

image

Абстрактная схема взаимодействия с системой

Ниже представлена абстрактная бизнес-логика взаимодействия пользователя с системой:

  1. Пользователь регистрируется в системе лояльности «Гофермарт».
  2. Пользователь совершает покупку в интернет-магазине «Гофермарт».
  3. Заказ попадает в систему расчёта баллов лояльности.
  4. Пользователь передаёт номер совершённого заказа в систему лояльности.
  5. Система связывает номер заказа с пользователем и сверяет номер с системой расчёта баллов лояльности.
  6. При наличии положительного расчёта баллов лояльности производится начисление баллов лояльности на счёт пользователя.
  7. Пользователь списывает доступные баллы лояльности для частичной или полной оплаты последующих заказов в интернет-магазине «Гофермарт».

Примечание: пункт 2 представлен как гипотетический и не требует реализации в данной работе.


Система расчета баллов лояльности


Система расчёта баллов лояльности является отдельным сервисом в доверенном контуре. В рамках командной разработки вам также предстоит разработать данный сервис.

Сводное API системы расчёта баллов лояльности будет предоставлено в конце.


Сводное HTTP API накопительной системы

Накопительная система лояльности «Гофермарт» должна предоставлять следующие HTTP-хендлеры:

  • POST /api/user/register — регистрация пользователя;
  • POST /api/user/login — аутентификация пользователя;
  • POST /api/user/orders — загрузка пользователем номера заказа для расчёта;
  • GET /api/user/orders — получение списка загруженных пользователем номеров заказов, статусов их обработки и информации о начислениях;
  • GET /api/user/balance — получение текущего баланса счёта баллов лояльности пользователя;
  • POST /api/user/balance/withdraw — запрос на списание баллов с накопительного счёта в счёт оплаты нового заказа;
  • GET /api/user/withdrawals — получение информации о выводе средств с накопительного счёта пользователем.

Общие ограничения и требования

  • хранилище данных — PostgreSQL;
  • структура таблиц остаётся на усмотрение студента;
  • типы и формат хранения данных (в том числе паролей и прочей чувствительной информации) остаётся на усмотрение студента;
  • клиент может поддерживать HTTP-запросы/ответы со сжатием данных;
  • клиент не обязан делать запросы соответственно нижеизложенной спецификации API, любая проверка запроса остаётся на усмотрение студента;
  • формат и алгоритм проверки аутентификации и авторизации пользователя остаётся на усмотрение студента;
  • номера заказов уникальны и никогда не повторяются;
  • номер заказа может быть принят в обработку только один раз от одного пользователя;
  • номер заказа может не иметь никакого начисления;
  • вознаграждение начисляется и тратится в виртуальных баллах из расчёта 1 балл = 1 рубль.

Регистрация пользователя

Хендлер: POST /api/user/register.

Регистрация производится по паре логин/пароль. Каждый логин должен быть уникальным. После успешной регистрации должна происходить автоматическая аутентификация пользователя.

Формат запроса:

POST /api/user/register HTTP/1.1
Content-Type: application/json
...

{
	"login": "<login>",
	"password": "<password>"
}

Возможные коды ответа:

  • 200 — пользователь успешно зарегистрирован и аутентифицирован;
  • 400 — неверный формат запроса;
  • 409 — логин уже занят;
  • 500 — внутренняя ошибка сервера.

Аутентификация пользователя

Хендлер: POST /api/user/login.

Аутентификация производится по паре логин/пароль.

Формат запроса:

POST /api/user/login HTTP/1.1
Content-Type: application/json
...

{
	"login": "<login>",
	"password": "<password>"
}

Возможные коды ответа:

  • 200 — пользователь успешно аутентифицирован;
  • 400 — неверный формат запроса;
  • 401 — неверная пара логин/пароль;
  • 500 — внутренняя ошибка сервера.

Загрузка номера заказа

Хендлер: POST /api/user/orders.

Хендлер доступен только аутентифицированным пользователям. Номером заказа является последовательность цифр произвольной длины.

Номер заказа может быть проверен на корректность ввода с помощью алгоритма Луна{target="_blank"}.

Формат запроса:

POST /api/user/orders HTTP/1.1
Content-Type: text/plain
...

12345678903

Возможные коды ответа:

  • 200 — номер заказа уже был загружен этим пользователем;
  • 202 — новый номер заказа принят в обработку;
  • 400 — неверный формат запроса;
  • 401 — пользователь не аутентифицирован;
  • 409 — номер заказа уже был загружен другим пользователем;
  • 422 — неверный формат номера заказа;
  • 500 — внутренняя ошибка сервера.

Получение списка загруженных номеров заказов

Хендлер: GET /api/user/orders.

Хендлер доступен только авторизованному пользователю. Номера заказа в выдаче должны быть отсортированы по времени загрузки от самых новых к самым старым. Формат даты — RFC3339.

Доступные статусы обработки расчётов:

  • NEW — заказ загружен в систему, но не попал в обработку;
  • PROCESSING — вознаграждение за заказ рассчитывается;
  • INVALID — система расчёта вознаграждений отказала в расчёте;
  • PROCESSED — данные по заказу проверены и информация о расчёте успешно получена.

Формат запроса:

GET /api/user/orders HTTP/1.1
Content-Length: 0

Возможные коды ответа:

  • 200 — успешная обработка запроса.

    Формат ответа:

    200 OK HTTP/1.1
    Content-Type: application/json
    ...
    
    [
    	{
            "number": "9278923470",
            "status": "PROCESSED",
            "accrual": 500,
            "uploaded_at": "2020-12-10T15:15:45+03:00"
        },
        {
            "number": "12345678903",
            "status": "PROCESSING",
            "uploaded_at": "2020-12-10T15:12:01+03:00"
        },
        {
            "number": "346436439",
            "status": "INVALID",
            "uploaded_at": "2020-12-09T16:09:53+03:00"
        }
    ]
    
  • 204 — нет данных для ответа.

  • 401 — пользователь не авторизован.

  • 500 — внутренняя ошибка сервера.

Получение текущего баланса пользователя

Хендлер: GET /api/user/balance.

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

Формат запроса:

GET /api/user/balance HTTP/1.1
Content-Length: 0

Возможные коды ответа:

  • 200 — успешная обработка запроса.

    Формат ответа:

    200 OK HTTP/1.1
    Content-Type: application/json
    ...
    
    {
    	"current": 500.5,
    	"withdrawn": 42
    }
    
  • 401 — пользователь не авторизован.

  • 500 — внутренняя ошибка сервера.

Запрос на списание средств

Хендлер: POST /api/user/balance/withdraw

Хендлер доступен только авторизованному пользователю. Номер заказа представляет собой гипотетический номер нового заказа пользователя в счет оплаты которого списываются баллы.

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

Формат запроса:

POST /api/user/balance/withdraw HTTP/1.1
Content-Type: application/json

{
	"order": "2377225624",
    "sum": 751
}

Здесь order — номер заказа, а sum — сумма баллов к списанию в счёт оплаты.

Возможные коды ответа:

  • 200 — успешная обработка запроса;
  • 401 — пользователь не авторизован;
  • 402 — на счету недостаточно средств;
  • 422 — неверный номер заказа;
  • 500 — внутренняя ошибка сервера.

Получение информации о выводе средств

Хендлер: GET /api/user/withdrawals.

Хендлер доступен только авторизованному пользователю. Факты выводов в выдаче должны быть отсортированы по времени вывода от самых новых к самым старым. Формат даты — RFC3339.

Формат запроса:

GET /api/user/withdrawals HTTP/1.1
Content-Length: 0

Возможные коды ответа:

  • 200 — успешная обработка запроса.

    Формат ответа:

    200 OK HTTP/1.1
    Content-Type: application/json
    ...
    
    [
        {
            "order": "2377225624",
            "sum": 500,
            "processed_at": "2020-12-09T16:09:57+03:00"
        }
    ]
    
  • 204 - нет ни одного списания.

  • 401 — пользователь не авторизован.

  • 500 — внутренняя ошибка сервера.


Всё, что ниже, — изменённая часть задания.


Взаимодействие с системой расчёта начислений баллов лояльности

Для взаимодействия с системой доступен один хендлер:

  • GET /api/orders/{number} — получение информации о расчёте начислений баллов лояльности.

Общее количество запросов информации о начислении не ограничено.

Конфигурирование сервиса накопительной системы лояльности

Сервис должн поддерживать конфигурирование следующими методами:

  • адрес и порт запуска сервиса: переменная окружения ОС RUN_ADDRESS или флаг -a
  • адрес подключения к базе данных: переменная окружения ОС DATABASE_URI или флаг -d
  • адрес системы расчёта начислений: переменная окружения ОС ACCRUAL_SYSTEM_ADDRESS или флаг -r

Система расчёта вознаграждений «Гофермарт»

Общие требования

Система представляет собой HTTP API со следующими требованиями к бизнес-логике:

  • регистрация новых механик вознаграждений;
  • приём номеров заказов от доверенного источника для расчёта вознаграждений;
  • проведение расчёта вознаграждений за заказы;
  • выдача информации о проведённом расчёте вознаграждений за заказ.

Сводное HTTP API системы расчёта баллов лояльности

Системы расчёта баллов лояльности должна предоставлять следующие HTTP-хендлеры:

  • GET /api/orders/{number} — получение информации о расчёте начислений баллов лояльности;
  • POST /api/orders — регистрация нового совершённого заказа;
  • POST /api/goods — регистрация информации о новой механике вознаграждения за товар.

Общие ограничения и требования

  • хранилище данных — PostgreSQL;
  • структура таблиц остаётся на усмотрение студента;
  • типы и формат хранения данных (в том числе паролей и прочей чувствительной информации) остаются на усмотрение студента;
  • клиент может поддерживать HTTP-запросы/ответы со сжатием данных;
  • клиент не обязан делать запросы соответственно нижеизложенной спецификации API, любая проверка запроса остаётся на усмотрение студента;
  • аутентификации запросов не требуется;
  • номера заказов уникальны и никогда не повторяются;
  • номер заказа может быть принят в обработку только один раз;
  • номер заказа может не иметь никакого начисления.

Получение информации о расчёте начислений

Хендлер: GET /api/orders/{number}.

Получение информации о расчёте начислений баллов лояльности за совершённый заказ.

Номером заказа является последовательность цифр произвольной длины. Номер заказа может быть проверен на корректность ввода с помощью алгоритма Луна{target="_blank"}.

Формат запроса:

GET /api/orders/{number} HTTP/1.1
Content-Length: 0

Возможные коды ответа:

  • 200 — успешная обработка запроса.

    Формат ответа:

    200 OK HTTP/1.1
    Content-Type: application/json
    ...
    
    {
        "order": "<number>",
        "status": "PROCESSED",
        "accrual": 500
    }
    

    Поля объекта ответа:

    • order — номер заказа;

    • status — статус расчёта начисления:

      • REGISTERED — заказ зарегистрирован, но не начисление не рассчитано;
      • INVALID — заказ не принят к расчёту, и вознаграждение не будет начислено;
      • PROCESSING — расчёт начисления в процессе;
      • PROCESSED — расчёт начисления окончен;
    • accrual — рассчитанные баллы к начислению, при отсутствии начисления — поле отсутствует в ответе.

  • 204 - заказ не зарегистрирован в системе расчета.

  • 429 — превышено количество запросов к сервису.

    Формат ответа:

    429 Too Many Requests HTTP/1.1
    Content-Type: text/plain
    Retry-After: 60
    
    No more than N requests per minute allowed
    
  • 500 — внутренняя ошибка сервера.

Регистрация нового совершённого заказа

Хендлер: POST /api/orders.

Регистрация нового совершённого заказа. Для начисления баллов состав заказа должен быть проверен на совпадения с зарегистрированными записями вознаграждений за товары. Начисляется сумма совпадений.

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

Формат запроса:

POST /api/orders HTTP/1.1
Content-Type: application/json

{
	"order": "<number>",
	"goods": [
		{
			"description": "Чайник Bork",
			"price": 7000
		},
		...
	]
}

Поля объекта запроса:

  • order — номер заказа;
  • goods — список купленых товаров:
    • description — наименование товара;
    • price — цена оплаченного товара.

Возможные коды ответа:

  • 202 — заказ успешно принят в обработку;
  • 400 — неверный формат запроса;
  • 409 — заказ уже принят в обработку;
  • 500 — внутренняя ошибка сервера.

Регистрация информации о вознаграждении за товар

Хендлер: POST /api/goods.

Регистрация информации о вознаграждении за товар. Хендлер используется менеджерами для добавления механик вознаграждения за покупки.

Полученные системой расчёта начислений составы чеков проверяются на совпадение с зарегистрированными в данном хендлере вознаграждениями.

Механика должна иметь уникальный ключ поиска (поле match).

Формат запроса:

POST /api/goods HTTP/1.1
Content-Type: application/json

{
	"match": "Bork",
	"reward": 10,
	"reward_type": "%"
}

Поля объекта запроса:

  • match — ключ поиска (проверяется на наличие в строке наименования товара), не может быть пустым;
  • reward — размер вознаграждения;
  • reward_type — тип вознаграждения:
    • % — процент от стоимости товара;
    • pt — точное количество баллов.

Возможные коды ответа:

  • 200 — вознаграждение успешно зарегистрировано;
  • 400 — неверный формат запроса;
  • 409 — ключ поиска уже зарегистрирован;
  • 500 — внутренняя ошибка сервера.

Конфигурирование сервиса системы расчёта вознаграждений

Сервис должн поддерживать конфигурирование следующими методами:

  • адрес и порт запуска сервиса: переменная окружения ОС RUN_ADDRESS или флаг -a
  • адрес подключения к базе данных: переменная окружения ОС DATABASE_URI или флаг -d