<aside> <img src="/icons/checklist_green.svg" alt="/icons/checklist_green.svg" width="40px" />

</aside>

Persistence Model

Table enrollments [note: 'Subscription 1 năm cho mỗi user–product'] 
{
  id                    uuid        [pk]
  user_id               uuid        [ref: > users.id]
  product_id            uuid        [not null, ref: > products.id]
	expires_at            timestamp   [null] 
	
  indexes {
    (user_id, product_id) [unique]
  }
}
Table enrollment_items [note: 'Các lần ghi nhận thời gian học của một enrollment, từ đơn hàng hoặc được tặng']
{
  id              uuid              [pk]
  enrollment_id   uuid              [not null, ref: > enrollments.id]
  order_item_id   uuid              [ref: > order_items.id, null, note: 'Có thể null nếu không qua đơn hàng']
  source          enrollment_source [default: 'purchase', note: 'purchased | gifted | scholarship | manual']
  granted_by      uuid              [ref: > users.id, null, note: 'Người cấp quyền (nếu không phải mua)']
  
  period_start    timestamp         [not null]
  period_end      timestamp         [not null]
  
  is_active       bool              [default: true]
  created_at      timestamp         [default: `now()`]

  indexes {
    (enrollment_id, order_item_id) [unique]
  }
}

Domain Rules

Học viên hợp lệ

Sản phẩm hợp lệ

Khóa học có product_id phải tồn tại trong bảng products

Quy tắc tạo một bản ghi mới

Domain Use Cases

Create Enrollment By User Command

Create Enrollment By Purchased Command

Learner Can Learn Query

List Active Enrollments By Learner Query

List Expiring Enrollments Query