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

12 — API Mapping (Homework Module)

Exact wire contract for every screen → endpoint. Base /api/v1; envelope per 00-shared/07. All endpoints from src/modules/homework/homework.controller.ts; business rules from homework.service.ts; attachments from files.controller.ts. Guard: @UseGuards(JwtAuthGuard) (homework.controller.ts:19) — no RBAC metadata (OQ-9). Tenant from JWT only; never in body (tenant is injected by BaseRepository, base.repository.ts:24-29).


0. Module-wide request envelope & client policy

AspectContract
Basehttps://api.<domain>/api/v1
HeadersAuthorization: Bearer <accessToken>; x-request-id; Content-Type: application/json; multipart for /files/upload
Response{success, message:"OK", data, meta?, timestamp, requestId} (response-envelope.interceptor.ts:49-52)
Error{success:false, message, error:{code, details?}, timestamp, requestId} (http-exception.filter.ts:73-81)
Paginationhomework/submissions are non-paginated arrays (no meta) — render all
Cachingclient list cache TTL 5 min; detail no cache (00-shared/06 §3.3)
Offlinereads cached; writes blocked (create/submit/grade) except attachment upload retry
Retrybackoff on 5xx/network; no auto-retry on 429 (api tier 100/min)

Screen: Homework list (teacher/student) — GET /homework/class/:classId

EndpointGET /api/v1/homework/class/:classId
ParamsclassId (MongoId)
Success200 data: [HomeworkDoc…] sorted dueDate desc (homework.repository.ts:20)
Sourcehomework.controller.ts:25-27
Errors404/400 invalid id (CastError → 400 VALIDATION_ERROR, http-exception.filter.ts:47-55); 5xx
Student variantclient resolves own classId from profile (PLAN.md:67 endpoint missing — OQ-6)
Paginationnone (full array)

HomeworkDoc shape (homework.schema.ts:8-35 + BaseSchema): _id, tenantId, teacherId, classId, subjectId, title, description?, attachments[], assignedDate, dueDate, status: 'active'|'closed', createdAt, updatedAt, isDeleted…


Screen: Homework detail — GET /homework/:id

EndpointGET /api/v1/homework/:id
Success200 data: HomeworkDoc
Errors404 RESOURCE_NOT_FOUND "Homework not found." (homework.service.ts:47)

Screen: Create homework — POST /homework

EndpointPOST /api/v1/homework (homework.controller.ts:22-24)
Body{teacherId, classId, subjectId, title, description?, attachments?: string[], dueDate} (homework.dto.ts:4-33; dueDate ISO date string)
Success201 data: HomeworkDoc — server sets assignedDate: now, status: 'active' (homework.service.ts:30-32)
Side effectemits HomeworkCreated {homeworkId, classId}in-app queue (homework.service.ts:34-41, event-queue-map.ts:22)
Errors400 VALIDATION_ERROR (decorators: IsMongoId, IsString, IsDateString); 5xx

Screen: Edit homework — PATCH /homework/:id

EndpointPATCH /api/v1/homework/:id (homework.controller.ts:31-36)
Bodyany subset of {title, description, attachments, dueDate, status} (homework.dto.ts:35-58) — classId/subjectId/teacherId immutable
Success200 data: HomeworkDoc ($set, version+1 via updateById, base.repository.ts:57-66)
Side effectemits HomeworkUpdated {homeworkId, changes[]}in-app (homework.service.ts:59-67, event-queue-map.ts:23)
Errors404 "Homework not found." (homework.service.ts:56-58); 400 invalid status enum value

Screen: Delete homework — DELETE /homework/:id

EndpointDELETE /api/v1/homework/:id (homework.controller.ts:37-39)
Success200 {message:"OK"}soft delete (homework.service.ts:70-81, base.repository.ts:68-74); submissions retained (no cascade)
Side effectemits HomeworkDeleted {homeworkId}audit-write queue (event-queue-map.ts:26)
Errors404 "Homework not found." (homework.service.ts:71-72)

Screen: Submit homework — POST /homework/:id/submit

EndpointPOST /api/v1/homework/:id/submit (homework.controller.ts:40-45)
Body{studentId, remarks?, attachments?: string[]} (submission.dto.ts:4-17)
Success201 data: SubmissionDoc — server sets submittedAt: now, status: 'submitted' (homework.service.ts:93-98)
Side effectemits HomeworkSubmitted {homeworkId, studentId, submissionId}in-app (homework.service.ts:99-110, event-queue-map.ts:24)
Errors404 "Homework not found." (homework.service.ts:87); 409 DUPLICATE_RESOURCE "Already submitted." (homework.service.ts:92) + unique index (homework-submission.schema.ts:37-40); 400
NoteNo due-date enforcement — late accepted (OQ-1)

SubmissionDoc shape (homework-submission.schema.ts:8-32): _id, tenantId, homeworkId, studentId, attachments[], remarks?, submittedAt, status: 'submitted'|'graded', gradedAt?, marks?


Screen: Submissions list (teacher) — GET /homework/:id/submissions

EndpointGET /api/v1/homework/:id/submissions (homework.controller.ts:46-48)
Success200 data: [SubmissionDoc…] insertion order (homework-submission.repository.ts:20-24)
Errors400 invalid id; 5xx

Screen: Grade submission — PATCH /homework/:id/submissions/:submissionId/grade

EndpointPATCH /api/v1/homework/:id/submissions/:submissionId/grade (homework.controller.ts:49-55)
Body{marks, remarks?} (submission.dto.ts:19-26) — marks has no validation decorator (OQ-4)
Success200 data: SubmissionDoc — sets marks, remarks, status:'graded', gradedAt: now (homework.service.ts:127-134)
Side effectemits HomeworkGraded {homeworkId, submissionId, marks}in-app (homework.service.ts:136-143, event-queue-map.ts:25)
Errors404 "Submission not found." (homework.service.ts:126); 400
Regraderepeatable — overwrites + re-emits (OQ-2)

Screen: Attachments — FilesModule

UploadPOST /api/v1/files/upload multipart file field, @Permissions('file.upload') (files.controller.ts:29-41); returns FileRecord doc (file.schema.ts:8-43) incl. _id → put id in attachments[]
DownloadGET /api/v1/files/:id/download file.read → stream (files.controller.ts:55-64)
MetaGET /api/v1/files/:id file.read (files.controller.ts:49-53)
DeleteDELETE /api/v1/files/:id file.delete (files.controller.ts:66-71) — not called by homework flows (attachment removal = homework PATCH replacing the array)
Limitsnone enforced server-side (size/mime) — client enforces (OQ-4/01)

Loading / streaming / realtime

ScreenLoadingStreamingRealtime
listAppSkeleton(planned) WS topic; re-fetch on focus
detailskeletonre-fetch on focus (grade may have landed)
create/editbutton spinner
submitbutton spinner + per-file upload progressupload stream
gradebutton spinner

Client-side error mapping table (module)

ScreencodeUI
submit409 DUPLICATE_RESOURCE"Already submitted" info state (not error)
any detail404 RESOURCE_NOT_FOUNDempty state "removed"
grade404back + refresh list
create/edit400 VALIDATION_ERRORfield-level errors
any401 → refresh → failsessionExpired
any429 RATE_LIMITEDcountdown, no retry
any5xxgeneric + requestId, retry

Optimistic / undo

  • No optimistic mutations — create/submit/grade/delete are all server-confirmed (side effects: events + notifications; 00-shared/07 §9).
  • Undo: only in-form attachment removal (local). Delete has confirm dialog, no undo (soft-delete but no restore endpoint).

Notifications surface (for the notification badge/detail)

GET /api/v1/notifications, GET /notifications/unread-count, PATCH /notifications/:id/read, PATCH /notifications/read-all (notifications.controller.ts:21-47). Homework event types are routed (event-queue-map.ts:22-25) but fail enum validation today (notification.schema.ts:7-12, inapp.worker.ts:46-53) — OQ-8; badge counts homework activity once the enum is extended.