TÀI LIỆU ĐẶC TẢ YÊU CẦU PHẦN MỀM (SRS) ​
HỆ THỐNG: NỀN TẢNG TRUY XUẤT NGUỒN GỐC GOTRACE ​
TXNG-F45 -- Cấu hình Gói Dịch vụ ​
| Thông tin | Chi tiết |
|---|---|
| Phiên bản | 1.0 |
| Ngày tạo | 01/07/2026 |
| Ngày cập nhật | 01/07/2026 |
| Tác giả | GoTrace Team |
| Người review | |
| Người phê duyệt |
Lịch sử thay đổi ​
| Ngày | Người cập nhật | Mô tả thay đổi |
|---|---|---|
| 01/07/2026 | GoTrace Team | Khởi tạo SRS v1.0 — Cấu hình động 4 gói dịch vụ (Cơ bản / Chuẩn hóa / Liên kết / Quản trị) theo bảng giá docs/sale/Sale_Pricing.md (hiệu lực 01/06/2026). Bảng mới service_plans: phí khởi tạo / chuẩn hóa / duy trì, quota QR-năm / SP / user / storage, phí tăng thêm, features JSONB (ma trận tính năng), chiết khấu 2y/3y, vòng đời SERVICE_PLAN_STATUS (DRAFT / ACTIVE / DEPRECATED). Chỉ PLATFORM_ADMIN CRUD. Seed 4 gói canonical. Module vận hành thương mại — KHÔNG có CTE/KDE truy xuất. |
1. Tổng quan tài liệu ​
1.1. Mục đích tài liệu ​
Tài liệu mô tả chi tiết chức năng Cấu hình Gói Dịch vụ (TXNG-F45) trong Module Quản trị Nền tảng của hệ thống GoTrace.
Chức năng cho phép Quản trị viên Nền tảng (PLATFORM_ADMIN) cấu hình động danh mục các gói dịch vụ thương mại mà GoTrace bán cho Doanh nghiệp (DN), theo bảng giá gốc docs/sale/Sale_Pricing.md (hiệu lực 01/06/2026). Mỗi gói định nghĩa đầy đủ:
- Nhóm phí: phí khởi tạo (
setup_fee), phí chuẩn hóa và liên kết (standardization_fee), phí duy trì hệ thống theo năm (maintenance_fee_year). - Quota / giới hạn: sản lượng mã QR/năm (
qr_quota_year), số sản phẩm tối đa (max_products), số người dùng tối đa (max_users), dung lượng lưu trữ (storage_gb). - Phí phát sinh vượt hạn mức: phí mỗi mã QR tăng thêm (
extra_qr_fee), phí mỗi mã sản phẩm tăng thêm (extra_product_fee). - Đào tạo & hỗ trợ: hình thức đào tạo (
training_type), số lần Onsite (training_onsite_count), số ngày hỗ trợ go-live (go_live_support_days), cam kết SLA (sla_support). - Ma trận tính năng (
featuresJSONB): so sánh chi tiết tính năng giữa 4 gói theo Phụ lục của Sale_Pricing. - Chính sách chiết khấu duy trì: chiết khấu 2 năm (
discount_2y_percent, mặc định 10%), 3 năm (discount_3y_percent, mặc định 20%), áp dụng trước VAT.
Gói dịch vụ được cấu hình tại F45 là nguồn dữ liệu chuẩn (canonical) cho luồng Kích hoạt & Vòng đời Dịch vụ DN (TXNG-F46): khi kích hoạt một DN, hệ thống chốt bản sao (plan_snapshot) cấu hình gói tại thời điểm kích hoạt để đảm bảo tính bất biến của hợp đồng.
Tài liệu là cơ sở cho đội ngũ phát triển (Developer), kiểm thử (QA), DBA và Business Analyst để triển khai chức năng phù hợp với BRD tương ứng (docs/brd/BRD_TXNG-F45_Cau_Hinh_Goi_Dich_Vu.md).
Phạm vi loại trừ (Out of scope): TXNG-F45 là module vận hành thương mại nội bộ, KHÔNG phát sinh Critical Tracking Event (CTE) / Key Data Element (KDE) truy xuất nguồn gốc. Việc kích hoạt, dùng thử, gia hạn, chấm dứt dịch vụ và chặn đăng nhập thuộc phạm vi TXNG-F46.
1.2. Thông tin chức năng ​
| Thuộc tính | Giá trị |
|---|---|
| Mã chức năng | TXNG-F45 |
| Tên chức năng | Cấu hình Gói Dịch vụ |
| Menu | TXNG > Quản trị Nền tảng > Gói Dịch vụ |
| Ưu tiên | Bắt buộc |
| Giai đoạn | v1.0 |
| Pháp lý | Chính sách thương mại nội bộ GoTrace (docs/sale/Sale_Pricing.md, 19/05/2026); Luật Giao dịch điện tử 2023 (căn cứ giá trị hợp đồng điện tử); Bộ luật Dân sự 2015 (hợp đồng dịch vụ); Nghị định 13/2023/NĐ-CP (bảo vệ dữ liệu cá nhân — chỉ áp dụng phần cấu hình, không lưu dữ liệu cá nhân trong F45). Module vận hành thương mại — KHÔNG áp dụng TCVN 12850:2019 / FDA / GS1 (không có CTE/KDE) |
| Liên thông | → TXNG-F46 (Kích hoạt & Vòng đời Dịch vụ DN — chọn service_plans.status = ACTIVE để kích hoạt, chốt plan_snapshot) |
→ TXNG-F16 (Cấp mã QR — ràng buộc qr_quota_year qua effective_qr_quota của DN) |
|
→ TXNG-F03 (Sản phẩm — ràng buộc max_products qua effective_max_products của DN) |
|
| ↔ TXNG-F01 (Quản lý Doanh nghiệp — gói được gán vào DN qua F46) |
1.3. Tác nhân tham gia (Actors) ​
| Actor | Vai trò | Quyền hạn |
|---|---|---|
| PLATFORM_ADMIN | Quản trị viên Nền tảng GoTrace (impl ROLE.ADMIN = numeric 1, chặn qua AdminGuard, API prefix /api/v1/admin/...) |
Full CRUD gói dịch vụ: tạo gói mới, sửa cấu hình phí/quota/features, đổi trạng thái gói (DRAFT → ACTIVE → DEPRECATED), xem danh sách / chi tiết / lịch sử version. Là role duy nhất được thao tác ghi. Nhân viên Sale thao tác gián tiếp qua tài khoản PLATFORM_ADMIN (SALE_STAFF không phải actor ghi trực tiếp) |
| ENTERPRISE_ADMIN | Quản trị viên Doanh nghiệp | Chỉ xem danh sách gói công khai (is_public = true AND status = ACTIVE) qua endpoint public tùy chọn GET /api/v1/service-plans/public để tham khảo bảng giá. KHÔNG thấy gói DRAFT/DEPRECATED, KHÔNG thao tác cấu hình |
| SYSTEM | Hệ thống tự động | Cung cấp cấu hình gói cho F46 khi kích hoạt (đọc service_plans → chốt plan_snapshot); validate ràng buộc quota khi F16/F03 kiểm tra hạn mức DN; KHÔNG tự thay đổi cấu hình gói |
Ghi chú phân quyền: Mọi endpoint ghi (POST/PUT/PATCH) đều đi qua prefix
/api/v1/admin/...vàAdminGuardchặn theoROLE.ADMIN. Endpoint đọc công khaiGET /api/v1/service-plans/publickhông yêu cầu quyền admin nhưng chỉ trả về gói công khai đang bán.
1.4. Tham chiếu UI/UX ​
| Tài liệu | Link |
|---|---|
| Mockup danh sách gói dịch vụ | docs/html/goi_dich_vu/service_plan_list.html (sẽ tạo trong Phase implementation) |
| Mockup tạo/sửa gói dịch vụ | docs/html/goi_dich_vu/service_plan_form.html |
| Mockup chi tiết gói + lịch sử version | docs/html/goi_dich_vu/service_plan_detail.html |
| Design System | apps/frontend/CLAUDE.md — Section Frontend UI/UX (HeroUI, DebouncedInput, CSelect, useFilter, TableWrapper, FormWrapper/FormRow, React Hook Form + Zod) |
2. Luồng nghiệp vụ (Business Flow) ​
2.1. Luồng nghiệp vụ tổng quan ​
┌──────────────────────────────────────────────────────────────────────────────────────┐
│ LUỒNG CẤU HÌNH GÓI DỊCH VỤ (F45) │
├──────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ╔══════════════════════════════════════════════════════════════════════════════╗ │
│ ║ SEED KHỞI TẠO: 4 GÓI CANONICAL (Migration) ║ │
│ ╚══════════════════════════════════════════════════════════════════════════════╝ │
│ ┌───────────────┐ ┌────────────────┐ ┌───────────────┐ ┌────────────────┐ │
│ │ PKG_BASIC │ │ PKG_STANDARD │ │ PKG_LINKED │ │ PKG_ENTERPRISE │ │
│ │ Gói Cơ bản │ │ Gói Chuẩn hóa │ │ Gói Liên kết │ │ Gói Quản trị │ │
│ │ status=ACTIVE │ │ status=ACTIVE │ │ status=ACTIVE │ │ status=ACTIVE │ │
│ └───────────────┘ └────────────────┘ └───────────────┘ └────────────────┘ │
│ │ │
│ ════════════════════════════════════════════════════════════════════════════════ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ PLATFORM_ADMIN mở SCR-F45-01 (Danh sách gói) │ │
│ │ • Xem/tìm kiếm/lọc theo trạng thái, từ khóa │ │
│ └───────────────────────────────┬────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────────────┼───────────────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ TẠO GÓI MỚI │ │ SỬA GÓI │ │ ĐỔI TRẠNG THÁI │ │
│ │ (UC-F45-01) │ │ (UC-F45-02) │ │ (UC-F45-03) │ │
│ │ SCR-F45-02 │ │ SCR-F45-02 │ │ SCR-F45-01/03 │ │
│ │ status=DRAFT│ │ • tăng │ │ DRAFT→ACTIVE │ │
│ │ │ │ version │ │ ACTIVE⇄DEPRECAT │ │
│ └──────┬──────┘ └──────┬──────┘ └────────┬────────┘ │
│ │ │ │ │
│ └──────────────────────────┼───────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ AUDIT: mỗi thao tác ghi service_plans.updated_by + version++ (khi sửa │ │
│ │ phí/quota); soft delete deleted_at; validate plan_code immutable │ │
│ └───────────────────────────────┬────────────────────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────────────────────┐ │
│ │ TIÊU THỤ: TXNG-F46 đọc gói status=ACTIVE để kích hoạt DN │ │
│ │ → chốt plan_snapshot (bất biến); gói DEPRECATED KHÔNG được chọn mới │ │
│ │ nhưng DN đang dùng vẫn giữ snapshot cũ │ │
│ └────────────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────────────────────┘
2.2. Diễn giải luồng ​
| Bước | Mô tả hành động | Hệ thống thực hiện |
|---|---|---|
| B1 | Migration seed 4 gói canonical (PKG_BASIC / PKG_STANDARD / PKG_LINKED / PKG_ENTERPRISE) theo Sale_Pricing.md | INSERT 4 bản ghi service_plans với đầy đủ phí, quota, features JSONB, status = ACTIVE, version = 1, display_order 1–4 |
| B2 | PLATFORM_ADMIN mở SCR-F45-01, tìm kiếm / lọc / xem danh sách gói | SELECT service_plans WHERE deleted_at IS NULL + filter (status, keyword) ORDER BY display_order; pagination |
| B3 | (Tạo mới) ADMIN click "Tạo gói" → điền form SCR-F45-02 → Lưu | 1. Validate server-side (plan_code UNIQUE + UPPER_SNAKE, phí ≥ 0, quota ≥ 0, features theo JSON schema) 2. INSERT service_plans {status: DRAFT, version: 1, created_by}3. Return 201 Created |
| B4 | (Sửa) ADMIN mở gói → sửa phí/quota/features/tính năng → Lưu | 1. Validate; plan_code KHÔNG được đổi (immutable — E-F45-002)2. UPDATE service_plans {updated_by}; nếu thay đổi phí/quota → version++3. Return 200 OK |
| B5 | (Đổi trạng thái) ADMIN đổi DRAFT→ACTIVE / ACTIVE⇄DEPRECATED | 1. Validate transition hợp lệ (Section 12) 2. UPDATE service_plans.status, updated_by3. Nếu → DEPRECATED: gói không hiện trong danh sách chọn khi kích hoạt mới ở F46 (nhưng DN đang dùng giữ plan_snapshot)4. Return 200 OK |
| B6 | (Xóa) ADMIN xóa gói (chỉ khi chưa DN nào dùng) | 1. Kiểm tra không có company_subscriptions tham chiếu plan_id (E-F45-006)2. Soft delete: SET deleted_at = NOW(), updated_by3. Return 200 OK |
| B7 | F46 kích hoạt DN | SELECT service_plans WHERE status = ACTIVE AND deleted_at IS NULL; chốt plan_snapshot JSONB vào company_subscriptions |
3. Phân loại / Trạng thái ​
3.1. Trạng thái gói dịch vụ (SERVICE_PLAN_STATUS — Canonical §2.45) ​
| Trạng thái | Mã | Mô tả | CSS class | Background | Color |
|---|---|---|---|---|---|
| Nháp | DRAFT |
Đang soạn cấu hình gói, chưa cho phép gán cho DN | .bdg.bdg-neutral |
#f0f2f5 | #8c99ab |
| Đang áp dụng | ACTIVE |
Đang bán, có thể gán cho DN khi kích hoạt (F46) | .bdg.bdg-success |
#e8f5e9 | #2e7d32 |
| Ngừng bán | DEPRECATED |
Ngừng bán gói mới; DN đang dùng vẫn giữ plan_snapshot |
.bdg.bdg-warning |
#fff8e1 | #fb8c00 |
3.2. Mã gói canonical (SERVICE_PLAN_CODE — Canonical §2.44) ​
| Mã | Tên gói (hiển thị) | Đối tượng sử dụng |
|---|---|---|
PKG_BASIC |
Gói Cơ bản | OCOP, HTX, hộ kinh doanh cần số hóa dữ liệu cơ bản, QR truy xuất, chứng nhận, vùng nguyên liệu, trang truy xuất công khai |
PKG_STANDARD |
Gói Chuẩn hóa | DN cần chuẩn hóa dữ liệu sản phẩm, quy trình sản xuất, lô, chứng nhận, kiểm nghiệm và QR truy xuất trên hệ thống thống nhất |
PKG_LINKED |
Gói Liên kết | DN có nhiều nhà cung cấp, đối tác phân phối, lô sản xuất cần liên kết dữ liệu để truy xuất toàn chuỗi cung ứng |
PKG_ENTERPRISE |
Gói Quản trị | DN xuất khẩu, DN quy mô lớn (BigCorp) cần dashboard, cảnh báo, phân quyền, mở rộng API và tích hợp nâng cao |
plan_codelà dữ liệu động; admin có thể thêm gói mới với mã UPPER_SNAKE_CASE bắt đầu bằngPKG_. 4 mã trên là seed canonical bắt buộc.
3.3. Hình thức đào tạo (Training Type) ​
| Mã | Tên | Mô tả |
|---|---|---|
ONLINE |
Đào tạo trực tuyến | Đào tạo qua họp trực tuyến, tài liệu hướng dẫn |
ONSITE |
Đào tạo tại chỗ | Đào tạo trực tiếp tại cơ sở DN (kèm training_onsite_count số lần) |
3.4. Chu kỳ thanh toán (Billing Cycle) ​
| Mã | Tên | Mô tả |
|---|---|---|
ANNUAL |
Theo năm | Phí duy trì tính theo năm (mặc định) |
4. Danh sách màn hình ​
| Mã màn hình | Tên màn hình | Chức năng chính | Vai trò sử dụng | Ghi chú |
|---|---|---|---|---|
| SCR-F45-01 | Danh sách Gói Dịch vụ | Hiển thị, tìm kiếm, lọc, đổi trạng thái danh sách gói | PLATFORM_ADMIN | Màn hình chính; summary theo trạng thái |
| SCR-F45-02 | Tạo / Sửa Gói Dịch vụ | Form tạo mới hoặc sửa cấu hình gói (phí, quota, features, chiết khấu) | PLATFORM_ADMIN | React Hook Form + Zod; FormWrapper/FormRow |
| SCR-F45-03 | Chi tiết Gói Dịch vụ | Xem toàn bộ cấu hình gói + lịch sử version + nút đổi trạng thái | PLATFORM_ADMIN | Tabs: Thông tin / Ma trận tính năng / Lịch sử version |
5. Mô tả chi tiết trường dữ liệu ​
5.1. SCR-F45-01: Danh sách Gói Dịch vụ ​
Summary cards (đếm theo trạng thái):
| Card | Nguồn dữ liệu |
|---|---|
| Tổng số gói | COUNT(service_plans WHERE deleted_at IS NULL) |
| Đang áp dụng | COUNT(status = ACTIVE) |
| Nháp | COUNT(status = DRAFT) |
| Ngừng bán | COUNT(status = DEPRECATED) |
Thanh công cụ (Toolbar):
| Phần tử | Loại | Mô tả |
|---|---|---|
| Tìm kiếm | Text Input (DebouncedInput, 300ms) | Tìm theo plan_code, plan_name (≥ 2 ký tự) |
| Lọc theo trạng thái | Dropdown (CSelect) | DRAFT / ACTIVE / DEPRECATED / Tất cả |
| Nút "Tạo gói" | Button (Primary) | Mở SCR-F45-02 (chế độ tạo mới) — PLATFORM_ADMIN |
Bảng dữ liệu (TableWrapper):
| Cột | Kiểu | Sortable | Mô tả |
|---|---|---|---|
| STT | Number | Không | Số thứ tự (theo display_order) |
| Mã gói | Text (Link) | Có | plan_code — click mở SCR-F45-03 |
| Tên gói | Text | Có | plan_name |
| Phí khởi tạo | Currency | Có | setup_fee (VND, format #,##0) |
| Phí chuẩn hóa | Currency | Có | standardization_fee |
| Phí duy trì/năm | Currency | Có | maintenance_fee_year |
| Tổng năm đầu | Currency | Không | setup_fee + standardization_fee + maintenance_fee_year (computed) |
| Quota QR/năm | Number | Có | qr_quota_year |
| SP tối đa | Number | Có | max_products |
| Trạng thái | Badge | Có | DRAFT / ACTIVE / DEPRECATED (color-coded §3.1) |
| Thao tác | Actions | Không | Xem / Sửa / Đổi trạng thái / Xóa (theo trạng thái + BR) |
Phân trang: 10 / 20 / 50 / 100 bản ghi/trang. Response envelope { page, page_size, total_items, total_pages }.
5.2. SCR-F45-02: Tạo / Sửa Gói Dịch vụ ​
Card 1: Thông tin định danh ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Mã gói | plan_code |
Text (3–30) | Có | UNIQUE (WHERE deleted_at IS NULL); regex ^[A-Z][A-Z0-9_]{2,29}$; immutable sau khi tạo |
Mã định danh gói (UPPER_SNAKE_CASE). Khi Sửa: trường read-only |
| Tên gói | plan_name |
Text (1–150) | Có | max 150 ký tự | Tên hiển thị gói (tiếng Việt có dấu) |
| Đối tượng sử dụng | target_audience |
Textarea | Không | max 2000 ký tự | Mô tả đối tượng khách hàng phù hợp |
| Thứ tự hiển thị | display_order |
Number | Không | ≥ 0; INT | Thứ tự sắp xếp trong danh sách (mặc định 0) |
| Công khai bảng giá | is_public |
Toggle | Không | boolean | Cho phép hiển thị ở endpoint public (mặc định true) |
| Ngày hiệu lực | effective_from |
Date | Không | ISO 8601 | Ngày cấu hình gói bắt đầu có hiệu lực |
Card 2: Cấu hình phí (Fees — VND, chưa gồm VAT) ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Phí khởi tạo | setup_fee |
Decimal(14,2) | Có | ≥ 0 | Phí khởi tạo hệ thống (khảo sát, thiết kế cấu trúc dữ liệu, cấu hình, mẫu QR) |
| Phí chuẩn hóa & liên kết | standardization_fee |
Decimal(14,2) | Có | ≥ 0 | Phí chuẩn hóa dữ liệu nền + liên kết chuỗi cung ứng + import dữ liệu ban đầu |
| Phí duy trì/năm | maintenance_fee_year |
Decimal(14,2) | Có | ≥ 0 | Phí duy trì hệ thống theo năm (hạ tầng, bảo mật, sao lưu, hỗ trợ) |
| Phí mã QR tăng thêm | extra_qr_fee |
Decimal(10,2) | Có | ≥ 0 | Phí mỗi mã QR vượt qr_quota_year |
| Phí mã SP tăng thêm | extra_product_fee |
Decimal(12,2) | Có | ≥ 0 | Phí mỗi mã sản phẩm vượt max_products (cộng vào phí duy trì kỳ tiếp) |
Tổng phí năm đầu (hiển thị read-only, computed):
setup_fee + standardization_fee + maintenance_fee_year. Từ năm 2:maintenance_fee_year.
Card 3: Cấu hình quota / giới hạn ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Sản lượng QR/năm | qr_quota_year |
Number (INT) | Có | ≥ 0 | Số mã QR được cấp/năm (ràng buộc F16) |
| Số SP tối đa | max_products |
Number (INT) | Có | ≥ 0 | Số mã sản phẩm tối đa (ràng buộc F03) |
| Số user tối đa | max_users |
Number (INT) | Có | ≥ 0 | Số tài khoản người dùng tối đa của DN |
| Dung lượng lưu trữ (GB) | storage_gb |
Number (INT) | Có | ≥ 0 | Dung lượng lưu trữ file (GB) |
Card 4: Đào tạo & hỗ trợ ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Hình thức đào tạo | training_type |
Dropdown | Có | Enum: ONLINE / ONSITE (§3.3) | Hình thức đào tạo tiêu chuẩn |
| Số lần Onsite | training_onsite_count |
Number (INT) | Có | ≥ 0; = 0 nếu ONLINE | Số buổi đào tạo tại chỗ |
| Hỗ trợ go-live (ngày) | go_live_support_days |
Number (INT) | Có | ≥ 0 | Số ngày hỗ trợ đưa hệ thống vào vận hành |
| SLA hỗ trợ | sla_support |
Text (1–100) | Có | max 100 ký tự | Cam kết hỗ trợ (vd: "Trong giờ hành chính", "24/7", "Ưu tiên 24/7") |
Card 5: Ma trận tính năng (features JSONB) ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Ma trận tính năng | features |
JSONB | Có | Theo JSON schema ma trận (BR-F45-04) | Object mô tả từng tính năng (bật/tắt/mức độ). Xem Section 18 và schema dưới |
JSON schema features (giá trị mỗi khóa ∈ {true, false, "OPTIONAL", "CUSTOM"} hoặc số/chuỗi mô tả mức):
| Khóa (feature key) | Kiểu giá trị | Ý nghĩa |
|---|---|---|
company_profile |
boolean | Hồ sơ doanh nghiệp/chủ thể |
product_catalog_standardization |
boolean | Chuẩn hóa danh mục sản phẩm (giới hạn theo max_products) |
material_input_standardization |
boolean | Chuẩn hóa thông tin nguyên liệu đầu vào |
certification_standardization |
boolean | Chuẩn hóa danh mục chứng nhận/chứng chỉ |
growing_area_standardization |
boolean | Chuẩn hóa danh mục vùng trồng/vùng nuôi |
customer_agent_standardization |
boolean | Chuẩn hóa dữ liệu khách hàng/đại lý |
staff_standardization |
boolean | Chuẩn hóa danh mục nhân viên |
production_process_standardization |
boolean | Chuẩn hóa danh mục quy trình sản xuất |
product_lot_code_consulting |
boolean | Tư vấn cấu trúc mã sản phẩm/lô |
qr_traceability |
boolean | QR truy xuất nguồn gốc |
public_trace_page |
"STANDARD" / "CUSTOM" |
Trang truy xuất công khai (chuẩn / tùy chỉnh) |
qr_scan_statistics |
true / "CUSTOM" |
Thống kê lượt quét QR |
supply_chain_linking |
boolean | Liên kết các chủ thể chuỗi cung ứng (chủ thể ≥ gói Chuẩn hóa) |
product_recall_management |
boolean | Quản lý thu hồi sản phẩm |
operation_dashboard |
true / "CUSTOM" |
Dashboard vận hành |
activity_log |
boolean | Nhật ký thao tác |
api_integration |
false / "BASIC" / "CUSTOM" |
API tích hợp (none / 1 API cơ bản / theo phạm vi) |
blockchain |
false / "OPTIONAL" |
Blockchain (không / tùy chọn mua thêm) |
Card 6: Chính sách chiết khấu & thanh toán ​
| Tên trường | Field name | Kiểu dữ liệu | Bắt buộc | Validation | Mô tả |
|---|---|---|---|---|---|
| Chiết khấu 2 năm (%) | discount_2y_percent |
Decimal(5,2) | Không | 0–100; mặc định 10 | Chiết khấu phí duy trì khi ký 2 năm (trước VAT) |
| Chiết khấu 3 năm (%) | discount_3y_percent |
Decimal(5,2) | Không | 0–100; mặc định 20 | Chiết khấu phí duy trì khi ký 3 năm (trước VAT) |
| Chu kỳ thanh toán | billing_cycle |
Dropdown | Không | Enum: ANNUAL (§3.4); mặc định ANNUAL | Chu kỳ tính phí duy trì |
| Đơn vị tiền tệ | currency |
Text (auto) | Không | mặc định VND | Đơn vị tiền tệ (read-only v1.0) |
Trường hệ thống (read-only, hiển thị ở SCR-F45-03) ​
| Tên trường | Field name | Kiểu dữ liệu | Mô tả |
|---|---|---|---|
| Phiên bản | version |
INT | Số version cấu hình, tăng khi sửa phí/quota (mặc định 1) |
| Trạng thái | status |
Enum | DRAFT / ACTIVE / DEPRECATED (§3.1) |
| Người tạo | created_by |
BIGINT FK | User tạo gói |
| Người cập nhật | updated_by |
BIGINT FK | User cập nhật gần nhất |
| Ngày tạo | created_at |
TIMESTAMPTZ | Thời điểm tạo |
| Ngày cập nhật | updated_at |
TIMESTAMPTZ | Thời điểm cập nhật gần nhất |
Hành động Footer ​
- Nút "Lưu" (Primary): Validate + tạo/cập nhật gói (status giữ nguyên; gói mới = DRAFT).
- Nút "Hủy" (Tertiary): Đóng form không lưu.
5.3. SCR-F45-03: Chi tiết Gói Dịch vụ ​
Header Info Box (read-only): plan_code lớn + badge trạng thái màu; plan_name; tổng phí năm đầu; version; người tạo/cập nhật + thời điểm.
Tabs:
- Tab "Thông tin": Hiển thị toàn bộ field từ SCR-F45-02 read-only (định danh, phí, quota, đào tạo, chiết khấu).
- Tab "Ma trận tính năng" ({FeatureMatrixTable}): Render
featuresJSONB thành bảng dễ đọc (✔ / — / Tùy chọn / Tùy chỉnh). - Tab "Lịch sử version" ({PlanVersionTimeline}): Hiển thị các mốc thay đổi (version, người sửa, thời điểm, tóm tắt trường thay đổi) — nguồn từ
updated_by+versionvà log audit.
Action buttons (theo status + role PLATFORM_ADMIN):
| Status | Hành động khả dụng |
|---|---|
| DRAFT | Sửa / Kích hoạt (→ ACTIVE) / Xóa (nếu chưa DN dùng) |
| ACTIVE | Sửa / Ngừng bán (→ DEPRECATED) |
| DEPRECATED | Sửa / Mở lại (→ ACTIVE) / Xóa (nếu chưa DN dùng) |
6. Danh sách Use Case ​
| ID | Tên Use Case | Actor chính | Mô tả ngắn |
|---|---|---|---|
| UC-F45-01 | Tạo gói dịch vụ | PLATFORM_ADMIN | Tạo gói mới với cấu hình phí/quota/features, status = DRAFT |
| UC-F45-02 | Sửa gói dịch vụ | PLATFORM_ADMIN | Chỉnh sửa cấu hình gói; tăng version khi sửa phí/quota; ghi audit |
| UC-F45-03 | Đổi trạng thái gói | PLATFORM_ADMIN | DRAFT→ACTIVE, ACTIVE⇄DEPRECATED |
| UC-F45-04 | Xem danh sách / chi tiết gói | PLATFORM_ADMIN, ENTERPRISE_ADMIN (public) | Tìm kiếm, lọc, xem chi tiết cấu hình + ma trận tính năng + lịch sử version |
7. Mô tả chi tiết Use Case ​
UC-F45-01: Tạo gói dịch vụ ​
Mô tả: PLATFORM_ADMIN tạo một gói dịch vụ mới với cấu hình đầy đủ phí, quota, tính năng.
Tiền điều kiện:
- User đã đăng nhập, role =
ROLE.ADMIN(PLATFORM_ADMIN), quaAdminGuard. plan_codedự kiến chưa tồn tại (trong các bản ghi chưa xóa mềm).
Hậu điều kiện:
- Một bản ghi
service_plansở status = DRAFT, version = 1 được tạo.
| Bước | Tác nhân | Hành động / Mô tả | Phản hồi / Xử lý hệ thống | Ghi chú |
|---|---|---|---|---|
| 1 | ADMIN | Click "Tạo gói" trên SCR-F45-01 | Mở SCR-F45-02 (chế độ tạo mới, form trống) | |
| 2 | ADMIN | Điền Card 1–6 (định danh, phí, quota, đào tạo, features, chiết khấu) | Validate realtime client-side (Zod) | |
| 3 | ADMIN | Click "Lưu" | 1. Validate toàn bộ form (server-side) 2. Kiểm tra plan_code UNIQUE + regex UPPER_SNAKE (E-F45-001)3. Kiểm tra phí ≥ 0, quota ≥ 0 (E-F45-003) 4. Kiểm tra features theo JSON schema (E-F45-004)5. INSERT service_plans {status: DRAFT, version: 1, created_by: current_user, created_at: NOW}6. Ghi log {action: CREATE, user, timestamp} 7. Return 201 Created + plan_id |
Status code: 201 |
Alternative Flow:
| Bước | Điều kiện | Xử lý |
|---|---|---|
| 3a | plan_code đã tồn tại (chưa xóa mềm) |
E-F45-001 "Mã gói đã tồn tại" |
| 3b | plan_code sai định dạng (không UPPER_SNAKE) |
E-F45-001 "Mã gói phải viết HOA, dùng chữ/số/gạch dưới" |
| 3c | Phí hoặc quota < 0 | E-F45-003 "Phí và quota phải ≥ 0" |
| 3d | features không đúng JSON schema |
E-F45-004 "Cấu trúc ma trận tính năng không hợp lệ" |
UC-F45-02: Sửa gói dịch vụ ​
Tiền điều kiện: User là PLATFORM_ADMIN; gói tồn tại, chưa xóa mềm.
Hậu điều kiện: Cấu hình cập nhật; nếu thay đổi phí/quota → version++; ghi audit; plan_code không đổi.
| Bước | Tác nhân | Hành động / Mô tả | Phản hồi / Xử lý hệ thống | Ghi chú |
|---|---|---|---|---|
| 1 | ADMIN | Click "Sửa" trên SCR-F45-01 hoặc SCR-F45-03 | Mở SCR-F45-02 với data hiện tại; plan_code read-only |
|
| 2 | ADMIN | Chỉnh sửa phí/quota/features/đào tạo/chiết khấu → "Lưu" | 1. Validate server-side 2. Kiểm tra plan_code KHÔNG bị đổi (E-F45-002)3. So sánh diff phí/quota so với bản ghi hiện tại 4. UPDATE service_plans {..., updated_by: current_user, updated_at: NOW}5. Nếu có thay đổi bất kỳ trong {setup_fee, standardization_fee, maintenance_fee_year, extra_qr_fee, extra_product_fee, qr_quota_year, max_products, max_users, storage_gb} → version = version + 16. Ghi log {action: UPDATE, user, timestamp, changes_json} 7. Return 200 OK |
Audit trail bắt buộc |
Alternative Flow:
| Bước | Điều kiện | Xử lý |
|---|---|---|
| 2a | Client gửi plan_code khác giá trị gốc |
E-F45-002 "Không được thay đổi mã gói sau khi tạo" |
| 2b | Phí/quota < 0 | E-F45-003 |
| 2c | features sai schema |
E-F45-004 |
| 2d | Sửa gói DEPRECATED | Cho phép sửa cấu hình; W-F45-001 "Gói đang ngừng bán — thay đổi không ảnh hưởng DN đang dùng (giữ plan_snapshot)" |
UC-F45-03: Đổi trạng thái gói ​
Tiền điều kiện: User là PLATFORM_ADMIN; transition hợp lệ theo Section 12.
Hậu điều kiện: status cập nhật; ghi audit.
| Bước | Tác nhân | Hành động / Mô tả | Phản hồi / Xử lý hệ thống |
|---|---|---|---|
| 1 | ADMIN | Trên SCR-F45-01/03 click "Kích hoạt" / "Ngừng bán" / "Mở lại" | Mở confirm dialog |
| 2 | ADMIN | Xác nhận | 1. Validate transition hợp lệ (E-F45-005 nếu không): DRAFT→ACTIVE; ACTIVE→DEPRECATED; DEPRECATED→ACTIVE 2. UPDATE service_plans.status, updated_by, updated_at3. Ghi log {action: STATUS_CHANGE, from, to, user} 4. Nếu → DEPRECATED: gói bị loại khỏi danh sách chọn khi kích hoạt mới ở F46 5. Return 200 OK |
Alternative Flow:
| Bước | Điều kiện | Xử lý |
|---|---|---|
| 2a | Transition không hợp lệ (vd DRAFT→DEPRECATED) | E-F45-005 "Chuyển trạng thái không hợp lệ" |
UC-F45-04: Xem danh sách / chi tiết gói ​
| Bước | Tác nhân | Hành động / Mô tả | Phản hồi / Xử lý hệ thống |
|---|---|---|---|
| 1 | ADMIN | Mở SCR-F45-01, nhập search / chọn filter | Debounce 300ms; SELECT service_plans WHERE deleted_at IS NULL + filter (status, keyword ILIKE plan_code/plan_name) ORDER BY display_order LIMIT N OFFSET M |
| 2 | ADMIN | Click 1 dòng | Navigate SCR-F45-03; SELECT chi tiết + render features thành ma trận |
| 3 | ENTERPRISE_ADMIN | Gọi GET /api/v1/service-plans/public |
SELECT service_plans WHERE status = ACTIVE AND is_public = true AND deleted_at IS NULL ORDER BY display_order (không trả trường nội bộ như created_by) |
8. Thiết kế Database Schema ​
8.1. ER Diagram ​
┌─────────────────────────────────┐ ┌─────────────────────────────────┐
│ users │ │ companies (F01) │
│ id (BIGINT, PK) │ │ id (BIGINT, PK) │
│ role (INT) │ │ status (INT) ── mirror F46 │
└──────────┬──────────────────────┘ └──────────┬──────────────────────┘
│ 1:N (created_by, updated_by) │ 1:N (qua F46)
▼ │
┌──────────────────────────────────────────────────────┼───────────────────────┐
│ service_plans (F45) │ │
│ id (BIGSERIAL, PK) │ │
│ plan_code (VARCHAR 30) ── UNIQUE WHERE deleted_at IS NULL │
│ plan_name (VARCHAR 150) │
│ target_audience (TEXT) │
│ setup_fee, standardization_fee, maintenance_fee_year (NUMERIC 14,2) │
│ qr_quota_year, max_products, max_users, storage_gb (INT) │
│ extra_qr_fee (NUMERIC 10,2), extra_product_fee (NUMERIC 12,2) │
│ training_type (VARCHAR 20), training_onsite_count (INT) │
│ go_live_support_days (INT), sla_support (VARCHAR 100) │
│ features (JSONB) │
│ discount_2y_percent, discount_3y_percent (NUMERIC 5,2) │
│ billing_cycle (VARCHAR 20), currency (VARCHAR 10) │
│ status (VARCHAR 20) ── DRAFT / ACTIVE / DEPRECATED │
│ display_order (INT), is_public (BOOLEAN), effective_from (DATE) │
│ version (INT) │
│ created_by, updated_by (BIGINT FK → users) │
│ created_at, updated_at (TIMESTAMPTZ), deleted_at (TIMESTAMPTZ NULL) │
└──────────────────────────────────┬────────────────────────────────────────────┘
│ 1:N (tham chiếu qua F46 khi kích hoạt)
▼
┌──────────────────────────────────────────┐
│ company_subscriptions (F46) │
│ plan_id (BIGINT FK → service_plans) │
│ plan_code (VARCHAR 30) ── snapshot │
│ plan_snapshot (JSONB) ── chốt cấu hình │
└──────────────────────────────────────────┘
8.2. Mô tả bảng ​
Bảng service_plans ​
| Cột | Kiểu dữ liệu | Nullable | Default | Mô tả | Constraint |
|---|---|---|---|---|---|
id |
BIGSERIAL | NOT NULL | Khóa chính | PRIMARY KEY | |
plan_code |
VARCHAR(30) | NOT NULL | Mã gói UPPER_SNAKE (PKG_*) | UNIQUE WHERE deleted_at IS NULL | |
plan_name |
VARCHAR(150) | NOT NULL | Tên hiển thị gói | ||
target_audience |
TEXT | NULL | Đối tượng sử dụng | ||
setup_fee |
NUMERIC(14,2) | NOT NULL | 0 | Phí khởi tạo (VND) | CHECK (setup_fee >= 0) |
standardization_fee |
NUMERIC(14,2) | NOT NULL | 0 | Phí chuẩn hóa & liên kết | CHECK (standardization_fee >= 0) |
maintenance_fee_year |
NUMERIC(14,2) | NOT NULL | 0 | Phí duy trì/năm | CHECK (maintenance_fee_year >= 0) |
qr_quota_year |
INT | NOT NULL | 0 | Sản lượng QR/năm | CHECK (qr_quota_year >= 0) |
max_products |
INT | NOT NULL | 0 | Số SP tối đa | CHECK (max_products >= 0) |
max_users |
INT | NOT NULL | 0 | Số user tối đa | CHECK (max_users >= 0) |
storage_gb |
INT | NOT NULL | 0 | Dung lượng lưu trữ (GB) | CHECK (storage_gb >= 0) |
extra_qr_fee |
NUMERIC(10,2) | NOT NULL | 0 | Phí mỗi QR tăng thêm | CHECK (extra_qr_fee >= 0) |
extra_product_fee |
NUMERIC(12,2) | NOT NULL | 0 | Phí mỗi SP tăng thêm | CHECK (extra_product_fee >= 0) |
training_type |
VARCHAR(20) | NOT NULL | 'ONLINE' | Hình thức đào tạo | CHECK IN ('ONLINE','ONSITE') |
training_onsite_count |
INT | NOT NULL | 0 | Số lần Onsite | CHECK (training_onsite_count >= 0) |
go_live_support_days |
INT | NOT NULL | 0 | Số ngày hỗ trợ go-live | CHECK (go_live_support_days >= 0) |
sla_support |
VARCHAR(100) | NULL | Cam kết SLA hỗ trợ | ||
features |
JSONB | NOT NULL | '{}' | Ma trận tính năng | |
discount_2y_percent |
NUMERIC(5,2) | NOT NULL | 10 | Chiết khấu 2 năm (%) | CHECK (discount_2y_percent BETWEEN 0 AND 100) |
discount_3y_percent |
NUMERIC(5,2) | NOT NULL | 20 | Chiết khấu 3 năm (%) | CHECK (discount_3y_percent BETWEEN 0 AND 100) |
billing_cycle |
VARCHAR(20) | NOT NULL | 'ANNUAL' | Chu kỳ thanh toán | CHECK IN ('ANNUAL') |
currency |
VARCHAR(10) | NOT NULL | 'VND' | Đơn vị tiền tệ | |
status |
VARCHAR(20) | NOT NULL | 'DRAFT' | Trạng thái gói | CHECK IN ('DRAFT','ACTIVE','DEPRECATED') |
display_order |
INT | NOT NULL | 0 | Thứ tự hiển thị | |
is_public |
BOOLEAN | NOT NULL | true | Công khai bảng giá | |
effective_from |
DATE | NULL | Ngày hiệu lực | ||
version |
INT | NOT NULL | 1 | Số version cấu hình | |
created_by |
BIGINT | NULL | User tạo | FOREIGN KEY → users(id) | |
updated_by |
BIGINT | NULL | User cập nhật | FOREIGN KEY → users(id) | |
created_at |
TIMESTAMPTZ | NOT NULL | NOW() | Thời điểm tạo | |
updated_at |
TIMESTAMPTZ | NOT NULL | NOW() | Thời điểm cập nhật | |
deleted_at |
TIMESTAMPTZ | NULL | Soft delete |
8.3. Indexes ​
| Tên index | Cột | Loại | Mục đích |
|---|---|---|---|
pk_service_plans |
id |
PRIMARY KEY | Khóa chính |
uq_service_plans_code |
plan_code |
UNIQUE (partial) WHERE deleted_at IS NULL | Đảm bảo mã gói duy nhất (BR-F45-01, BR-F45-08) |
idx_service_plans_status |
status |
B-tree | Lọc theo trạng thái |
idx_service_plans_display_order |
display_order |
B-tree | Sắp xếp danh sách |
8.4. Migration SQL ​
-- =====================================================================
-- Migration: TXNG-F45 — service_plans (Cấu hình Gói Dịch vụ)
-- =====================================================================
CREATE TABLE IF NOT EXISTS service_plans (
id BIGSERIAL PRIMARY KEY,
plan_code VARCHAR(30) NOT NULL,
plan_name VARCHAR(150) NOT NULL,
target_audience TEXT,
setup_fee NUMERIC(14,2) NOT NULL DEFAULT 0 CHECK (setup_fee >= 0),
standardization_fee NUMERIC(14,2) NOT NULL DEFAULT 0 CHECK (standardization_fee >= 0),
maintenance_fee_year NUMERIC(14,2) NOT NULL DEFAULT 0 CHECK (maintenance_fee_year >= 0),
qr_quota_year INT NOT NULL DEFAULT 0 CHECK (qr_quota_year >= 0),
max_products INT NOT NULL DEFAULT 0 CHECK (max_products >= 0),
max_users INT NOT NULL DEFAULT 0 CHECK (max_users >= 0),
storage_gb INT NOT NULL DEFAULT 0 CHECK (storage_gb >= 0),
extra_qr_fee NUMERIC(10,2) NOT NULL DEFAULT 0 CHECK (extra_qr_fee >= 0),
extra_product_fee NUMERIC(12,2) NOT NULL DEFAULT 0 CHECK (extra_product_fee >= 0),
training_type VARCHAR(20) NOT NULL DEFAULT 'ONLINE'
CHECK (training_type IN ('ONLINE','ONSITE')),
training_onsite_count INT NOT NULL DEFAULT 0 CHECK (training_onsite_count >= 0),
go_live_support_days INT NOT NULL DEFAULT 0 CHECK (go_live_support_days >= 0),
sla_support VARCHAR(100),
features JSONB NOT NULL DEFAULT '{}'::jsonb,
discount_2y_percent NUMERIC(5,2) NOT NULL DEFAULT 10 CHECK (discount_2y_percent BETWEEN 0 AND 100),
discount_3y_percent NUMERIC(5,2) NOT NULL DEFAULT 20 CHECK (discount_3y_percent BETWEEN 0 AND 100),
billing_cycle VARCHAR(20) NOT NULL DEFAULT 'ANNUAL' CHECK (billing_cycle IN ('ANNUAL')),
currency VARCHAR(10) NOT NULL DEFAULT 'VND',
status VARCHAR(20) NOT NULL DEFAULT 'DRAFT'
CHECK (status IN ('DRAFT','ACTIVE','DEPRECATED')),
display_order INT NOT NULL DEFAULT 0,
is_public BOOLEAN NOT NULL DEFAULT true,
effective_from DATE,
version INT NOT NULL DEFAULT 1,
created_by BIGINT REFERENCES users(id),
updated_by BIGINT REFERENCES users(id),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ
);
CREATE UNIQUE INDEX IF NOT EXISTS uq_service_plans_code
ON service_plans (plan_code) WHERE deleted_at IS NULL;
CREATE INDEX IF NOT EXISTS idx_service_plans_status
ON service_plans (status);
CREATE INDEX IF NOT EXISTS idx_service_plans_display_order
ON service_plans (display_order);
-- =====================================================================
-- SEED: 4 gói canonical theo docs/sale/Sale_Pricing.md (hiệu lực 01/06/2026)
-- =====================================================================
INSERT INTO service_plans (
plan_code, plan_name, target_audience,
setup_fee, standardization_fee, maintenance_fee_year,
qr_quota_year, max_products, max_users, storage_gb,
extra_qr_fee, extra_product_fee,
training_type, training_onsite_count, go_live_support_days, sla_support,
features, discount_2y_percent, discount_3y_percent,
billing_cycle, currency, status, display_order, is_public,
effective_from, version
) VALUES
-- ----- PKG_BASIC — Gói Cơ bản -----
(
'PKG_BASIC', 'Gói Cơ bản',
'Dành cho chủ thể OCOP, HTX, hộ kinh doanh cần số hóa dữ liệu cơ bản, QR truy xuất, chứng nhận, vùng nguyên liệu và trang truy xuất công khai.',
2000000, 3000000, 4500000,
5000, 10, 2, 1,
150, 490000,
'ONLINE', 0, 7, 'Trong giờ hành chính',
'{
"company_profile": true,
"product_catalog_standardization": true,
"material_input_standardization": true,
"certification_standardization": true,
"growing_area_standardization": true,
"customer_agent_standardization": true,
"staff_standardization": true,
"production_process_standardization": false,
"product_lot_code_consulting": false,
"qr_traceability": true,
"public_trace_page": "STANDARD",
"qr_scan_statistics": true,
"supply_chain_linking": false,
"product_recall_management": false,
"operation_dashboard": true,
"activity_log": false,
"api_integration": false,
"blockchain": false
}'::jsonb,
10, 20, 'ANNUAL', 'VND', 'ACTIVE', 1, true, DATE '2026-06-01', 1
),
-- ----- PKG_STANDARD — Gói Chuẩn hóa -----
(
'PKG_STANDARD', 'Gói Chuẩn hóa',
'Dành cho Doanh nghiệp cần chuẩn hóa dữ liệu sản phẩm, quy trình sản xuất, lô, chứng nhận, kiểm nghiệm và QR truy xuất trên một hệ thống thống nhất.',
3000000, 5000000, 9500000,
20000, 50, 5, 3,
120, 490000,
'ONLINE', 0, 15, '24/7',
'{
"company_profile": true,
"product_catalog_standardization": true,
"material_input_standardization": true,
"certification_standardization": true,
"growing_area_standardization": true,
"customer_agent_standardization": true,
"staff_standardization": true,
"production_process_standardization": true,
"product_lot_code_consulting": true,
"qr_traceability": true,
"public_trace_page": "STANDARD",
"qr_scan_statistics": true,
"supply_chain_linking": false,
"product_recall_management": false,
"operation_dashboard": true,
"activity_log": false,
"api_integration": false,
"blockchain": "OPTIONAL"
}'::jsonb,
10, 20, 'ANNUAL', 'VND', 'ACTIVE', 2, true, DATE '2026-06-01', 1
),
-- ----- PKG_LINKED — Gói Liên kết -----
(
'PKG_LINKED', 'Gói Liên kết',
'Dành cho Doanh nghiệp có nhiều nhà cung cấp, đối tác phân phối, lô sản xuất cần liên kết dữ liệu để truy xuất toàn bộ chuỗi cung ứng.',
6000000, 8000000, 25500000,
100000, 150, 20, 10,
100, 490000,
'ONSITE', 1, 30, 'Ưu tiên 24/7',
'{
"company_profile": true,
"product_catalog_standardization": true,
"material_input_standardization": true,
"certification_standardization": true,
"growing_area_standardization": true,
"customer_agent_standardization": true,
"staff_standardization": true,
"production_process_standardization": true,
"product_lot_code_consulting": true,
"qr_traceability": true,
"public_trace_page": "STANDARD",
"qr_scan_statistics": "CUSTOM",
"supply_chain_linking": true,
"product_recall_management": true,
"operation_dashboard": "CUSTOM",
"activity_log": true,
"api_integration": "BASIC",
"blockchain": "OPTIONAL"
}'::jsonb,
10, 20, 'ANNUAL', 'VND', 'ACTIVE', 3, true, DATE '2026-06-01', 1
),
-- ----- PKG_ENTERPRISE — Gói Quản trị -----
(
'PKG_ENTERPRISE', 'Gói Quản trị',
'Dành cho Doanh nghiệp xuất khẩu, DN quy mô lớn (BigCorp) hoặc doanh nghiệp cần dashboard, cảnh báo, phân quyền, mở rộng API và tích hợp nâng cao.',
9000000, 15000000, 85000000,
500000, 500, 50, 50,
80, 490000,
'ONSITE', 3, 60, 'Ưu tiên 24/7',
'{
"company_profile": true,
"product_catalog_standardization": true,
"material_input_standardization": true,
"certification_standardization": true,
"growing_area_standardization": true,
"customer_agent_standardization": true,
"staff_standardization": true,
"production_process_standardization": true,
"product_lot_code_consulting": true,
"qr_traceability": true,
"public_trace_page": "CUSTOM",
"qr_scan_statistics": "CUSTOM",
"supply_chain_linking": true,
"product_recall_management": true,
"operation_dashboard": "CUSTOM",
"activity_log": true,
"api_integration": "CUSTOM",
"blockchain": "OPTIONAL"
}'::jsonb,
10, 20, 'ANNUAL', 'VND', 'ACTIVE', 4, true, DATE '2026-06-01', 1
)
ON CONFLICT DO NOTHING;
Đối chiếu tổng phí năm đầu (setup + standardization + maintenance): PKG_BASIC = 9.500.000; PKG_STANDARD = 17.500.000; PKG_LINKED = 39.500.000; PKG_ENTERPRISE = 109.000.000 VND — khớp 100% Sale_Pricing.md. Từ năm 2 =
maintenance_fee_year: 4.500.000 / 9.500.000 / 25.500.000 / 85.000.000 VND.
9. Thiết kế API ​
9.1. Danh sách endpoint ​
| # | Method | Endpoint | Mô tả | Auth / Role |
|---|---|---|---|---|
| 1 | GET | /api/v1/admin/service-plans |
Danh sách gói (filter status, keyword; pagination) | Bearer; PLATFORM_ADMIN |
| 2 | POST | /api/v1/admin/service-plans |
Tạo gói mới (status = DRAFT) | Bearer; PLATFORM_ADMIN |
| 3 | GET | /api/v1/admin/service-plans/:id |
Chi tiết gói | Bearer; PLATFORM_ADMIN |
| 4 | PUT | /api/v1/admin/service-plans/:id |
Sửa cấu hình gói (tăng version khi sửa phí/quota) | Bearer; PLATFORM_ADMIN |
| 5 | PATCH | /api/v1/admin/service-plans/:id/status |
Đổi trạng thái gói (DRAFT/ACTIVE/DEPRECATED) | Bearer; PLATFORM_ADMIN |
| 6 | DELETE | /api/v1/admin/service-plans/:id |
Xóa mềm gói (chỉ khi chưa DN dùng) | Bearer; PLATFORM_ADMIN |
| 7 | GET | /api/v1/service-plans/public |
Danh sách gói công khai (ACTIVE + is_public) | Bearer; mọi role đăng nhập (tùy chọn) |
9.2. Chi tiết API ​
9.2.1. GET /api/v1/admin/service-plans ​
Query params: status (DRAFT/ACTIVE/DEPRECATED), keyword (≥ 2 ký tự, match plan_code/plan_name), page (default 1), page_size (default 20, ∈ {10,20,50,100}).
Response 200:
{
"success": true,
"statusCode": 200,
"data": {
"items": [
{
"id": 1,
"plan_code": "PKG_BASIC",
"plan_name": "Gói Cơ bản",
"setup_fee": 2000000,
"standardization_fee": 3000000,
"maintenance_fee_year": 4500000,
"first_year_total": 9500000,
"qr_quota_year": 5000,
"max_products": 10,
"status": "ACTIVE",
"display_order": 1,
"version": 1
}
],
"pagination": { "page": 1, "page_size": 20, "total_items": 4, "total_pages": 1 }
}
}
9.2.2. POST /api/v1/admin/service-plans ​
Request:
{
"plan_code": "PKG_PREMIUM",
"plan_name": "Gói Cao cấp",
"target_audience": "DN chuỗi đa quốc gia",
"setup_fee": 12000000,
"standardization_fee": 18000000,
"maintenance_fee_year": 120000000,
"qr_quota_year": 1000000,
"max_products": 1000,
"max_users": 100,
"storage_gb": 100,
"extra_qr_fee": 60,
"extra_product_fee": 490000,
"training_type": "ONSITE",
"training_onsite_count": 5,
"go_live_support_days": 90,
"sla_support": "Ưu tiên 24/7",
"features": { "company_profile": true, "qr_traceability": true, "api_integration": "CUSTOM" },
"discount_2y_percent": 10,
"discount_3y_percent": 20,
"billing_cycle": "ANNUAL",
"display_order": 5,
"is_public": true,
"effective_from": "2026-07-01"
}
Response 201:
{ "success": true, "statusCode": 201, "data": { "id": 5, "plan_code": "PKG_PREMIUM", "status": "DRAFT", "version": 1 } }
Response 409 (trùng mã):
{ "success": false, "statusCode": 409, "error": { "code": "E-F45-001", "message": "Mã gói đã tồn tại" } }
9.2.3. GET /api/v1/admin/service-plans/:id ​
Response 200: trả về toàn bộ field service_plans (kể cả features, discount_*, audit fields, first_year_total computed).
Response 404:
{ "success": false, "statusCode": 404, "error": { "code": "E-F45-007", "message": "Không tìm thấy gói dịch vụ" } }
9.2.4. PUT /api/v1/admin/service-plans/:id ​
Request: như POST nhưng KHÔNG chấp nhận đổi plan_code (nếu gửi khác giá trị gốc → 400 E-F45-002).
Response 200:
{ "success": true, "statusCode": 200, "data": { "id": 1, "plan_code": "PKG_BASIC", "version": 2 } }
Response 400 (đổi mã gói):
{ "success": false, "statusCode": 400, "error": { "code": "E-F45-002", "message": "Không được thay đổi mã gói sau khi tạo" } }
9.2.5. PATCH /api/v1/admin/service-plans/:id/status ​
Request:
{ "status": "ACTIVE" }
Response 200:
{ "success": true, "statusCode": 200, "data": { "id": 1, "status": "ACTIVE" } }
Response 400 (transition không hợp lệ):
{ "success": false, "statusCode": 400, "error": { "code": "E-F45-005", "message": "Chuyển trạng thái không hợp lệ" } }
9.2.6. DELETE /api/v1/admin/service-plans/:id ​
Response 200:
{ "success": true, "statusCode": 200, "data": { "id": 5, "deleted_at": "2026-07-01T10:30:00Z" } }
Response 409 (đang có DN dùng):
{ "success": false, "statusCode": 409, "error": { "code": "E-F45-006", "message": "Không thể xóa gói đang có doanh nghiệp sử dụng" } }
9.2.7. GET /api/v1/service-plans/public ​
Response 200: danh sách gói status = ACTIVE AND is_public = true, chỉ trả trường công khai (plan_code, plan_name, target_audience, phí, quota, features, discount_, sla_support, training_), KHÔNG trả created_by/updated_by/deleted_at.
10. Test Cases cho QA ​
| Mã | Mô tả | Tiền điều kiện | Bước thực hiện | Kết quả mong đợi |
|---|---|---|---|---|
| TC-01-01 | Tạo gói mới hợp lệ | Login PLATFORM_ADMIN | POST service-plans với plan_code mới, phí/quota hợp lệ, features hợp schema | 201; status = DRAFT, version = 1 |
| TC-01-02 | Tạo gói trùng mã | Đã có PKG_BASIC | POST với plan_code = "PKG_BASIC" | 409 E-F45-001 |
| TC-01-03 | Tạo gói sai định dạng mã | Login ADMIN | POST plan_code = "pkg-basic" | 400 E-F45-001 (regex fail) |
| TC-01-04 | Tạo gói phí âm | Login ADMIN | POST setup_fee = -1 | 400 E-F45-003 |
| TC-01-05 | Tạo gói quota âm | Login ADMIN | POST qr_quota_year = -100 | 400 E-F45-003 |
| TC-01-06 | Tạo gói features sai schema | Login ADMIN | POST features = "not-an-object" | 400 E-F45-004 |
| TC-02-01 | Sửa phí gói → tăng version | Gói version = 1 | PUT maintenance_fee_year mới | 200; version = 2 |
| TC-02-02 | Sửa chỉ tên gói (không đụng phí/quota) | Gói version = 1 | PUT plan_name mới | 200; version giữ = 1 |
| TC-02-03 | Cố đổi plan_code khi sửa | Gói tồn tại | PUT plan_code khác gốc | 400 E-F45-002 |
| TC-02-04 | Sửa gói DEPRECATED | Gói DEPRECATED | PUT cấu hình | 200 + W-F45-001; không ảnh hưởng DN đang dùng |
| TC-03-01 | Kích hoạt gói DRAFT→ACTIVE | Gói DRAFT | PATCH status = ACTIVE | 200; status = ACTIVE |
| TC-03-02 | Ngừng bán ACTIVE→DEPRECATED | Gói ACTIVE | PATCH status = DEPRECATED | 200; gói bị loại khỏi chọn F46 |
| TC-03-03 | Mở lại DEPRECATED→ACTIVE | Gói DEPRECATED | PATCH status = ACTIVE | 200 |
| TC-03-04 | Transition không hợp lệ DRAFT→DEPRECATED | Gói DRAFT | PATCH status = DEPRECATED | 400 E-F45-005 |
| TC-04-01 | Xóa gói chưa DN dùng | Gói không có subscription | DELETE service-plans/:id | 200; deleted_at set |
| TC-04-02 | Xóa gói đang có DN dùng | Gói có company_subscriptions | DELETE service-plans/:id | 409 E-F45-006 |
| TC-05-01 | Danh sách + filter status | Có 4 gói | GET ?status=ACTIVE | Trả đúng gói ACTIVE |
| TC-05-02 | Tìm kiếm keyword | Có PKG_BASIC | GET ?keyword=Cơ bản | Trả PKG_BASIC |
| TC-05-03 | Pagination | > 20 gói | GET ?page=2&page_size=20 | Đúng trang 2 |
| TC-05-04 | Chi tiết gói không tồn tại | id không có | GET service-plans/9999 | 404 E-F45-007 |
| TC-06-01 | Public trả gói ACTIVE public | Có gói ACTIVE is_public | GET public | Không có DRAFT/DEPRECATED; không có created_by |
| TC-07-01 | Multi-tenant / quyền: DN gọi admin API | Login ENTERPRISE_ADMIN | GET /admin/service-plans | 403 (AdminGuard) |
| TC-08-01 | Seed 4 gói đúng số | DB sau migration | SELECT * FROM service_plans | 4 gói khớp Sale_Pricing (đối chiếu Section 8.4) |
| TC-09-01 | Performance list | 100 gói | GET service-plans | Response ≤ 500ms |
| TC-09-02 | Performance chi tiết | 1 gói | GET service-plans/:id | Response ≤ 500ms; page load ≤ 2s |
11. Acceptance Criteria ​
| Mã | Tiêu chí chấp nhận |
|---|---|
| AC-F45-01 | PLATFORM_ADMIN tạo được gói mới với đầy đủ phí/quota/features; gói mới ở status = DRAFT, version = 1 |
| AC-F45-02 | Hệ thống chặn plan_code trùng và sai định dạng UPPER_SNAKE (E-F45-001) |
| AC-F45-03 | plan_code không thể thay đổi sau khi tạo (E-F45-002) |
| AC-F45-04 | Sửa bất kỳ trường phí/quota nào làm tăng version; sửa trường phi-phí/quota không tăng version |
| AC-F45-05 | Đổi trạng thái chỉ theo transition hợp lệ (DRAFT→ACTIVE, ACTIVE⇄DEPRECATED); transition khác bị chặn (E-F45-005) |
| AC-F45-06 | Gói DEPRECATED không xuất hiện trong danh sách chọn khi kích hoạt mới ở F46; DN đang dùng giữ plan_snapshot |
| AC-F45-07 | Không thể xóa gói đang có DN sử dụng (E-F45-006); xóa là soft delete (deleted_at) |
| AC-F45-08 | Mọi thao tác ghi (create/update/status/delete) ghi updated_by + timestamp (audit) |
| AC-F45-09 | Endpoint public chỉ trả gói ACTIVE + is_public, ẩn trường nội bộ |
| AC-F45-10 | 4 gói canonical được seed đúng 100% số liệu Sale_Pricing.md (đối chiếu tổng phí năm đầu) |
| AC-F45-11 | Chỉ role ROLE.ADMIN (PLATFORM_ADMIN) truy cập được endpoint /api/v1/admin/service-plans/* (AdminGuard) |
| AC-F45-12 | Tất cả tiền hiển thị VND, chưa gồm VAT; chiết khấu 2y=10%/3y=20% mặc định, cấu hình được |
| AC-F45-13 | Danh sách gói có pagination + filter status + search keyword (debounce 300ms) |
| AC-F45-14 | Page load ≤ 2s; API read ≤ 500ms |
12. Chuyển đổi trạng thái (State Transitions) ​
SERVICE_PLAN_STATUS state machine:
┌─────────┐
(tạo mới) │ DRAFT │
──────────► │ │
└────┬────┘
│ Kích hoạt (UC-F45-03)
▼
┌─────────┐ Ngừng bán ┌──────────────┐
│ ACTIVE │ ─────────────► │ DEPRECATED │
│ │ ◄───────────── │ │
└─────────┘ Mở lại └──────────────┘
| Từ trạng thái | Sự kiện | Sang trạng thái | Điều kiện | Actor |
|---|---|---|---|---|
| (none) | Tạo gói | DRAFT | Validate hợp lệ | PLATFORM_ADMIN |
| DRAFT | Kích hoạt | ACTIVE | Cấu hình đầy đủ | PLATFORM_ADMIN |
| ACTIVE | Ngừng bán | DEPRECATED | — | PLATFORM_ADMIN |
| DEPRECATED | Mở lại | ACTIVE | — | PLATFORM_ADMIN |
Transition KHÔNG hợp lệ (chặn, E-F45-005): DRAFT→DEPRECATED, ACTIVE→DRAFT, DEPRECATED→DRAFT, và mọi self-transition.
Xóa mềm (
deleted_at) áp dụng cho DRAFT và DEPRECATED khi chưa DN nào dùng; không phải mộtstatusmà là cờ soft delete độc lập.
13. Notification List ​
| Mã | Sự kiện kích hoạt | Người nhận | Kênh | Template message |
|---|---|---|---|---|
| N-F45-01 | Tạo gói mới | PLATFORM_ADMIN (người tạo) | In-app | "Đã tạo gói dịch vụ [plan_name] ([plan_code]) ở trạng thái Nháp." |
| N-F45-02 | Kích hoạt gói (→ ACTIVE) | PLATFORM_ADMIN | In-app | "Gói [plan_name] đã được kích hoạt và sẵn sàng gán cho doanh nghiệp." |
| N-F45-03 | Ngừng bán gói (→ DEPRECATED) | PLATFORM_ADMIN | In-app | "Gói [plan_name] đã ngừng bán. Doanh nghiệp đang dùng vẫn giữ cấu hình đã chốt." |
| N-F45-04 | Sửa phí/quota (version++) | PLATFORM_ADMIN | In-app | "Cấu hình gói [plan_name] đã cập nhật sang phiên bản v[version]." |
Module vận hành thương mại nội bộ: notification chỉ gửi in-app cho nhóm PLATFORM_ADMIN. Không gửi cho DN (DN chỉ xem bảng giá public).
14. Error / Warning Message Handling ​
14.1. Error (chặn hành động) ​
| Mã | Điều kiện kích hoạt | Message (tiếng Việt) | HTTP | Xử lý hệ thống |
|---|---|---|---|---|
| E-F45-001 | plan_code trùng hoặc sai định dạng UPPER_SNAKE |
"Mã gói đã tồn tại hoặc không hợp lệ (viết HOA, dùng chữ/số/gạch dưới)." | 409 / 400 | Chặn tạo, giữ form |
| E-F45-002 | Cố đổi plan_code khi sửa |
"Không được thay đổi mã gói sau khi tạo." | 400 | Chặn update |
| E-F45-003 | Phí hoặc quota < 0 | "Phí và quota phải lớn hơn hoặc bằng 0." | 400 | Chặn lưu |
| E-F45-004 | features không đúng JSON schema |
"Cấu trúc ma trận tính năng không hợp lệ." | 400 | Chặn lưu |
| E-F45-005 | Transition trạng thái không hợp lệ | "Chuyển trạng thái không hợp lệ." | 400 | Chặn đổi trạng thái |
| E-F45-006 | Xóa gói đang có DN dùng | "Không thể xóa gói đang có doanh nghiệp sử dụng." | 409 | Chặn xóa |
| E-F45-007 | Không tìm thấy gói theo id | "Không tìm thấy gói dịch vụ." | 404 | Trả lỗi |
| E-F45-008 | Role không phải PLATFORM_ADMIN gọi endpoint admin | "Bạn không có quyền thực hiện thao tác này." | 403 | AdminGuard chặn |
14.2. Warning (cho phép tiếp tục) ​
| Mã | Điều kiện | Message | Xử lý |
|---|---|---|---|
| W-F45-001 | Sửa cấu hình gói DEPRECATED | "Gói đang ngừng bán — thay đổi không ảnh hưởng doanh nghiệp đang dùng (giữ plan_snapshot)." | Cho phép lưu, hiển thị cảnh báo |
| W-F45-002 | Ngừng bán gói còn DN đang dùng | "Gói còn [N] doanh nghiệp đang sử dụng — họ vẫn giữ cấu hình đã chốt." | Cho phép, ghi log |
15. Ma trận truy xuất (Traceability Matrix) ​
| Use Case | Screen | Acceptance Criteria | Test Case | Error / Warning | Notification |
|---|---|---|---|---|---|
| UC-F45-01 | SCR-F45-02 | AC-F45-01, AC-F45-02, AC-F45-10, AC-F45-12 | TC-01-01..06, TC-08-01 | E-F45-001/003/004 | N-F45-01 |
| UC-F45-02 | SCR-F45-02 | AC-F45-03, AC-F45-04, AC-F45-08 | TC-02-01..04 | E-F45-002/003/004; W-F45-001 | N-F45-04 |
| UC-F45-03 | SCR-F45-01, SCR-F45-03 | AC-F45-05, AC-F45-06, AC-F45-08 | TC-03-01..04 | E-F45-005; W-F45-002 | N-F45-02, N-F45-03 |
| UC-F45-04 | SCR-F45-01, SCR-F45-03 | AC-F45-07, AC-F45-09, AC-F45-11, AC-F45-13, AC-F45-14 | TC-04-01..02, TC-05-01..04, TC-06-01, TC-07-01, TC-09-01..02 | E-F45-006/007/008 | — |
16. Quy tắc nghiệp vụ (Business Rules) ​
| Mã | Quy tắc | Giải thích / Cơ sở |
|---|---|---|
| BR-F45-01 | plan_code UNIQUE (partial WHERE deleted_at IS NULL), regex ^[A-Z][A-Z0-9_]{2,29}$, immutable sau khi tạo |
Đảm bảo tính ổn định định danh gói cho F46 snapshot; tránh phá vỡ tham chiếu |
| BR-F45-02 | Chỉ PLATFORM_ADMIN (ROLE.ADMIN) được CRUD gói qua /api/v1/admin/... + AdminGuard |
Phân quyền vận hành nền tảng; Sale thao tác qua tài khoản admin |
| BR-F45-03 | Mọi phí ≥ 0 và mọi quota ≥ 0 (CHECK constraint) | Đảm bảo toàn vẹn dữ liệu tài chính |
| BR-F45-04 | features phải tuân JSON schema ma trận tính năng (Section 5.2 Card 5) |
Chuẩn hóa hiển thị ma trận tính năng, tránh dữ liệu rác |
| BR-F45-05 | Gói DEPRECATED không được chọn khi kích hoạt mới ở F46; DN đang dùng giữ plan_snapshot (bất biến) |
Bảo vệ hợp đồng đã ký; căn cứ Bộ luật Dân sự 2015 |
| BR-F45-06 | Chiết khấu mặc định 2y = 10%, 3y = 20% (áp dụng trước VAT); có thể cấu hình theo gói | Theo chính sách Sale_Pricing.md mục "Chính sách khác" |
| BR-F45-07 | Sửa bất kỳ trường phí/quota (setup_fee, standardization_fee, maintenance_fee_year, extra_qr_fee, extra_product_fee, qr_quota_year, max_products, max_users, storage_gb) → version++ và ghi audit updated_by |
Truy vết thay đổi giá/quota; đảm bảo minh bạch |
| BR-F45-08 | Soft delete bằng deleted_at; unique index partial để tái dùng mã sau xóa |
Bảo toàn lịch sử; chuẩn repo |
| BR-F45-09 | Seed đúng 4 gói canonical (PKG_BASIC/STANDARD/LINKED/ENTERPRISE) khớp 100% Sale_Pricing.md | Nguồn canonical cho billing/kích hoạt |
| BR-F45-10 | Mọi giá là VND (NUMERIC), chưa gồm VAT; hiển thị dd/MM/yyyy cho ngày, API/DB ISO 8601 |
Chuẩn hiển thị & convention repo |
17. Ràng buộc & Giả định (Constraints / Assumptions) ​
17.1. Ràng buộc ​
- Module vận hành thương mại: TXNG-F45 KHÔNG phát sinh Critical Tracking Event (CTE) / Key Data Element (KDE) truy xuất nguồn gốc. Không áp dụng TCVN 12850:2019 / FDA FSMA 204 / GS1 EPCIS cho chức năng này.
- Phân quyền cứng: Toàn bộ thao tác ghi chỉ dành cho
PLATFORM_ADMIN(implROLE.ADMIN= numeric 1), chặn quaAdminGuard, prefix/api/v1/admin/.... ENTERPRISE_ADMIN chỉ xem bảng giá public. - Tính bất biến hợp đồng: Thay đổi cấu hình gói (kể cả giá) KHÔNG tác động ngược tới DN đang dùng — F46 đã chốt
plan_snapshottại thời điểm kích hoạt. - Không multi-tenant scope trong F45:
service_planslà bảng cấu hình nền tảng dùng chung, KHÔNG cócompany_id. Ràng buộc multi-tenant chỉ áp dụng ở F46 (bảngcompany_subscriptionslọc theocompany_id). - Tiền tệ: v1.0 chỉ hỗ trợ VND;
currencyđể mở rộng tương lai. Giá chưa gồm VAT. - Chu kỳ thanh toán: v1.0 chỉ ANNUAL.
- SLA hiệu năng: Page load ≤ 2 giây; API read (list/detail) ≤ 500ms; API write ≤ 1 giây.
17.2. Giả định ​
- Bảng
usersvàcompanies(F01) đã tồn tại; FKcreated_by/updated_by→users(id). - Migration seed 4 gói chạy 1 lần khi khởi tạo hệ thống (idempotent qua
ON CONFLICT DO NOTHING+ unique index). - F46 sẽ đọc
service_planskhi kích hoạt; ràng buộc "không xóa gói đang dùng" dựa trên tồn tại bản ghicompany_subscriptions.plan_id. - Số liệu Sale_Pricing.md (19/05/2026, hiệu lực 01/06/2026) là nguồn chuẩn; khi bảng giá đổi, admin cập nhật qua UI (không cần migration mới).
- Việc tăng version chỉ là số nguyên đơn giản (không tạo bản ghi lịch sử version riêng trong v1.0); lịch sử chi tiết trước/sau thuộc phạm vi audit log chung.
18. Phụ lục (Appendix) ​
18.1. Bảng phí 4 gói (đối chiếu Sale_Pricing.md) ​
| Hạng mục | PKG_BASIC | PKG_STANDARD | PKG_LINKED | PKG_ENTERPRISE |
|---|---|---|---|---|
| Tên gói | Gói Cơ bản | Gói Chuẩn hóa | Gói Liên kết | Gói Quản trị |
| Phí khởi tạo (VND) | 2.000.000 | 3.000.000 | 6.000.000 | 9.000.000 |
| Phí chuẩn hóa & liên kết (VND) | 3.000.000 | 5.000.000 | 8.000.000 | 15.000.000 |
| Phí duy trì/năm (VND) | 4.500.000 | 9.500.000 | 25.500.000 | 85.000.000 |
| Tổng phí năm đầu (VND) | 9.500.000 | 17.500.000 | 39.500.000 | 109.000.000 |
| Từ năm 2 (VND) | 4.500.000 | 9.500.000 | 25.500.000 | 85.000.000 |
| Sản lượng QR/năm | 5.000 | 20.000 | 100.000 | 500.000 |
| Số SP tối đa | 10 | 50 | 150 | 500 |
| Số user tối đa | 2 | 5 | 20 | 50 |
| Dung lượng lưu trữ (GB) | 1 | 3 | 10 | 50 |
| Phí QR tăng thêm (VND) | 150 | 120 | 100 | 80 |
| Phí SP tăng thêm (VND) | 490.000 | 490.000 | 490.000 | 490.000 |
| Đào tạo | Online | Online | 01 lần Onsite | 03 lần Onsite |
| Hỗ trợ go-live (ngày) | 7 | 15 | 30 | 60 |
| SLA hỗ trợ | Trong giờ hành chính | 24/7 | Ưu tiên 24/7 | Ưu tiên 24/7 |
Chiết khấu duy trì: 2 năm giảm 10%, 3 năm giảm 20% (trước VAT). Báo giá chưa gồm VAT, chưa gồm chi phí in tem vật lý và phí bên thứ ba.
18.2. Ma trận so sánh tính năng 4 gói (Sale_Pricing Phụ lục) ​
Quy ước: ✔ = có · — = không · Tùy chọn = mua thêm · Tùy chỉnh = mức cao hơn / cấu hình riêng.
| Nhóm tính năng | feature key | Cơ bản | Chuẩn hóa | Liên kết | Quản trị |
|---|---|---|---|---|---|
| Hồ sơ DN/chủ thể | company_profile |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa danh mục sản phẩm | product_catalog_standardization |
Tối đa 10 SKU | Tối đa 50 SKU | Tối đa 150 SKU | Tối đa 500 SKU |
| Chuẩn hóa nguyên liệu đầu vào | material_input_standardization |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa chứng nhận/chứng chỉ | certification_standardization |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa vùng trồng/vùng nuôi | growing_area_standardization |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa khách hàng/đại lý | customer_agent_standardization |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa danh mục nhân viên | staff_standardization |
✔ | ✔ | ✔ | ✔ |
| Chuẩn hóa quy trình sản xuất | production_process_standardization |
— | ✔ | ✔ | ✔ |
| Tư vấn cấu trúc mã SP/lô | product_lot_code_consulting |
— | ✔ | ✔ | ✔ |
| QR truy xuất nguồn gốc | qr_traceability |
✔ | ✔ | ✔ | ✔ |
| Trang truy xuất công khai | public_trace_page |
✔ (STANDARD) | ✔ (STANDARD) | ✔ (STANDARD) | Tùy chỉnh (CUSTOM) |
| Thống kê lượt quét QR | qr_scan_statistics |
✔ | ✔ | Tùy chỉnh | Tùy chỉnh |
| Liên kết chủ thể chuỗi cung ứng | supply_chain_linking |
— | — | ✔ | ✔ |
| Quản lý thu hồi sản phẩm | product_recall_management |
— | — | ✔ | ✔ |
| Dashboard vận hành | operation_dashboard |
✔ | ✔ | Tùy chỉnh | Tùy chỉnh |
| Phân quyền người dùng | (map max_users) |
2 user | 5 user | 20 user | 50 user |
| Dung lượng lưu trữ | (map storage_gb) |
1GB | 3GB | 10GB | 50GB |
| Nhật ký thao tác | activity_log |
— | — | ✔ | ✔ |
| API tích hợp | api_integration |
— | — | 1 API cơ bản (BASIC) | Tùy phạm vi (CUSTOM) |
| Blockchain | blockchain |
— | Tùy chọn | Tùy chọn | Tùy chọn |
| Đào tạo tiêu chuẩn | (map training_type) |
Online | Online | 1 buổi Onsite | 3 buổi Onsite |
| Hỗ trợ go-live | (map go_live_support_days) |
7 ngày | 15 ngày | 30 ngày | 60 ngày |
| SLA hỗ trợ | (map sla_support) |
Trong giờ hành chính | 24/7 | Ưu tiên 24/7 | Ưu tiên 24/7 |
18.3. Công thức tính phí liên quan ​
- Tổng phí năm đầu =
setup_fee+standardization_fee+maintenance_fee_year. - Phí từ năm 2 =
maintenance_fee_year(× (1 − chiết khấu kỳ) nếu ký nhiều năm). - Phí duy trì 2 năm =
maintenance_fee_year× 2 × (1 −discount_2y_percent/100), trước VAT. - Phí duy trì 3 năm =
maintenance_fee_year× 3 × (1 −discount_3y_percent/100), trước VAT. - Phí vượt QR = (số QR dùng −
qr_quota_year−bonus_qr_quota) ×extra_qr_fee(chỉ tính phần dương;bonus_*do F46 quản lý). - Phí vượt SP = (số SP −
max_products−bonus_max_products) ×extra_product_fee, cộng vào phí duy trì kỳ tiếp.
Hết tài liệu SRS TXNG-F45.