Provisioner cấp tài nguyên thật cho mỗi workspace: CREATE DATABASE riêng → migrate schema nền → cấp owner role → spawn PM2 instance (dải cổng BE 41000–41999 / FE 42000–42999) + routing Caddy on-demand HTTPS.
| Thành phần | Vai trò |
|---|---|
| Workspace · WorkspaceMembership · WorkspaceCreationRequest | Danh mục workspace + thành viên + luồng xin tạo |
| provisioner.js | DB riêng · migrate one-shot qua RT CLI (env override DB_NAME) · owner role + bump epoch · spawn PM2 |
| clean-workspace.js · ws-env.js | Xóa an toàn (từ chối DB dùng chung, idempotent) · xem env instance |
| caddyApi · workspaceGateService | Routing FE theo domain (WS_CADDY_ROUTING=1) · gate trạng thái workspace |
WS_RUNTIME_ROOT, PM2 local, dải cổng thủ công| Tham chiếu | Khuyến nghị |
|---|---|
| PostgreSQL vận hành chuẩn | Ưu tiên cao: pg_dump định kỳ từng DB workspace + kiểm tra restore — bắt buộc trước khi Vĩnh An go-live (dữ liệu thanh tra được) |
| Kubernetes operator pattern | Khi >5–10 workspace: tách provisioner thành reconcile-loop (desired state trong CP, actuator tách riêng) — chưa cần ngay, nhưng đừng thêm logic mới phụ thuộc path local |
| Odoo.sh / Shopify | Thêm trạng thái vòng đời workspace rõ ràng (provisioning → active → suspended → archived) gắn với billing/subscription |
Core không phải module nghiệp vụ — thay ma trận vai trò bằng tác nhân × năng lực, kèm cơ chế/quyền gate từng năng lực. R đọc · W thực hiện · A duyệt.
| Năng lực | Cơ chế / quyền gate | SUPER | OWNER/QTHT | DEV | SVC | USER |
|---|---|---|---|---|---|---|
| Yêu cầu tạo workspace | WorkspaceCreationRequest | A | — | — | — | W (request) |
| Provision / destroy | script + quyền admin CP | W | — | — | — | — |
| Xem trạng thái provisioning | membership | R | R | — | — | — |
| Backup / restore per-WS (P3 — đích) | system.admin.backup.* | W | R (restore theo duyệt) | — | — | — |
| ws:env / scripts vận hành | shell trên host | W | — | — | — | — |
SUPER = super admin CP · OWNER/QTHT = chủ workspace / quản trị WS · DEV = developer/publisher · SVC = service-to-service (runtime/hook) · USER = người dùng cuối. Mục ghi (đích) = theo khuyến nghị P1–P5, chưa có ở hiện trạng.