Диаграмма последовательности - ludmilashibaevasoft-maker/Ludmila-Shibaeva- GitHub Wiki
Use Cases ..... Диаграмма последовательности
' https://plantuml.com/sequence-diagram
' === Настройка внешнего вида ===
skinparam sequenceMessageAlign center
skinparam responseMessageBelowArrow true
skinparam ParticipantPadding 20
skinparam BoxPadding 10
title Диаграмма последовательности - Покупка товара в интернет-магазине
' === Акторы и участники ===
actor "Покупатель" as Customer
participant "Веб-интерфейс\n(SPA/Мобильное приложение)" as Frontend
participant "API Gateway" as Gateway
participant "Сервис Корзины\n(Cart Service)" as CartService
participant "Сервис Заказов\n(Order Service)" as OrderService
participant "Сервис Склада\n(Inventory Service)" as Inventory
participant "Платежный шлюз\n(Stripe/YooKassa)" as PaymentGateway
participant "Сервис Нотификации\n(Notification Service)" as Notify
database "БД Заказов\n(PostgreSQL)" as OrderDB
database "БД Склада\n(Redis Cache)" as InventoryDB
' === Основной сценарий ===
Customer -> Frontend: Нажимает "Оформить заказ"
activate Frontend
Frontend -> Frontend: Валидация формы\n(адрес, контакты)
Frontend -> Gateway: POST /api/v1/orders\n{ cart_id, delivery_info, payment_method }
activate Gateway
Gateway -> Gateway: Аутентификация пользователя\n(JWT validation)
Gateway -> CartService: GET /carts/{cart_id}/items
activate CartService
CartService -> CartService: Получение списка товаров\nиз корзины
CartService --> Gateway: { items: [{product_id, quantity, price}] }
deactivate CartService
Gateway -> Inventory: POST /inventory/reserve\n{ items }
activate Inventory
Inventory -> InventoryDB: Проверка остатков\n(SELECT stock FROM products WHERE id IN (...))
Inventory -> InventoryDB: Резервирование товара\n(UPDATE stock SET reserved = reserved + quantity)
alt Недостаточно товара на складе
Inventory --> Gateway: 409 Conflict\n{ error: "INSUFFICIENT_STOCK", failed_items: [...] }
Gateway --> Frontend: 409 Conflict
Frontend --> Customer: Показать ошибку:\n"Товара нет в наличии"
note right of Customer
Конец сценария
Клиент может изменить
количество или удалить товар
end note
deactivate Inventory
deactivate Gateway
deactivate Frontend
' Убираем stop - вместо этого просто выходим из alt
else Товар зарезервирован успешно
Inventory --> Gateway: 200 OK\n{ reservation_id: "res_123", expires_at: "15 мин" }
deactivate Inventory
Gateway -> OrderService: POST /orders\n{ user_id, items, delivery_info, payment_method, reservation_id }
activate OrderService
OrderService -> OrderService: Создание заказа\n(status = "PENDING_PAYMENT")
OrderService -> OrderDB: INSERT INTO orders (...)
OrderService -> OrderDB: INSERT INTO order_items (...)
OrderService --> Gateway: 201 Created\n{ order_id, payment_url, amount }
deactivate OrderService
Gateway -> Gateway: Формирование платежной ссылки
Gateway --> Frontend: 201 Created\n{ order_id, payment_url, amount }
deactivate Gateway
Frontend --> Customer: Перенаправление на\nстраницу оплаты
deactivate Frontend
' === Сценарий оплаты ===
Customer -> PaymentGateway: Вводит данные карты\nна странице оплаты
activate PaymentGateway
PaymentGateway -> PaymentGateway: Валидация карты,\nсписание средств
alt Платеж отклонен
PaymentGateway --> Customer: Показать ошибку оплаты
Customer -> Frontend: Возврат в корзину
note right of PaymentGateway
Заказ остается в статусе
PENDING_PAYMENT и будет
автоматически отменен по таймауту
end note
deactivate PaymentGateway
' Выход из сценария без stop
else Платеж успешен
PaymentGateway -> PaymentGateway: Списание средств
PaymentGateway --> Customer: "Оплата прошла успешно"
deactivate PaymentGateway
Customer -> Frontend: Перенаправление на\nстраницу успеха
activate Frontend
Frontend -> Gateway: GET /api/v1/orders/{order_id}/status
activate Gateway
Gateway -> OrderService: GET /orders/{order_id}
activate OrderService
' === Асинхронная обработка после оплаты ===
OrderService -> OrderService: Обновление статуса\n(status = "PAID")
OrderService -> OrderDB: UPDATE orders SET status = 'PAID'
OrderService -> Inventory: POST /inventory/confirm\n{ reservation_id }
activate Inventory
Inventory -> InventoryDB: Финализация резерва\n(перевод reserved -> sold)
Inventory --> OrderService: 200 OK
deactivate Inventory
OrderService -> Notify: POST /notifications/email\n{ user_id, template: "order_confirmation" }
activate Notify
Notify -> Notify: Отправка письма\nс подтверждением
Notify --> OrderService: 202 Accepted
deactivate Notify
OrderService -> Notify: POST /notifications/sms\n{ phone, text: "Ваш заказ №{id} оплачен" }
activate Notify
Notify -> Notify: Отправка SMS
Notify --> OrderService: 202 Accepted
deactivate Notify
OrderService --> Gateway: { status: "PAID", delivery_status: "PROCESSING" }
deactivate OrderService
Gateway --> Frontend: 200 OK
deactivate Gateway
Frontend --> Customer: Отображение\nподтверждения заказа
deactivate Frontend
end
end
' === Обработка таймаута (параллельный процесс) ===
== Фоновый процесс: Отмена заказа по таймауту ==
note over OrderService
Scheduled job (каждую минуту)
SELECT * FROM orders
WHERE status = 'PENDING_PAYMENT'
AND created_at < NOW() - INTERVAL '15 minutes'
end note
OrderService -> OrderService: Находит просроченные заказы
OrderService -> OrderService: UPDATE status = 'CANCELLED'
OrderService -> Inventory: POST /inventory/release\n{ reservation_id }
activate Inventory
Inventory -> InventoryDB: Освобождение резерва
Inventory --> OrderService: 200 OK
deactivate Inventory
OrderService -> Notify: POST /notifications/email\n{ template: "order_cancelled" }
activate Notify
Notify --> OrderService: 202 Accepted
deactivate Notify
@enduml````