Every screen of the Files module, its intent, route, composition, states, permissions,
platform behavior and events. Authoritative components in 00-shared/03 ; this file
enumerates which ones each screen uses with module specifics. Structure mirrors
design-docs/auth/05_Screen_Inventory.md.
States = idle / loading / success / empty / error(offline, rate, invalid) / disabled / permission.
Analytics follow {module}.{screen}.{action} (proposed). Auth guards are (planned)
(RBAC decorators exist on every route, guards not yet implemented).
Field Detail
Purpose List a context's files (student, fee, circular) newest-first
Source GET /api/v1/files → array createdAt desc (files.service.ts:48-50); client filters by its context key
Widgets AppListTile rows: FileTypeIcon + originalName, mimeType, size, date; trailing AppMenu
Entry context screen "Files" section; pull-to-refresh re-fetches
States loading skeleton; empty AppEmptyState; offline AppOfflineBanner; permission (403) → locked tile
Permissions file.read (files.controller.ts:44)
Row actions Download (GET /:id/download), Detail sheet, Delete (admin, file.delete)
Analytics files.list.refresh, files.list.open_detail (proposed)
Note No server pagination/filter — large tenants get full lists; client-side filter only (proposed)
Field Detail
Purpose Pick a local file → upload via multipart
Route sheet on context screen; FAB or "Attach" affordance
Source POST /api/v1/files/upload, field file (files.controller.ts:29-41)
Permissions file.upload (files.controller.ts:30)
Content picker row (system picker / camera (forward-looking)), selected-file preview card, Upload CTA
States idle → picking (system) → selected (validate) → uploading (progress, cancelled) → success/error
Cancellation client-side abort; no server cancel endpoint
Analytics files.upload.pick, files.upload.start, files.upload.success, files.upload.failure(code) (proposed)
Field Detail
Purpose Show multipart transfer progress (client-computed; no server progress API)
Widgets AppProgress + filename + size + Cancel text button
Terminal states success → tile appears; error → inline retry (POST re-send, idempotency not server-enforced — retry creates a new record)
Note Server buffers whole file in RAM; UI should treat >25 MB as risky (no cap enforced)
Field Detail
Purpose Fetch GET /:id/download and deliver bytes to OS
Permissions file.read (files.controller.ts:56)
Widgets AppProgress row/notification; cancel aborts transport, not server work
Terminal states done → open with system viewer (share intent (forward-looking)); fail → retry (no Range/resume)
Note Server sets Content-Disposition: attachment (files.controller.ts:61) — the OS decides save vs open
Field Detail
Purpose Metadata + actions for one file
Source GET /api/v1/files/:id → 404 File not found (files.service.ts:54)
Rows name, type, size, uploaded date, provider id (dev only)
Actions Download; Delete (if file.delete); Copy name
States loading, not-found (deleted elsewhere → leave list), permission
Field Detail
Purpose Confirm permanent object deletion
Source DELETE /api/v1/files/:id → { message: 'File deleted' } (files.controller.ts:66-71)
Permissions file.delete (files.controller.ts:67)
Copy destructive: "Delete file? The stored copy is removed permanently."
Terminal success → optimistic removal; 404 → already gone, remove row silently
Field Detail
Purpose Surfaced when a role lacks file.read / file.upload / file.delete
Trigger 403 from guard (planned); role lookup client-side fallback
Widgets AppEmptyState with lock icon + "Ask admin for access"
Full-screen view for image mimeTypes after download (buffer → Image.file); no server
thumbnails yet (schema fields thumbnailFileId etc. unpopulated, file.schema.ts:31-37).
AppListTile, AppMenu, AppSnackbar, AppDialog, AppEmptyState, AppSkeleton,
AppOfflineBanner, AppButton, AppBottomSheet, AppProgress, AppAvatar (sender/uploader
contexts). Module-specific: FileTypeIcon, UploadProgressCard, DownloadManagerSheet,
FileTile — defined in 07_Component_Library.md .
files.list.{refresh,open_detail}, files.detail.{open,download,delete},
files.upload.{pick,start,success,failure,cancel}, files.download.{start,success,failure,retry},
files.delete.{confirm,cancel,success}.
Upload sheet: portrait bottom sheet; landscape/tablet → centered dialog ≤ 480 dp.
File list on tablet: master-detail (list ↔ detail sheet); desktop hover row highlight.
All sheets keyboard-aware; no text fields except optional caption (planned).