From 3d3f10647b3a4e9c016d6e0a51cb19d59aa13f88 Mon Sep 17 00:00:00 2001 From: Dmitry Kopylov Date: Sat, 17 May 2025 15:06:08 +0300 Subject: [PATCH] [HW-1] added docs --- docs/README.md | 18 ++ docs/homework-1/README.md | 274 ++++++++++++++++++ docs/homework-1/cart.http | 86 ++++++ docs/homework-1/http-client.env.example.json | 5 + docs/homework-1/img/cart-cart-clear.plantuml | 13 + docs/homework-1/img/cart-cart-clear.png | Bin 0 -> 15458 bytes .../img/cart-cart-item-add.plantuml | 21 ++ docs/homework-1/img/cart-cart-item-add.png | Bin 0 -> 28772 bytes .../img/cart-cart-item-delete.plantuml | 13 + docs/homework-1/img/cart-cart-item-delete.png | Bin 0 -> 16219 bytes docs/homework-1/img/cart-cart-list.plantuml | 25 ++ docs/homework-1/img/cart-cart-list.png | Bin 0 -> 36555 bytes 12 files changed, 455 insertions(+) create mode 100644 docs/README.md create mode 100644 docs/homework-1/README.md create mode 100644 docs/homework-1/cart.http create mode 100644 docs/homework-1/http-client.env.example.json create mode 100644 docs/homework-1/img/cart-cart-clear.plantuml create mode 100644 docs/homework-1/img/cart-cart-clear.png create mode 100644 docs/homework-1/img/cart-cart-item-add.plantuml create mode 100644 docs/homework-1/img/cart-cart-item-add.png create mode 100644 docs/homework-1/img/cart-cart-item-delete.plantuml create mode 100644 docs/homework-1/img/cart-cart-item-delete.png create mode 100644 docs/homework-1/img/cart-cart-list.plantuml create mode 100644 docs/homework-1/img/cart-cart-list.png diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..36737af --- /dev/null +++ b/docs/README.md @@ -0,0 +1,18 @@ +# Домашние задания + +## Введение + + В рамках учебного проекта предстоит реализовать систему, состоящую из нескольких сервисов, которая +будет моделировать работу простого интернет магазина включая такие бизнес процессы как: + +- добавление товаров в корзину и их удаление из нее +- просмотр содержимого корзины +- оформление заказа по текущему составу корзины +- создание заказа +- оплата заказа +- отмена заказа пользователем или по истечению времени ожидания оплаты + +## Содержание + +1. [Основы Go](./homework-1) + diff --git a/docs/homework-1/README.md b/docs/homework-1/README.md new file mode 100644 index 0000000..194c3a1 --- /dev/null +++ b/docs/homework-1/README.md @@ -0,0 +1,274 @@ +# Домашнее задание по модулю "Основы Go" + +Необходимо реализовать сервис для работы с корзиной пользователя Cart + +## Основное задание + + Необходимо имплементировать сервис, отвечающий за работу с корзиной пользователя (сервис Cart). Логика работы методов +и их контракты описаны ниже. + +Требования к решению: + +1. Используем HTTP, на основе стандартной библиотеки Go 1.23 +2. Для определения существования товара делаем поход в сервис `products` +3. Состояние храним в in-memory, персистентное хранилище на данный момент не требуется +4. Никакого резерва стоков не делаем, логика простейшая + +## Дополнительное задание + +1. Делаем Middleware, который будет логировать поступающие запросы +2. Делаем валидацию входящих структур на основе любой Open Source библиотеки (можно подсмотреть + тут - https://awesome-go.com/validation/) +3. Делаем ретраи в `products` на 420/429 статус в виде Client Middleware. 3 ретрая, потом ошибка + +## Спецификация + +### Добавить товар в корзину + + Идентификатором товара является числовой идентификатор SKU. Метод добавляет указанный товар в корзину +определенного пользователя. Каждый пользователь имеет числовой идентификатор userID. При добавлении в корзину +проверяем, что товар существует в специальном сервисе. + +Один и тот же товар может быть добавлен в корзину несколько раз, при этом количество экземпляров складывается. + +| Метод | URI | +|-------|-------------------------------------------------| +| POST | /user//cart/ | + +**Параметры запроса:** + +| Параметр | Тип параметра | Тип данных | Пример | Описание | +|----------|---------------|------------|--------|------------------------------------------------------------------| +| user_id | query path | int64 | 1007 | Идентификатор пользователя, в корзину которого добавляется товар | +| sku_id | query path | int64 | 2008 | Идентификатор товара, добавляемого в корзину | +| count | body | uint32 | 12 | Количество товаров, добавляемое в корзину | + +**Параметры ответа:** + +отсутствуют + +**Параметры ошибочных ответов:** + +| Сценарий | HTTP код ошибки | Описание | +|-------------------------------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------| +| Добавление валидного SKU для пользователя (user_id) с нулевым или отрицательным значением | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) | +| Добавление SKU с нулевым или отрицательным значением | 400 | SKU должен быть натуральным числом (больше нуля) | +| Добавление SKU с нулевым или отрицательным количеством (count) | 400 | Количество должно быть натуральным числом (больше нуля) | +| Добавление несуществующего SKU в корзину | 412 | SKU должен существовать в сервисе `products` | + +**Диаграмма последовательности:** + +![cart-cart-item-add](img/cart-cart-item-add.png) + + +### Удалить товар из корзины + + Метод полностью удаляет все количество товара из корзины пользователя. Если у пользователя вовсе нет данной позиции, +то возвращается такой же ответ, как будто бы все позиции данного sku были успешно удалены. + +| Метод | URI | +|--------|-------------------------------------------------| +| DELETE | /user//cart/ | + +**Параметры запроса:** + +| Параметр | Тип параметра | Тип данных | Пример | Описание | +|----------|---------------|------------|--------|------------------------------------------------------------------| +| user_id | query path | int64 | 1007 | Идентификатор пользователя, в корзину которого добавляется товар | +| sku_id | query path | int64 | 2008 | Идентификатор товара, удаляемого из корзины | + +**Параметры ответа:** + +отсутствуют + +**Параметры ошибочных ответов:** + +| Сценарий | HTTP код ошибки | Описание | +|------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------| +| Удаление SKU с нулевым или отрицательным значением | 400 | SKU должен быть натуральным числом (больше нуля) | +| Удаление SKU с нулевым или отрицательным пользователем (user_id) | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) | + +**Диаграмма последовательности:** + +![cart-cart-item-delete](img/cart-cart-item-delete.png) + + +### Очистить корзину пользователя + + Метод полностью очищает корзину пользователя. Если у пользователя нет корзины или она пуста, то, как и при успешной +очистке корзины, необходимо вернуть код ответа 204 No Content. + +| Метод | URI | +|--------|----------------------| +| DELETE | /user//cart | + +**Параметры запроса:** + +| Параметр | Тип параметра | Тип данных | Пример | Описание | +|----------|---------------|------------|--------|------------------------------------------------------------------| +| user_id | query path | int64 | 1007 | Идентификатор пользователя, в корзину которого добавляется товар | + +**Параметры ответа:** + +отсутствуют + +**Параметры ошибочных ответов:** + +| Сценарий | HTTP код ошибки | Описание | +|----------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------| +| Удаление корзины с нулевым или отрицательным пользователем (user_id) | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) | + +**Диаграмма последовательности:** + +![cart-cart-clear](img/cart-cart-clear.png) + + +### Получить содержимое корзины + + Метод возвращает содержимое корзины пользователя на текущий момент. Если корзины у переданного пользователя нет, +либо она пуста, следует вернуть 404 код ответа. Товары в корзине упорядочены в порядке возрастания sku. + +| Метод | URI | +|-------|--------------------------| +| GET | /user//cart | + +**Параметры запроса:** + +| Параметр | Тип параметра | Тип данных | Пример | Описание | +|----------|---------------|------------|--------|------------------------------------------------------------------| +| user_id | query path | int64 | 1007 | Идентификатор пользователя, в корзину которого добавляется товар | + +**Параметры ответа:** + +| Параметр | Тип данных | Пример | Описание | +|----------------|------------|--------------------------------------------------|----------------------------------------------| +| items[i].sku | int64 | 2008 | Идентификатор товара в корзине пользователя | +| items[i].name | string | "Гречка пропаренная, в пакетиках для варки, 400" | Наименование товара | +| items[i].count | uint32 | 10 | Количество единиц товара | +| items[i].price | uint32 | 16 | Стоимость единицы товара в условных единицах | +| total_price | uint32 | 160 | Суммарная стоимость всех товаров в корзине | + + +**Пример ответа:** + +```json +{ + "items" : [ + { + "sku": 2958025, + "name": "Roxy Music. Stranded. Remastered Edition", + "count": 2, + "price": 1028 + }, + { + "sku": 773297411, + "name": "Кроссовки Nike JORDAN", + "count": 1, + "price": 2202 + } + ], + "total_price": 4258 +} +``` + +**Параметры ошибочных ответов:** + +| Сценарий | HTTP код ошибки | Описание | +|--------------------------------------------------------------------|-----------------|-------------------------------------------------------------------------| +| Запрос корзины с нулевым или отрицательным пользователем (user_id) | 400 | Идентификатор пользователя должен быть натуральным числом (больше нуля) | + + +**Диаграмма последовательности:** + +![cart-cart-list](img/cart-cart-list.png) + + +## Взаимодействие с Product service + +Если, вызвав `make run-all`, развернуть деплоймент, swagger этого сервиса +можно увидеть локально по адресу: [http://localhost:8082/docs/](http://localhost:8082/docs/) + +Сервис поддерживает следующие операции: + + +#### GET /product?count=10&start_after_sku=0 + +Эта операция имеет два необязательных параметра: + - `count` — сколько элементов вернуть и + - `start_after_sku` — после какого элемента начать вывод. + +Response: +``` +[ + { + name string + price int32 + sku int64 + }, +] +``` + +#### GET /product/<sku> + +Эта операция выводит данные товара с заданным `sku`. + +Response: +``` + { + name string + price int32 + sku int64 + } +``` + +Обратите внимание, сервис `products` отдаёт цены в `int32` формате. +В JSON нет беззнаковых целых, поэтому `int32`. +Вам же, внутри своих сервисов, для совместимости их между собой +следует использовать беззнаковый тип `uint32`. + +Также следует обратить внимание на то, что он выведен на `localhost:8082` лишь +для вашего удобства работы с данными. + +Ваш сервис `cart`, запущенный докер-контейнером, сможет подключиться к `products` +по адресу `products:8082` — заниматься маршрутизацией будет сам докер. + +Авторизация на запрос выполняется с помощью заголовка `X-API-KEY` и токена `testToken`. + +## Makefile + +В рамках данного задания необходимо имплементировать следующие таргеты: + +- run-all — запускает сервисы. На данный момент их должно стать два: + - `products` — уже реализован + - `cart` — разрабатываемый вами в качестве домашнего задания + +## Ожидаемый результат + +- с помощью команды `make run-all` можно запустить приложение +- приложение слушает HTTP-запросы на порту 8080 +- реализованы API-методы + - POST /user//cart/ + - DELETE /user//cart/ + - DELETE /user//cart + - GET /user//cart +- методы реализуют заявленную бизнес-логику +- методы валидируют запросы и отдают описанные в спецификации коды ошибок +- информация о пользователях и их состоянии корзины хранится в памяти приложения +- при рестарте приложения состояние системы теряется + +## Автоматические проверки +Ваше решение должно проходить автоматические проверки: + +- Компиляция +- Линтер +- Unit-тесты (если есть) +- Автотесты + +Прохождение автоматических проверок влияет на итоговую оценку за домашнюю работу. + +## Сценарии тестирования с примерами запроса (для тьютора) + +Сценарий тестирования следует описать в [cart.http](./cart.http) + +### Дедлайны сдачи и проверки задания: +- 24 мая 23:59 (сдача) / 27 мая, 23:59 (проверка) diff --git a/docs/homework-1/cart.http b/docs/homework-1/cart.http new file mode 100644 index 0000000..aa5ed20 --- /dev/null +++ b/docs/homework-1/cart.http @@ -0,0 +1,86 @@ +### add 1 sku to cart +POST http://localhost:8080/user/31337/cart/1076963 +Content-Type: application/json + +{ + "count": 1 +} +### expected {} 200 OK; must add 1 item + +### add 5 sku to cart +POST http://localhost:8080/user/31337/cart/1076963 +Content-Type: application/json + +{ + "count": 5 +} +### expected {} 200 OK; must add 5 more item, 1076963 - must be 6 items + +### add unknown sku to cart +POST http://localhost:8080/user/31337/cart/1076963000 +Content-Type: application/json + +{ + "count": 1 +} +### expected {} 412 Precondition Failed; invalid sku + +### add another sku to cart +POST http://localhost:8080/user/31337/cart/1148162 +Content-Type: application/json + +{ + "count": 1 +} +### expected {} 200 OK; must add 1 item + +### invalid user +POST http://localhost:8080/user/0/cart/1148162 +Content-Type: application/json + +{ + "count": 1 +} +### expected {} 400 Bad Request + +### invalid sku +POST http://localhost:8080/user/31337/cart/0 +Content-Type: application/json + +{ + "count": 1 +} +### expected {} 400 Bad Request + +### invalid count +POST http://localhost:8080/user/31337/cart/1148162 +Content-Type: application/json + +{ + "count": 0 +} +### expected {} 400 Bad Request + +# ======================================================================================== + +### delete whole sku from cart +DELETE http://localhost:8080/user/31337/cart/1076963 +Content-Type: application/json +### expected {} 200 OK; must delete item from cart + +### delete whole cart +DELETE http://localhost:8080/user/31337/cart +Content-Type: application/json +### expected {} 204 No Content; must delete cart + +# ======================================================================================== + +### get list of a cart +GET http://localhost:8080/user/31337/cart +Content-Type: application/json +### expected {} 200 OK; must show cart + +### get invalid list of cart +GET http://localhost:8080/user/0/cart +Content-Type: application/json +### 400 bad request diff --git a/docs/homework-1/http-client.env.example.json b/docs/homework-1/http-client.env.example.json new file mode 100644 index 0000000..f3f141c --- /dev/null +++ b/docs/homework-1/http-client.env.example.json @@ -0,0 +1,5 @@ +{ + "dev": { + "port": "8080" + } +} diff --git a/docs/homework-1/img/cart-cart-clear.plantuml b/docs/homework-1/img/cart-cart-clear.plantuml new file mode 100644 index 0000000..ce0f174 --- /dev/null +++ b/docs/homework-1/img/cart-cart-clear.plantuml @@ -0,0 +1,13 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs + +u -> c : DELETE /user//cart +activate c +c -> cs : cart.DeleteItemsByUserID +c -> u : Response: 204 No Content +deactivate c + +@enduml diff --git a/docs/homework-1/img/cart-cart-clear.png b/docs/homework-1/img/cart-cart-clear.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef96b06cc715b336edccc5880e9735890bb1b7c GIT binary patch literal 15458 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 literal 0 HcmV?d00001 diff --git a/docs/homework-1/img/cart-cart-item-add.plantuml b/docs/homework-1/img/cart-cart-item-add.plantuml new file mode 100644 index 0000000..730a769 --- /dev/null +++ b/docs/homework-1/img/cart-cart-item-add.plantuml @@ -0,0 +1,21 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs +collections ProductService as p + +u -> c : POST /user//cart/\n\t- count +activate c + +c -> p : GET /product/ +activate p + p -> c : \nResponse: 200 OK\n\t- name\n\t- price\n\t- sku +deactivate p +c -> c : validate product exists +c -> cs : cart.AddItem() +c -> u : Response: 200 OK + +deactivate c + +@enduml diff --git a/docs/homework-1/img/cart-cart-item-add.png b/docs/homework-1/img/cart-cart-item-add.png new file mode 100644 index 0000000000000000000000000000000000000000..8d36e4799b40d889a574b37c2be6d7d4defec2c5 GIT binary patch literal 28772 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%0At_(fyo)Nd4Ox- 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 literal 0 HcmV?d00001 diff --git a/docs/homework-1/img/cart-cart-item-delete.plantuml b/docs/homework-1/img/cart-cart-item-delete.plantuml new file mode 100644 index 0000000..0e3e590 --- /dev/null +++ b/docs/homework-1/img/cart-cart-item-delete.plantuml @@ -0,0 +1,13 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs + +u -> c : DELETE /user//cart/ +activate c +c -> cs : cart.DeleteItem(userID, skuID) +c -> u : Response: 204 No Content +deactivate c + +@enduml diff --git a/docs/homework-1/img/cart-cart-item-delete.png b/docs/homework-1/img/cart-cart-item-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..ff2befc4ec8208d4a77fc2f1a578afdf48365c76 GIT binary patch literal 16219 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

gsT+EFJ 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 HuigD$i8_vA literal 0 HcmV?d00001 diff --git a/docs/homework-1/img/cart-cart-list.plantuml b/docs/homework-1/img/cart-cart-list.plantuml new file mode 100644 index 0000000..df61339 --- /dev/null +++ b/docs/homework-1/img/cart-cart-list.plantuml @@ -0,0 +1,25 @@ +@startuml + +actor User as u +collections Cart as c +database CartStorage as cs +collections ProductService as p + +u -> c : GET /user//cart +activate c +c -> cs : cart.GetItemsByUserID +alt cart exists + loop for each item in cart + c -> p : GET /product/ + activate p + p -> c : Response: 200 OK\n\t- name\n\t- price\n\t- sku + deactivate p + c -> c : calculate total price + end + c -> u : Response: 200 OK\n\t- []item\n\t- total_price +else + c -> u : Response: 404 Not Found +end +deactivate c + +@enduml diff --git a/docs/homework-1/img/cart-cart-list.png b/docs/homework-1/img/cart-cart-list.png new file mode 100644 index 0000000000000000000000000000000000000000..b0e3b70e5c3f2a35be86cf5d1274d29ee1cfe109 GIT binary patch literal 36555 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

^w9XM&%f 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