Tài liệu Thiết kế Cơ sở dữ liệu

Module Xác thực
AUTH
Phiên bản1.0
Hệ thốngHệ thống Xác thực
ModuleAUTH - Xác thực
Cơ sở dữ liệuauth_db
ORMDrizzle ORM
Ngày2026-08-05
Tác giảNam Nguyen
SRS Liên quanSRS Xác thực

Mục lục

1. Tổng quan

1.1 Mục đích

Tài liệu này định nghĩa thiết kế cơ sở dữ liệu cho module Xác thực (cơ sở dữ liệu: auth_db).

1.2 Yêu cầu được đề cập

Yêu cầu SRSGiải pháp Cơ sở dữ liệu
FR-001 Đăng kýauth_users, auth_accounts
FR-002 Đăng nhậpauth_users, auth_sessions
FR-008/FR-009 Xác minhauth_verification
FR-011 Vai tròauth_roles, auth_user_roles

1.3 Sơ đồ ERD

Sơ đồ ERD
Hình 1: ERD Module Xác thực

2. Thiết kế Schema

2.1 Chiến lược Cơ sở dữ liệu

Khía cạnhQuyết định
Cơ sở dữ liệuauth_db
Quy tắc đặt tên bảngauth_<table_name>
Khóa chínhUUID (via gen_random_uuid())
Dấu thời giancreated_at, updated_at with NOW() default

2.2 Bảng: auth_users

Tên CộtKiểu Dữ liệuNullableMặc địnhMô tả
iduuidNOgen_random_uuid()Khóa chính
emailvarchar(255)YESNULLEmail duy nhất
phonevarchar(20)YESNULLSố điện thoại duy nhất
namevarchar(100)NO-Tên hiển thị
password_hashvarchar(255)YESNULLbcrypt hash
email_verifiedbooleanNOfalseCờ xác minh email
phone_verifiedbooleanNOfalseCờ xác minh số điện thoại
statusvarchar(20)NOactiveactive, inactive, banned
created_attimestampNONOW()Thời gian tạo
updated_attimestampNONOW()Thời gian cập nhật cuối
CREATE TABLE auth_users (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email           VARCHAR(255) UNIQUE,
  phone           VARCHAR(20) UNIQUE,
  name            VARCHAR(100) NOT NULL,
  password_hash   VARCHAR(255),
  email_verified  BOOLEAN NOT NULL DEFAULT false,
  phone_verified  BOOLEAN NOT NULL DEFAULT false,
  status          VARCHAR(20) NOT NULL DEFAULT 'active'
                  CHECK (status IN ('active', 'inactive', 'banned')),
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  CONSTRAINT auth_users_email_or_phone CHECK (email IS NOT NULL OR phone IS NOT NULL)
);

2.3 Bảng: auth_sessions

CREATE TABLE auth_sessions (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  token           VARCHAR(500) NOT NULL,
  refresh_token   VARCHAR(500),
  ip_address      VARCHAR(45),
  user_agent      TEXT,
  expires_at      TIMESTAMP NOT NULL,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

2.4 Bảng: auth_accounts

CREATE TABLE auth_accounts (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  provider        VARCHAR(50) NOT NULL,
  provider_id     VARCHAR(255) NOT NULL,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  CONSTRAINT auth_accounts_provider_unique UNIQUE (provider, provider_id)
);

2.5 Bảng: auth_verification

CREATE TABLE auth_verification (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  code            VARCHAR(10) NOT NULL,
  type            VARCHAR(20) NOT NULL
                  CHECK (type IN ('email', 'phone', 'password_reset')),
  expires_at      TIMESTAMP NOT NULL,
  used            BOOLEAN NOT NULL DEFAULT false,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

2.6 Bảng: auth_roles

CREATE TABLE auth_roles (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name            VARCHAR(50) NOT NULL UNIQUE,
  description     TEXT,
  permissions     JSONB DEFAULT '[]',
  created_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

Vai trò Hệ thống Mặc định

Vai tròMô tảĐăng ký Tự độngQuyền hạn
userTài khoản người dùng thông thường (mặc định). Có thể tạo tổ chức và nhận vai trò cấp tổ chức.Có (mặc định)Quyền hạn trong phạm vi tổ chức
super_adminQuản trị viên hệ thống có toàn quyền truy cập tất cả người dùng, vai trò và tổ chức.Không (chỉ tạo bởi admin qua POST /admin/create-user)Truy cập toàn bộ hệ thống

Lưu ý: Tài khoản super_admin chỉ có thể được tạo bởi admin hiện tại qua POST /admin/create-user. Endpoint đăng ký (POST /sign-up/email) chỉ gán vai trò user.

2.7 Bảng: auth_user_roles

CREATE TABLE auth_user_roles (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  role_id         UUID NOT NULL REFERENCES auth_roles(id) ON DELETE CASCADE,
  assigned_at     TIMESTAMP NOT NULL DEFAULT NOW(),
  assigned_by     UUID REFERENCES auth_users(id),
  CONSTRAINT auth_user_roles_unique UNIQUE (user_id, role_id)
);

2.8 Bảng: auth_organizations

CREATE TABLE auth_organizations (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name            VARCHAR(100) NOT NULL,
  slug            VARCHAR(100) NOT NULL UNIQUE,
  logo            VARCHAR(500),
  metadata        JSONB,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

2.9 Bảng: auth_members

CREATE TABLE auth_members (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  organization_id UUID NOT NULL REFERENCES auth_organizations(id) ON DELETE CASCADE,
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  role            VARCHAR(50) NOT NULL DEFAULT 'member',
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  CONSTRAINT auth_members_unique UNIQUE (organization_id, user_id)
);

2.10 Bảng: auth_teams

CREATE TABLE auth_teams (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  name            VARCHAR(100) NOT NULL,
  organization_id UUID NOT NULL REFERENCES auth_organizations(id) ON DELETE CASCADE,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

2.11 Bảng: auth_team_members

CREATE TABLE auth_team_members (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  team_id         UUID NOT NULL REFERENCES auth_teams(id) ON DELETE CASCADE,
  user_id         UUID NOT NULL REFERENCES auth_users(id) ON DELETE CASCADE,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  CONSTRAINT auth_team_members_unique UNIQUE (team_id, user_id)
);

2.12 Bảng: auth_invitations

CREATE TABLE auth_invitations (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  organization_id UUID NOT NULL REFERENCES auth_organizations(id) ON DELETE CASCADE,
  email           VARCHAR(255) NOT NULL,
  token_hash      VARCHAR(64) UNIQUE,
  role            VARCHAR(50) DEFAULT 'member',
  team_id         UUID REFERENCES auth_teams(id) ON DELETE SET NULL,
  employer_id     UUID,
  status          VARCHAR(20) NOT NULL DEFAULT 'pending'
                  CHECK (status IN ('pending', 'accepted', 'rejected', 'canceled', 'expired', 'revoked')),
  expires_at      TIMESTAMP NOT NULL,
  accepted_at     TIMESTAMP,
  inviter_id      UUID NOT NULL REFERENCES auth_users(id),
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMP NOT NULL DEFAULT NOW()
);

Định nghĩa Cột (cột mới):

Tên CộtKiểu Dữ liệuMô tả
token_hashvarchar(64)SHA-256 hash của token mời gốc. Chỉ lưu hash; token gốc được gửi qua URL email. Ràng buộc UNIQUE đảm bảo không có token trùng lặp.
employer_iduuidTham chiếu tùy chọn đến tổ chức nhà tuyển dụng. Được sử dụng cho các lời mời vai trò cụ thể (ví dụ: vai trò HR cần ngữ cảnh nhà tuyển dụng).
accepted_attimestampDấu thời gian khi lời mời được chấp nhận. NULL cho đến khi được chấp nhận.
updated_attimestampDấu thời gian sửa đổi cuối. Cập nhật khi gửi lại, thu hồi hoặc thay đổi trạng thái.

Giá trị Trạng thái:

Trạng tháiMô tả
pendingLời mời đã gửi, đang chờ phản hồi
acceptedLời mời đã được chấp nhận (trạng thái cuối)
rejectedLời mời bị từ chối bởi người được mời
canceledĐã hủy bởi người gửi lời mời (cũ)
expiredToken đã hết hạn (tự động đặt khi xác minh)
revokedĐã thu hồi bởi người gửi lời mời (chỉ chủ sở hữu)

2.13 Bảng: auth_organization_roles

CREATE TABLE auth_organization_roles (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  organization_id UUID NOT NULL REFERENCES auth_organizations(id) ON DELETE CASCADE,
  role            VARCHAR(50) NOT NULL,
  description     VARCHAR(500),
  permission      VARCHAR(255) NOT NULL,
  created_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMP NOT NULL DEFAULT NOW(),
  CONSTRAINT auth_org_roles_unique UNIQUE (organization_id, role)
);

Định nghĩa Cột:

Tên CộtMô tả
organization_idFK tham chiếu auth_organizations, CASCADE khi xóa
roleTên vai trò, duy nhất trong tổ chức (2-50 ký tự, chữ cái số + gạch dưới)
descriptionMô tả tùy chọn về mục đích vai trò
permissionCác quyền hạn phân tách bằng dấu phẩy theo định dạng resource:action (tối đa 255 ký tự)

Định dạng Quyền hạn: resource:action (ví dụ: job:read, member:update)

Vai trò Tổ chức Mặc định

Mỗi tổ chức có thể định nghĩa vai trò riêng. Dưới đây là các vai trò tổ chức tiêu chuẩn thường được sử dụng:

Vai tròMô tảQuyền hạn Thường gặp
EmployerChủ sở hữu/quản trị viên tổ chức quản lý hồ sơ công ty và đăng tin tuyển dụng. Được gán tự động khi người dùng tạo tổ chức.job:create, job:update, job:delete, application:read, member:read, settings:read, settings:update
HRThành viên đội ngũ tuyển dụng nội bộ quản lý quy trình tuyển dụng.job:read, job:create, job:update, application:read, application:update, interview:create, interview:update, member:read
CandidateỨng viên tìm việc nộp đơn vào các vị trí trong tổ chức.job:read, application:create, application:read (chỉ của bản thân)

Lưu ý: Vai trò tổ chức độc lập với vai trò cấp hệ thống (user, super_admin). Người dùng có vai trò hệ thống user có thể có các vai trò tổ chức khác nhau trong các tổ chức khác nhau.

3. Chỉ mục

-- auth_users
CREATE INDEX idx_auth_users_email ON auth_users(email);
CREATE INDEX idx_auth_users_phone ON auth_users(phone);
CREATE INDEX idx_auth_users_status ON auth_users(status);

-- auth_sessions
CREATE INDEX idx_auth_sessions_user_id ON auth_sessions(user_id);
CREATE INDEX idx_auth_sessions_token ON auth_sessions(token);
CREATE INDEX idx_auth_sessions_expires ON auth_sessions(expires_at);

-- auth_verification
CREATE INDEX idx_auth_verification_user_id ON auth_verification(user_id);
CREATE INDEX idx_auth_verification_code ON auth_verification(code);
CREATE INDEX idx_auth_verification_type ON auth_verification(type);

-- auth_user_roles
CREATE INDEX idx_auth_user_roles_user_id ON auth_user_roles(user_id);
CREATE INDEX idx_auth_user_roles_role_id ON auth_user_roles(role_id);

-- auth_organizations
CREATE INDEX idx_auth_organizations_slug ON auth_organizations(slug);

-- auth_members
CREATE INDEX idx_auth_members_org_id ON auth_members(organization_id);
CREATE INDEX idx_auth_members_user_id ON auth_members(user_id);

-- auth_teams
CREATE INDEX idx_auth_teams_org_id ON auth_teams(organization_id);

-- auth_team_members
CREATE INDEX idx_auth_team_members_team_id ON auth_team_members(team_id);
CREATE INDEX idx_auth_team_members_user_id ON auth_team_members(user_id);

-- auth_invitations
CREATE UNIQUE INDEX idx_auth_invitations_token_hash ON auth_invitations(token_hash);
CREATE INDEX idx_auth_invitations_org_id ON auth_invitations(organization_id);
CREATE INDEX idx_auth_invitations_email ON auth_invitations(email);
CREATE INDEX idx_auth_invitations_status ON auth_invitations(status);
CREATE INDEX idx_auth_invitations_inviter_id ON auth_invitations(inviter_id);
CREATE INDEX idx_auth_invitations_employer_id ON auth_invitations(employer_id);

-- auth_organization_roles
CREATE INDEX idx_auth_org_roles_org_id ON auth_organization_roles(organization_id);

4. Di chuyển dữ liệu

4.1 Chiến lược Di chuyển dữ liệu

Khía cạnhQuyết định
Công cụDrizzle ORM (drizzle-kit)
Cơ sở dữ liệuauth_db
Hoàn tácBắt buộc cho mỗi lần di chuyển dữ liệu

4.2 Thứ tự Di chuyển dữ liệu

Thứ tựDi chuyển dữ liệuMô tả
1001_create_usersTạo bảng auth_users
2002_create_sessionsTạo bảng auth_sessions
3003_create_accountsTạo bảng auth_accounts
4004_create_verificationTạo bảng auth_verification
5005_create_rolesTạo bảng auth_roles
6006_create_user_rolesTạo bảng auth_user_roles
7007_create_organizationsTạo bảng auth_organizations
8008_create_membersTạo bảng auth_members
9009_create_teamsTạo bảng auth_teams
10010_create_team_membersTạo bảng auth_team_members
11011_create_invitationsTạo bảng auth_invitations
12012_create_org_rolesTạo bảng auth_organization_roles
13013_create_indexesTạo tất cả chỉ mục

5. Từ điển Dữ liệu

BảngMô tảGiải quyếtS dòng Đánh giá (Năm 1)
auth_usersTài khoản người dùngFR-001, FR-00210,000
auth_sessionsPhiên đăng nhập và token của người dùngFR-002, FR-003, FR-00450,000
auth_accountsTài khoản OAuth providerFR-00110,000
auth_verificationMã xác minh email/số điện thoạiFR-005, FR-006, FR-008, FR-00920,000
auth_rolesVai trò người dùngFR-01110
auth_user_rolesPhân công vai trò người dùngFR-01115,000
auth_organizationsTổ chứcFR-015100
auth_membersThành viên tổ chứcFR-015500
auth_teamsĐội nhóm trong tổ chứcFR-016300
auth_team_membersThành viên đội nhómFR-0161,000
auth_invitationsLời mời tổ chức với xác minh dựa trên tokenFR-017, FR-018, FR-019, FR-0205,000
auth_organization_rolesVai trò tổ chức tùy chỉnhFR-01550