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

</aside>

Persistence Model

Table users [note: 'Bảng lưu người dùng hệ thống (Learner/Instructor/Admin)'] 
{
  id                uuid                     [pk, note: 'Khóa chính người dùng']
  type              user_type                [default: 'learner', note: 'learner/instructor/admin']  
  email             varchar                  [unique, not null, note: 'Email đăng nhập']  
  password_hash     varchar                  [not null, note: 'Hash mật khẩu (BCrypt)']
  is_email_verified bool                     [default: false, note: 'Đã xác thực email?']
  full_name         varchar                  [not null, note: 'Họ tên đầy đủ']
  phone_number      varchar                  [null, note: 'Số điện thoại liên hệ (nếu cần SMS/2FA)']
  avatar_url        varchar                  [null, note: 'Link ảnh đại diện']
  status            user_status              [default: 'active', note: 'active/blocked/suspended']
  last_login_at     timestamp                [null, note: 'Lần đăng nhập cuối']
  created_at        timestamp                [default: `now()`, note: 'Tạo tài khoản']  
  updated_at        timestamp                [default: `now()`, note: 'Cập nhật thông tin']  
  deleted_at        timestamp                [null, note: 'Soft-delete tài khoản']
  
  indexes {
    (email) [unique]
    (phone_number) [unique]
  }  
}
Table email_verifications {
  id           uuid       [pk]
  user_id      uuid       [not null, ref: > users.id]
  code         varchar    [not null, unique, note: 'Mã 6 chữ số ngẫu nhiên']
  expires_at   timestamp  [not null, note: 'Thời điểm mã hết hạn (ví dụ 15 phút sau khi tạo)']
  used_at      timestamp  [null, note: 'Ghi khi người dùng nhập đúng code'}
  created_at   timestamp  [default: now()]
  updated_at   timestamp  [default: now()]
}
Table password_reset_tokens {
  id            uuid      [pk]
  user_id       uuid      [not null, ref: > users.id]
  token         varchar   [not null, unique, note: 'Token random, mã hóa (ví dụ JWT hoặc UUID)']
  used_at       timestamp  [null, note: 'Ghi khi người dùng nhập đúng code'}
  expires_at    timestamp [not null]
  created_at    timestamp [default: now()]
  
  indexes { (user_id) }
}

Domain Use Cases

Login Command

Register User Command

Send Verification Command

Verify Email Command

Change Password Command

Request Password Reset Command

Confirm Password Reset Command

Refresh Token Command

Logout Command

Get Current User Query