Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

09 — User Behaviour (Leave Module)

Observed and expected user behaviours around leave, mapped to what the API actually enforces. Behaviors are (proposed) product expectations unless cited to source; metrics are analytics (proposed).


1. Requesting leave

  • Frequency: teachers request a few times per term (sick + planned); admins configure once. High-trust, low-frequency writes.
  • Pre-request ritual: users check balance first (GET /leave/balance) because approval is balance-gated (leave.service.ts:188-189) — the client should surface balance inline on the request form (proposed) to collapse this step.
  • Date planning: users plan around weekends; the server counts them (leave.service.ts:310-312) — expect mismatch complaints; the request form shows the inclusive count up front (06 §2.4).
  • Overlap behavior: users may file overlapping pending requests (e.g., sick leave on top of planned leave). No server rule rejects this (gap — createRequest leave.service.ts:126-156 has no overlap check); a client warning on submit is the mitigation (proposed).

2. Checking balance

  • Cadence: before each request; after each approval (deduction is live-computed, leave.service.ts:87-88 — always fresh).
  • Mental model: users think "12 days/year" and forget carry-forward; the card must visually separate daysPerYear | carriedForward | daysUsed | daysRemaining (:66-74).
  • Year boundary: balance resets per calendar year with prev-year carry (:92-97,107-112) — Jan behavior surprises users; caption it.

3. Approving (org admin)

  • Ritual: open queue, skim reasons, decide fast; self-approval is impossible (leave.service.ts:179-180) — admins delegate to a peer.
  • Balance surprise: approval of a request that exceeds balance 409s (:188-189); admin's mental model must be "reject or wait" — the UI offers reject-with-note as the fallback action.
  • Double-decision: second decision 409s (:175-178) — UI refreshes and greys the row.
  • Batch desire: admins want batch approve (proposed) — no server support (one PATCH per id, leave.controller.ts:49-53).

4. Substituting (substitute teacher)

  • Discovery: substitute checks "My Substitutions" (GET /leave/substitutions/teacher/:id, leave.controller.ts:79-83); no push today ((planned) notification, IMPLEMENTATION_PLAN.md:163).
  • Conflict avoidance: server rejects clashes at assign time (leave.service.ts:241-250); substitutes rely on admin accuracy — no accept/decline loop exists (gap).
  • No-show tracking: completed/cancelled states are schema-only (substitution.schema.ts:7-11); behavior tracking is (planned) via Timetable integration.

5. Reading the calendar

  • Use: planning coverage, checking who is out before scheduling meetings — calendar is approved-only (leave.service.ts:290) and tenant-wide.

6. Behavioural expectations (proposed)

ExpectationDesign response
Users distrust stale balancebalance always refetched on screen open; RefreshIndicator; caption "live"
Fast approvalApprovals queue default filter pending; approve = 1 tap, reject = 2 taps max
Requesters check status oftenstatus chips on list; (planned) push on decision event (events/leave-events.ts:10-18)
Admins never re-decideafter decision, row leaves pending view
Substitutes plan morningssubstitutions sorted by date asc (leave.service.ts:275-280), grouped by day

7. Metrics (proposed)

leave.request.submit → decision time (median/P90); balance-check → submit conversion; approval → substitution assignment rate; clash-rejection rate (signal of poor coverage planning); reject-with-"insufficient balance" rate (gap indicator for request-form balance preview).