Trường Số QA/02 Students (SIS)
Trường Số · QA test suite · Phase 1 · 10/09/2026

02 · Students (SIS)

Test cases for PRD 02. Every case names the fixture data it needs (see the dashboard fixtures table), numbered steps, and one observable expected result. Trace points to the user story or rule in the PRD.

Key facts, origin and limits
Cases
61
P0 / P1
13 / 35
Regression pack
18
PRD
02 Students (SIS)
Phase
P1

Drafted by an AI assistant in a single session on 10/09/2026 as part of the Trường Số QA suite, under the request quoted verbatim on the dashboard. A proposal for team review, not a sign-off.

Sources

  • The Trường Số PRD set (Draft v1, 10/09/2026): user stories, screen tables, business rules and permission matrices, plus the Cloud theme reference.

Limits

  • Phase 1 (authoring) only. Cases are executed in Phase 2 against the local build; results are recorded in testcases.json and runs/run-1/, and every result field is still not_run.
  • Cases inherit any open question or inconsistency in the PRDs they trace to.

1Summary

P0
13
P1
35
P2
12
P3
1
Typefunctionalui-uxedgenegativeregressionflowa11yperfsecurityi18n
Count33567001072

2Test cases

IDTitleTypePriorityPhasePreconditionsStepsExpected resultPRD traceData neededRun 1
TS-STU-001Student list header, tabs and countsfunctionalP0P1As U-ACAD-A (branch A) on /students.
  1. Read the header and tab bar.
h1 "Học viên"; buttons Nhập từ Excel and + Thêm học viên; tabs in order Tất cả · Đang học · Chờ xếp lớp · Học thử · Bảo lưu · Sắp hết buổi · Nợ học phí · Đã nghỉ, each with a count; Đang học includes S1, S6, S7; Chờ xếp lớp includes S3; Bảo lưu S4; Sắp hết buổi S6 (2 left) and S1 is NOT included (5 left); Nợ học phí S7; Đã nghỉ S5.STU list §5Fixtures belowNot run
TS-STU-002Student list columns match the specfunctionalP1P1As U-OWNER with "Tất cả chi nhánh".
  1. Read the column headers.
Mã HV, Họ tên, Lớp, Trạng thái, Phụ huynh, Buổi còn lại, Công nợ, Điểm danh 30 ngày, Chi nhánh, Ngày nhập học, Thao tác. With one branch selected the Chi nhánh column is hidden.02 §5 columnsFixtures belowNot run
TS-STU-003Row formatting rulesui-uxP1P1S1, S3, S6, S7 visible.
  1. Inspect the rows.
S1: code HV-000123, name link with small text "8 tuổi", class chip "Movers 2A", chip Đang học green; S3: dashed chip "Chưa xếp lớp"; S6: Buổi còn lại "2" in red; S7: Công nợ "3.000.000 đ" in red; monthly-plan S2 shows "-" for Buổi còn lại; guardian phone click copies to clipboard with toast "Đã sao chép".02 §5 notesFixtures belowNot run
TS-STU-004Row height 44 px and 50 rows per pageui-uxP2P1Tenant BIG with > 50 students in branch A.
  1. Measure a row in devtools.
  2. Scroll to the pagination.
Row height 44 px; pagination shows 50 per page with total count; Cloud table header uppercase 12 px light grey.02 §5, Cloud theme §2Fixtures belowNot run
TS-STU-005Search by name without accents, guardian phone, code, usernamefunctionalP0P1As U-ACAD-A.
  1. Type "nguyen an" in search.
  2. Type "0901234567".
  3. Type "HV-000128".
  4. Type S1's FLYER username.
Each query returns the matching student within ~300 ms; the guardian-phone match highlights the phone cell; no client-side full-list filtering (network request per query with q=).STU-01Fixtures belowNot run
TS-STU-006Filters: branch, class, level, guardian consent, start date rangefunctionalP1P1As U-OWNER.
  1. Apply class = C1.
  2. Add consent = Chưa đồng ý Zalo.
  3. Add start date range covering only this month.
Result set narrows at each step and counts update; URL reflects filters; Xoá bộ lọc resets.02 §5 filtersFixtures belowNot run
TS-STU-007Empty state textui-uxP1P1Owner of tenant EMPTY.
  1. Open /students.
Exactly "Chưa có học viên. Chuyển đổi từ khách hàng hoặc thêm trực tiếp." with a primary + Thêm học viên button.02 §5 empty stateFixtures belowNot run
TS-STU-008Column visibility persists via view-configsfunctionalP2P1As U-ACAD-A.
  1. Hide column Ngày nhập học; reload; log in from another browser.
Column stays hidden in both browsers; GET /v3/crm/view-configs/student_list returns the config.02 §5 view key student_listFixtures belowNot run
TS-STU-009Bulk actions: Gửi thông báo, Xuất Excel, Chuyển lớpfunctionalP1P1As U-ACAD-A.
  1. Select S1 and S6.
  2. Read the bulk bar.
  3. Click Xuất Excel.
Bulk bar shows "2 đã chọn" and the three actions; xlsx downloads with 2 rows and the visible columns.02 §5 bulk, students.exportFixtures belowNot run
TS-STU-010Teacher sees only students of own classessecurityP0P1As U-TEACH (C1 at A, C3 at B).
  1. Open /students.
  2. Open /students/<S7 id> (in C2).
List contains only C1 and C3 students (S1, S6, S2, ...) and not S7; direct URL for S7 returns 404 page; API 404.02 §9 students.view own classesFixtures belowNot run
TS-STU-011Admissions read scope shows limited fieldssecurityP1P1As U-ADM.
  1. Open /students/<S1 id>.
Only name, class, guardian visible; tabs Học phí, Tài liệu, Ghi chú, Nhật ký hidden; no Sửa button.02 §9 admissions readFixtures belowNot run
TS-STU-012Create a walk-in student with all required fieldsfunctionalP0P1As U-ACAD-A.
  1. Click + Thêm học viên.
  2. Fill Họ và tên "Bùi Minh Khang", Ngày sinh 02/02/2017, Giới tính Nam, Chi nhánh Quận 1, Trình độ Starters, Phụ huynh 1: "Bùi Văn Long", Bố, 0977000010, consent ticked; Tài khoản FLYER: tạo mới.
  3. Save.
Drawer closes; toast shows the generated username and a one-time password with "Sao chép" (shown once); student appears in tab Chờ xếp lớp with status Chờ xếp lớp; code is the next sequential HV-number; no lead is created in /crm/customers; guardian record created with E.164 phone +84977000010 displayed as 0977 000 010.STU-02, 12 §8 phoneFixtures belowNot run
TS-STU-013Student form validation matrixnegativeP1P1Create drawer open.
  1. Enter name "A" (1 char) then 81 chars.
  2. Enter birthday giving age 2, then age 81.
  3. Leave Chi nhánh empty.
  4. Leave Phụ huynh phone empty for a child.
  5. Upload a 6 MB photo.
Inline errors: "2–80 ký tự"; "Tuổi 3–80"; "Chọn chi nhánh"; "Bắt buộc"; "Tối đa 5 MB". Save stays disabled until all are fixed.02 §5 student form validationFixtures belowNot run
TS-STU-014Adult learner (18+) does not need a guardian phoneedgeP1P1Create drawer.
  1. Enter birthday giving age 20; leave guardian empty; choose Tài khoản FLYER liên kết có sẵn and pick S8's account or create new.
  2. Save.
Save allowed; guardian block shows "Bản thân" relationship auto-created with the student's own phone if entered; no "Thiếu phụ huynh" chip.02 §6 rule 3Fixtures belowNot run
TS-STU-015Existing guardian suggested by phone in the formfunctionalP1P1Create drawer.
  1. Type 0901234567 in Phụ huynh 1 phone.
Suggestion "Trần Thị Hoa (mẹ của Nguyễn An, Nguyễn Bình)" appears; selecting it links G1 instead of creating a duplicate.02 §5 guardian suggested by phoneFixtures belowNot run
TS-STU-016Link an existing FLYER account by username or phonefunctionalP1P1Create drawer.
  1. Choose "liên kết có sẵn"; search by a known username.
Search returns the learner with display name; selecting fills the link; after save the profile rail shows that username.STU-02 Tài khoản FLYER radioFixtures belowNot run
TS-STU-017Same learner at a second branch creates a second recordedgeP2P1S1 exists at A.
  1. Create a student at branch B linking S1's learner profile.
Save succeeds; a second record with its own code exists at B; both profiles show a note "Cũng học tại Quận 1 / Thủ Đức"; creating a third record at A with the same learner fails with a unique-constraint message.02 §6 rule 1Fixtures belowNot run
TS-STU-018Twins with same guardian and birthday allowed after warningedgeP2P1Student "Nguyễn An" born 2018 with G1 exists.
  1. Create "Nguyễn Anh" same birthday, same guardian.
Duplicate warning listing S1; admin confirms; second student created.02 §11 twinsFixtures belowNot run
TS-STU-019Profile header and right railfunctionalP0P1As U-ACAD-A on /students/<S1 id>.
  1. Read header and right rail.
Header: avatar, "Nguyễn An", HV-000123, "8 tuổi", chip Đang học, branch Quận 1, class chip Movers 2A, chip "Cần lưu ý"; buttons Sửa · Xếp lớp · Thu học phí · Gửi tin · kebab with Bảo lưu, Nghỉ học, Chuyển chi nhánh, Ẩn danh hoá. Right rail: Phụ huynh chính (Trần Thị Hoa · Mẹ · 0901 234 567 · Zalo: Đã đồng ý), Số dư buổi 5, Công nợ 9.600.000 đ, Tài khoản FLYER username + last active.02 §5 profileFixtures belowNot run
TS-STU-020Profile tabs in the specified orderfunctionalP1P1On S1 profile.
  1. Read the tab bar.
Tổng quan · Phụ huynh · Lớp & lịch sử · Điểm danh · Học phí · Học tập · Tài liệu · Ghi chú · Nhật ký; each tab is deep-linkable (#attendance etc.).02 §5 tabsFixtures belowNot run
TS-STU-021Tổng quan tab shows personal info, consent summary and timelinefunctionalP1P1S1 profile.
  1. Open Tổng quan.
Birthday, gender, school, address, level, allergies (health note) shown; consent summary lists Zalo granted with date; timeline entries created, converted, enrolled in chronological order with actor.02 §5 Tổng quanFixtures belowNot run
TS-STU-022Kebab actions hidden for roles without students.statussecurityP1P1As U-ADM and U-ACC.
  1. Open S1 profile kebab.
Bảo lưu / Nghỉ học / Chuyển chi nhánh / Ẩn danh hoá absent; U-ACC sees Học phí tab and read-only profile.02 §9Fixtures belowNot run
TS-STU-023Add a second guardian with flagsfunctionalP0P1S1 profile, tab Phụ huynh.
  1. Click + Thêm phụ huynh; name "Nguyễn Văn Tùng", Bố, 0903000001, email, Zalo consent ticked, flags Liên hệ chính off, Người thanh toán ON.
  2. Save.
Two cards; G1 keeps Liên hệ chính; new guardian has Người thanh toán and G1 loses it (exactly one payer); guardian_added event fired.STU-03Fixtures belowNot run
TS-STU-024Exactly one primary contact and one payernegativeP1P1S1 with two guardians.
  1. Untick Liên hệ chính on G1 without setting it on the other.
Save refused with "Cần một liên hệ chính"; setting it on the other guardian moves the flag.STU-03 exactly oneFixtures belowNot run
TS-STU-025Guardian shared by siblings is one recordfunctionalP1P1G1 on S1 and S2.
  1. Edit G1 email from S1 profile.
  2. Open S2 tab Phụ huynh.
S2 shows the updated email; GET /v3/school/guardians?phone=0901234567 returns one record.STU-03, 02 §7 unique (tenant, phone)Fixtures belowNot run
TS-STU-026Changing a guardian phone writes audit and re-verifies ZalofunctionalP1P1G1 on S1.
  1. Change phone to 0901234568; save.
  2. Open tab Nhật ký.
Audit row "guardian.update" with before/after phone; Zalo status on the card changes to "Đang kiểm tra" then a result (stub); an audit entry on both students sharing G1.STU-03, 12 §6 mandatory auditFixtures belowNot run
TS-STU-027Guardian phone uniqueness: entering another guardian's phone mergesedgeP2P1S6 has G2 (0912000002).
  1. On S1 add a guardian with phone 0912000002.
Dialog "Số điện thoại thuộc Lê Văn Nam" offers "Liên kết" (links G2 to S1) or cancel; no duplicate record.02 §7, test seed 02Fixtures belowNot run
TS-STU-028Gửi lại thông tin đăng nhập sends credentials to primary contactfunctionalP2P1S1 profile tab Phụ huynh; ZALO stub.
  1. Click Gửi lại thông tin đăng nhập; confirm.
POST /students/{id}/credentials/resend called; message row type credentials to G1 via ZNS (template credentials) with status sent; toast "Đã gửi".02 §8 credentials/resend, 07 §6 credentials to primary contactFixtures belowNot run
TS-STU-029Guardian phone displayed as 0xxx xxx xxx and stored E.164i18nP2P1G1.
  1. Read the phone on the card.
  2. Read the API value.
Card shows "0901 234 567"; API returns "+84901234567".12 §8 phoneFixtures belowNot run
TS-STU-030Enroll a Waiting student from the profilefunctionalP0P1S3 (Waiting) as U-ACAD-A; C1 has 11/12.
  1. Click Xếp lớp; choose C1, start date next Tuesday, fee plan FP1.
  2. Confirm.
Enrollment created; S3 status Đang học; C1 shows 12/12 and status Đầy; S3 appears on rosters only for sessions on or after the start date; sessions before the start date do not count as absences in S3 attendance tab.STU-04Fixtures belowNot run
TS-STU-031Enroll into a full class offers waiting listnegativeP1P1S3 Waiting; C2 12/12.
  1. Xếp lớp → C2.
API 409 CLASS_FULL; UI offers "Thêm vào danh sách chờ"; accepting creates enrollment status waiting; S3 stays Chờ xếp lớp.CLS-07, 03 §8 enrollments 409Fixtures belowNot run
TS-STU-032Enroll a Withdrawn student re-activates the recordfunctionalP1P1S5 Withdrawn.
  1. Xếp lớp S5 into C1 (after freeing a seat) or C4.
Status Đang học; same code HV-000127 (record reused); status history shows withdrawn → active.02 §6 rule 6Fixtures belowNot run
TS-STU-033Pause a student (Bảo lưu)functionalP0P1S1 Active, package expiry E.
  1. Kebab → Bảo lưu; from today, expected return in 30 days, reason "Về quê".
  2. Confirm.
Status Bảo lưu; roster of C1 sessions in the window no longer lists S1; package expiry becomes E + pause length (visible on Học phí tab after resume, "frozen" chip meanwhile); a reminder task dated 7 days before expected return appears in the today plan of the care owner; status history row with dates.STU-05Fixtures belowNot run
TS-STU-034Pause requires reason and datesnegativeP1P1Pause dialog.
  1. Submit with empty reason; then with return date before start.
Inline errors; API 400 when called directly.STU-05, 02 §6 manual transitions need reasonFixtures belowNot run
TS-STU-035Pause longer than 90 days needs branch manager approvalfunctionalP1P1As U-ACAD-A.
  1. Pause S1 for 120 days.
Dialog shows "Cần quản lý chi nhánh duyệt"; status Bảo lưu with an approval pending marker; U-BM-A gets a notification; as U-BM-A the same request completes without approval.02 §6 rule 5Fixtures belowNot run
TS-STU-036Resume asks for the class and re-activatesfunctionalP0P1S4 Paused.
  1. Kebab → Tiếp tục học; choose class C1 (or new).
  2. Confirm.
Status Đang học; enrollment in C1 resumes from the resume date; package expiry shows the extension (original + paused days).STU-05 resume, 02 §11 pause overlapping expiryFixtures belowNot run
TS-STU-037Pausing a Waiting student is an invalid transitionnegativeP1P1S3 Waiting.
  1. Call POST /students/{S3}/status {to: paused, ...}.
HTTP 409 INVALID_TRANSITION; UI does not offer Bảo lưu for a Waiting student.02 §3 lifecycle, 02 §8 409Fixtures belowNot run
TS-STU-038Withdraw with reason shows refund estimatefunctionalP0P1S1 Active with 5 remaining sessions on FP3 (unit price 250,000).
  1. Kebab → Nghỉ học; date today; reason select "chi phí"; confirm.
All enrollments end today; status Đã nghỉ; dialog result shows "Buổi chưa dùng: 5 · Ước tính hoàn: 1.250.000 đ" (minus admin fee if policy) with link "Tạo phiếu hoàn"; churn report lists S1 with reason "chi phí".STU-06Fixtures belowNot run
TS-STU-039Withdraw reason list and free textfunctionalP1P1Withdraw dialog.
  1. Open the reason select.
Options exactly: chi phí, chuyển nhà, không hài lòng, hoàn thành mục tiêu, khác; choosing khác requires free text.STU-06Fixtures belowNot run
TS-STU-040Withdrawn student is hidden from rosters and pickersfunctionalP1P1S5 Withdrawn.
  1. Open C1 roster; open the attendance sheet of the next session; open the enrollment picker.
S5 absent from roster and sheet; picker lists S5 with chip Đã nghỉ (re-enrollment allowed) but not as default.02 §6 rule 6Fixtures belowNot run
TS-STU-041Transfer a student to another branch with package balancefunctionalP0P1As U-BM-A? (branch manager needs branch B scope; use U-OWNER). S1 at A with 5 sessions.
  1. Kebab → Chuyển chi nhánh; to Thủ Đức, effective next Monday, target class C3, note.
  2. Confirm.
A enrollment ends; a new B record exists with the same learner profile and code convention; guardians shared; balance 5 at B and 0 at A; Học phí tab at A shows entry "chuyển đi", at B "chuyển đến"; timeline entry on both profiles; API returns new_student_id.STU-07Fixtures belowNot run
TS-STU-042Academic admin cannot transfersecurityP1P1As U-ACAD-A.
  1. Look for Chuyển chi nhánh; call POST /students/{id}/transfer.
Action absent; API 403.02 §9 students.transferFixtures belowNot run
TS-STU-043Học tập tab shows FLYER datafunctionalP1P1S1 with FLYER activity in the stub.
  1. Open tab Học tập.
Sections: study time this month, assignments assigned/completed, latest scores per skill (4), placement result, latest exam entries; values match the stub /v3/parent/learner/{id}/report.STU-08Fixtures belowNot run
TS-STU-044Học tập empty stateui-uxP1P1A student whose learner has no FLYER usage.
  1. Open tab Học tập.
Exactly "Chưa có dữ liệu học tập"; no zeros rendered as fake data.STU-08 emptyFixtures belowNot run
TS-STU-045Learner deleted on FLYER sideedgeP2P1Stub returns 404 for the learner.
  1. Open the profile.
Right rail shows chip "Tài khoản đã xoá"; Học tập tab empty; the rest of the profile works.02 §11Fixtures belowNot run
TS-STU-046Teacher can view learning data only for own-class studentssecurityP2P1As U-TEACH.
  1. Open S1 Học tập tab.
  2. Call GET learner report for S7.
S1 works; S7 returns 404.02 §9 students.learning.viewFixtures belowNot run
TS-STU-047Upload a document with typefunctionalP1P1S1 profile tab Tài liệu as U-ACAD-A.
  1. Upload birth-cert.pdf (2 MB), type Giấy khai sinh.
  2. Click the file link.
Row with type, name, uploader, time; link is a signed URL that expires (opening after 15 min gives 403); the file is not reachable without the signature.STU-09, 12 §3 uploadsFixtures belowNot run
TS-STU-048Reject disallowed file types and sizenegativeP1P1Tab Tài liệu.
  1. Upload a .exe; upload a 25 MB pdf.
Errors "Định dạng không hỗ trợ (pdf, jpg, png, xlsx, docx)" and "Tối đa 20 MB".12 §3 file uploadsFixtures belowNot run
TS-STU-049Flagged note appears on roster and attendance sheet for teachersfunctionalP0P1S1 note "Dị ứng đậu phộng" flagged Cần lưu ý.
  1. As U-TEACH open the C1 attendance sheet and the class roster.
S1 row shows "Cần lưu ý: dị ứng đậu phộng"; a non-flagged staff-only note is not visible to the teacher anywhere.STU-09, 02 §6 rule 8Fixtures belowNot run
TS-STU-050Note visibility staff vs teacherssecurityP1P1A note with visibility staff on S1.
  1. As U-TEACH call GET /students/{S1}/notes.
Response excludes staff-only notes; includes flagged notes only.02 §6 rule 8Fixtures belowNot run
TS-STU-051Teacher can add notes but not edit profilesecurityP1P1As U-TEACH on S1.
  1. Add a note.
  2. Try PATCH /students/{S1} display_name.
Note saved with author and time; PATCH 403; no Sửa button.02 §9 students.edit teacher notes onlyFixtures belowNot run
TS-STU-052Anonymise a withdrawn studentfunctionalP0P1As U-OWNER on S5 (Withdrawn) with a document and a paid invoice.
  1. Kebab → Ẩn danh hoá; enter request reference "REQ-2026-001"; confirm.
Name becomes "Học viên đã xoá", phone/email of the guardian null (if not shared), documents deleted; the invoice list still shows the invoice with the anonymised name and amounts intact; audit entry student.anonymise with the reference; event student_anonymised.STU-10, 12 §4 deletionFixtures belowNot run
TS-STU-053Anonymise refused for Active student and for non-ownernegativeP1P1S1 Active; U-BM-A.
  1. As U-OWNER try on S1.
  2. As U-BM-A try on S5.
S1: action disabled with tooltip "Chỉ áp dụng cho học viên đã nghỉ"; API 409. U-BM-A: action absent; API 403.STU-10 Given, 02 §9 students.anonymise owner onlyFixtures belowNot run
TS-STU-054Student code is tenant-wide sequential and never reusedfunctionalP1P1Note the highest code.
  1. Create a student at branch A, then one at branch B.
  2. Delete nothing; anonymise one; create another.
Codes increase by one across branches; the anonymised code is not reissued.02 §6 rule 2Fixtures belowNot run
TS-STU-055Import creates students without guardians with warning chipedgeP2P1Import of a student row lacking g1_phone for a child (warning tolerated by import for age ≥ 18 only; for a child this is an error). Use an adult row without guardian and a child row with "Bỏ qua dòng lỗi".
  1. Run the import and open the list.
Adult imported without chip; a child imported only when the import explicitly allows; such a record shows chip "Thiếu phụ huynh" and the list tab filter "Thiếu phụ huynh" lists it.02 §11 import without guardiansFixtures belowNot run
TS-STU-056Student attendance tab month viewfunctionalP1P1S1 with SES-PAST marked.
  1. Open tab Điểm danh.
Month calendar with a chip per session (Có mặt green etc.), rates for 30 and 90 days, absences table (date, class, status, reason, make-up booked), button + Thêm phép.02 §5 Điểm danh tab, 04 §4Fixtures belowNot run
TS-STU-057Student Học phí tabfunctionalP1P1S1.
  1. Open tab Học phí.
Package balance card (5 / 24, expiry date), tuition list with status chips (INV-1 Chưa thanh toán, INV-4 Đã thanh toán), receipts list with PT numbers, button Tạo hoá đơn.02 §5 Học phí tabFixtures belowNot run
TS-STU-058Edit drawer prefilled and saves partial changesfunctionalP1P1S1.
  1. Click Sửa; change Địa chỉ; save.
PATCH sends only changed fields; toast "Đã lưu"; Tổng quan shows the new address; audit entry student.update with before/after.02 §8 PATCH partialFixtures belowNot run
TS-STU-059Profile page in en localei18nP2P1As U-ACAD-A in en.
  1. Open S1 profile.
Tabs Overview · Guardians · Classes & history · Attendance · Tuition · Learning · Documents · Notes · Audit log; status chip "Active"; money "9,600,000 đ" or "VND 9,600,000" consistently.12 §8Fixtures belowNot run
TS-STU-060Profile at 1024 px and 390 pxui-uxP3P1S1.
  1. View at 1024 and 390.
1024: right rail moves below the tabs or stays with no horizontal overflow. 390: header stacks; tabs scroll horizontally; console minimum notice acceptable.12 §9Fixtures belowNot run
TS-STU-061Keyboard: student list rows and actions reachablea11yP2P1/students.
  1. Tab from the search field through the table.
Focus reaches the tab bar, filters, each row link and action buttons in order; Enter opens the profile; focus ring visible.12 §9 WCAGFixtures belowNot run

Trường Số (truongso.net) · FLYER internal