Every screen of the Homework module, its intent, route, composition, states,
permissions, platform behavior, and events. Authoritative components in 00-shared/03 ;
module components in 07_Component_Library.md . Analytics events follow
{module}.{screen}.{action} (proposed).
States = idle / loading / success / empty / error(offline, 404, 409, network) / disabled / permission.
Role gating is client-side UI policy (server has no homework RBAC — OQ-9).
Field Detail
Purpose Browse homework of one class, sorted by due date desc (homework.repository.ts:20)
Entry Homework tab; role-default class preselected; returns to after detail/edit
Exit → detail; → create; → edit; class switch
Inputs Class filter AppDropdown (from Academics module), AppSearchBar (client-side filter; no q param on API)
Composition Class selector header + AppSectionHeader ("Due soon" / "Past due" client groups) + homework cards + AppFAB "New homework" (teacher)
States loading AppSkeleton(list); empty AppEmptyState ("No homework for this class"); error AppErrorState (404 class invalid → "Class not found"); offline cached + banner
Source GET /api/v1/homework/class/:classId → array (non-paginated; no meta — client renders all)
Row actions AppMenu: Edit, Delete (teacher/admin); student: none
Analytics homework.list.open, homework.list.filter_class, homework.list.search
Adaptive phone full-width cards; tablet/desktop 2-col grid + master-detail detail pane
a11y row semantics button, card label = title + subject + due; FAB labeled "New homework"
Field Detail
Purpose Pending/assigned homework for the student's class
Entry Homework tab (student)
Differences from #1 Class fixed = student profile classId (Students module); no FAB; no edit/delete; card shows my submission state chip (none/submitted/graded+marks)
My-state source GET /homework/:id/submissions filtered client-side by my studentId — per-card fetch only for visible cards (proposed: server flag); OQ-6
States as #1; plus "Submitted" chip state
Analytics homework.list.open, homework.student.view
Field Detail
Purpose Full homework: title, subject, class, description, attachments, due date, status, assigned date; role-shaped actions
Source GET /homework/:id → 404 RESOURCE_NOT_FOUND "Homework not found." (homework.service.ts:47)
Composition Header (title + subject chip + status badge), meta block (class, teacher, assignedDate, dueDate via AppInfoRow), AppMarkdownViewer description, AppAttachmentList (download/preview), role-actions: teacher → Edit/Delete menu + "Submissions (N)"; student → Submit CTA or submission/grade block; parent → read-only
Student block if no submission: AppButton "Submit"; if submitted: status chip + submittedAt; if graded: marks + remarks + gradedAt
States loading skeleton; 404 empty state ("This homework was removed"); offline banner
Analytics homework.detail.open
Adaptive master-detail right pane ≥ 840 dp
Field Detail
Purpose Create (POST /homework) or edit (PATCH /homework/:id)
Fields title (req), description (opt), class (req, create only — immutable after), subject (req, create only), dueDate (req), attachments (opt), status (edit only: active/closed) — exact fields CreateHomeworkDto / UpdateHomeworkDto (homework.dto.ts:4-58)
Exit success → detail; back → draft prompt (create)
States validation per 08_Form_Specifications.md ; 400 field errors; 5xx kept-form
Analytics homework.create.submit, homework.create.success, homework.edit.submit
Field Detail
Purpose One-time student submission: remarks + optional attachments
Source POST /homework/:id/submit (SubmitHomeworkDto — submission.dto.ts:4-17)
Precondition no existing submission for (studentId, homeworkId) — server 409 guard (homework.service.ts:88-92)
Composition remarks AppTextField (multiline), AppAttachmentUploader (file.upload), Submit button
States uploading (progress per file), submitting (button spinner), success → detail "Submitted"; 409 → "Already submitted" info state (navigates to detail); 404 → removed
Analytics homework.submit.start, homework.submit.success, homework.submit.duplicate
Field Detail
Purpose All submissions of one homework for grading
Source GET /homework/:id/submissions → array (non-paginated)
Composition AppSectionHeader "N submitted"; rows: student name, submittedAt, status chip (submitted/graded), marks badge if graded, attachment icons, late badge (client-computed)
Row action tap → grading sheet (graded rows open read-only w/ regrade path)
States loading; empty (AppEmptyState "No submissions yet"); 404
Analytics homework.submissions.open, homework.submissions.grade_open
Field Detail
Purpose Grade one submission: marks + remarks
Source PATCH /homework/:id/submissions/:submissionId/grade (GradeSubmissionDto — submission.dto.ts:19-26)
Composition student header, submittedAt, attachment previews, marks AppTextField (numeric, client-validated ≥ 0 — OQ-4), remarks field, "Grade" button; regrade mode shows existing grade + overwrite warning
States grading (button spinner); 404 "Submission not found."; 400 (client validation); success → row updated + snackbar
Analytics homework.grade.submit, homework.grade.regrade
Field Detail
Purpose Show marks + teacher remarks to the student
Source from GET /homework/:id/submissions (own row) or the submit response
Composition success-mark card (marks, tabular figures), AppMarkdownViewer remarks, gradedAt/submittedAt, attachments
Analytics homework.feedback.view
Field Detail
Purpose Preview or download homework/submission attachments
Source GET /files/:id/download → stream with Content-Disposition (files.controller.ts:55-64); requires file.read
Behavior PDF/image → in-app viewer; other types → share sheet/external app; long-press menu (Save, Share)
States downloading (progress), error (404 file removed)
AppListTile, AppCard, AppButton, AppTextField, AppDropdown, AppDatePicker,
AppMarkdownViewer, AppAttachmentTile, AppBadge, AppChips, AppMenu, AppDialog,
AppBottomSheet, AppSkeleton, AppEmptyState, AppErrorState, AppOfflineBanner,
AppFAB, AppSnackbar, AppSectionHeader, AppInfoRow. Module-specific:
HomeworkCard, SubmissionRow, LateBadge, AttachmentUploader, GradeSheetBody,
SubmissionStatusChip — defined in 07_Component_Library.md .
homework.list.{open,filter_class,search}, homework.create.{submit,success,failed},
homework.detail.open, homework.edit.{submit,success}, homework.delete.{confirm,success},
homework.submit.{start,success,duplicate,failed}, homework.grade.{open,submit,regrade},
homework.feedback.view, homework.attachment.{preview,download,failed}.
Forms: keyboard-avoidance + scroll; Enter submits single-field steps.
Grade sheet on desktop: full-width split — submissions list left, grade form right.
List: 2-column at ≥ 600 dp; 3-column ≥ 1200 dp.