Sheet 4 · Entity Relationship Diagram (diagram-design)

Sơ đồ quan hệ thực thể ERD

ERD của CTC ERP được thiết kế theo chuẩn editorial diagram-design (thực thể 2 khoang: Header + Thuộc tính mono `#PK` / `→FK`, cardinality 2 đầu, viền accent trên thực thể gốc). Mô hình được phân tách thành 3 tầng kiến trúc để giữ mật độ đọc rõ ràng và chuẩn xác.

1. Bảng mô tả đối tượng (Object Description)

Đối tượng (Object)Định dạng khoáMô tả & Ý nghĩa nghiệp vụ
Đối tác (Contact)ct1..ct10Gốc quan hệ khách hàng / đối tác: công ty, ngành (nganh:*), phân loại, tổng giá trị hợp đồng rollup.
Dự án (Project)pj1..pj16Thực thể trung tâm vận hành: liên kết contactId, tiến độ bán hàng (dealStage), giá trị (dealValue), và tiến độ giao hàng (status).
Công việc (Task)CTC-n (t1..)Sản phẩm bàn giao (Deliverable) bóc tách từ WBS: kanban 4 cột, deadline, assignee, tag 3 chiều (gp:*, nganh:*, viec:*).
Hoá đơn GTGT (Invoice)CTC-INV-*Hoá đơn GTGT bán hàng & báo giá: 5 trạng thái vòng đời, line-items chi tiết, hỗ trợ OCR scan hoá đơn đầu vào.
Giao dịch (Transaction)tx1..tx9Sổ thu/chi tài chính thực tế: dòng tiền dự án, gắn contactId/projectId/invoiceId, tag bản chất dòng tiền (tc:*).
Nhà cung cấp (Vendor)vd1..Danh bạ NCC (Media, In ấn, Thiết bị, Server...): theo dõi công nợ cam kết vs đã duyệt chi, ngưỡng duyệt BOD > 5tr.
Quy trình tự động (Workflow)wf1..wf3Canvas tự động hoá React Flow: trigger (đổi status / định kỳ), condition, actions (tạo task, gửi Telegram/GWS).
Tài khoản & Phân quyềnu0..u7Gốc danh tính RBAC: vai trò (admin/member), mảng phân quyền 23 module (modules[]), chức danh (title).

2. Ký pháp sơ đồ (Notation & Legend)

Ký hiệuÝ nghĩa trong mô hình dữ liệu
1Đúng một (Exactly one)
0..1Không hoặc một (Zero or one)
1..*Một hoặc nhiều (One or more)
0..* / NKhông hoặc nhiều (Zero or more)
# / →# Khóa chính (Primary Key PK) · Khóa ngoại (Foreign Key FK) trong khoang thuộc tính
Quy ước nhận diện màu (Color Key):
Xanh Lime Accent Thực thể gốc trung tâm (Project, Invoice, AuthUser) · Navy Thực thể dữ liệu chuẩn · Đỏ Rust Điểm kiểm soát phê duyệt / Rủi ro (Vendor Approval >5tr).

3. Tầng Vận hành & Bán hàng (Operations & Sales Layer)

ORD Tầng Vận hành & Phễu Bán hàngMô hình dữ liệu thực thể quản trị dự án, công việc và đối tác CTC ERPKHÁCH HÀNG & TIẾP NHẬNTRUNG TÂM VẬN HÀNHTHỰC THI DELIVERABLES & LỊCH1 đối tác - N dự án10..*lịch sử tương tác10..*bóc tách WBS11..*gắn tag 3 chiềuN1..*mốc deadline10..*chuỗi lặp tự sinhN0..1ENTITYĐối tác (Contact)# id (ct1..ct10) company · name dealStage (7)→ assigneeId (u1..u7) tags[] (nganh/gp) contactStatus rollupDealValueENTITYNhật ký Tương tác# id (act1..)→ contactId (ct*) type (call/meeting/note) content at · createdByENTITYDự án (Project)# id (pj1..pj16)→ contactId (ct*) dealStage (won/lost) dealValue (VNĐ) status (planning..done)→ memberIds[] (u*) startDate · dueDateENTITYCông việc (Deliverable)# id · key (CTC-n)→ projectId (pj*)→ contactId (ct*)→ assigneeId (u*) status (todo..done) priority (urgent..low) tags[] (gp/nganh/viec) subtasks[] · links[]ENTITYMa trận Tag Định danh gp:* (8 giải pháp) nganh:* (10 ngành) viec:* (8 loại việc) tc:* (8 dòng tiền) (Trọng số 1/n)ENTITYLịch & Nhắc việc# id (ev1..) title · type (4) start · end→ recurringId (rec*) assigneeIds[]ENTITYKhuôn Sự kiện Lặp# id (rec*) freq (weekly/monthly) interval · until daysOfWeek[]LEGENDThực thể trung tâm (Project)Thực thể nghiệp vụQuan hệ luồng cốt lõi (1 - N)Quan hệ liên kết tham chiếu
Đọc sơ đồ Tầng Vận hành: Đối tác (Contact) là điểm khởi nguồn — 1 đối tác sở hữu nhiều Dự án (Project) và lịch sử Tương tác (Activity); Mỗi Dự án là thực thể trung tâm bóc tách thành nhiều Công việc (Task CTC-*); Mỗi Task được gắn ma trận Tag 3 chiều (gp:*, nganh:*, viec:*) để phục vụ đo lường KPI; Dự án liên kết lịch deadline và sự kiện lặp trên Calendar.

Đặc tả quan hệ chi tiết — Tầng Vận hành

Quan hệ thực thểCardinalityÝ nghĩa nghiệp vụ & Ràng buộc toàn vẹn
Contact → Project 1 — 0..* 1 đối tác có thể có nhiều dự án qua các năm; Project.contactId là khoá ngoại bắt buộc; Tổng giá trị đối tác trên UI là tổng dealValue các dự án chưa lost.
Project → Task 1 — 1..* Mỗi dự án phải bóc tách thành ít nhất 1 Deliverable/Task; Task.projectId liên kết trực tiếp; mã task tự tăng dạng CTC-n duy nhất toàn tenant.
Contact → Activity 1 — 0..* Lịch sử tương tác chăm sóc khách hàng (gọi điện, họp, email, zalo); phục vụ truy vết quá trình tư vấn.
Task → Tag Matrix N — 1..* Gắn tag 3 chiều: Giải pháp (gp:), Ngành (nganh:), Loại việc (viec:). Trọng số tính phân bổ doanh số/khối lượng là 1/n cho n tag cùng nhóm.
Project → CalendarEvent 1 — 0..* Các mốc deadline bàn giao và lịch họp dự án được hiển thị đồng bộ trên Calendar.
CalendarEvent → EventRecurrence N — 0..1 Sự kiện lặp định kỳ (họp tuần, nhắc việc tháng) được sinh tự động từ khuôn mẫu chu kỳ.
Ràng buộc toàn vẹn Tầng Vận hành: ① Mã task CTC-n là duy nhất và tăng đơn điệu · ② Khi tạo task, các mảng subtasks, tags, links luôn được khởi tạo mảng rỗng [] (không được undefined/null) · ③ Khi chuyển task sang done, hệ thống tự động ghi nhận thời điểm completedAt.

4. Tầng Kế toán, Tài chính & Công nợ (Finance & Invoices Layer)

ORD Tầng Kế toán, Tài chính & Công nợMô hình dữ liệu hoá đơn, sổ thu chi, công nợ NCC và tính toán hoa hồngHỢP ĐỒNG & THU NHẬPHOÁ ĐƠN & NHÀ CUNG CẤPSỔ TÀI CHÍNH & ĐỐI SOÁTxuất HĐ theo mốc10..*mark-paid sinh thu10..*tự sinh hàng thángN0..1đợt chi theo HĐ10..*tổng hợp chi phíN1tính hoa hồng deal10..*chi NCC đã duyệt11ENTITYDự án (Project Ref)# id (pj1..pj16)→ contactId (ct*) dealValue (Doanh số) status (acceptance/done)ENTITYThu nhập & Thuế TNCN# id (income-config)→ userId (u1..u7) baseSalary (Lương cứng) commissionPct (% hoa hồng) dependents (Người phụ thuộc) taxModel2026 (Luỹ tiến 7 bậc)ENTITYHoá đơn GTGT (Invoice)# id · number (CTC-INV-*)→ contactId · projectId status (draft..overdue) total · vatAmount items[] (Line-items) scanOcrUrlENTITYNhà cung cấp (Vendors AP)# id (vd1..) name · serviceType contractValue (Cam kết) paidAmount (Đã duyệt) status (signed..paid) bankInfoENTITYGiao dịch Thu / Chi# id (tx1..) type (income/expense) amount (VNĐ)→ contactId · projectId→ invoiceId · recurringId status (pending/done) tags[] (tc:*)ENTITYKhoản Thu/Chi Định kỳ# id (rec1..) name · type amount · dayOfMonth status (active/inactive) lastRunENTITYĐợt Thanh toán NCC# id (vp1..)→ vendorId (vd*) amount · paymentDate→ approvedBy (BOD >5tr) status (pending/paid) noteENTITYQuyết toán Lãi Lỗ (P&L) totalRevenue (Thực thu) totalExpense (Thực chi) vendorCosts (Chi phí NCC) grossMargin (% Lợi nhuận) closed (Chỉ đọc sau đóng)LEGENDThực thể trung tâm (Invoice)Thực thể tài chính / công nợQuan hệ ghi nhận doanh thu (1 - N)Giao dịch chi tự sinh từ thanh toán NCC
Đọc sơ đồ Tầng Kế toán: Dự án xuất Hoá đơn GTGT (Invoice) theo từng đợt mốc hợp đồng; Khi hoá đơn được đánh dấu thanh toán (Mark Paid), hệ thống tự động ghi 1 dòng Giao dịch thu (Transaction income); Khoản định kỳ (Recurrence) tự sinh giao dịch chi hàng tháng; Nhà cung cấp (Vendor) theo dõi cam kết vs thực chi, thanh toán > 5tr bắt buộc có phê duyệt BOD; Dữ liệu đối soát P&L và tính thu nhập/hoa hồng cá nhân.

Đặc tả quan hệ chi tiết — Tầng Kế toán & Dòng tiền

Quan hệ thực thểCardinalityÝ nghĩa nghiệp vụ & Ràng buộc toàn vẹn
Project → Invoice 1 — 0..* Hoá đơn GTGT phát hành theo các đợt tạm ứng, nghiệm thu và quyết toán hợp đồng dự án.
Invoice → Transaction 1 — 0..* Mỗi lần nhận tiền thanh toán hoá đơn sẽ sinh bản ghi giao dịch thu tương ứng gắn invoiceId.
Transaction → Recurrence N — 0..1 Giao dịch định kỳ tự động chạy vào ngày N hàng tháng (chi phí server, tool, văn phòng, lương).
Vendor → VendorPayment 1 — 0..* Quản trị công nợ NCC: Giá trị hợp đồng cam kết − Tổng các đợt thanh toán đã duyệt = Còn phải trả.
VendorPayment → Transaction 1 — 1 Đợt thanh toán NCC sau khi được duyệt sẽ tự động ghi sổ chi (Transaction expense) trong sổ tài chính.
Project → IncomeConfig 1 — 0..* Tính hoa hồng dự án per-user dựa trên dealValue hoặc thực thu kết hợp biểu thuế TNCN 2026.
Ràng buộc toàn vẹn Tầng Kế toán: ① Hoá đơn quá hạn (quá dueDate và chưa thu đủ) tự động gắn tag cảnh báo đỏ overdue · ② Giao dịch dự kiến (status: pending) không được cộng vào số dư thực tế · ③ Mọi khoản chi NCC > 5.000.000đ bắt buộc phải có trường approvedBy của Admin/BOD.

5. Tầng Tự động hoá, AI & Phân quyền (Automation, AI & Security Layer)

ERD Tầng Phân quyền, Tự động hoá & Trợ lý ngoàiMô hình dữ liệu phân quyền bốn trục, workflow engine, kỹ năng với hai mức chia sẻ, và khoá API gắn danh tính cho trợ lý ngoàiTỰ ĐỘNG HOÁ & RUNSDANH TÍNH & PHÂN QUYỀN (RBAC)KỸ NĂNG, BOT & REVIEW LAYERsở hữu quy trình10..*lịch sử thực thi10..*sở hữu kỹ năng10..*gửi / duyệt yêu cầu10..*1 khoá = 1 người10..*skill_ids[] phát hànhNNghim nhận xét @tag10..*cấu hình relay bot10..*ENTITYTài khoản & Phân quyền# id (u0.. / au_hex) username · display_name role (admin/member) data_scope (self/team/all) modules[] (24 phân hệ) session_ver (thu hồi phiên) title (Chức danh)ENTITYQuy trình Tự động hoá# id (wf1..) name · active (mặc định 0)→ owner_id (u*) shared_with[] trigger (status/scan) actions[] (5 loại)ENTITYLịch sử Chạy Tự động# id (wfr1..)→ wf_id (wf*)→ user_id (u*) run_key · status logs[] · atENTITYSổ tay Kỹ năng & SOP# id (sk_hex) name · category→ owner_id (u*) shared_with[] (mức Xem) shared_edit[] (mức Sửa) published · versions[]ENTITYYêu cầu Phát triển# id (req1..) title · kind (skill/wf)→ requester_id (u*)→ reviewer_id (admin) target_id status (new..released)ENTITYReview Layer Ghim Toạ độ# id (pin.cid)→ target_cid · pin_pos thread[] (comments) resolved (boolean) mentions[] (@user)ENTITYBot Telegram & Relay# id (bot_hex) name · token (băm)→ owner_id (u*) poll_mode (poll/inbound) activeENTITYKhoá API cho Trợ lý ngoài# id (khoá) key_hash (chỉ SHA-256)→ scope_user_id (u*) — DANH TÍNH skill_ids[] → phát hành last_used_at · revoked_atLEGENDĐiểm kiểm soát danh tính & quyềnThực thể hệ thống / per-userQuan hệ sở hữu trực tiếp (1 - N)Quan hệ nhiều-nhiều qua cột JSON
Đọc sơ đồ Tầng Hệ thống: Tài khoản (AuthUser) là gốc danh tính — sở hữu Quy trình tự động hoá (Workflow), Sổ tay kỹ năng (Skill), Đề xuất phát triển (DevRequest), và Cấu hình Bot Relay; Workflow thực thi sinh lịch sử WorkflowRun; Review Layer ghim comment toạ độ và @mention đa tầng; Bot Relay kiểm soát an toàn qua danh sách Whitelist domain.

Đặc tả quan hệ chi tiết — Tầng Hệ thống & Tự động hoá

Quan hệ thực thểCardinalityÝ nghĩa nghiệp vụ & Ràng buộc toàn vẹn
AuthUser → Workflow 1 — 0..* Nhân sự tạo và sở hữu quy trình tự động hoá; có thể chia sẻ quyền xem qua mảng shared_with[].
Workflow → WorkflowRun 1 — 0..* Mỗi lần trigger kích hoạt (status_change hoặc daily_scan) ghi lại 1 log thực thi chống lặp run-key.
AuthUser → Skill 1 — 0..* Sổ tay SOP chuẩn hoá quy trình thực thi nghiệp vụ, hỗ trợ import Markdown và nâng version.
AuthUser → DevRequest 1 — 0..* Kênh gửi đề xuất tạo mới hoặc chỉnh sửa tính năng/kỹ năng; Admin duyệt qua 5 trạng thái.
AuthUser → CommentThread 1 — 0..* Review Layer kiểu Figma: ghim pin toạ độ trên màn hình, @mention thành viên và nhận thông báo realtime SSE.
AuthUser → BotConfig 1 — 0..* Cấu hình bot Telegram cá nhân, bảo mật token hash phía server, chỉ relay tới domain Whitelist.
AuthUser → BotApiKey 1 — 0..* Thêm 03/09. bot_api_keys.scope_user_id → auth_users.id. Một người có thể có nhiều khoá (mỗi workspace một khoá), nhưng một khoá chỉ thuộc đúng một người — đó là điều làm khoá trở thành danh tính chứ không phải mật khẩu dùng chung. Chỉ lưu SHA-256; thu hồi bằng revoked_at có hiệu lực tức thì. Khoá không mở được phân hệ mà chính người đó không có.
BotApiKey → Skill 0..* — 0..* Thêm 03/09. Quan hệ nhiều-nhiều không có bảng nối: danh sách nằm trong cột JSON bot_api_keys.skill_ids. Đây là đường "phát hành kỹ năng cho trợ lý" — agent cầm khoá chỉ biết những kỹ năng có id trong mảng đó.
AuthUser → Skill (chia sẻ) 0..* — 0..* Đổi 03/09. Hai quan hệ chia sẻ song song, cũng lưu dạng cột JSON: skills.shared_with = mức Xem, skills.shared_edit = mức Sửa. Một người chỉ nằm ở đúng một trong hai. Người mức Sửa đổi được nội dung nhưng không đổi được chính hai danh sách này — chỉ chủ sở hữu làm được.
AuthUser → Revision 1 — 0..* Thêm 02/09. revisions.actor_id + revisions.source: mỗi phiên bản state biết ai ghi và qua đường nào (web/api-key/agent/system). Trước đó không truy được thay đổi về người nào.
Ràng buộc toàn vẹn Tầng Hệ thống: ① Token bot Telegram không bao giờ trả full về client · ② Webhook relay chỉ chấp nhận domain nằm trong Whitelist an toàn · ③ Mọi thay đổi dữ liệu đều được ghi nhận vào chuỗi Revision snapshot trong bảng revisions làm nguồn sự thật duy nhất · ④ Khoá API chỉ lưu băm SHA-256, bản rõ hiện một lần lúc cấp · ⑤ Trợ lý ngoài chỉ tạo được bản ghi mới ở trạng thái nháp (kỹ năng draft, quy trình active = 0) — không sửa bản có sẵn, không xoá, không đổi được hai danh sách chia sẻ.
Sơ đồ đã dựng lại 03/09/2026. Sơ đồ tầng hệ thống nay có BOT_API_KEY (khoá gắn danh tính cho trợ lý ngoài, chỉ lưu SHA-256, mang skill_ids để phát hành kỹ năng), skills.shared_edit bên cạnh shared_with, và auth_users đủ bốn trục phân quyền kèm data_scope · session_ver. Dựng lại bằng analysis-site/generate_erds.py — sửa mô hình thì sửa script rồi chạy lại, đừng sửa tay tệp SVG.