09 — User Behaviour (Files Module)
- 1. Uploading
- 2. Downloading
- 3. Managing the list
- 4. Permissions
- 5. Offline & flaky networks
- 6. Trust & safety posture (UI copy guidance)
Behavioral expectations and patterns for file handling, derived from the server's actual semantics (buffered upload/download, no limits, no TTL). Global behavior baselines: 00-shared/08_Interaction_&_Motion, 00-shared/09_Accessibility_Baseline.
1. Uploading
- One file at a time. Server accepts a single
filepart (FileInterceptor('file'),files.controller.ts:31). Multi-file = repeated POSTs; UI queues sequential uploads(proposed). - Immediate feedback. After picking, users expect: preview (name/type/size), progress, then the tile appearing in list. Progress must be client-computed (transport-level); the server exposes no progress API.
- Retry mindset. A failed POST re-sends the whole body (no idempotency key, no multipart resume). Users accept this for ≤ 25 MB; for larger files warn first (08_Form_Specifications.md §1.3).
- No replace. Users cannot overwrite a file — delete + re-upload (no
file.update). UI must make this visible before they try.
2. Downloading
- Attachment-first. Server always responds
Content-Disposition: attachment(files.controller.ts:61), so "open" on mobile really means "download then open". Do not promise in-place preview of PDFs without a local save step. - Buffered = slow-feeling. The whole object round-trips through the API memory
(
files.service.ts:62); large files show a long "connecting" phase. Show indeterminate progress until first bytes. - No resume. Interrupted downloads restart from zero (no
Rangeheaders served). Cancel is client-side only. - Trust the mimeType… carefully. The
Content-Typeheader is the client-suppliedmimeTypeechoed back (files.controller.ts:60). A spoofed type will mislabel the file in the OS. UI should render the icon from the same field (consistent, even if wrong).
3. Managing the list
- Newest first is the server order (
files.service.ts:48-50) — matches expectation of "just uploaded appears on top". - Context grouping is client-side. Users think files belong to a fee record or student; the server doesn't know. If a module links files to entities, it must maintain that linkage itself (local index, 13_State_Management.md).
- Deletion is permanent. Stored copy is hard-deleted at provider
(
files.service.ts:68); metadata soft-deleted. No undo, no restore endpoint — confirm dialog must say so.
4. Permissions
- Users without
file.readsee no files; withoutfile.uploadno Attach control; withoutfile.deleteno delete action. Role mapping is the only signal today (guards(planned)— roles come from RBAC,permissions.constants.ts:86-88).
5. Offline & flaky networks
- Upload/download failures: inline retry; never silently drop. Offline: banner + disabled
actions, outbox queue
(forward-looking). - Signed-URL expiry UX
(planned): if a direct provider URL 403s (expired TTL), client re-requests a fresh URL — never show the raw 403.
6. Trust & safety posture (UI copy guidance)
- Warn on large uploads and on downloads > 25 MB.
- On download of unknown types (
application/octet-streamor unusual mime), show "Open with caution"(proposed)— server does no scanning. - No TTL exists today: files persist until deleted (global 3-day retention tier is
(planned),IMPLEMENTATION_PLAN.md:176).