Диаграмма последовательности - 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````