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

03 — User Journeys (Homework Module)

End-to-end journeys computed from homework.controller.ts, homework.service.ts, files.controller.ts, event-queue-map.ts and PLAN.md §6.1–6.5. Each journey: entry, intent, decision points, system responses, loading, failures, recovery, exit, abandonment, offline. (planned) / (forward-looking) marks per global rules.


1. Teacher creates homework with attachment (PLAN.md 6.1)

entry: Homework tab → FAB "New homework"; intent: assign work to a class
sequenceDiagram
    actor T as Teacher
    participant F as CreateFormScreen
    participant R as HomeworkRepository (client)
    participant FILE as POST /files/upload
    participant API as POST /api/v1/homework
    participant Q as BullMQ in-app queue
    T->>F: class, subject, title, description, dueDate, attach file
    F->>FILE: multipart upload (progress %)
    FILE-->>F: file record {_id, originalName, size, mimeType} (files.service.ts:27-46)
    F->>R: submit {teacherId, classId, subjectId, title, description?, attachments:[_id], dueDate}
    R->>API: POST /api/v1/homework (envelope data = homework doc)
    API-->>R: 201 homework doc (status 'active', assignedDate now)
    API->>Q: HomeworkCreated {homeworkId, classId} (homework.service.ts:34-41)
    R-->>F: success → navigate detail
    F-->>T: "Homework assigned" snackbar
  • Decision point: due date picker min = today (client-side; server only validates IsDateString, homework.dto.ts:31-32).
  • Attachments: upload first via FilesModule, then reference _id in attachments[]. Upload is a separate request — a failure mid-upload must not create the homework.
  • Failure: 400 VALIDATION_ERROR (missing title/dueDate/MongoIds, homework.dto.ts:4-33) → field errors; 5xx → AppErrorState + retry (form state kept).
  • Exit: success → detail screen; abandonment → draft resume (client memo, (proposed)).
  • Offline: creation blocked (write queue not defined for homework create), attachment upload queued with retry per 00-shared/07 §10.

2. Student views my-class homework (PLAN.md 6.2)

entry: Homework tab; intent: see what's due and my submission status
sequenceDiagram
    actor S as Student
    participant P as Student profile (Students module)
    participant L as HomeworkListScreen
    participant API as GET /api/v1/homework/class/:classId
    S->>L: open Homework tab
    L->>P: my classId (cached profile)
    L->>API: GET /homework/class/{classId}
    API-->>L: data[] sorted dueDate desc (homework.repository.ts:20)
    L-->>S: cards: title, subject, due date, status badge, my submission state
  • No dedicated student endpoint — classId resolution from the profile is the OQ-6 workaround (PLAN.md:67 lists GET /api/v1/homework as intended; not implemented).
  • Per-card my-state: client cross-checks against GET /homework/:id/submissions (only feasible for a single homework; full per-student state is (planned) — OQ-6).
  • Failure: 404 → AppEmptyState; 5xx → AppErrorState + retry; pull-to-refresh.
  • Loading: AppSkeleton(list); cache TTL 5 min (volatile — due dates change).

3. Student submits homework (PLAN.md 6.3)

entry: homework detail → "Submit" (only if not already submitted)
sequenceDiagram
    actor S as Student
    participant D as HomeworkDetailScreen
    participant R as HomeworkRepository
    participant FILE as POST /files/upload
    participant API as POST /api/v1/homework/:id/submit
    S->>D: open homework detail, compose remarks + attach file
    D->>FILE: upload (progress, retryable)
    FILE-->>D: file record id
    D->>R: submit {studentId, remarks?, attachments?}
    R->>API: POST /api/v1/homework/{id}/submit
    API-->>R: 201 submission doc {status:'submitted', submittedAt now} (homework.service.ts:93-98)
    API->>Q: HomeworkSubmitted {homeworkId, studentId, submissionId} (homework.service.ts:99-110)
    R-->>D: success → detail shows "Submitted" state
    D-->>S: "Submitted" confirmation + lightImpact
  • Exactly-once: double-tap / retry → second call returns 409 DUPLICATE_RESOURCE "Already submitted." (homework.service.ts:92) — client maps to "Already submitted" info state, not an error.
  • Submit button disabled permanently after success (server truth; no optimistic write — the doc id comes from the server, 00-shared/07 §9).
  • Failure: 404 homework deleted meanwhile → RESOURCE_NOT_FOUND empty state; network loss mid-upload → upload pending/retry, no silent corruption (10 §2).
  • Offline: submit blocked; guidance + draft kept locally (offline queue (planned)).

4. Teacher grades + feedback (PLAN.md 6.4)

entry: homework detail → "Submissions" tab → tap student row → grade sheet
sequenceDiagram
    actor T as Teacher
    participant G as GradingSheetScreen
    participant R as HomeworkRepository
    participant API as PATCH /api/v1/homework/:id/submissions/:submissionId/grade
    T->>G: open submission, view attachments + remarks
    G->>R: grade {marks, remarks?}
    R->>API: PATCH …/grade
    API-->>R: 200 updated submission {status:'graded', gradedAt, marks, remarks}
    API->>Q: HomeworkGraded {homeworkId, submissionId, marks} (homework.service.ts:136-143)
    R-->>G: row flips to "Graded" (marks visible)
    G-->>T: snackbar "Graded" + advance to next ungraded row (proposed)
  • Regrade: grading an already-graded submission overwrites and emits another HomeworkGraded (OQ-2) — confirm dialog on regrade ("This will overwrite the existing grade").
  • Validation: client enforces marks ≥ 0 and ≤ max marks (configurable; server has no decorator — submission.dto.ts:20-21, OQ-4).
  • Failure: 404 "Submission not found." (homework.service.ts:126) → row refresh; network loss → grade sheet keeps typed values, retry offered.
  • No optimistic grading (side effect + notification event): server-confirmed only.

5. Edit / delete homework (PLAN.md 6.5)

entry: homework detail → menu → Edit / Delete
sequenceDiagram
    actor T as Teacher
    participant D as HomeworkDetailScreen
    participant API as PATCH /api/v1/homework/:id | DELETE
    T->>D: Edit → form prefilled (title, description, attachments, dueDate, status)
    D->>API: PATCH /homework/{id} (only title, description, attachments, dueDate, status)
    API-->>D: 200 updated doc; HomeworkUpdated {homeworkId, changes[]} → in-app (event-queue-map.ts:23)
    T->>D: Delete → confirm dialog
    D->>API: DELETE /homework/{id}
    API-->>D: 200 {message:"OK"}; HomeworkDeleted → audit-write queue (event-queue-map.ts:26)
    D-->>T: back to list; removed row (server-confirmed, no optimistic delete)
  • Immutable fields: classId, subjectId, teacherId are not in UpdateHomeworkDto (homework.dto.ts:35-58) — form disables them after create.
  • Delete is soft (base.repository.ts:68-74); GET /homework/class/:classId will no longer return it (isDeleted filter). Submissions are not deleted (no cascade, OQ-1/01).
  • Failure: 404 if already removed (refresh list); offline → blocked.

6. Late submission handling

entry: student submits after dueDate (server allows — OQ-1)
  • Server accepts late submissions; submittedAt is server-set (homework.service.ts:96).
  • Client derives isLate = submittedAt > dueDate after the response and shows a tertiary badge "Late · 2d" on the submission row (no server flag exists — the badge is client-computed, (forward-looking) pending a server isLate field).
  • Grading sheet highlights late rows (AppBadge warning) so the teacher can apply policy.
  • Open question (OQ-1): when the overdue scheduler lands (Homework.md:60), late-rejection or late-marking becomes server-authoritative — client must render whatever the server returns, never block submission client-side.

7. Parent sees pending / grade (read-only)

entry: notification deep link (planned) or child's device — no parent API today (OQ-5)
  • (planned) GET /homework/class/:classId read-only + GET /homework/:id/submissions for the child's row (parent → student linkage lives in the Students module).
  • Today: parent sees homework activity only through in-app notifications (planned — OQ-8); deep link studylyon://homework/:id (00-shared/05 §4).

8. Cross-cutting

EntryBehaviorStatus
Deep link studylyon://homework/:idopens detail (role-gated actions)(forward-looking) client
Push "homework graded"opens grade feedback(planned) push infra (00-shared/12 B3)
Notification → homeworkHomeworkGraded etc. become in-app notifications(planned) — enum gap OQ-8

Abandonment & exit rules: create form → back = draft prompt; grade sheet → back keeps typed values until dismissed; offline → list from cache + banner; permission denial (role-gated UI) → controls hidden, not errors.