Every screen of the Transport module, its intent, route, composition, states and
permissions. Authoritative components in 00-shared/03 ; this file enumerates
which ones each screen uses with module specifics. Format mirrors auth/05 .
States = idle / loading / success / empty / error(offline, 409 conflict, 404, 401) /
disabled / permission. Analytics events follow {module}.{screen}.{action}
(proposed; SDK open - 00-shared/10 §8).
Field Detail
Purpose Hub: counts + quick entry to vehicles, drivers, routes, assignment
Source GET /transport/vehicles, GET /transport/routes, GET /transport/drivers (page=1, limit=1 cheapest) - transport.controller.ts:36-40, 66-70, 96-100; totals from meta.totalItems (transport.service.ts:75, 146, 215)
Widgets 3 AppCard stat tiles (vehicles / routes / drivers) + AppListTile shortcuts + FAB "Assign student"
States per-tile skeleton -> counts; error -> AppErrorState per tile
Permissions transport.vehicle.read + transport.route.read + transport.driver.read; tile hidden when permission missing (permissions.constants.ts:62-74)
Analytics transport.overview.open (proposed)
Field Detail
Source GET /transport/vehicles?page&limit (defaults 1, 20), sorted by plateNumber asc (transport.controller.ts:36-40, transport.service.ts:61-76)
Widgets AppListTile per vehicle (plateNumber, model, capacity, status AppBadge), pagination footer, FAB "New vehicle"
Row action tap -> detail; AppMenu -> Edit / Delete (confirm)
Empty "No vehicles yet" + CTA create
Permissions list = transport.vehicle.read; FAB/menu = .create / .update / .delete
Analytics transport.vehicles.list (proposed)
Field Detail
Source GET /transport/vehicles/:id (transport.controller.ts:42-46); 404 -> AppErrorState
Content plateNumber, model, capacity, type (bus/van/car), status, year, color, insuranceExpiry, notes - vehicle.schema.ts:21-46
Actions Edit (.update), Delete with dependency guard (.delete); if route references vehicle -> 409 message + navigate to routes (transport.service.ts:94-99)
Field Detail
Source GET /transport/drivers?page&limit, sorted by firstName (transport.controller.ts:96-100, transport.service.ts:201-216)
Widgets AppListTile (full name, licenseNumber, phone, status badge: active/inactive/on_leave), pagination, FAB "New driver"
Row action detail; menu -> Edit / Delete
Empty "No drivers yet"
Permissions transport.driver.* (permissions.constants.ts:70-73)
Field Detail
Source GET /transport/drivers/:id (transport.controller.ts:102-106)
Content firstName, lastName, licenseNumber, phone, email, status, licenseExpiry, address, emergencyContact, joinedAt, notes - driver.schema.ts:15-46
Delete guard 409 when route references driver (transport.service.ts:241-246)
Field Detail
Source GET /transport/routes?page&limit, sorted by name (transport.controller.ts:66-70, transport.service.ts:132-147)
Widgets AppListTile (name, startPoint -> endPoint, stop count, status badge), pagination, FAB "New route"
Row action detail; menu -> Edit / Delete
Empty "No routes yet"
Permissions transport.route.* (permissions.constants.ts:66-69)
Field Detail
Source GET /transport/routes/:id (transport.controller.ts:72-76)
Content name, startPoint, endPoint, ordered stops list, vehicle + driver refs (names when resolved; ids are raw ObjectIds in payload - route.schema.ts:26-30), status, estimatedDuration, notes
Actions Edit (route editor), Delete (409 if assignments exist, transport.service.ts:168-171), "Assign students" shortcut
Field Detail
Purpose Create/update route incl. ordered stop list
Form name*, startPoint*, endPoint*, stops (reorderable {name, order} list), vehicleId picker, driverId picker, estimatedDuration, notes - create-route.dto.ts:21-60
Stops ReorderableListView; order field is client-set, sent as array of {name, order} (route.schema.ts:23-24)
Conflicts 409 duplicate name on create (transport.service.ts:113-116); on update name change to existing -> 409 (unique index route.schema.ts:44)
Permissions create = .route.create, update = .route.update
Field Detail
Purpose Create a route assignment for one student
Source POST /transport/assign (transport.controller.ts:120-124) with AssignRouteDto (assign-route.dto.ts:4-26)
Form route picker, student picker, shift (morning/evening/both), optional stopName, notes
Conflicts 409 "Student already assigned to this route" (transport.service.ts:252-258) - inline, offer "view existing"
Note student picker filtered to transportRequired students when available (student.schema.ts:53-54)
Field Detail
Source GET /transport/assignments/:studentId - assignments with populated route (transport.controller.ts:126-130, route-assignment.repository.ts:20-24)
Widgets AppListTile per assignment (route name, shift badge, stopName, status), delete via DELETE /transport/assignments/:id (transport.controller.ts:132-136)
Empty "No route assigned" + CTA assign
Permissions transport.assign (read context) or transport.route.read
Map of vehicles with routes + live positions. No backend surface
(IMPLEMENTATION_PLAN.md:229).
Boarding list per route/shift with QR scan (forward-looking).
Fee calculation per route/student (IMPLEMENTATION_PLAN.md:229).
AppTextField, AppButton, AppSnackbar, AppCard, AppListTile, AppBottomSheet,
AppDialog, AppMenu, AppSkeleton, AppEmptyState, AppOfflineBanner, AppFAB,
AppChips, AppBadge, AppAvatar, AppErrorState, AppPagination. Module-specific:
RouteStopEditor (reorderable stops), AssignmentShiftPicker, StatTile - defined
in 07_Component_Library.md .
transport.overview.open, transport.vehicles.{list,open,create,update,delete},
transport.drivers.{list,open,create,update,delete},
transport.routes.{list,open,create,update,delete},
transport.assign.{submit,duplicate,success},
transport.assignments.{list,remove} (all proposed).
Forms: keyboard-avoidance + scroll; tablet/desktop constrained width
(00-shared/05 §2).
Route stop editor: full-width on phone; two-column stop list + preview on tablet.
Lists: master-detail on tablet; desktop hover row highlights.