14 - QA Checklist (Houses Module)
- 1. Core flows (must pass)
- 2. Validation & conflicts (negative paths)
- 3. Reassignment & transfer semantics
- 4. Soft-delete & reference integrity (the big gap)
- 5. Multi-tenancy
- 6. UI/UX (manual + golden)
- 7. E2E regression seeds (manual fixtures)
- 8. Backend follow-ups (flagged to engineering)
Module-specific quality gates on top of 00-shared/10 (QA baseline: performance budgets, offline matrix, a11y, motion, security). Every item is testable and maps to source.
1. Core flows (must pass)
| # | Scenario | Expectation | Source |
|---|---|---|---|
| 1.1 | Create house → appears in list | POST 201; doc in GET list, createdAt order (no server sort) | houses.controller.ts:24-34, houses.service.ts:30 |
| 1.2 | Create house with only name+code | 201; color/motto absent (optional, create-house.dto.ts:13-21) | house.schema.ts:15-19 |
| 1.3 | House detail → identity fields render | name, code, color, motto round-trip verbatim (trim only) | houses.service.ts:36-40, house.schema.ts:9-19 |
| 1.4 | Update house → PATCH applies | $set full DTO; untouched fields stable | houses.service.ts:42-49, houses.controller.ts:44 |
| 1.5 | Soft delete → list excludes it | isDeleted: true filtered by scoped query | houses.service.ts:51-54, base.repository.ts |
| 1.6 | Reassign student house via PATCH /students/:id | houseId changes; student detail reflects | update-student.dto.ts:45-48, student.service.ts:142-155 |
2. Validation & conflicts (negative paths)
| # | Scenario | Expectation | Source |
|---|---|---|---|
| 2.1 | Create with duplicate code | 409 verbatim House code "X" already exists. | houses.service.ts:19-21; index house.schema.ts:23 |
| 2.2 | Create with duplicate name (different code) | Allowed (no check/index) - document as by-design; UI soft-warns | houses.service.ts:19-21 checks code only |
| 2.3 | Duplicate color across houses | Allowed - palette conflict is a UX concern, not API error | house.schema.ts:15-16 |
| 2.4 | Concurrent create of same code (race) | One 201, other → Mongo E11000 → 500 as wired today; gap: should map to 409 (planned) | house.schema.ts:23, error filter |
| 2.5 | Update code to an existing one | No service check (houses.service.ts:42-49); unique index throws → generic error; client normalizes to conflict copy (08 §3) | gap |
| 2.6 | Missing name or code | 400 (class-validator @IsString required) | create-house.dto.ts:5-11 |
| 2.7 | Invalid color (e.g. blue!) | Accepted (free string) - client must validate hex before send | create-house.dto.ts:13-16 |
| 2.8 | Unauthenticated call | 401 | houses.controller.ts:19-20 |
3. Reassignment & transfer semantics
| # | Scenario | Expectation | Source |
|---|---|---|---|
| 3.1 | Transfer student (class change) | houseId unchanged (transfer $set excludes house) | student.service.ts:185-192 |
| 3.2 | Clear a student's house | PATCH with houseId omitted/null - field optional | update-student.dto.ts:45-48 |
| 3.3 | Set house on create | houseId IsMongoId accepted | create-student.dto.ts:39-42 |
| 3.4 | houseId pointing at a deleted house | Allowed; no referential validation - students show "house unavailable"; client must render fallback | gap (09 G2) |
| 3.5 | House member count after reassignment | Changes only after refetch (client join) - expect ~ unverified count | 07 §5, 13 §4 |
4. Soft-delete & reference integrity (the big gap)
| # | Scenario | Expectation | Source |
|---|---|---|---|
| 4.1 | Delete house with members | No 409, no cascade - soft delete succeeds; students keep dangling houseId (student.schema.ts:41-42). Client warns pre-delete (07 §7); server guard (planned) | houses.service.ts:51-54 |
| 4.2 | Delete already-deleted house | 404 (scoped filter excludes deleted) | houses.service.ts:53 |
| 4.3 | Recreate house with same code after delete | Allowed (soft-deleted row excluded by scoped query) - old students still point at the deleted _id, new house gets a new _id: historical membership silently orphaned. Document + test | base.repository.ts scoped filter |
| 4.4 | Detail of deleted house via stale link | 404 → "House not found" UX | houses.service.ts:38 |
5. Multi-tenancy
| # | Scenario | Expectation | Source |
|---|---|---|---|
| 5.1 | Tenant B queries houses | sees only B's rows | base.repository.ts scoped filter (house.repository.ts:9-15) |
| 5.2 | Cross-tenant duplicate codes | allowed - uniqueness per tenant | house.schema.ts:23 |
| 5.3 | tenantId in request body | ignored - server never reads it from body | AGENTS.md |
6. UI/UX (manual + golden)
| # | Check |
|---|---|
| 6.1 | Pagination boundaries: page 1 Prev disabled; last page Next disabled (meta.hasNext/hasPrevious) |
| 6.2 | 409 inline error under Code; focus + live-region |
| 6.3 | PATCH full-set prefill: edit opens with all 4 fields filled (08 §4) |
| 6.4 | Color round-trip: swatch selected → stored hex → detail banner identical (11 §3-4) |
| 6.5 | Contrast matrix: 8 presets × light/dark × white text ≥ AA (11 §4) |
| 6.6 | Unverified count shows ~ + tooltip; verified count shows exact |
| 6.7 | Offline: cached list + banner; mutations blocked (00-shared/10 §2) |
| 6.8 | Empty states: list, detail members, search-less grid |
| 6.9 | Permission gating: read-only role sees no FAB/menu; 403 copy on deep link |
| 6.10 | Skeleton < 200 ms perceived; content < 2 s on network (00-shared/10 §1) |
| 6.11 | Delete dialog copy accurate: "members keep their house reference" (no fake cascade promise, 09 §2) |
7. E2E regression seeds (manual fixtures)
- 2 tenants, identical house codes (proves 5.2 isolation).
- House with a
#-less color value and one withcolormissing (fallback path, 11 §3). - Student assigned to a house that is then soft-deleted (4.1, 4.3 orphan check).
- 3 houses with the same name, different codes (2.2 by-design duplicates).
- Duplicate-code create race reproduced by two parallel POSTs (2.4).
8. Backend follow-ups (flagged to engineering)
| # | Item | Priority |
|---|---|---|
| 1 | Map E11000 race to 409 on create (2.4) | High |
| 2 | Duplicate-code check on update (2.5) | Medium |
| 3 | GET /students?houseId= or members endpoint (G1) | High |
| 4 | Delete guard / cascade for assigned students (G2) | High |
| 5 | sort/q on houses list (G5) | Low |
| 6 | House events + RBAC guards on endpoints (IMPLEMENTATION_PLAN.md:239 audit) | Medium |