Appearance
Kế hoạch kiểm thử (QA Test Plan) — Hồ sơ bệnh án v2.2.0
File này dùng để làm gì: chuyển FR thành coverage, seed data, test case, tiêu chí vào/ra và test oracle để QA/UAT bám đúng.
Nên đọc trước:
decision-brief.md→ D1 phạm vi kiểm thử → D2 ca kiểm thử → D3 dữ liệu seed → D5 tiêu chí vào/ra.
Lịch sử thay đổi
| Phiên bản | Ngày | Tác giả | Thay đổi |
|---|---|---|---|
| 2.2.0 | 30/04/2026 | QA/PO + Security Lead | Tham chiếu permission-spec.md P12 — bổ sung 44 TC-PERM-* dẫn xuất cho Permission v2: TC-PERM-HD-01..07 (hard-deny 7 TC), TC-PERM-BM-01..05 (branch_mode 5 TC), TC-PERM-PO-01..04 (portal 4 TC), TC-PERM-MR-01..03 (multi-role 3 TC), TC-PERM-CI-01..04 (cache invalidation 4 TC), TC-PERM-EO-01..08 (emergency override 8 TC), TC-PERM-MASK-01..06 (field masking 6 TC), TC-PERM-MIG-01..04 (migration 4 TC), TC-PERM-CO-01..03 (Compliance UI SCR-18 3 TC). Total core TC = 108 + 44 TC-PERM = 152 TC. Phase 4 exit yêu cầu 100% Phase 4 TC-PERM (37 TC) đạt; Migration TC-PERM-MIG (4 TC) đạt ở Phase 1. |
| 2.1.0 | 30/04/2026 | QA/PO | Bổ sung 9 TC theo cập nhật UI v2.2.0 + dev v2.1.0: (1) TC-030A/B/C/D — rule câu xác nhận tự gõ (DEC-021): độ dài ≥20 ký tự, từ khoá "đồng ý"/"thực hiện", chặn dán, log nhịp gõ; (2) TC-090/090A/090B/090C — luồng "Khách từ chối thủ thuật" (DEC-024): happy path huỷ order_item + ghi sổ "Kết quả: Khách từ chối thủ thuật", thiếu y tá làm chứng → chặn, đã có BA DL → giữ nguyên BA DL chỉ huỷ phần thủ thuật, user thiếu quyền clinical_record.refuse_procedure hoặc order.update → CTA ẩn / API 403; (3) TC-NTF-14 — notification noti_clinical_procedure_refused đến QL CN + Sale phụ trách. Total core TC = 108 (99 + 9). |
| 2.0.0 | 30/04/2026 | QA/PO | Đồng bộ theo glossary canonical 34 thuật ngữ, PRD/UI/Dev v2.0.0 và _consistency-matrix.md; giữ coverage 99 TC core + D6 regression, cập nhật nhãn/copy tiếng Việt cho Hồ sơ bệnh án. |
| 1.5.10 | 29/04/2026 | QA/PO | Biên tập lại văn phong test oracle theo tiếng Việt SaaS thẩm mỹ viện: đổi nút/hộp thoại/thông báo nhanh/tải file/gửi/xác nhận sang copy nghiệp vụ tự nhiên; không đổi số lượng TC, scope hoặc AC |
| 1.5.7 | 28/04/2026 | QA/PO | Bổ sung D6 regression theo Ma trận ranh giới ảnh hưởng: smoke module trực tiếp/gián tiếp/không ảnh hưởng là go-live gate, không cộng vào 99 core TC |
| 1.5.6 | 28/04/2026 | QA/PO | Đồng bộ Dynamic Permission v2: bổ sung test no-action/grant/revoke/portal split/branch_mode/is_pos_only, seed user theo action và entry gate permission seed |
| 1.5.1 | 28/04/2026 | QA/PO | Fix review đa góc nhìn: autosave conflict, low-risk audit, P0 exit gate, Phase 5B/6 entry và rollback/go-live oracle |
| 1.5 | 28/04/2026 | QA/PO | Hardening sau review đa góc nhìn: thêm oracle source/API/role vận hành, signed checklist, sequence monotonic/gap audit, close reminder theo config và Sale-safe no raw clinical |
| 1.4 | 28/04/2026 | QA/PO | Chuẩn hóa theo po-ba-workflow mới: khai báo đầu vào chuẩn, heading tiếng Việt-first và rule QA là file dẫn xuất |
| 1.3.2 | 27/04/2026 | QA/PO | Thêm TC chống false-positive Workbench need_record và validate intake đúng KH/CN/record |
| 1.3.1 | 27/04/2026 | QA/PO | Bổ sung test P0 cho safe-alert dictionary, token session intake và cutoff Chốt ngày phòng khám theo CN |
| 1.3 | 27/04/2026 | QA/PO | Thêm coverage cho Trang xem an toàn (Sale), Bàn việc bác sĩ, Phiếu khách tự khai, Trang điều phối phòng khám và Chốt ngày phòng khám |
| 1.2 | 27/04/2026 | PO | Thêm coverage kiểm tra sẵn sàng/phát hành safety, product classification 3 trạng thái và unknown allergy risk = block |
| 1.1 | 21/04/2026 | PO | Đổi QA scope theo Day-1: test locked cross-branch + emergency override; verify walk-in link qua reference_appointment_id |
| 1.0 | 21/04/2026 | PO | Initial QA plan — 63 TC core + entry/exit criteria + edge case matrix |
Đầu vào chuẩn (Canonical Inputs)
| File | Vai trò | Nếu conflict |
|---|---|---|
SOURCE_OF_TRUTH.md | Nguồn sự thật chuẩn + Solution Lock | Ưu tiên cao nhất |
decision-brief.md | Tóm tắt phạm vi, rủi ro và điểm còn mở | Chỉ định hướng độ ưu tiên test |
prd.md | FR, AC, lifecycle, ý nghĩa công thức nghiệp vụ | Ưu tiên ngữ nghĩa nghiệp vụ |
ui-spec.md / dev-spec.md | Quy ước UI, API/data, task và truy vết | Theo truth đã khóa ở trên |
Traceability rule: nếu test oracle khác với PRD/UI/Dev, phải sửa upstream hoặc ghi mismatch; QA Plan không tự tạo requirement mới. Mapping tổng hợp xem
_consistency-matrix.md.
D1) Phạm vi kiểm thử
D1.1) Loại test và phân bổ
| Test type | Coverage | Notes |
|---|---|---|
| Unit test (BE) | ≥80% logic functions | Sequence generator, allergy policy lookup, permission bộ lọc, form validation |
| Integration test (BE + DB) | ≥70% action endpoints | Mutation luồng, event trigger, Hasura permission, cross-table consistency |
| E2E test (FE + BE) | ≥50% happy path + critical edge | Playwright tests cho SCR-04, SCR-06/07, SCR-09, SCR-10 |
| Manual test (QA) | 100% FR functional AC | 99 TC core + edge cases |
| Performance test | Autosave + ICD-10 search + form load | Tool: k6. Target: p95 <2s |
| Security test | Dynamic Permission v2 + sensitive data masking | Penetration test tầng 3 access, grant/revoke, portal split, branch scope |
| UAT (BS pilot) | End-to-end luồng với champion BS | 2 BS per CN × 1 tuần trước pilot D0 |
D1.2) Phân loại ưu tiên
| Priority | Định nghĩa | % of TC |
|---|---|---|
| P0 | Blocker — chặn go-live nếu không đạt | ~30% |
| P1 | Major — ảnh hưởng user experience lớn | ~50% |
| P2 | Minor — nhỏ, có workaround | ~20% |
D1.3) Môi trường test
| Env | Purpose | Data |
|---|---|---|
| Dev | Developer self-test | Seed 5 KH demo + 2 CN demo |
| Staging | QA integration + UAT | Mirror production (sanitized customer data) + 2 CN pilot mock setup |
| Production | Pilot 2 CN | Real data, feature flag control |
D2) Ma trận ca kiểm thử (Traceability)
108 core TC (99 cũ + 9 bổ sung v2.1.0) mapping trực tiếp PRD A11 traceability matrix. Bảng dưới là FR-level canonical coverage; AC-level step detail cho P0/P1 phải được hoàn tất trong QA execution sheet trước khi bắt đầu test cycle của từng phase.
TC bổ sung v2.1.0: TC-030A/B/C/D (rule câu xác nhận tự gõ — DEC-021), TC-090/090A/090B/090C (luồng Khách từ chối thủ thuật — DEC-024), TC-NTF-14 (notification từ chối thủ thuật).
D2.1. FR-001 — Bật/tắt module PK per CN (4 TC)
| TC ID | Tên ca kiểm thử | Mức ưu tiên | AC | Kết quả mong đợi |
|---|---|---|---|---|
| TC-001 | Bật module PK cho 1 CN không ảnh hưởng CN khác | P0 | AC-001.1 | CN khác vẫn có UI nguyên bản, không thấy tab Hồ sơ BA |
| TC-002 | Bật module lần đầu yêu cầu hoàn thành 5 bước | P0 | AC-001.2 | Nút "Gửi phát hành" bị khóa khi còn bước chưa đủ |
| TC-003 | Cấu hình chưa đủ → BS tạo BA bị chặn | P0 | AC-001.3 | Hộp thoại "Cấu hình chưa đầy đủ: thiếu bước 4 Phân loại dịch vụ — kỹ thuật" |
| TC-004 | Admin tắt module giữa lúc BS đang điền BA | P1 | AC-001.4 | BA nháp vẫn lưu trong DB, UI ẩn module và gửi thông báo cho Admin |
D2.2. FR-002 — Cấu hình 5 bước (4 TC)
| TC ID | Tên ca kiểm thử | Mức ưu tiên | AC | Kết quả mong đợi |
|---|---|---|---|---|
| TC-005 | Nhập CSV danh mục KT hợp lệ | P0 | AC-002.3 | Đọc đúng file, ghi DB, hiển thị bảng xem trước |
| TC-006 | Nhập CSV sai định dạng (thiếu cột bắt buộc) | P0 | AC-002.3 | Thông báo lỗi nói rõ dòng và trường bị thiếu |
| TC-007 | Phân loại hàng loạt nhiều DV vào 1 KT | P1 | AC-002.4 | Chọn nhiều dòng + thanh thao tác hiển thị + áp dụng thành công |
| TC-008 | Quay lại sửa bước 2 sau khi hoàn thành bước 5 | P1 | AC-002.2 | Sidebar cho phép chuyển bước tự do, không bắt đặt lại từ đầu |
D2.3. FR-003 — Phân loại dịch vụ — kỹ thuật (4 TC)
| TC ID | Tên ca kiểm thử | Mức ưu tiên | AC | Kết quả mong đợi |
|---|---|---|---|---|
| TC-009 | 1 DV tại 2 CN phân loại vào 2 KT khác nhau | P0 | AC-003.1 | DB lưu riêng, query theo chi nhánh đúng |
| TC-010 | Đơn có DV đã phân loại cần BA → gửi thông báo cho BS | P0 | AC-003.2 | BS nhận thông báo trong 5 giây sau order_insert |
| TC-011 | Đơn chỉ có DV explicitly_no_ba → không gửi thông báo | P0 | AC-003.4 | Không tạo event, không tự tạo clinical_record, vẫn có audit quyết định |
| TC-012 | DV mới sau khi module hoạt động mặc định unclassified | P0 | AC-003.2, AC-003.5 | Không đạt kiểm tra sẵn sàng/phát hành, Admin + QL CN nhận cảnh báo |
D2.4. FR-004 — Tạo lượt khám + walk-in (4 TC) [CRITICAL]
| TC ID | Tên ca kiểm thử | Mức ưu tiên | AC | Kết quả mong đợi |
|---|---|---|---|---|
| TC-013 | Tạo lượt khám với order_item_id = NULL (khách đến trực tiếp) | P0 blocker | AC-004.1 | Tạo thành công, event trigger không panic, tạo được clinical_record |
| TC-014 | Tạo clinical_record từ appointment đã có order | P0 | AC-004.2 | Unique theo appointment + form_type, FK valid |
| TC-015 | Gói 5 buổi = 5 appointment = tối đa 5 clinical_record mỗi form_type | P0 | AC-004.3 | Mỗi appointment/form_type có 1 clinical_record riêng, dùng chung clinical_profile nếu cùng KH/CN/type |
| TC-016 | Khách đến trực tiếp liên kết đơn sau + lượt khám thuần | P1 | AC-004.4, AC-004.5 | Liên kết reference_appointment_id đúng; lượt khám thuần không sinh form/in/scan và không tính là BA cần hoàn thành |
D2.5. FR-005 — Điền BA DL (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-017 | Auto-fill hành chính từ customer profile | P0 | AC-005.1 | Họ tên, sinh ngày, giới, địa chỉ, SĐT load đúng |
| TC-018 | BS CN A chỉ thấy KT CN A trong dropdown | P0 | AC-005.2 | Hasura bộ lọc branch_id enforce |
| TC-019 | ICD-10 search "L83" → trả "Acanthosis nigricans" | P0 | AC-005.3 | <100ms, match fuzzy search |
| TC-020 | Autosave 30s + reload browser | P1 | AC-005.4 | Form data khôi phục đúng, draft marked |
| TC-021 | Bấm Hoàn thành khi thiếu ICD-10 chính | P0 | AC-005.5 | Hiển thị lỗi rõ ràng và đưa focus về trường ICD-10 chính |
D2.6. FR-006 — Điền BA TM 4 phân hệ (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-022 | Chọn DV mắt → tự hiện section Mắt | P0 | AC-006.1 | Section expanded, others collapsed |
| TC-023 | BS tick bật thêm section Mũi | P1 | AC-006.2 | Section Mũi expand, data saved khi lưu nháp |
| TC-024 | Nhập số đo góc trán mũi = "abc" | P0 | AC-006.3 | Validation number-only, error hint |
| TC-025 | Nhập số đo thiếu unit | P2 | AC-006.4 | Placeholder "Ví dụ: 130 (độ)" hint |
| TC-026 | Autosave TM 60 field → không lag | P1 | AC-006.5 | <500ms round-trip p95 |
D2.7. FR-007 — 5 form shared (15 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-027 | Auto-fill customer vào cam đoan | P0 | AC-007.1 | Họ tên, CCCD, địa chỉ correct |
| TC-028 | 4 form shared hiện đúng header CN (placeholder resolved) | P0 | AC-007.2 | CN Cao Lãnh header khác CN Tân Bình II |
| TC-029 | Admin thử edit schema form tiền sử dị ứng | P0 | AC-007.3 | Operation blocked, message "Form chuẩn BYT không sửa được" |
| TC-030 | Cam đoan: KH tự gõ câu xác nhận sai format chung | P0 | AC-007.4, DEC-021 | Validation không đạt, gợi ý câu đúng theo placeholder |
| TC-030A | Câu xác nhận <20 ký tự (DEC-021 rule độ dài) | P0 legal | AC-007.4, DEC-021 | Validation FE inline lỗi error.confirmation_too_short "Câu xác nhận phải có ít nhất 20 ký tự và chứa từ 'đồng ý' hoặc 'thực hiện'."; nút "Lưu phiếu" khoá; server cũng reject 422 nếu bypass FE |
| TC-030B | Câu xác nhận đủ 20 ký tự nhưng thiếu từ khoá "đồng ý"/"thực hiện" | P0 legal | AC-007.4, DEC-021 | Validation lỗi error.confirmation_too_short; "Lưu phiếu" khoá; nhập thêm từ "đồng ý" → unblock |
| TC-030C | KH cố dán nội dung từ clipboard vào textarea câu xác nhận | P0 legal | AC-007.4, DEC-021 | FE bắt event paste → ngăn dán + thông báo nhanh error.confirmation_paste_blocked "Vui lòng để khách tự gõ trên màn hình. Không cho dán nội dung."; câu vẫn rỗng |
| TC-030D | Tốc độ gõ bất thường (≥10 ký tự liên tiếp <50ms — gợi ý macro/auto-typer) | P0 legal | AC-007.4, DEC-021 | FE log nhịp phím + cảnh báo nhân viên trong console + popup yêu cầu khách gõ lại; server lưu typed_at, typed_duration_ms để audit; nếu duration_ms quá ngắn so với độ dài câu → flag suspicious_typing=true trong audit log |
| TC-031 | Đơn thuốc: thêm 5 dòng thuốc | P0 | AC-007.5 | Mỗi dòng required + save structured |
| TC-032 | Phiếu theo dõi điều trị: thêm entry mới không sửa entry cũ | P1 | AC-007.6 | Entry cũ readonly, audit timestamp |
| TC-090 | Khách từ chối thủ thuật happy path (DEC-024) | P0 legal | DEC-024 | BS bấm "Khách từ chối thủ thuật" trong SCR-08 Cam đoan → hộp thoại confirm.refuse_procedure → BS điền lý do (≥30 ký tự) + chọn y tá làm chứng → bấm Xác nhận. Kết quả: (a) clinical_record.customer_refused_procedure=true, refusal_reason lưu, witness_nurse_id lưu; (b) order_item của thủ thuật bị huỷ (status=cancelled, cancel_reason="customer_refused_procedure"); (c) sổ khám hiện cột "Kết quả: Khách từ chối thủ thuật"; (d) KHÔNG tạo Bệnh án thủ thuật mới; (e) medical_record_access_log ghi action=refuse_procedure; (f) NTF-14 noti_clinical_procedure_refused gửi QL CN + Sale phụ trách KH |
| TC-090A | Khách từ chối thủ thuật thiếu y tá làm chứng | P0 legal | DEC-024 | Hộp thoại không cho Xác nhận khi witness_nurse_id rỗng; copy lỗi error.refusal_witness_required "Vui lòng chọn người làm chứng (y tá) trước khi xác nhận khách từ chối thủ thuật."; server cũng reject 422 nếu bypass FE |
| TC-090B | Khách từ chối thủ thuật khi đã có BA DL hoàn thành | P0 | DEC-024 | BA DL với form_type='DL' đã completed/signed không bị thay đổi status; chỉ huỷ order_item thủ thuật; sổ khám hiện 1 dòng BA DL bình thường + 1 dòng "Khám tư vấn — Khách từ chối thủ thuật" cho lượt khám TM tương ứng |
| TC-090C | User thiếu quyền clinical_record.refuse_procedure hoặc order.update | P0 security | DEC-024 + Permission v2 | (a) Thiếu refuse_procedure: CTA "Khách từ chối thủ thuật" ẩn ở SCR-08; gọi action trực tiếp → 403; (b) Thiếu order.update: CTA hiện nhưng khi xác nhận → 422 "Bạn không có quyền huỷ đơn dịch vụ. Liên hệ QL CN."; (c) Audit log ghi attempt fail với reason |
| TC-NTF-14 | Notification noti_clinical_procedure_refused | P1 | DEC-024 | Sau khi BS confirm refuse: trong 5 giây, QL CN của CN nhận in-app notification "Khách {customer_name} từ chối thủ thuật {service_name} tại {branch}. Lý do: {reason_excerpt}"; Sale phụ trách KH (nếu có) cũng nhận; deeplink mở SCR-13 Trang xem an toàn của KH; payload KHÔNG chứa diagnosis/ICD/form_data |
D2.8. FR-008 — Autosave 30s (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-033 | Tự lưu thành công + cập nhật thời gian lưu | P0 | AC-008.1 | Nhãn "Lưu lần cuối: X giây trước" |
| TC-034 | Mạng lỗi → thử lại 3 lần | P0 | AC-008.5 | Thông báo nhanh "Chưa lưu được — kiểm tra mạng" sau khi thử lại không thành công |
| TC-035 | DS BA nháp sort updated_at DESC | P1 | AC-008.3 | BA mới nhất hiện đầu |
| TC-036 | BS xoá nháp | P1 | AC-008.4 | Soft delete, admin vẫn thấy để audit |
| TC-037 | Xung đột tự lưu (2 tab cùng BA) | P1 | AC-008.2 | Hộp thoại xung đột, mặc định chọn Tải lại; Ghi đè chỉ sau khi xác nhận và có audit |
D2.9. FR-009 — In + upload scan (6 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-038 | Xem trước PDF đủ 6 biểu mẫu (DL) | P0 | AC-009.1 | PDF chứa 6 trang + header CN + ký hiệu |
| TC-039 | In lại nhiều lần (audit trail) | P1 | AC-009.2 | printed_at update, không chặn |
| TC-040 | Tải PDF 15MB | P0 | AC-009.3 | Tải thành công, gán vào clinical_record |
| TC-041 | Tải 1 file cả bộ nhưng thiếu gán biểu mẫu/checklist bắt buộc | P0 | AC-009.5 | Trạng thái vẫn printed, trả danh sách biểu mẫu bắt buộc còn thiếu |
| TC-042 | Tải file 25MB → lỗi | P0 | AC-009.3 | Hiển thị lỗi "File quá lớn — tối đa 20MB" |
| TC-042A | Tải đủ checklist scan bắt buộc theo case | P0 legal | AC-009.5, AC-009.6 | Trạng thái chuyển signed, mandatory_scan_checklist_đạted=true, có signed_at |
D2.10. FR-010 — Allergy safety (6 TC) [SAFETY CRITICAL]
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-043 | KT rủi ro cao + KH chưa có dị ứng → chặn | P0 safety | AC-010.1-010.2 | Nút Hoàn thành bị khóa + chuyển sang form tiền sử dị ứng |
| TC-044 | KT rủi ro trung bình + KH chưa có dị ứng → xác nhận | P0 safety | AC-010.2 | Hộp thoại bắt nhập lý do bỏ qua + ghi vào skip_log |
| TC-045 | KT rủi ro thấp + KH chưa có dị ứng → cảnh báo | P1 | AC-010.2, AC-010.3 | Thông báo cảnh báo + BS xác nhận tiếp tục; ghi allergy_check_skip_log dạng đã xem cảnh báo, không bắt lý do |
| TC-046 | KH đã có dị ứng < 12 tháng + BS tick "không đổi" | P1 | AC-010.5 | Copy form_data từ lần gần nhất, instance mới |
| TC-047 | KH có dị ứng > 12 tháng | P1 | AC-010.4 | Treat as chưa có, yêu cầu cập nhật |
| TC-047A | KT rủi ro unknown + BS bấm hoàn thành | P0 safety | AC-010.1, AC-010.6 | Chặn hoàn thành, hiển thị đường mở tới màn phân loại rủi ro; không cho bỏ qua bằng xác nhận |
D2.11. FR-011 — Permission 3 tầng + audit (11 core TC + 44 TC-PERM-* dẫn xuất) [SECURITY CRITICAL]
Canonical: 44 TC-PERM-* nằm ở
permission-spec.mdP12 (HD/BM/PO/MR/CI/EO/MASK/MIG/CO). Bảng dưới là 11 TC FR-level; 44 TC-PERM-* QA Lead phải tạo execution sheet riêng theo P12.
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-048 | Sale query raw clinical_record tầng 3 | P0 security | AC-011.2 | API không expose raw clinical_record; chỉ trả sales_safe_clinical_summary đã mask |
| TC-049 | BS CN B mở BA CN A trong case thường | P0 | AC-011.3 | Chỉ thấy tầng 1+2, tầng 3 bị khóa, không có request/approve/consent UI |
| TC-050 | BS CN B dùng quyền xem khẩn cấp | P0 | AC-011.4 | Xem ngay + audit log + thông báo QL + admin |
| TC-051 | BS CN B quay lại màn sau khi case thường đã xử lý manual ngoài app | P1 | AC-011.3 | Hệ thống vẫn giữ tầng 3 ở trạng thái khóa trong Day-1; không có bị ẩn grant path |
| TC-052 | Lễ tân xem clinical_record | P0 | AC-011.2 | Chỉ thấy trạng thái, không thấy diagnosis/notes |
| TC-052A | Người dùng không có action clinical_record.view_summary mở tab BA | P0 security | AC-011.8, AC-011.12 | UI ẩn tab/block; API trả FORBIDDEN hoặc dữ liệu tối thiểu rỗng, không trả field tầng 1/2/3 |
| TC-052B | Grant clinical_record.view_medical_detail cho Medical Lead/BS cùng CN | P0 security | AC-011.8, AC-011.11 | Sau refetch/relogin thấy chi tiết tầng 3 đúng branch scope; access log ghi thao tác xem tầng 3 |
| TC-052C | Thu hồi clinical_record.view_medical_detail khi user đang mở màn chi tiết | P0 security | AC-011.9, AC-011.12 | Sau khi tải lại quyền/đăng nhập lại, UI chuyển sang trạng thái khóa/không có quyền; API không trả diagnosis/form_data/scan từ cache |
| TC-052D | Portal split Admin/POS/CRM/Staff | P0 security | AC-011.10 | Action cấp ở POS không làm Admin/CRM hiện menu; portal sai bị đường dẫn/API chặn |
| TC-052E | branch_mode giới hạn record scope dù có action | P0 security | AC-011.11 | Branch-scoped user không thấy BA CN khác; multi-branch chỉ thấy CN được gán; all chỉ Admin/Ops |
| TC-052F | Role is_pos_only=true thử mở Admin/CRM đường dẫn | P0 security | AC-011.10 | Đường dẫn guard chặn, API không trả dữ liệu Admin/CRM |
D2.12. FR-012 — Sổ khám + sổ thủ thuật (4 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-053 | Bộ lọc theo ngày + CN + BS | P0 | AC-012.1 | Query trả đúng rows |
| TC-054 | Export Excel sổ khám | P1 | AC-012.2 | File Excel valid, columns đủ |
| TC-055 | Sổ thủ thuật chỉ hiện ca có KT procedure | P0 | AC-012.3 | Bộ lọc WHERE has procedure KT |
| TC-056 | QL CN chỉ xem CN mình | P0 | AC-012.4 | Hasura branch bộ lọc |
D2.13. FR-013 — Notification (3 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-057 | Order với DV mapping → BS nhận notification | P0 | AC-013.1 | Within 5s, deeplink working |
| TC-058 | Scheduler đọc close_reminder_times theo CN | P1 | AC-013.2 | Gửi đúng theo config CN, dedupe theo reminder slot; không hardcode 19h |
| TC-059 | 1 BS nhận 1 notification per appointment cần BA | P1 | AC-013.3 | Dedupe đúng |
D2.14. FR-014 — Sequence generator (4 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-060 | 100 concurrent insert → không conflict | P0 safety | AC-014.1 | Unique + monotonic, không trùng mã |
| TC-061 | STT sổ khám reset sang năm mới 1/1 | P0 | AC-014.2 | Sequence reset về 00001 |
| TC-062 | Retry không đạted transaction/rollback sequence | P1 | AC-014.3 | Không tái dùng số đã cấp; nếu có gap thì có audit void/reason, UI/report không vỡ |
| TC-063 | Admin edit next_number emergency | P2 | AC-014.4 | Can override, audit log |
D2.15. FR-015 — Kiểm tra sẵn sàng & phát hành safety (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-064 | Kiểm tra sẵn sàng không đạt vì còn DV unclassified | P0 SaaS | AC-015.1 | Nút Phát hành bị khóa, deeplink về SCR-04d đúng bộ lọc |
| TC-065 | Phát hành hộp thoại hiển thị xem trước tác động | P0 | AC-015.2 | Số DV cần BA/no BA, risk count, user quyền, support owner đúng |
| TC-066 | Schedule phát hành với effective_at tương lai | P1 | AC-015.3 | Trạng thái scheduled, chưa hiện UI vận hành trước giờ hiệu lực |
| TC-067 | Sửa config khi đang hoạt động tạo draft mới | P0 | AC-015.4 | Runtime vẫn dùng published config cũ tới khi phát hành lại |
| TC-068 | Pause module sau đang hoạt động | P0 | AC-015.5 | UI PK ẩn, BA cũ giữ nguyên, audit trạng thái paused |
D2.16. FR-016 — Trang xem an toàn (Sale) Trang xem an toàn + handoff BS (7 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-069 | Sale mở SCR-13 xem KH có BA/tầng 3 | P0 security | AC-016.1 | Không thấy diagnosis/form_data/scan/ảnh; API cũng không trả field tầng 3 |
| TC-070 | Sale tạo handoff cho BS | P0 | AC-016.3 | clinical_sales_handoff.status=sent, NTF-12 tới BS, Workbench có task |
| TC-071 | Sale thử export thông tin phòng khám | P0 security | AC-016.4 | Chỉ export lịch sử DV thương mại nếu có quyền CRM; không có y tế tầng 3 |
| TC-072 | BS acknowledge handoff | P1 | AC-016.5 | Sale thấy trạng thái đã nhận, không thấy ghi chú chuyên môn |
| TC-085 | Safe-alert dictionary không leak tầng 3 | P0 security | AC-016.6 | Response chỉ có safe_alert_level/code/text đã duyệt; không có diagnosis, ICD-10, tên bệnh, raw allergy/form_data |
| TC-085A | Sale nhập handoff có từ ngữ chẩn đoán/y lệnh | P0 security | AC-016.6 | UI/API cảnh báo và chặn pattern cấm, yêu cầu ghi theo lời KH tự mô tả hoặc chuyển BS |
| TC-085B | Grant/revoke clinical_sales.view_safe_summary và clinical_sales_handoff.create | P0 security | AC-016.1, AC-016.7 | Grant: SCR-13/CTA hiện sau refetch; revoke: block/CTA ẩn và API no-leak |
D2.17. FR-017 — Bàn việc bác sĩ (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-073 | Workbench gom đủ 6 nhóm việc | P0 | AC-017.1-017.2 | Cần tạo BA, nháp, in/ký, tải scan, handoff, thông tin KH tự khai đều hiển thị đúng |
| TC-074 | Nút xử lý một lần bấm từ Workbench | P0 | AC-017.2 | Điều hướng đúng màn tiếp theo, giữ đúng ngữ cảnh KH/hồ sơ |
| TC-075 | Timeline y tế tối giản theo quyền | P0 security | AC-017.3 | BS cùng CN xem đủ; BS CN khác chỉ tầng 1+2 nếu chưa dùng quyền xem khẩn cấp |
| TC-076 | Việc printed chưa scan >4h ưu tiên cao | P0 | AC-017.4 | Nhóm "Cần tải scan" sắp lên đầu, có nhãn đỏ |
| TC-088 | Workbench không sinh need_record sai DV | P0 data | AC-017.6 | Lượt hẹn không có product mapped_requires_ba không xuất hiện ở nhóm "Cần tạo BA", dù CN có DV khác cần BA |
D2.18. FR-018 — Customer Clinical Intake (6 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-077 | KH gửi thông tin tự khai tại tablet | P1 | AC-018.1-018.2 | Gửi bằng token hợp lệ, lưu submitted, xoá phiên, không còn dữ liệu tạm trên máy |
| TC-078 | BS nhận thông tin KH tự khai vào BA | P0 | AC-018.3-018.4 | Điền sẵn form, source_type=customer_intake, source_ref_id=intake_id, audit người kiểm tra |
| TC-079 | BS từ chối thông tin KH tự khai | P1 | AC-018.3 | Lưu từ chối_reason, thông tin tự khai không dùng trong form |
| TC-080 | Thông tin tự khai chưa được nhận không vượt qua guard dị ứng | P0 safety | AC-018.5 | Hoàn thành BA rủi ro cao vẫn bị chặn tới khi BS nhận thông tin/điền phiếu dị ứng |
| TC-086 | Token thông tin tự khai hết hạn hoặc dùng lại bị chặn | P0 security | AC-018.1, AC-018.6 | Token hết hạn/đã dùng không tạo bản ghi mới; ghi audit security event; tablet yêu cầu lễ tân mở phiên mới |
| TC-089 | Không nhận nhầm thông tin tự khai sang KH/CN/hồ sơ khác | P0 data | AC-018.1, AC-018.4, AC-018.7 | Mở phiên sai lịch hẹn/KH bị từ chối; nhận vào clinical_record khác KH/CN/lịch hẹn bị từ chối |
D2.19. FR-019 — Trang điều phối phòng khám + Chốt ngày phòng khám (5 TC)
| TC ID | Title | Priority | AC | Expected |
|---|---|---|---|---|
| TC-081 | Trang điều phối phòng khám role scope | P0 security | AC-019.2 | QL CN chỉ thấy CN mình; Admin/Ops thấy toàn chuỗi |
| TC-082 | Dashboard hiển thị lệch cấu hình | P0 | AC-019.1 | DV chưa phân loại, KT unknown, thiếu quyền hiển thị đúng và mở chi tiết đúng |
| TC-083 | Chốt ngày bị chặn vì hồ sơ đã in nhưng chưa scan >24h | P0 ops | AC-019.3 | Không cho chuyển closed; yêu cầu người phụ trách/hạn xử lý hoặc xử lý scan |
| TC-084 | Scheduler cảnh báo chốt ngày | P0 | AC-019.5 | Theo close_reminder_times nhắc QL; theo close_cutoff_time cảnh báo Ops/Admin nếu chưa chốt |
| TC-087 | Giờ chốt ngày theo cấu hình CN | P0 | AC-019.5 | CN có close_cutoff_time=19:30 cảnh báo đúng 19:30; CN chưa cấu hình dùng mặc định 20:00 VN |
D3) Dữ liệu seed kiểm thử
D3.1) Khách hàng test (staging)
| # | Họ tên | CCCD | Sinh ngày | Đặc điểm |
|---|---|---|---|---|
| 1 | Nguyễn Thị A | 001199012345 | 12/03/1990 | Có phiếu dị ứng với Lidocaine (12/2025) |
| 2 | Trần Văn B | 001199054321 | 25/07/1985 | Mới (chưa có phiếu dị ứng) |
| 3 | Lê Minh C | 001198067890 | 10/10/1988 | KH cũ (trước khi bật module) |
| 4 | Phạm Thị D | 001200098765 | 05/05/1995 | Đang có appointment draft |
| 5 | Hoàng Văn E | 001199012378 | 20/11/1992 | Có BA ở CN Cao Lãnh (cross-branch test) |
D3.2) Chi nhánh test
- CN Cao Lãnh DL — Module PK bật, cấu hình 5 bước đủ, 37 KT
- CN Tân Bình II TM — Module PK bật, cấu hình 5 bước đủ, 27 KT
- CN Hải Châu spa — Module PK TẮT (negative test DEC-001)
D3.3) Kỹ thuật và mapping test
- KT Laser CO2 fractional —
allergy_risk_level = high - KT Tiêm filler —
allergy_risk_level = high - KT Khám tư vấn —
allergy_risk_level = low - KT Lột nhẹ BHA —
allergy_risk_level = medium - KT mới chưa phân loại —
allergy_risk_level = unknownđể test block/kiểm tra sẵn sàng - Mapping: DV "Laser trị nám Premium" → KT Laser CO2 (tại CN Cao Lãnh)
D3.4) User test
| User | Business role seed | Portal | branch_mode | Action seed trọng yếu | Test |
|---|---|---|---|---|---|
| bs.phat@test | doctor | Staff/Admin | branch | clinical_record.view_summary, view_medical_detail, edit_medical_form, print, doctor_workbench.access | Điền BA, ký, tham chiếu xem bị khóa cross-branch |
| bs.huong@test | doctor | Staff/Admin | branch | clinical_record.view_summary, view_medical_detail, emergency_override, doctor_workbench.access | BA TM, emergency override |
| medical.lead@test | medical_lead | Staff/Admin | multi_branch | clinical_record.view_medical_detail, edit_medical_form, doctor_workbench.view_branch_queue | Grant/revoke tầng 3, branch_mode multi |
| yt.lan@test | nurse | Staff/Admin | branch | clinical_record.view_summary, edit_admin_shared, upload_scan, doctor_workbench.access | Tải bản scan đã ký, witness sign |
| lt.mai@test | receptionist_clinic | POS/Staff | branch | clinical_record.view_summary, customer_clinical_intake.open_session | POS, xem trạng thái BA, mở intake token |
| sale.tuan@test | sales | CRM | all | clinical_sales.view_safe_summary, clinical_sales_handoff.create | Test CẤM tầng 3, grant/revoke sales-safe |
| pos.only@test | receptionist_pos_only | POS | branch | customer_clinical_intake.open_session; is_pos_only=true | POS-only không mở Admin/CRM |
| ql.huong@test | branch_manager | Admin | branch | clinic_module.access, clinical_record.export_visit_log, clinic_ops.view_branch_dashboard, clinic_daily_close.close_branch_day | Sổ khám, export, dashboard CN, chốt ngày |
| admin.binh@test | admin | Admin | all | clinic_module.configure, clinic_module.publish, clinic_ops.view_all_dashboard | Bật module, cấu hình, phát hành |
Hasura role vận hành cho staff là
user; bảng trên là business role/mặc định seed để test Dynamic Permission v2. QA phải có bước grant/revoke trực tiếp trong Dynamic Permission UI cho các action P0.
D3.5) Dữ liệu vận hành test
clinical_sales_handoff: 1 sent, 1 acknowledged, 1 closed cho KH Nguyễn Thị A.customer_clinical_intake: 1 submitted chờ BS, 1 accepted, 1 rejected có reason.clinic_daily_close: Cao Lãnhpending_issues, Tân Bình IIclosed, Sóc Trăngopen.- Backlog: 2 BA
printedchưa scan >24h, 3 BA draft >24h, 1 DVunclassified, 1 KTunknown.
D4) Chi tiết ca kiểm thử (template + bắt buộc hoàn tất trước execution)
Bảng D2 là danh mục canonical. QA Lead phải tạo execution sheet chi tiết cho toàn bộ P0 và các P1 thuộc phase trước khi phase đó vào test; không được dùng trạng thái "TBD" khi handoff pilot.
TC ID: TC-043
Title: KT rủi ro cao + KH chưa có dị ứng → chặn hoàn thành
Priority: P0 (safety)
Preconditions:
- KH Trần Văn B (không có phiếu dị ứng) tại CN Cao Lãnh
- BS Phát tạo đơn DV "Laser trị nám Premium" (mapping KT Laser CO2, allergy_risk_level = high)
- BS Phát mở form BA DL, điền đủ trường bắt buộc
Steps:
1. BS bấm "Hoàn thành"
2. Hệ thống kiểm tra: KT Laser CO2 → high + KH chưa có dị ứng → áp dụng rule chặn
3. Kết quả mong đợi: nút Hoàn thành bị khóa, banner đỏ "BẮT BUỘC: Điền phiếu tiền sử dị ứng trước khi hoàn thành thủ thuật xâm lấn"
4. Bấm link "Điền phiếu dị ứng" → chuyển sang SCR-08c
5. Điền phiếu dị ứng → gửi
6. Quay lại form BA → bấm "Hoàn thành"
7. Kết quả mong đợi: trạng thái → completed
Post-conditions:
- clinical_form_instance (type=ALLERGY) tồn tại với KH này
- clinical_record.status = completed
- allergy_check_skip_log: không có bản ghi (không bỏ qua)
Negative variations:
- TC-043.1: BS cố bấm "Hoàn thành" lần 2 → vẫn bị chặn
- TC-043.2: BS tải lại trang → rule vẫn được áp dụng
- TC-043.3: BS đăng xuất/đăng nhập lại → rule chặn vẫn nhất quánD5) Tiêu chí vào/ra
D5.1) Tiêu chí vào (QA bắt đầu test Phase X)
| Phase | Entry criteria |
|---|---|
| Phase 1 (admin) | Migration đạt + Hasura metadata deploy + admin UI render + smoke test admin setup 5 bước ≥1 CN |
| Phase 2 (form BA DL + shared) | Phase 1 QA đạt + form renderer build + 5 template seed + autosave endpoint up |
| Phase 3 (BA TM + allergy) | Phase 2 QA đạt + BA TM schema seed + allergy_check_policy seed + skip_log table ready |
| Phase 4 (permission) | Phase 3 QA đạt + masked views/actions deploy + access_log + endpoint xem khẩn cấp + module_permission_action seed + role_module.actions theo portal + Dynamic Permission UI lưu/tải lại quyền được |
| Phase 5 (sổ + notification) | Phase 4 QA đạt + view queries + scheduler deploy + notification template |
| Phase 5B (Sales/Ops surfaces) | Phase 5 smoke đạt + sales_safe_view/action + Bàn việc bác sĩ + intake + Chốt ngày phòng khám handlers deploy |
| Phase 6 (pilot hardening) | Phase 5B QA đạt + go-live checklist E2 đạt + rollback/app-pause drill + support roster D0 confirmed |
D5.2) Tiêu chí ra (đạt để handoff pilot)
Per phase:
- 100% P0 TC đạt
- ≥90% P1 TC đạt
- 0 P0 bug outstanding
- ≤3 P1 bugs outstanding (must be known + workaround documented)
Overall pilot go-live:
- ≥95% 108 core TC đạt (99 core + 9 TC bổ sung v2.1.0 cho DEC-021/DEC-024)
- 100% P0 safety + security + SaaS kiểm tra sẵn sàng + ops + legal TC đạt (all P0 rows in D2, including TC-030A, TC-030B, TC-030C, TC-030D, TC-042A, TC-043, TC-044, TC-047A, TC-048, TC-049, TC-050, TC-052A, TC-052B, TC-052C, TC-052D, TC-052E, TC-052F, TC-060, TC-064, TC-067, TC-068, TC-069, TC-071, TC-075, TC-080, TC-081, TC-083, TC-084, TC-085, TC-085A, TC-085B, TC-086, TC-087, TC-088, TC-089, TC-090, TC-090A, TC-090B, TC-090C)
- 100% D6 regression theo ranh giới ảnh hưởng đạt: quy ước module trực tiếp, guard module gián tiếp và smoke module không ảnh hưởng không có regression ngoài phạm vi
- UAT sign-off từ 2 BS champion + 1 y tá + 1 lễ tân + 1 Sale + 1 QL CN mỗi CN pilot
- Load test: 50 BS đồng thời điền form, tự lưu p95 <500ms, không mất dữ liệu
- Security test: Sale không truy cập được tầng 3 qua any API path; raw
clinical_record/clinical_form_instancekhông expose cho vận hành roleuser - Legal/Ops smoke: checklist ký/scan đủ, máy scan/máy in/tài khoản tải file đạt, danh sách hỗ trợ D0 đã gọi thử
D5.3) Tiêu chí sau pilot (sau 30 ngày pilot)
D6) Regression theo ranh giới ảnh hưởng
D6 dẫn xuất từ PRD A12 + SoT DEC-044. Các REG case dưới đây không cộng vào 99 core TC, nhưng là go-live gate bắt buộc để chứng minh feature lớn không làm đổi sai module ngoài scope.
D6.1) Regression module ảnh hưởng trực tiếp
| ID | Phạm vi | Oracle đạt | Priority |
|---|---|---|---|
| REG-DIR-001 | Settings / Branch Detail | User không có clinic_module.configure không thấy tab/nút cấu hình; CN spa thuần không thấy menu/module Phòng khám; phát hành bị chặn khi R-01..R-10 chưa đạt | P0 |
| REG-DIR-002 | Dynamic Permission / Auth | Grant/revoke action thay đổi UI/API sau refetch; portal split admin/pos/crm đúng; Sale hard deny tầng 3 dù role seed bị grant nhầm | P0 |
| REG-DIR-003 | Appointment / POS / Order | Appointment walk-in order_item_id = NULL không panic event/job/report; đơn DV cần BA tạo notification đúng; DV không cần BA không tạo task giả | P0 |
| REG-DIR-004 | Customer / CRM / Trang xem an toàn (Sale) | Customer Detail hiển thị tab BA theo quyền; Sale chỉ thấy safe summary/handoff text, không thấy diagnosis/scan/y lệnh qua bất kỳ API/query | P0 |
| REG-DIR-005 | Clinical forms / Print / Scan | Runtime user không mutate raw form table; print không tự chuyển signed; signed chỉ đạt khi đủ mandatory scan checklist theo case | P0 |
| REG-DIR-006 | Notification / Export / Logs | Payload thông báo không chứa tầng 3; export chỉ field allowlist; access log ghi khi mở tầng 3/xem khẩn cấp | P0 |
| REG-DIR-007 | Workbench / Phiếu khách tự khai / Chốt ngày | Workbench không false-positive; token KH tự khai hết hạn/khác KH/CN bị từ chối; chốt ngày không đạt khi còn BA P0 chưa xử lý | P0 |
D6.2) Smoke module ảnh hưởng gián tiếp
| ID | Module | Oracle đạt | Priority |
|---|---|---|---|
| REG-IND-001 | Dashboard / Report chung | Không có KPI/doanh thu/lương/report tổng mới đọc BA hoặc form_data; dashboard hiện hữu vẫn load như trước | P1 |
| REG-IND-002 | Ticket / Task / Project | Task/ticket/project hiện hữu liên quan appointment/order không panic với walk-in; không phát sinh workflow clinical generic Day-1 | P1 |
| REG-IND-003 | Mobile / Push | Push/deeplink chỉ dùng text an toàn; mở deeplink vẫn kiểm quyền server-side trước khi thấy dữ liệu clinical | P0 |
| REG-IND-004 | Support / Incident / Complaint | Có category/runbook support nếu cần; complaint/CSKH không tự động nhận dữ liệu tầng 3 hoặc scan | P1 |
D6.3) Smoke module không ảnh hưởng
| ID | Module | Oracle đạt | Priority |
|---|---|---|---|
| REG-NO-001 | Wallet / Ví / Khuyến mãi | Menu, permission, voucher/wallet transaction và scheduler giữ nguyên; không có clinical action trong wallet | P1 |
| REG-NO-002 | Salary / KPI / Timekeeping | Không thêm chỉ tiêu BA vào lương/KPI/chấm công; đường dẫn/report hiện hữu không đổi dữ liệu | P1 |
| REG-NO-003 | Affiliate / Achievement / Gamification | Không phát sinh achievement/campaign/affiliate trigger từ BA hoặc appointment cần BA | P2 |
| REG-NO-004 | CMS / Geo / Conversation | Không thêm content/config/message clinical ngoài notification safe text đã duyệt | P2 |
| REG-NO-005 | Finance / P&L | Báo cáo tài chính/P&L không thêm chi phí, thủ thuật, scan, mã BA hoặc diagnosis | P1 |
| REG-NO-006 | Warehouse / Inventory | Đơn thuốc/form BA không tạo xuất kho/nhập kho hoặc thay đổi tồn kho Day-1 | P1 |
D6.4) Quy tắc exit cho regression boundary
- REG-DIR P0 không đạt = chặn go-live.
- REG-IND/REG-NO không đạt = chặn nếu làm đổi hành vi hoặc quyền ngoài scope; nếu chỉ là lỗi hiển thị không ảnh hưởng dữ liệu/quyền, PO + TL + QA quyết định cách xử lý tạm bằng văn bản.
- Mọi phát hiện muốn đưa clinical data sang module indirect/no-impact phải tạo DEC mới trong
SOURCE_OF_TRUTH.mdtrước khi implement.
D7) Công cụ kiểm thử
| Tool | Purpose |
|---|---|
| Go testing (built-in) | BE unit + integration test |
| Playwright | E2E browser test (FE critical luồngs) |
| k6 | Load/performance test |
| Postman / Bruno | API manual test collection |
| pgTAP | DB migration test |
| OWASP ZAP | Security scan (permission + auth) |
| Hasura Console | Metadata + permission verify manual |
D8) Quản lý lỗi
- Tool: Linear (project
CLINICAL) - Severity: S1 (chặn go-live) / S2 (major) / S3 (minor) / S4 (trivial)
- SLA: S1 fix trong 4h, S2 trong 1 day, S3 trong 3 days, S4 in backlog
- Regression test: sau mỗi bug fix, related TC re-run
Kết thúc QA Test Plan v2.1.0. D2 là danh mục TC chuẩn (108 TC: 99 core + 9 TC bổ sung cho DEC-021 typed-confirmation và DEC-024 refuse-procedure); execution sheet chi tiết phải hoàn tất theo phase trước khi QA chạy.