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

01 — Product Overview (Homework Module)

StudyLyon — multi-tenant ERP / School Management API. This package designs the Homework module client (Flutter, forward-looking spec) against the implemented NestJS backend. All endpoints, DTO fields, schemas, domain events, queue routes, and wire contracts are derived directly from src/modules/homework/**, src/modules/files/**, src/modules/notifications/**, src/infrastructure/bullmq/**, src/modules/rbac/permissions.constants.ts, studylyon-blueprint/04-Modules/Homework.md, PLAN.md §6, and docs/IMPLEMENTATION_PLAN.md. No feature is invented; gaps are flagged in Assumptions & Open Questions.


1. Purpose

Homework is the assignment lifecycle: a teacher creates an assignment for one class and subject with a due date and optional file attachments; a student submits work (remarks + optional attachments) exactly once per homework; the teacher grades the submission with marks + remarks; the parent sees pending and graded homework (read-only; no parent API exists yet — OQ-5). Every state change emits a domain event that is routed over BullMQ to in-app notifications.

ResponsibilitySource
Create homework (teacherId, classId, subjectId, title, description?, attachments?, dueDate)homework.service.ts:27-43 create()
List homework for a class (sorted dueDate desc)homework.repository.ts:17-21
Get / update / soft-delete homeworkhomework.service.ts:45-81
Accept exactly-once student submission (409 on duplicate)homework.service.ts:83-112 submit()
List submissions of a homeworkhomework-submission.repository.ts:20-24
Grade a submission (marks, remarks, status→graded, gradedAt)homework.service.ts:120-145 gradeSubmission()
File attachments (upload/download/delete via FilesModule)files.controller.ts:29-71, files.service.ts:27-70
Domain events → BullMQ in-app / audit-write queuesevent-queue-map.ts:22-26, inapp.worker.ts, queue-bridge.service.ts:40-75
Multi-tenant scoping + soft-delete filtering on every querybase.repository.ts:20-30

2. Business goals

GoalMeasure
Zero lost submissionsunique index {tenantId, homeworkId, studentId} + service-level 409 (homework-submission.schema.ts:37-40, homework.service.ts:92)
Teacher grading turnaroundgraded state visible immediately after PATCH grade (homework.service.ts:127-134)
Class-level visibilityGET /homework/class/:classId scoped + sorted by due date (homework.repository.ts:19-20)
Cross-tenant isolationevery query tenant-scoped via BaseRepository.scopedFilter (base.repository.ts:24-29)
Audit trail of homework changesHomeworkUpdated/HomeworkDeleted events → audit-write queue (event-queue-map.ts:23,26)

3. User goals

  • Teacher: create a homework with a due date and attachments in seconds; see which students submitted; grade with marks + remarks and re-grade when needed.
  • Student: see pending homework for my class; submit exactly once (with optional attachment); see my marks and teacher feedback.
  • Parent (read): follow child's pending homework and grades.
  • Org admin: oversee homework activity; nothing admin-specific exists in the API (OQ-7).

4. Stakeholders

Class teachers, students, parents, subject coordinators (read), org admin, notification delivery pipeline (in-app worker), audit/compliance (event log), QA + design + engineering.

5. Why this exists

Homework is a daily, high-frequency academic workflow. The backend implements the full CRUD + submit + grade loop with strict one-submission-per-student semantics; the client must make this loop frictionless (upload progress, due-date awareness, grade feedback) without ever violating the server's invariants (no resubmission, no marks editing without a grade call).

6. Dependencies

DependencyRoleSource
Files moduleattachment upload/download/delete; file.upload/read/delete permsfiles.controller.ts:30,44,50,56,67
Storage providerobject storage behind STORAGE_PROVIDER tokenstorage-provider.ts:21-27
Notifications modulein-app notification read API for homework eventsnotifications.controller.ts:21-47
BullMQ in-app queueHomeworkCreated/Updated/Submitted/Graded → notification jobsevent-queue-map.ts:22-25
BullMQ audit-write queueHomeworkDeleted → audit log jobevent-queue-map.ts:26
Academic modulesClass, Subject, Student, Teacher referenced idshomework.schema.ts:9-16, homework-submission.schema.ts:9-13
Mongo collectionshomework, homework_submissionsblueprint 03-Database/COLLECTIONS.md:1900-1958

7. Success metrics

  • Homework creation → visible to class < 2 s (create + list round-trip).
  • Submission success rate ≥ 99.5% of attempts (excl. intended 409 duplicates).
  • Duplicate-submission 409 handled gracefully 100% of the time (never a crash/blank).
  • Graded feedback visible immediately after PATCH …/grade success.
  • Zero cross-tenant leaks in lists/details (tenant scope on every query).

8. Edge cases

  • Duplicate submission → 409 DUPLICATE_RESOURCE "Already submitted." (homework.service.ts:92) — also structurally enforced by unique index (homework-submission.schema.ts:37-40).
  • Submit to unknown homework → 404 RESOURCE_NOT_FOUND "Homework not found." (homework.service.ts:87,47).
  • Grade unknown submission → 404 "Submission not found." (homework.service.ts:126,135).
  • Update/delete unknown homework → 404 (homework.service.ts:56-58,71-72).
  • Late submission: the server does not check dueDate on submit — late submissions are accepted (OQ-1). The UI must show a late badge derived client-side.
  • Regrading: PATCH …/grade is repeatable; each call overwrites marks/remarks, resets gradedAt, and emits another HomeworkGraded (OQ-2).
  • Closed homework: status: 'closed' is settable via update (homework.dto.ts:55-58), but nothing enforces it — submit/grade still work on closed homework (OQ-3).
  • Marks validation: GradeSubmissionDto.marks has no class-validator decorator (submission.dto.ts:20-21) — negative/non-numeric values are not blocked at the DTO layer (OQ-4).
  • Delete homework: soft-delete only (base.repository.ts:68-74); submissions are not cascaded (no cascade in remove(), homework.service.ts:70-81).
  • Attachment limits: no size/mime limits in code (files.controller.ts:39, files.service.ts:27-46) — client must enforce (see 14_QA_Checklist.md).
  • Update semantics: only title, description, attachments, dueDate, status are updatable; classId/subjectId/teacherId are immutable after create (homework.dto.ts:35-58 vs 4-33).
  • findByClass sort: newest due date first (dueDate: -1, homework.repository.ts:20).

9. Assumptions (module)

  • Mobile client is forward-looking: backend is complete; this package is the UI-side spec (00-shared/12 A1).
  • "Student sees homework scoped to my class" (PLAN.md:67, 6.2) has no dedicated endpoint — the client resolves the student's classId from the Students module profile, then calls GET /homework/class/:classId (OQ-6).
  • attachments: string[] on homework and submissions are file record ids returned by POST /files/upload (files.service.ts:27-46); the blueprint's storage path sl/{tenantId}/homework/{uuid} (Homework.md:58) is plan-only — actual storage names files ${randomUUID()}--${originalname} (files.service.ts:31).
  • The blueprint's domain-event table (Homework.md:37-41: HomeworkAssigned, HomeworkSubmitted) is stale; the code emits HomeworkCreated/Updated/Deleted/ Submitted/Graded (homework.service.ts:34,59,73,99,136). Code wins.
  • Blueprint "Reminders and due alerts" (Homework.md:17) and "Overdue detection via scheduled job" (Homework.md:60) are not implemented — no scheduler/worker exists (OQ-1).
  • HomeworkCreated/Updated/Submitted/Graded are routed to the in-app queue (event-queue-map.ts:22-25), but NotificationType enum (notification.schema.ts:7-12) does not contain these values — notification persistence currently fails Mongoose enum validation; treat the in-app notification surface as (planned) until the enum is extended (OQ-8).
  • Homework endpoints are guarded only by JwtAuthGuard (homework.controller.ts:19) — no @Permissions() metadata and no homework.* permissions exist (permissions.constants.ts:1-97). Any authenticated user can call every homework endpoint today (OQ-9).

10. Open questions (module-level; global ledger in 00-shared/12)

#ItemImpact
OQ-1No due-date enforcement and no overdue scheduler exists — late/duplicate-submission-after-due are accepted silentlyLate-submission UI semantics, badge copy, future enforcement
OQ-2Grading can be repeated with no regrade guard — each call emits HomeworkGradedRegrade confirmation UX; audit noise
OQ-3status: 'closed' is not enforced anywhere"Closed" filter vs. submit/grade gating in UI
OQ-4marks has no validation decorator (submission.dto.ts:20-21)Client-side range validation only; flag to backend
OQ-5No parent-facing homework API (IMPLEMENTATION_PLAN.md:227 "parent view" is (planned))Parent persona is read-only via… nothing yet
OQ-6No GET /homework (student's own class) endpoint despite PLAN.md:67Student list resolves classId from student profile
OQ-7No admin/dashboard homework endpointsOrg admin has no homework surface beyond notifications
OQ-8NotificationType enum lacks homework event types — in-app homework notifications fail validation today (inapp.worker.ts:46-53)Notification badge/detail UX (planned)
OQ-9No RBAC on homework endpoints; no homework.* perms in ALL_PERMISSIONS (permissions.constants.ts) despite blueprint intent (Homework.md:66-71)Role-gated UI must wait for server-side perms
OQ-10No homework emails: email.worker.ts:40-42 warns "No handler" for unknown event typesEmail reminders (planned)

11. Glossary (this module)

TermMeaning
Homeworkhomework doc: assignment scoped to teacherId+classId+subjectId, dueDate, optional attachments, status active/closed
Submissionhomework_submissions doc: one per (homework, student); status submitted/graded; marks optional
Attachmentstring[] of files record ids (uploaded via FilesModule)
Gradedsubmission status after PATCH …/grade; sets marks, remarks, gradedAt
Envelope{success,message,data,meta?,timestamp,requestId} (response-envelope.interceptor.ts:49-52)
409 Duplicateexactly-once submission semantics: service check + unique index