# PR 3 — File Attachments Student + Parent Side — Final Review

**VERDICT: PASS**

## Branch

`feature/file-attachments-views` branched from `f02f0a1` (dev at the time of PR 2 merge). One feature commit lands the entire PR 3.

## Scope

### New files (4)

| File | Purpose |
|---|---|
| `client/src/pages/student/Resources.tsx` | Student course resources — read-only mirror of teacher Resources, 4 tabs (Syllabus / Test Papers / Homework Sheets / Past Exam Papers) with download + inline preview |
| `client/src/pages/student/Homework.tsx` | Student homework — read-only list with Submit / View Detail / Marked Script surfacing; status tabs (To Do / Submitted / Graded / Overdue) |
| `client/src/pages/student/Tests.tsx` | Student tests — same shape with `test_date` + `duration_minutes` fields and marked-script surfacing |
| `client/src/pages/parent/Resources.tsx` | Per-child resources viewer with child switcher; reads /users/children then mirrors student Resources |

### Modified (6)

| File | Purpose |
|---|---|
| `client/src/App.tsx` | Routes for /homework, /tests, /resources (student) and /parent-resources |
| `client/src/components/Nav.tsx` | Nav entries: student gets Homework / Tests / Course Resources; parent gets Course Resources |
| `client/src/pages/dashboard/StudentDashboard.tsx` | Plan §6.4 callout: "N marked scripts available" when student has any returned submission, links to /assignments |
| `client/src/pages/student/Assignments.tsx` | "View Marked Script" button on completed tab when `submission.status === 'returned'`; inline modal with iframe (PDF) / img (image) / Open + Download actions; `status` field added to `AssignmentSubmission` type |
| `client/src/pages/parent/AcademicProgress.tsx` | Plan §7.1: "Marked Scripts" section above the bento stats; lists the teacher's returned marked scripts for the selected child with Preview + Download |
| `client/src/store/assignments.ts` | `AssignmentSubmission.status` + `attachments[]` types added so the marked-script modal can match by submission id |
| `server/src/controllers/attachments.controller.js` | Plan §7.3 RBAC widening: privileged readers (admin / principal / systems_admin) see all marked scripts; parents see marked scripts and submissions for their own children via a JOIN on `parent_students`; `parent` role added to `UPLOAD_ROLES` per PR 1 code-review follow-up |

## Verification (orchestrator)

- `npm install` on both server and client (fresh worktree)
- `cd server && npm run db:init` clean (PR 1 + PR 2 schema already in place, idempotent)
- `cd client && npm run build` — production build green:
  ```
  ✓ built in 14.95s
  PWA v0.19.8
  precache  19 entries (5057.21 KiB)
  files generated
    dist/sw.js
    dist/workbox-*.js
  ```
  5,057 KiB precache (+49 KiB vs PR 2).
- Server boot detached via `Start-Process node`; `/api/health` → 200.
- Smoke (PowerShell `Invoke-RestMethod`):
  - `POST /api/auth/login` (teacher + student) → JWT
  - `GET /api/attachments?parent_kind=subject` as teacher → 200, `[]`
  - `GET /api/attachments?parent_kind=marked_script` as teacher → 200, `[]`
  - `GET /api/assignments/my/submissions` as student → 200, `[]`

Server is healthy on `http://localhost:3001`.

## Out of scope (deferred)

These are tracked from PR 1 / PR 2 code-review notes and aren't blocking:

- HMAC-signed `/api/uploads` (replaces the open static mount — security)
- Magic-byte MIME sniff on upload (defense in depth)
- Soft-delete cleanup service for orphaned files on disk
- Offline-write protection in `client/src/store/api.ts` to skip `/attachments` on the network-down POST path
- `attachments.uploaded_at` vs the `created_at` column convention (sync engine merge code falls back to `created_at`; consider renaming or adding `updated_at`)
- Bulk ZIP download of all course materials
- "Download my submission" round-trip (still uses base64 in Zustand state; v1 follows the marked-script pattern but the data path needs server-side join work that's a hardening pass)

## Next step

The orchestrator takes this back to the user with: "PR 3 is green on `feature/file-attachments-views`. Ready to merge to `dev` and push."

VERDICT: PASS
