mirror of
				https://github.com/3ybactuk/marketplace-go-service-project.git
				synced 2025-10-31 06:23:44 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			263 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			263 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Домашнее задание по модулю "Межсервисное взаимодействие и основы эксплуатации"
 | ||
| 
 | ||
| Добавить сервис LOMS и организовать взаимодействие между cart и loms с использованием gRPC.
 | ||
| 
 | ||
| ## Основное задание
 | ||
| 
 | ||
| Необходимо:
 | ||
| - Имплементировать сервис, отвечающий за учет заказов и стоки по товарам. Логика работы методов и их контракты описаны ниже.
 | ||
| - Реализовать взаимодействие сервисов cart и loms через gRPC.
 | ||
| 
 | ||
| Требование к решению:
 | ||
| - Создать protobuf контракт сервиса loms.
 | ||
| - В каждом проекте нужно добавить в Makefile команды для генерации .go файлов из proto файлов и установки нужных зависимостей (используем protoc).
 | ||
| - Состояние храним в in-memory, персистентное хранилище на данный момент не требуется. 2 репозитория - Stock и Order. 
 | ||
| - Код должен быть покрыт тестами (тесты на методы репозитория - не требуются). 
 | ||
| - Добавить gRPC интерцептор, который будет валидировать запросы через proto-gen-validator (правила валидации указываются в *.proto).
 | ||
| - Добавить HTTP-gateway. HTTP-запросы также должны проходить валидацию через добавленный выше gRPC интерцептор. 
 | ||
| 
 | ||
| ## Дополнительное задание
 | ||
| - Добавить swagger-ui и возможность совершать запросы из swagger к сервису. 
 | ||
| - Написать end-to-end тесты на все новые методы . 
 | ||
| 
 | ||
| ## Спецификация LOMS (Logistics and Order Management System)
 | ||
| 
 | ||
| Сервис отвечает за учет заказов и стоки по товарам.
 | ||
| 
 | ||
| ### OrderCreate
 | ||
| 
 | ||
| Создает новый заказ для пользователя из списка переданных товаров с резервированием нужного количества стоков:
 | ||
| + заказ получает статус "new"
 | ||
| + резервирует нужное количество единиц товара
 | ||
| + если удалось зарезервировать стоки, заказ получает статус "awaiting payment"
 | ||
| + если не удалось зарезервировать стоки, заказ получает статус "failed", изменение стоков не происходит
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                                                     | gRPC код ошибки (HTTP) | Описание                                                                        |
 | ||
| |------------------------------------------------------------------------------|------------------------|---------------------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением userId                           | 3 (400)                | Идентификатор пользователя должен быть натуральным числом (больше нуля)         |
 | ||
| | Вызов c пустым списком товаров                                               | 3 (400)                | Идентификатор товара должен быть натуральным числом (больше нуля)               |
 | ||
| | Вызов с нулевыми или отрицательными значениями sku в списке                  | 3 (400)                | Количество должно быть натуральным числом (больше нуля)                         |
 | ||
| | Вызов с нулевыми или отрицательными значениями Count для любого sku в списке | 3 (400)                | Count должен быть натуральным числом (больше нуля)                              |
 | ||
| | Превышение стоков хотя бы у одного товара                                    | 9 (400)                | Для всех товаров сток должен быть больше или равен запрашиваемому               |
 | ||
| | Отсутствие информации по стокам в системе                                    | 9 (400)                | Невозможно создать заказ, если по хотя бы одному товару нет информации о стоках |
 | ||
| | Все остальные случаи                                                         | 13 или 2 (500)         | Проблемы из-за неисправностей в системе                                         |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| {
 | ||
|     userId int64
 | ||
|     items []{
 | ||
|         sku int64
 | ||
|         count uint32
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {
 | ||
|     orderId int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### OrderInfo
 | ||
| 
 | ||
| Показывает информацию по заказу. Товары в ответе должны быть отсортированы по SKU в порядке возрастания. 
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                            | gRPC код ошибки (HTTP) | Описание                                                            |
 | ||
| |-----------------------------------------------------|------------------------|---------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением orderId | 3 (400)                | Идентификатор заказа должен быть натуральным числом (больше нуля)   |
 | ||
| | Заказ с указанным orderId отсутствует в системе     | 5 (404)                | Можно получить информацию только для существующего в системе заказа |
 | ||
| | Все остальные случаи                                | 13 или 2 (500)         | Проблемы из-за неисправностей в системе                             |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| {
 | ||
|     orderId int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {
 | ||
|     status string // (new | awaiting payment | failed | payed | cancelled)
 | ||
|     userId int64
 | ||
|     items []{
 | ||
|         sku int64
 | ||
|         count uint32
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### OrderPay
 | ||
| 
 | ||
| Помечает заказ оплаченным. Зарезервированные товары должны перейти в статус купленных.
 | ||
| + удаляем зарезервированные стоки на товаре
 | ||
| + заказ получает статус "payed"
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                            | gRPC код ошибки (HTTP) | Описание                                                          |
 | ||
| |-----------------------------------------------------|------------------------|-------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением orderId | 3 (400)                | Идентификатор заказа должен быть натуральным числом (больше нуля) |
 | ||
| | Оплата несуществующего заказа                       | 5 (404)                | Можно оплачивать только существующий заказ                        |
 | ||
| | Оплата оплаченного заказа                           | 0 (200)                | Оплата оплаченного заказа разрешается                             |
 | ||
| | Оплата заказа в статусе != "awaiting payment"       | 9 (400)                | Оплата заказа в невалидном статусе невозможна                     |
 | ||
| | Все остальные случаи                                | 13 или 2 (500)         | Проблемы из-за неисправностей в системе                           |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| {
 | ||
|     orderId int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {}
 | ||
| ```
 | ||
| 
 | ||
| ### OrderCancel
 | ||
| 
 | ||
| Отменяет заказ, снимает резерв со всех товаров в заказе.
 | ||
| + зарезервированные стоки на товаре становятся свободными стоками
 | ||
| + заказ получает статус "cancelled"
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                            | gRPC код ошибки (HTTP) | Описание                                                          |
 | ||
| |-----------------------------------------------------|------------------------|-------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением orderId | 3 (400)                | Идентификатор заказа должен быть натуральным числом (больше нуля) |
 | ||
| | Отмена несуществующего заказа                       | 5 (404)                | Можно отменять только существующий заказ                          |
 | ||
| | Отмена отмененного заказа                           | 0 (200)                | Отмена отмененного заказа разрешается (идемпотентность)           |
 | ||
| | Отмена заказа в статусе == "payed" или "failed"     | 9 (400)                | Невозможность отменить неудавшийся заказ, а также оплаченный      |
 | ||
| | Все остальные случаи                                | 13 или 2 (500)         | Проблемы из-за неисправностей в системе                           |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| {
 | ||
|     orderId int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {}
 | ||
| ```
 | ||
| 
 | ||
| ### StocksInfo
 | ||
| 
 | ||
| Возвращает количество товаров, которые можно купить. Если товар был зарезервирован у кого-то в заказе и ждет оплаты, его купить нельзя.
 | ||
| - данные по товарам берутся из stock-data.json (embed)
 | ||
| - структура stock:
 | ||
|   - sku - товар
 | ||
|   - total_count - всего товаров
 | ||
|   - reserved - количество зарезервированных
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                         | gRPC код ошибки (HTTP) | Описание                                                           |
 | ||
| |--------------------------------------------------|------------------------|--------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением sku  | 3 (400)                | Идентификатор товара должен быть натуральным числом (больше нуля)  |
 | ||
| | Товара в запросе нет в базе стоков               | 5 (404)                | Можно получить информацию по стокам, если она есть в бд            |
 | ||
| | Все остальные случаи                             | 13 или 2 (500)         | Проблемы из-за неисправностей в системе                            |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| {
 | ||
|     sku int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {
 | ||
|     count uint32
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ## Доработки сервиса cart
 | ||
| 
 | ||
| ### POST /checkout/<user_id>
 | ||
| 
 | ||
| Требуется добавить метод checkout - оформить заказ по всем товарам корзины. Вызывает loms.OrderCreate.
 | ||
| Сервис cart имеет HTTP-интерфейс. Взаимодействие с LOMS - через gRPC.
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| 
 | ||
| | Сценарий                                            | HTTP код ошибки | Описание                                                                |
 | ||
| |-----------------------------------------------------|-----------------|-------------------------------------------------------------------------|
 | ||
| | Вызов с нулевым или отрицательным значением user_id | 400             | Идентификатор пользователя должен быть натуральным числом (больше нуля) |
 | ||
| | Вызов для пустой корзины                            | 404             | Невозможно оформить заказ для пустой корзины                            |
 | ||
| | Все остальные случаи                                | 500             | Проблемы из-за неисправностей в системе                                 |
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| Request
 | ||
| ```
 | ||
| POST /checkout/<user_id> (user_id - int64)
 | ||
| ```
 | ||
| 
 | ||
| Response
 | ||
| ```
 | ||
| {
 | ||
|     order_id int64
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### POST /user/<user_id>/cart/<sku_id>
 | ||
| 
 | ||
| Требуется добавить запрос в метод добавления товаров в корзину на проверку наличия стоков с помощью вызова gRPC метода loms.StocksInfo.
 | ||
| 
 | ||
| **Параметры ошибочных ответов:**
 | ||
| Сценарии из прошлых домашних заданий без изменений. 
 | ||
| 
 | ||
| | Сценарий                                | HTTP код ошибки | Описание                                                           |
 | ||
| |-----------------------------------------|-----------------|--------------------------------------------------------------------|
 | ||
| | Превышение стоков при добавлении товара | 412             | Невозможно добавить товара по количеству больше, чем есть в стоках |
 | ||
| | Все остальные случаи                    | 500             | Проблемы из-за неисправностей в системе                            |
 | ||
| 
 | ||
| 
 | ||
|     
 | ||
| # Путь покупки товаров:
 | ||
| 
 | ||
| - <cart_host>/user/{user_id}/cart/{sku_id} - Добавляем товар в корзину с проверкой на наличие стоков.
 | ||
| - <cart_host>/user/{user_id}/cart || <cart_host>/user/{user_id}/cart/{sku_id} - Можем удалять товары из корзины. 
 | ||
| - <cart_host>/user/{user_id}/cart - Можем получить состав корзины.
 | ||
| - <cart_host>/checkout/{user_id} - Создаем заказ по товарам из корзины. 
 | ||
| - <order_host>/order/pay with body { "orderId": {order_id} } - Оплачиваем заказ.
 | ||
| - <order_host>/order/cancel with body { "orderId": {order_id} } - Можем отменить заказ до оплаты.
 | ||
| 
 | ||
| ### Примечания
 | ||
| * e2e тесты проверяют HTTP коды ошибок, однако gRPC коды должны быть те, что указаны в требованиях. Например, могут быть проблемы с codes.FailedPrecondition, подробнее [тут](https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go).
 | ||
| * Запросы из cart.http, loms.http & loms.grpc основаны на данных, что лежат в stock-data.json
 | ||
| 
 | ||
| ## Автоматические проверки
 | ||
| 
 | ||
| Ваше решение должно проходить автоматические проверки:
 | ||
| 
 | ||
| - Компиляция
 | ||
| - Линтер
 | ||
| - Unit-тесты (если есть)
 | ||
| - Автотесты
 | ||
| 
 | ||
| Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу.
 | ||
| 
 | ||
| ### Дедлайны сдачи и проверки задания: 
 | ||
| - 7 июня 23:59 (сдача) / 10 июня, 23:59 (проверка)
 | 
