Cấu trúc Dữ liệu: Shell
Tài liệu này chi tiết cấu trúc cơ sở dữ liệu của Shell — nguồn sự thật trung tâm cho nền tảng VENI-AI.
1. Tổng quan
Cơ sở dữ liệu Shell quản lý cô lập đa thuê bao, định danh, RBAC, thanh toán và danh mục dịch vụ toàn cầu. Sử dụng PostgreSQL với Drizzle ORM và thiết kế lược đồ hướng tên miền.
Mô hình đa thuê bao: "Dùng chung Cơ sở dữ liệu, Dùng chung Lược đồ." Mọi bảng liên quan đến thuê bao đều có cột organization_id. Cô lập được thực thi ở lớp ứng dụng/ORM.
Lược đồ chia thành năm miền logic:
| Miền | Bảng |
|---|---|
| Định danh | users, user_credentials, user_sessions, identity_providers, oauth_accounts |
| Tổ chức | organizations, organization_plan_history, onboarding_requests |
| Phân quyền | roles, user_roles, permissions, role_permissions |
| Thương mại | subscription_plans, plan_apps, plan_limits, plan_usage |
| Danh mục | apps, app_health_checks |
2. Mô hình Tên miền Cốt lõi
3. Miền Định danh
identity_providers
Các nhà cung cấp xác thực bên ngoài (OAuth2, SAML, LDAP).
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
providerId | varchar(100) | Slug duy nhất (ví dụ: google, keycloak). |
type | varchar(50) | oauth2, saml, hoặc ldap. |
clientId | varchar(255) | OAuth client ID. |
clientSecret | text | Client secret đã mã hóa. |
authUrl | varchar(500) | URL endpoint ủy quyền. |
tokenUrl | varchar(500) | URL endpoint token. |
config | jsonb | Cấu hình bổ sung. Mặc định: {}. |
status | varchar(20) | ACTIVE hoặc INACTIVE. Mặc định: ACTIVE. |
createdAt | timestamptz |
users
Tất cả người dùng trên mọi tổ chức.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. Định danh người dùng toàn cầu (sub trong JWT). |
email | varchar(320) | Email chính duy nhất. |
username | varchar(100) | Tên đăng nhập duy nhất. |
firstName | varchar(100) | Họ. |
lastName | varchar(100) | Tên. |
providerId | uuid | FK đến identity_providers.id. |
organizationId | uuid | FK đến organizations.id. |
status | varchar(20) | ACTIVE, INACTIVE, hoặc SUSPENDED. Mặc định: ACTIVE. |
preferences | jsonb | Tùy chọn giao diện (chủ đề, ngôn ngữ, v.v.). Mặc định: {}. |
securitySettings | jsonb | Cấu hình bảo mật. Mặc định: {}. |
createdAt | timestamptz | |
updatedAt | timestamptz |
user_credentials
Thông tin mật khẩu và MFA cho người dùng đăng nhập local.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
userId | uuid | FK đến users.id (unique). |
passwordHash | varchar(255) | Hash bcrypt của mật khẩu. |
passwordHistory | jsonb | Lịch sử hash để ngăn tái sử dụng. |
failedLoginCount | integer | Số lần đăng nhập thất bại. Mặc định: 0. |
lockedUntil | timestamptz | Thời điểm hết hạn khóa tài khoản. |
lastLoginAt | timestamptz | |
mfaStatus | varchar(20) | ACTIVE hoặc DISABLED. |
mfaSecret | varchar(255) | TOTP secret. |
mfaBackupCodes | jsonb | Mã dự phòng một lần. |
recoveryEmail | varchar(320) | Email khôi phục tài khoản. |
createdAt | timestamptz | |
updatedAt | timestamptz |
oauth_accounts
Liên kết người dùng với tài khoản OAuth của họ.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
userId | uuid | FK đến users.id. |
providerId | uuid | FK đến identity_providers.id. |
providerUserId | varchar(255) | ID người dùng từ nhà cung cấp. |
accessToken | text | Access token đã mã hóa. |
refreshToken | text | Refresh token đã mã hóa. |
tokenExpiresAt | timestamptz | |
createdAt | timestamptz |
user_sessions
Phiên đăng nhập và refresh token đang hoạt động.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
userId | uuid | FK đến users.id. |
sessionToken | varchar(128) | Định danh phiên duy nhất. |
refreshToken | varchar(128) | Refresh token duy nhất. |
deviceInfo | jsonb | Metadata trình duyệt/thiết bị. |
ipAddress | inet | Địa chỉ IP client. |
status | varchar(20) | ACTIVE hoặc REVOKED. Mặc định: ACTIVE. |
expiresAt | timestamptz | Thời gian hết hạn phiên. |
lastActivityAt | timestamptz | |
createdAt | timestamptz | |
updatedAt | timestamptz |
4. Miền Tổ chức
organizations
Thực thể gốc cho mọi thuê bao trên nền tảng.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
name | varchar(255) | Tên pháp lý. |
slug | varchar(100) | Định danh duy nhất thân thiện với URL. |
domain | varchar(253) | Tên miền email doanh nghiệp (để tự động cấp phát). |
type | varchar(50) | ENTERPRISE, STARTUP, INDIVIDUAL, NON_PROFIT, GOVERNMENT. Mặc định: ENTERPRISE. |
subscriptionPlan | varchar(50) | Mã gói hiện tại: HOBBY, PRO, ENTERPRISE. Mặc định: HOBBY. |
subscriptionStatus | varchar(50) | Trạng thái subscription Stripe. Mặc định: active. |
billingInterval | varchar(20) | monthly hoặc yearly. Mặc định: monthly. |
trialStartDate | timestamptz | Ngày bắt đầu dùng thử. |
trialEndDate | timestamptz | Ngày kết thúc dùng thử. |
stripeCustomerId | varchar(255) | ID khách hàng Stripe. |
stripeSubscriptionId | varchar(255) | ID subscription Stripe. |
settings | jsonb | Cấu hình riêng của tổ chức. Mặc định: {}. |
complianceData | jsonb | Metadata tuân thủ pháp lý. Mặc định: {}. |
status | varchar(20) | ACTIVE, INACTIVE, SUSPENDED. Mặc định: ACTIVE. |
createdAt | timestamptz | |
updatedAt | timestamptz |
organization_plan_history
Lịch sử không thể thay đổi của tất cả các lần thay đổi gói cước.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
organizationId | uuid | FK đến organizations.id. |
previousPlan | varchar(50) | Mã gói trước khi thay đổi. |
newPlan | varchar(50) | Mã gói sau khi thay đổi. |
reason | varchar(50) | upgrade, downgrade, trial_start, trial_end, stripe_checkout, admin_override, cancellation. |
metadata | jsonb | Ngữ cảnh bổ sung. |
changedBy | uuid | Người dùng đã kích hoạt thay đổi. |
createdAt | timestamptz |
onboarding_requests
Quy trình onboarding doanh nghiệp B2B.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
orgName | varchar(255) | Tên tổ chức được yêu cầu. |
orgType | varchar(50) | Loại tổ chức. Mặc định: ENTERPRISE. |
contactEmail | varchar(320) | Email liên hệ. |
firstName | varchar(100) | Họ người nộp đơn. |
lastName | varchar(100) | Tên người nộp đơn. |
applicantEmail | varchar(320) | Email người nộp đơn. |
companySize | integer | Số nhân viên. |
ssoInterest | boolean | Có yêu cầu tích hợp SSO không. |
subscriptionPlan | varchar(50) | Gói cước được yêu cầu. |
status | varchar(30) | PENDING, APPROVED, REJECTED. Mặc định: PENDING. |
rejectionReason | text | Lý do từ chối. |
organizationId | uuid | FK đến organizations.id (thiết lập khi duyệt). |
reviewedBy | uuid | Admin đã xem xét. |
reviewedAt | timestamptz | |
createdAt | timestamptz | |
updatedAt | timestamptz |
5. Miền Phân quyền
roles
Định nghĩa vai trò theo phạm vi nền tảng hoặc dịch vụ cụ thể.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
name | varchar(100) | Tên vai trò (ví dụ: admin, member). |
displayName | varchar(255) | Nhãn hiển thị cho người dùng. |
description | text | Mô tả vai trò. |
serviceScope | varchar(50) | PLATFORM hoặc slug dịch vụ. Mặc định: PLATFORM. |
isSystem | boolean | Nếu true, không thể xóa. Mặc định: false. |
isDefault | boolean | Nếu true, tự động gán cho người dùng mới. Mặc định: false. |
organizationId | uuid | FK đến organizations.id (null cho vai trò toàn nền tảng). |
status | varchar(20) | ACTIVE hoặc INACTIVE. Mặc định: ACTIVE. |
createdAt | timestamptz | |
updatedAt | timestamptz |
user_roles
Bảng liên kết gán vai trò cho người dùng.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
userId | uuid | FK đến users.id. |
roleId | uuid | FK đến roles.id. |
organizationId | uuid | Phạm vi tổ chức của lần gán này. |
assignedAt | timestamptz | Thời điểm gán vai trò. |
expiresAt | timestamptz | Thời hạn vai trò (tùy chọn). |
permissions
Mã quyền hạn chi tiết theo định dạng resource:action.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
code | varchar(255) | Mã duy nhất (ví dụ: drive:files:read). |
appId | uuid | FK đến apps.id (null cho quyền nền tảng). |
type | varchar(10) | p (policy) hoặc g (group). Mặc định: p. |
resource | varchar(100) | Tên tài nguyên. |
action | varchar(100) | Tên hành động. |
isSystem | boolean | Nếu true, không thể xóa. Mặc định: false. |
description | text | |
createdAt | timestamptz |
role_permissions
Bảng liên kết gán quyền hạn cho vai trò.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
roleId | uuid | FK đến roles.id. |
permissionId | uuid | FK đến permissions.id. |
6. Miền Thương mại
subscription_plans
Danh mục sản phẩm cho trang giá và kiểm soát quota.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
code | varchar(50) | Mã gói duy nhất (ví dụ: HOBBY, PRO, ENTERPRISE). |
name | varchar(100) | Tên hiển thị. |
tagline | varchar(255) | Mô tả marketing ngắn. |
monthlyPrice | real | Giá USD mỗi tháng. |
yearlyPrice | real | Giá USD mỗi năm. |
section | varchar(20) | individual hoặc business. |
ctaLabel | varchar(100) | Nhãn nút kêu gọi hành động. |
ctaLink | varchar(255) | URL kêu gọi hành động. |
features | jsonb | Danh sách tính năng: [{ "label": "...", "included": true }]. |
status | varchar(20) | active, hidden, hoặc deprecated. |
stripeProductId | varchar(255) | ID sản phẩm Stripe. |
stripeMonthlyPriceId | varchar(255) | ID giá Stripe cho thanh toán hàng tháng. |
stripeYearlyPriceId | varchar(255) | ID giá Stripe cho thanh toán hàng năm. |
createdAt | timestamptz | |
updatedAt | timestamptz |
plan_apps
Bảng liên kết các ứng dụng nào được bao gồm trong mỗi gói.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
planId | uuid | FK đến subscription_plans.id. |
appId | uuid | FK đến apps.id. |
createdAt | timestamptz |
plan_limits
Định nghĩa quota cho từng gói (ví dụ: dung lượng tối đa, số thành viên tối đa).
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
planId | uuid | FK đến subscription_plans.id. |
limitKey | varchar(100) | Khóa quota (ví dụ: storage_gb, members). |
limitValue | integer | Giá trị tối đa được phép. |
period | varchar(20) | monthly hoặc lifetime. Mặc định: monthly. |
createdAt | timestamptz | |
updatedAt | timestamptz |
plan_usage
Bộ đếm sử dụng luân phiên theo tổ chức và kỳ thanh toán.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
organizationId | uuid | FK đến organizations.id. |
limitKey | varchar(100) | Khớp với plan_limits.limitKey. |
periodKey | varchar(20) | Kỳ thanh toán (ví dụ: 2026-03). |
count | integer | Số lần sử dụng hiện tại. Mặc định: 0. |
updatedAt | timestamptz |
7. Miền Danh mục
apps
Tất cả ứng dụng satellite SCS đã đăng ký.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
slug | varchar(255) | Định danh duy nhất thân thiện URL (ví dụ: drive). |
name | varchar(255) | Tên hiển thị. |
type | varchar(50) | SERVICE hoặc các loại khác. Mặc định: SERVICE. |
apiUrl | text | URL API nội bộ. |
uiUrl | text | URL entry Module Federation. |
icon | varchar(255) | URL hoặc định danh icon. |
description | text | Mô tả ứng dụng. |
category | varchar(100) | Danh mục ứng dụng. |
status | varchar(20) | AVAILABLE, MAINTENANCE, DISABLED. Mặc định: AVAILABLE. |
metadata | jsonb | Metadata tùy ý. Mặc định: {}. |
createdAt | timestamptz | |
updatedAt | timestamptz |
app_health_checks
Kết quả kiểm tra sức khỏe của các ứng dụng đã đăng ký.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | PK. |
appId | uuid | FK đến apps.id. |
statusCode | integer | Mã HTTP status trả về. |
responseTimeMs | integer | Thời gian phản hồi tính bằng ms. |
success | boolean | Kiểm tra có thành công không. |
checkedAt | timestamptz | Thời điểm thực hiện kiểm tra. |
8. Kiểm toán
audit_log
Bảng phân vùng ghi tất cả sự kiện nền tảng. Phân vùng theo createdAt.
| Trường | Kiểu | Mô tả |
|---|---|---|
id | uuid | |
userId | uuid | Người thực hiện. |
organizationId | uuid | Ngữ cảnh tổ chức. |
eventType | varchar(100) | Danh mục sự kiện (ví dụ: USER_LOGIN). |
action | varchar(100) | Hành động cụ thể được thực hiện. |
resource | varchar(100) | Loại tài nguyên mục tiêu. |
resourceId | varchar(100) | ID tài nguyên mục tiêu. |
eventData | jsonb | Payload sự kiện bổ sung. |
ipAddress | inet | IP client. |
severity | varchar(20) | info, warning, critical. Mặc định: info. |
createdAt | timestamptz | Khóa phân vùng. |