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

</aside>


Persistence Model

Table products 
{
  id                uuid              [pk, note: 'Khóa chung cho mọi “sản phẩm” (Course, Specialization, Bundle…)']
  
  title             varchar           [not null, note: 'Tiêu đề sản phẩm']  
  slug              varchar           [unique, not null, note: 'URL thân thiện cho sản phẩm']  
  short_description text              [not null, note: 'Mô tả ngắn hiển thị danh sách']
  description       text              [note: 'Mô tả chi tiết sản phẩm']

  type              product_type      [not null, note: 'Loại sản phẩm: course | specialization | bundle | ...']
  category_id       uuid              [ref: > categories.id, note: 'Thuộc danh mục nào']  
  owner             uuid              [ref: > users.id, note: 'Người tạo (Giảng viên/Admin)']
  thumbnail         varchar           [not null, note: 'Ảnh thumbnail nhỏ']
  label             product_labels    [default: 'new', note: 'Nhãn: new/hot/featured/best_seller']
  status            product_status    [default: 'draft', note: 'Trạng thái: draft/published/archived']
  
  rating_avg        float             [default: 0, note: "Danh gia trung binh"]
  rating_cnt        int               [default: 0, note: "Danh giá trung binh"]
  enrollment_cnt    int               [default: 0, note: "Số lượt đăng ký"]

  created_at        timestamp         [default: `now()`, note: 'Thời điểm khởi tạo product record']
  updated_at        timestamp         [default: `now()`, note: 'Cập nhật lần cuối']
  deleted_at        timestamp         [null, note: 'Thời điểm xóa (soft-delete)']

  indexes {
    (type, slug) [unique]
  }
}
Table product_related {
  product_id uuid [not null, ref: > products.id]
  related_id uuid [not null, ref: > products.id]
  order int [not null, default: 0]
  notes text
}
Table courses [note: 'Bảng chính lưu thông tin các khóa học'] 
{
  product_id        uuid                    [pk, ref: > products.id, note: 'Tham chiếu đến products.id và chứa chi tiết Course']  

  requirements      text                    [not null, note: 'Yêu cầu tham gia sản phẩm']
  learning_outcomes text                    [not null, note: 'Kết quả đạt được sản phẩm']

  preview_video     varchar                 [note: 'Link video preview (nếu có)']  
  preview_img       varchar                 [not null, note: 'Ảnh preview banner']  
  
  difficulty        course_difficulty_level [not null, default: 'easy', note: 'Mức độ: easy/medium/hard']  
  
  regular_price     int                     [not null, note: 'Giá gốc khóa học (đơn vị nhỏ nhất, ví dụ VND)']
  discounted_price  int                     [not null, note: 'Giá ưu đãi khóa học (đơn vị nhỏ nhất, ví dụ VND)']
}
Table product_prequisites [note: 'Liên kết khóa học với các khóa phải hoàn thành trước'] 
{
  product_id        uuid                    [ref: > products.id, note: 'Khóa học chính']  
  required_id       uuid                    [ref: > products.id, note: 'Khóa học yêu cầu trước']  
  
  indexes { 
    (product_id, required_id) [pk] 
  } 
}

Domain Rules

Loại sản phẩm

Slug (URL-friendly)

Soft-delete vs Archive

Giá khóa học