Giao diện
US-S05: Kiểm tra các trạng thái chặn chuyển nhượng (luồng 3A) ​
Thuộc FS: 00-overview.md — SAPP-26297 Chuyển nhượng học viên (tool
sapp.011) Phần chung (tổng quan, roles, flow tổng, related features, NFR, Open Questions, References) xem ở Overview. File này chỉ chứa nội dung riêng của US.Cơ chế chạy bước, tự chấm, xác nhận GHI → US-S01. Câu SQL → US-S02 §4. Bảng mã từ chối là của Ops (theo guide QA), không phải rule mind_keep cài.
| Field | Value |
|---|---|
| US ID | US-S05 |
| Role thực hiện | R1 - Người dùng tool — Assumption (OQ về G-01 → OQ-S-01) |
| Phase | As-built (đã triển khai @ e77c47a) |
| Priority | N/A — as-built |
| Status | Draft |
| NFR liên quan | NFR-S-01, NFR-S-02 — xem Overview §5 |
| OQ liên quan | OQ-S-01, OQ-S-03, OQ-S-12, OQ-S-14 — xem Overview §6 |
1. US Statement ​
text
As a Người dùng tool [Assumption — OQ-S-01]
I want dựng từng điều kiện sai (lớp nhận khác môn / Revision, người nhận có tiến độ / không NORMAL / đã nhận chuyển nhượng,
lớp đi kèm sai trạng thái) rồi xác nhận Ops trả đúng mã lỗi và không đổi dữ liệu
So that [Assumption — OQ-S-18] chắc chắn chuyển nhượng bị chặn đúng chỗ theo guide QA của SAPP-262972. Dependencies & Definition Of Ready ​
N/A — đã triển khai. Dependency runtime:
| # | Cần sẵn sàng | Ai cung cấp | Trạng thái |
|---|---|---|---|
| D1 | Case 0.1 đạt; A, B, C NORMAL 0% (US-S02) | Tester | — |
3. Business Rules ​
| ID | Rule | Áp dụng ở | Đã cover bởi (AC) | Nguồn code (Mode B/C) |
|---|---|---|---|---|
| BR-01 | Sau mỗi case của 3A chạy câu kiểm toàn vẹn (bước "3.7"): không type nào đổi so với trước khi gọi, số bản ghi A→B không tăng — tester đọc kết quả SQL | M1 - mọi case | AC-M1.1 → AC-M1.4 | fe/src/ui/components/works/sapp/sapp-26297-flows.ts:1033-1037,461-467 |
| BR-02 | Lớp nhận không hợp lệ (3.1 khác môn, 3.2 là lớp Revision): tester tìm lớp bằng câu SQL đọc rồi tự điền ô lớp nhận (mặc định trống); chấm "Từ chối đúng" 400|100331 · exceptions.transfer_receiving_class_invalid | M1 - case 3.1, 3.2 | AC-M1.1 | sapp-26297-flows.ts:1039-1074 |
| BR-03 | Người nhận có tiến độ (3.3) hoặc không NORMAL (3.4): dựng bằng SQL GHI, chấm 400|100332 · exceptions.transfer_condition_no_longer_valid | M1 - case 3.3, 3.4 | AC-M1.2 | sapp-26297-flows.ts:1076-1100 |
| BR-04 | Người nhận đã nhận chuyển nhượng môn này (3.5): chuyển A→B thành công, SQL xác nhận có bản ghi hiệu lực chặn B, chuyển C→B bị 400|100332, hủy A→B thành công, rồi C→B phải thành công | M1 - case 3.5 | AC-M1.3 | sapp-26297-flows.ts:1102-1121 |
| BR-05 | Lớp đi kèm sai trạng thái (3.6): dựng A tại F1 → RESERVED, chấm 400|100333 · exceptions.transfer_linked_class_invalid_status, đủ 5 khoá replacements, và error.replacements.status = RESERVED; hướng dẫn đối chiếu câu thông báo FS ghép từ 5 tham số và biến thể Revision dựng tay | M1 - case 3.6 | AC-M1.4 | sapp-26297-flows.ts:1123-1159 |
4. Design ​
a. Mối liên hệ giữa các màn & User Flow ​
text
[Tab "3A · Chặn chuyển nhượng"]
↓ mỗi case
[SQL dựng / tìm (đọc hoặc GHI)] → [chuyển nhượng (GHI Ops) — kỳ vọng bị từ chối] → [SQL "3.7" kiểm toàn vẹn]
└─ 3.5: chuyển A→B → SQL c35 → C→B (bị chặn) → hủy A→B → C→B (thành công)b. Chi tiết từng màn ​
Màn M1 - Tab "3A · Chặn chuyển nhượng" ​
| Field | Value |
|---|---|
| Figma frame | N/A |
| Trigger vào màn | Bấm tab "3A · Chặn chuyển nhượng" |
| Mô tả ngắn | Tóm tắt: "Mỗi case dựng một điều kiện sai rồi xác nhận Ops trả đúng mã lỗi. Sau MỖI case chạy bước 3.7: không đổi trạng thái, không sinh bản ghi." 6 case |
UI States ​
| State | Khi nào | Hiển thị | Figma frame |
|---|---|---|---|
| Default | Vào tab | Tóm tắt + 6 case đóng | N/A |
| Loading | Bước đang chạy | Theo US-S01 | N/A |
| Has data | Bước chạy xong | ✓/✗ + "x/y đạt"; case 3.6 có khung "Verify replacements kỹ nhất…" | N/A |
| Empty | N/A | — | N/A |
| Error | Không gọi được Ops | Hộp đỏ 13042 | N/A |
| Disabled | Fixture thiếu L1 / A / B | Nút khoá "Chưa điền: …" | N/A |
Fields ​
| Field | Required | Type | Default | Format | Validation | Error Message | Visibility | Depends On |
|---|---|---|---|---|---|---|---|---|
transfer_to_class_id (3.1, 3.2) | Yes (theo ý case) | Text | Trống — tester điền id lớp tìm được từ SQL c31 / c32 | id Ops | ⚠️ Observed: trống không bị coi là "chưa điền", nút không khoá (EC-M1.1) | — | Bước chuyển nhượng 3.1, 3.2 | SQL c31, c32 |
transfer_from (3.5 bước 3, 5) | Yes | Text | {user_c} | id Ops | US-S01 BR-10 | "Chưa điền: …" | Bước chuyển nhượng C→B | Fixture |
| Các field chuyển nhượng khác | — | — | Như US-S03 | — | — | — | — | Fixture |
Actions ​
A1 - Chạy các bước của một case ​
| Item | Description |
|---|---|
| Trigger | Mở case, chạy từng bước (US-S01) |
| Behavior | Thao tác dùng: chuyển nhượng (GHI), hủy (GHI, 3.5); SQL c31, c32, c35, c36.1 (đọc), c33, c34, c36.2 (GHI), int (đọc). Ghi vào: Ops dev/staging, DB Ops dev/staging. Không có đường PROD |
| Success Result | Các check đạt theo bảng case; SQL "3.7" không thấy thay đổi |
Error cases:
| Case | Expected Handling |
|---|---|
| Ops trả mã khác kỳ vọng | Check ✗ + giá trị thực |
| Không gọi được Ops | Hộp đỏ 13042 |
Bảng case (6 case):
| Mã case | Tên | Bước | Kỳ vọng tool chấm |
|---|---|---|---|
| 3.1 | Lớp nhận khác môn học | SQL c31 (đọc) · chuyển nhượng (tester điền lớp) · SQL int | 400|100331 transfer_receiving_class_invalid |
| 3.2 | Lớp nhận là lớp Revision | SQL c32 (đọc) · chuyển nhượng (tester điền lớp) · SQL int | 400|100331 |
| 3.3 | Người nhận đã có tiến độ | SQL c33 (GHI 3/10) · chuyển nhượng · SQL int | 400|100332 transfer_condition_no_longer_valid |
| 3.4 | Người nhận không ở trạng thái NORMAL | SQL c34 (GHI RESERVED) · chuyển nhượng · SQL int | 400|100332 |
| 3.5 | Người nhận đã nhận chuyển nhượng môn này (AC8) | chuyển A→B · SQL c35 · chuyển C→B · hủy A→B · chuyển C→B | C→B lần 1 400|100332; sau hủy A→B thì C→B thành công (AC12) |
| 3.6 | Lớp đi kèm sai trạng thái (AC6) | SQL c36 (GHI) · chuyển nhượng · hướng dẫn câu FS · SQL int | 400|100333 transfer_linked_class_invalid_status + đủ 5 replacements + replacements.status = RESERVED |
Acceptance Criteria của màn M1 ​
AC-M1.1 - Lớp nhận không hợp lệ ​
gherkin
Scenario Outline: 100331
Given tester đã tìm được <lớp> bằng SQL <panel> và điền vào ô transfer_to_class_id
When người dùng chạy bước chuyển nhượng
Then HTTP 400, error.code = "400|100331", error.message = "exceptions.transfer_receiving_class_invalid"
And SQL "3.7" cho thấy không có type nào đổi, số bản ghi A→B không tăng
Examples:
| case | lớp | panel |
| 3.1 | Lesson khác subject_id | c31 |
| 3.2 | lớp REVISION bất kỳ | c32 |Maps to:
- Business Rule: BR-01, BR-02
AC-M1.2 - Người nhận không đủ điều kiện ​
gherkin
Scenario Outline: 100332 phía người nhận
Given đã chạy SQL <panel>: <dựng>
When người dùng chạy bước chuyển nhượng A → B tại L2
Then HTTP 400, error.code = "400|100332", error.message = "exceptions.transfer_condition_no_longer_valid"
And SQL "3.7" không thấy thay đổi
Examples:
| case | panel | dựng |
| 3.3 | c33 | B tại L2 tiến độ 3/10 |
| 3.4 | c34 | B tại L2 → RESERVED |Maps to:
- Business Rule: BR-01, BR-03
AC-M1.3 - Người nhận đã nhận chuyển nhượng cùng môn ​
gherkin
Given A, B, C NORMAL 0%
When người dùng chạy "1. Chuyển nhượng A → B"
Then "Cập nhật thành công"
When người dùng chạy "3. Chuyển nhượng C → B cùng môn"
Then HTTP 400, error.code = "400|100332"
When người dùng chạy "4. Hủy A → B" rồi "5. Chạy lại C → B"
Then cả hai bước "Cập nhật thành công"Maps to:
- Business Rule: BR-04
AC-M1.4 - Lớp đi kèm sai trạng thái ​
gherkin
Given đã chạy SQL c36: A tại F1 → RESERVED
When người dùng chạy bước chuyển nhượng
Then HTTP 400, error.code = "400|100333", error.message = "exceptions.transfer_linked_class_invalid_status"
And error.replacements có đủ student_name, status, class_code, linked_class_type, lesson_class_code
And error.replacements.status = "RESERVED"
And SQL "3.7" không thấy thay đổiMaps to:
- Business Rule: BR-01, BR-05
Negative AC / Edge Cases của màn M1 ​
| ID | Tình huống | Hành vi mong đợi |
|---|---|---|
| EC-M1.1 | ⚠️ Observed — quên điền lớp nhận ở 3.1 / 3.2 | Hành vi hiện tại: ô trống không bị coi là "chưa điền" nên nút Chạy không khoá; request gửi thiếu field ⇒ Ops trả 422 thay vì 100331, check ✗ (sapp-26297-flows.ts:1049-1053,1066-1070 · sapp-26297-step-call.tsx:428-430) — OQ-S-03 |
| EC-M1.2 | Không dọn điều kiện đã dựng giữa các case | Case sau có thể nhận mã khác (vd B vẫn RESERVED từ 3.4) — tester chạy 0.2 |
| EC-M1.3 | Biến thể Revision của 3.6 | Không có bước tự động — chỉ hướng dẫn dựng tay rồi chạy lại |
5. Cross-feature AC ​
Không có.