Trường Số QA/11 Data model, API and imports
Trường Số · QA test suite · Phase 1 · 10/09/2026
11 · Data model, API and imports
Test cases for PRD 11. 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
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.jsonandruns/run-1/, and every result field is stillnot_run. - Cases inherit any open question or inconsistency in the PRDs they trace to.
1Summary
P0
6
P1
16
P2
5
P3
0
| Type | functional | ui-ux | edge | negative | regression | flow | a11y | perf | security | i18n |
|---|---|---|---|---|---|---|---|---|---|---|
| Count | 17 | 0 | 0 | 2 | 1 | 1 | 0 | 1 | 3 | 2 |
2Test cases
| ID | Title | Type | Priority | Phase | Preconditions | Steps | Expected result | PRD trace | Data needed | Run 1 |
|---|---|---|---|---|---|---|---|---|---|---|
| TS-DAT-001 | List endpoints paginate with the standard envelope | functional | P1 | P1 | API session. |
| Response ListResponse with pagination {limit, page, prev_page, next_page, total_pages, total_count}; limit above 200 clamped or rejected (400). | 11 §1 envelopes, 12 §2 limit ≤ 200 | Fixtures below | Not run |
| TS-DAT-002 | Error envelope and domain codes | functional | P1 | P1 | API. |
| Each returns ErrorRespone {code, message, details} with the documented code and HTTP 409 (202 for PENDING_APPROVAL). | 11 §1 errors | Fixtures below | Not run |
| TS-DAT-003 | X-Locale header changes API labels | i18n | P1 | P1 | API. |
| Labels Vietnamese then English; error messages likewise. | 11 §1 auth header, 12 §8 | Fixtures below | Not run |
| TS-DAT-004 | Cross-tenant ids return 404 on every new /v3/school endpoint | security | P0 | P1 | Two tenants; ids from the other tenant. |
| 404 for every one; never 200 or 403; no data leak in the body. | 12 §3 authorisation, test seed 00/10 | Fixtures below | Not run |
| TS-DAT-005 | Tenant is resolved from the token, not from client ids | security | P0 | P1 | API as U-ACAD-A. |
| Branch B: 403 (out of scope); other tenant: 404; nothing created. | 12 §3 | Fixtures below | Not run |
| TS-DAT-006 | Jobs pattern for long operations | functional | P2 | P1 | API. |
| Status pending → running (progress %) → done with result or error report; UI never blocks. | 11 §1 jobs | Fixtures below | Not run |
| TS-DAT-007 | Domain events published for writes | functional | P2 | P1 | Event stub log. |
| Events student.status_changed, attendance.saved, payment.recorded appear with tenant_id and ids; messaging and aggregates consume them (message row / dashboard tile updates). | 11 §1 events | Fixtures below | Not run |
| TS-DAT-008 | Import templates per entity download with allowed values | functional | P0 | P1 | As U-OWNER /crm/imports (or /settings/data). |
| xlsx with the VI header row exactly per PRD 11 (Mã HV, Họ tên, Ngày sinh, Giới tính, Chi nhánh, Trạng thái, Trình độ, Trường, Địa chỉ, PH1 họ tên, PH1 SĐT, PH1 quan hệ, PH1 email, PH1 Zalo đồng ý, PH2 ..., Tài khoản FLYER, Ghi chú), one example row, hidden sheet with enums and branch codes. | 11 §4 templates | Fixtures below | Not run |
| TS-DAT-009 | Column mapping auto-maps by header and allows remap | functional | P1 | P1 | A students file with one renamed header. |
| Known headers auto-mapped; the renamed column listed as unmapped with a manual select; custom fields offered for students. | 11 §4 wizard | Fixtures below | Not run |
| TS-DAT-010 | Validation preview with errors, warnings, error file, skip toggle | functional | P0 | P1 | Students file: 10 rows, 2 invalid phones, 1 missing birthday, 1 unknown level. |
| Counts: 3 errors (phones and birthday), 1 warning (level created as custom); download error file lists row numbers and reasons; "Bỏ qua dòng lỗi" toggle enables commit of 7 rows. | 11 §4 validation preview | Fixtures below | Not run |
| TS-DAT-011 | Phone normalisation rules | functional | P1 | P1 | File with phones "0901234567", "+84 901 234 567", "84901234567", "12345". |
| First three normalise to +84901234567 (and warn about duplicates); "12345" is an error for a guardian. | 11 §4 data quality | Fixtures below | Not run |
| TS-DAT-012 | Date parsing: dd/MM/yyyy, yyyy-MM-dd and Excel serial | functional | P1 | P1 | File with birthdays "15/03/2018", "2018-03-15", serial 43174. |
| All three become 2018-03-15. | 11 §4 dates | Fixtures below | Not run |
| TS-DAT-013 | Names trimmed and double spaces collapsed, casing preserved | functional | P2 | P1 | Name " nguyễn Văn A ". |
| Stored "nguyễn Văn A". | 11 §4 names | Fixtures below | Not run |
| TS-DAT-014 | Missing branch code offers create for owner only | functional | P1 | P1 | File with branch code "BD" (missing). |
| Owner: prompt "Tạo chi nhánh BD?"; academic admin: error row only. | 11 §4 branch codes | Fixtures below | Not run |
| TS-DAT-015 | Dedupe strategies for students: skip, merge, overwrite | functional | P0 | P1 | File containing S1 (same code) with a new address and a second guardian. |
| Skip: S1 untouched. Merge: address filled only if blank, second guardian added, existing fields kept. Overwrite: fields replaced. Guardians merged by phone in all modes. | 11 §4 dedupe | Fixtures below | Not run |
| TS-DAT-016 | Commit runs as a job with progress and result tabs | functional | P1 | P1 | Valid file 200 rows. |
| Progress bar; success/failed counts; detail page with Thành công and Lỗi tabs; cancel available while pending. | 11 §4 commit | Fixtures below | Not run |
| TS-DAT-017 | Rollback within 24 h when unmodified | functional | P1 | P1 | Completed import. |
| First: created rows deleted, merged rows kept with audit note. Second: refused "Có bản ghi đã được sửa sau khi nhập". | 11 §4 rollback | Fixtures below | Not run |
| TS-DAT-018 | Full import order on Empty Center | flow | P0 | P1 | Tenant EMPTY; fixture files for steps 1–8. |
| Each step succeeds referencing the previous (teacher by phone, room by name, class by code); classes generate sessions from max(start_date, import date) with earlier sessions held; enrollments with capacity warnings not blocked; opening balances create packages with sessions_total = remaining flagged is_opening and a tuition "Số dư đầu kỳ" for debt; attendance history creates sheets marked by "Import". | 11 §4 import order | Fixtures below | Not run |
| TS-DAT-019 | Classes import pattern parsing | functional | P1 | P1 | Pattern "T3 18:00-19:30; T5 18:00-19:30" and an invalid "Thứ ba 6h". |
| First parses into two weekday rows; second is an error with the row number. | 11 §4 step 4 | Fixtures below | Not run |
| TS-DAT-020 | Opening balance requires at least one of sessions or debt | negative | P1 | P1 | Row with only student code. |
| Error "Cần Buổi còn lại hoặc Còn nợ". | 11 §4 step 7 | Fixtures below | Not run |
| TS-DAT-021 | Attendance history requires an existing session | negative | P1 | P1 | Row for a class date with no session. |
| Error "Không có buổi học ngày dd/MM cho lớp X". | 11 §4 step 8 | Fixtures below | Not run |
| TS-DAT-022 | Import of 5,000 rows validates within 60 s asynchronously | perf | P1 | P1 | 5,000-row students file. |
| Completes ≤ 60 s; UI responsive during processing; progress shown. | 12 §2 import | Fixtures below | Not run |
| TS-DAT-023 | Import permissions by role | security | P1 | P1 | U-BM-A, U-ACC, U-ACAD-A, U-TEACH. |
| BM: all entities; ACC: finance (balances) only; ACAD: students, classes, enrollments; teacher: no access. | 10 §9 settings.data | Fixtures below | Not run |
| TS-DAT-024 | Leads import unchanged | regression | P1 | P1 | Leads file. |
| Works as before with dedupe, round-robin assignment and error report. | 11 §4 bulk-customers existing | Fixtures below | Not run |
| TS-DAT-025 | Identifier formats | functional | P1 | P1 | Seed data. |
| HV-000123; MOV-2609-01; PT-Q1-202609-0001; PC-Q1-202609-0001; invoice code = payment_code. | 11 §5 identifiers | Fixtures below | Not run |
| TS-DAT-026 | Retention job anonymises stale leads | functional | P2 | P1 | Lead with last activity 25 months ago; nightly job trigger. |
| Lead name/phone anonymised; audit entry; leads with recent activity untouched. | 11 §5 leads retention, 12 §4 | Fixtures below | Not run |
| TS-DAT-027 | Import wizard in en locale | i18n | P2 | P1 | en. |
| Steps and messages English; template headers stay Vietnamese (documented) with English key row if provided. | 12 §8 | Fixtures below | Not run |
Trường Số (truongso.net) · FLYER internal