09 - User Behaviour (Transport Module)
- 1. Defaults
- 2. Read behaviour
- 3. Conflict behaviour (users hit these constantly)
- 4. Deletion mental model
- 5. Status lifecycle expectations
- 6. Search expectations (gap)
- 7. Multi-tenant behaviour
- 8. Permission-aware behaviour
Behaviour patterns, defaults and expectations for transport users. Wherever server behaviour constrains UX, the source is cited and the client adapts.
1. Defaults
| Context | Default | Source |
|---|---|---|
| List page size | 20, page 1 | transport.controller.ts:38, 68, 98 |
| List sort | vehicles plateNumber asc; routes name asc; drivers firstName asc | transport.service.ts:71, 142, 211 |
| Vehicle status on create | active | vehicle.schema.ts:33-34 |
| Driver status on create | active | driver.schema.ts:30-31 |
| Route status on create | active | route.schema.ts:32-33 |
| Assignment status | active; assignedAt = now | route-assignment.schema.ts:23-28, transport.service.ts:264 |
| Assignment stops | [] | route.schema.ts:23-24 |
| New-entity nav | -> detail screen | conventional |
2. Read behaviour
- List -> detail: taps on rows; users expect full info on detail. ObjectId
refs (
route.schema.ts:26-30) arrive unresolved - users expect vehicle plate / driver name, so the client resolves via cached list data or fetch; show "Not assigned" when absent (never raw ObjectId). - Pagination: users page rather than scroll infinitely (00-shared/01);
footer shows
metaposition (transport.service.ts:75). - Refresh: pull-to-refresh re-fetches; sorted server-side - client never re-sorts.
3. Conflict behaviour (users hit these constantly)
- Duplicate plate on vehicle create - user corrects plate; expects inline
error, not a dialog (
transport.service.ts:38-45). - Duplicate license/phone on driver create - two independent uniqueness
rules (
driver.schema.ts:50-51); error must say WHICH field conflicted (transport.service.ts:177-190). - Duplicate route name - rename or accept 409 (
transport.service.ts:113-116). - Student already on route - user intent is usually "change shift or stop"
(schema allows a second assignment for a different route - uniqueness is per
route+student,
route-assignment.schema.ts:42-45); the assign sheet must offer "View existing / edit instead" (06 §11). - Delete blocked by reference - users understand dependencies; dialog
explains "vehicle is assigned to a route" and navigates to the blocker
(
transport.service.ts:94-99, 168-171, 241-246).
4. Deletion mental model
- Deletes are soft (
base.repository.ts:68-74) - nothing is permanently gone; list queries exclude deleted (isDeleted: false,base.repository.ts:20-30). UI copy: "Remove" not "Delete forever". - A removed vehicle/driver/route reappears only via re-create (no restore endpoint exists - gap).
5. Status lifecycle expectations
- Vehicle:
active -> maintenance -> activeis the common loop (vehicle.schema.ts:13-17); maintenance vehicles should be prevented from new route assignment client-side (no server check - QA item 14 §3). - Driver:
active -> on_leave -> active(driver.schema.ts:7-11); expired license warning is client-side heuristic (no server validation oflicenseExpiry). - Assignment: no status-flip endpoint exists (
route-assignment.schema.ts:23-28has the field;DELETE /assignments/:idis the only mutation) - UI offers Remove only; "mark inactive" is(planned).
6. Search expectations (gap)
- Users will type to filter lists (plate, name, phone). Backend lists accept
only
page/limit(transport.controller.ts:36-40, 66-70, 96-100). Client: local filter of loaded pages + clear hint; server-side search is(planned)(flagged in 01 §5).
7. Multi-tenant behaviour
- Every document is tenant-scoped and never user-controlled
(
base.repository.ts:20-36;AGENTS.mdconventions) - no tenant picker, no cross-tenant results, ever.
8. Permission-aware behaviour
- Surfaces gate on
transport.vehicle.*,transport.route.*,transport.driver.*,transport.assign(permissions.constants.ts:62-74). - Read-only roles see lists/detail, no FAB/menu actions; 403 -> permission copy, never "error" (06 §0).