Skip to content

Instantly share code, notes, and snippets.

@v0ff4k
Created April 29, 2026 12:12
Show Gist options
  • Select an option

  • Save v0ff4k/da9c5f3899d413c3674e234e39780504 to your computer and use it in GitHub Desktop.

Select an option

Save v0ff4k/da9c5f3899d413c3674e234e39780504 to your computer and use it in GitHub Desktop.
Проектирование заказа интернет магазина

Проектирование заказа интернет магазина

Условия:

Есть заказ, который содержит:

пользователя;
телефон;
e-mail;
список товаров;
данные доставки;
данные оплаты.

Доставка:

Есть 2 типа доставки:

самовывоз;
доставка на адрес.

Для самовывоза нужно: хранить идентификатор пункта выдачи.

Для доставки на адрес — город, улицу, дом, квартиру.

Оплата:

Есть 2 способа оплаты:

картой;
в кредит.

Для оплаты в кредит нужно дополнительно хранить:

название кредитного провайдера;
срок кредита в месяцах.

Что нужно сделать:

Разработать структуру таблиц БД для хранения заказа, товаров заказа, доставки и оплаты.
Описать связи между таблицами.
Показать декомпозицию решения по сущностям и зонам ответственности.
Кратко описать базовую логику оформления заказа: какие данные приходят, какие проверки нужны, что и в каком порядке должно сохраняться.
Сделать декомпозицию.

важно в решении:

  • адекватность структуры БД;
    
  • качество декомпозиции;
    
  • понятность логики;
    
  • готовность решения к расширению;
    
  • ясность объяснения.
    

ответ:

  • Декомпозиция в текстовом формате
  • Бизнес-логика в виде ER-диаграмма / диаграмма сущностей и связей
  • Плюсом будет Sequence Diagram и иные UML-диаграммы

Решение:

1. Декомпозиция по сущностям и зонам ответственности:

  • Order (Заказ) - агрегат, основной объект, хранит общую информацию, статус, связывает пользователя с товарами, доставкой и оплатой. Ответственность: жизненный цикл заказа.

  • OrderItem (Позиция заказа) - принадлежит заказу, хранит товар, количество, цену. Отвечает за состав заказа.

  • Delivery (Доставка) - стратегия доставки, определяет способ и адрес/пункт. Отвечает за расчет стоимости (не в условии) и формирование данных для отгрузки.

  • Payment (Оплата) - стратегия оплаты, хранит способ и специфические данные (кредит). Отвечает за обработку платежа (внешние системы).

  • User (Пользователь) - учетная запись, может иметь несколько заказов.

  • PickupPoint (Пункт выдачи) - справочник.

Логика оформления заказа:

  1. Получение данных от клиента (корзина, контактные данные, выбранная доставка и оплата, данные доставки/оплаты).
  2. Валидация: наличие товаров, доступность товаров (остатки), корректность контактных данных, корректность адреса/пункта выдачи, для кредита - проверка провайдера и срока.
  3. Создание заказа: создать запись order со статусом 'new', сохранить телефон, email, user_id (если авторизован).
  4. Сохранение позиций заказа: для каждого товара из корзины - сохранить product_id, quantity, текущую цену, сумму.
  5. Сохранение доставки: создать запись delivery с type, привязать к order_id. Если самовывоз - указать pickup_point_id, если адрес - город, улицу и т.д.
  6. Сохранение оплаты: создать запись payment с type, amount (сумма заказа). Если кредит - указать provider и term.
  7. Инициировать обработку оплаты (внешний сервис). Для карты - запрос на шлюз, для кредита - запрос в кредитную систему.
  8. В зависимости от результата - обновить статус заказа (оплачен/не оплачен, отказ).
  9. Отправить уведомления пользователю и менеджерам.

2. Структура таблиц БД (реляционная модель)


@startuml
!theme plain
skinparam linetype ortho

entity "user" as user {
  * id : INT <<PK>>
  --
  name : VARCHAR
  email : VARCHAR
  phone : VARCHAR
  created_at : DATETIME
}

entity "order" as order {
  * id : INT <<PK>>
  --
  user_id : INT <<FK>>
  phone : VARCHAR
  email : VARCHAR
  status : ENUM
  created_at : DATETIME
  updated_at : DATETIME
}

entity "order_item" as order_item {
  * id : INT <<PK>>
  --
  order_id : INT <<FK>>
  product_id : INT <<FK>>
  quantity : INT
  price : DECIMAL
  total : DECIMAL
}

entity "product" as product {
  * id : INT <<PK>>
  --
  sku : VARCHAR
  name : VARCHAR
  price : DECIMAL
  stock : INT
}

entity "delivery" as delivery {
  * id : INT <<PK>>
  --
  order_id : INT <<FK>>
  type : ENUM
  pickup_point_id : INT <<FK>>
  city : VARCHAR
  street : VARCHAR
  house : VARCHAR
  apartment : VARCHAR
}

entity "pickup_point" as pickup_point {
  * id : INT <<PK>>
  --
  name : VARCHAR
  address : TEXT
  city : VARCHAR
}

entity "payment" as payment {
  * id : INT <<PK>>
  --
  order_id : INT <<FK>>
  type : ENUM
  amount : DECIMAL
  credit_provider : VARCHAR
  credit_term_months : INT
  status : ENUM
}

user ||--o{ order : "has"
order ||--|| delivery : "has one"
delivery }o--|| pickup_point : "refers to (optional)"
order ||--|| payment : "has one"
order ||--|{ order_item : "contains"
order_item }o--|| product : "references"

note right of order : "phone/email скопирован\n из user или введенных данных"
note right of delivery : "Если type = 'pickup' → pickup_point_id\n То type = 'address' → address fields"
note right of payment : "Поля credit_provider/term_months\n только если type = 'credit'"
@enduml

Screen of a UML image

3. Sequence-диаграмма (оформление заказа)


@startuml
!theme plain
title "Оформление заказа: Sequence Diagram"

actor Клиент as Client
participant "CheckoutController" as Controller
participant "CheckoutService" as Service
participant "ProductRepository" as ProductRepo
database "База данных" as DB
participant "PaymentGateway" as Gateway

Client -> Controller: POST /checkout\n{user, items, delivery, payment}
activate Controller

Controller -> Service: createOrder(requestDTO)
activate Service

Service -> ProductRepo: checkStock(items)
activate ProductRepo
ProductRepo -> DB: SELECT stock FROM product WHERE id IN (...)
DB --> ProductRepo: stocks
ProductRepo --> Service: OK / NotEnoughStock
deactivate ProductRepo

alt Недостаточно товара
    Service --> Controller: ValidationError
    Controller --> Client: 422 Unprocessable
else Товар в наличии
    Service -> DB: BEGIN TRANSACTION
    
    Service -> DB: INSERT INTO order (...)
    DB --> Service: order_id
    
    loop Каждый товар
        Service -> DB: INSERT INTO order_item (order_id, product_id, quantity, price)
    end
    
    Service -> DB: INSERT INTO delivery (order_id, type, ...)
    
    alt Оплата "credit"
        Service -> DB: INSERT INTO payment (order_id, 'credit', provider, term)
    else Оплата "card"
        Service -> DB: INSERT INTO payment (order_id, 'card')
    end
    
    Service -> DB: UPDATE product SET stock = stock - quantity
    
    Service -> DB: COMMIT
    
    Service -> Gateway: processPayment(payment_details)
    activate Gateway
    Gateway --> Service: payment_result
    deactivate Gateway
    
    alt Оплата успешна
        Service -> DB: UPDATE order SET status = 'paid'\nUPDATE payment SET status = 'success'
        Service --> Controller: OrderCreatedResponse
        Controller --> Client: 200 OK
    else Оплата отклонена
        Service -> DB: UPDATE order SET status = 'cancelled'\nUPDATE payment SET status = 'failed'
        Service -> DB: UPDATE product SET stock = stock + quantity
        Service --> Controller: PaymentFailed
        Controller --> Client: 402 Payment Required
    end
end
deactivate Service
deactivate Controller
@enduml

Screen of a UML Sequence

ссылка на полное изображение "Screen of a UML Sequence"

4. Диаграмма состояний (жизненный цикл заказа)

@startuml
!theme plain
title "Жизненный цикл заказа (State Machine)"

[*] --> New : Создан заказ

New --> PaymentPending : Выбран способ оплаты
PaymentPending --> Paid : Платеж успешен
PaymentPending --> Cancelled : Платеж отклонен/таймаут

Paid --> Shipped : Товары переданы в доставку
Shipped --> Completed : Заказ доставлен/получен

New --> Cancelled : Пользователь отменил\nдо оплаты
PaymentPending --> Cancelled : Таймаут оплаты

Completed --> [*]
Cancelled --> [*]

note right of Shipped : Для самовывоза:\nShipped = готов к выдаче
note left of PaymentPending : Включает ожидание\nколлбэка платежной системы
@enduml

Screen of a UML image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment