============================================================
  Smoke test: enrollment workflow + bulk marks CSV upload
  Time: 2026-06-25T22:29:40.126Z
============================================================

[1] Student student5@school.com self-enrols in class_id=2 (Grade 2)
  student token len: 201
  HTTP 201 -> {"id":6,"uid":"96d52c5a-411f-44ce-86ff-c79ebb1573bf","student_id":10,"class_id":2,"section":"A","roll_number":null,"admission_date":"2026-06-26","academic_year":"2026","status":"inactive","created_at":"2026-06-26 00:29:40","updated_at":"2026-06-26 00:29:40","last_synced_at":null,"sync_status":"pending","is_deleted":0,"request_status":"pending","requested_at":"2026-06-25T22:29:40.424Z","approved_by":null,"approved_at":null,"rejection_reason":null}
  PASS: request_status=pending, status=inactive

[2] Admin GET /api/enrollments/pending
  HTTP 200, 1 rows
  PASS: enrollment 6 visible to admin

[3] Admin POST /api/enrollments/:id/approve
  HTTP 200 -> {"id":6,"uid":"96d52c5a-411f-44ce-86ff-c79ebb1573bf","student_id":10,"class_id":2,"section":"A","roll_number":null,"admission_date":"2026-06-26","academic_year":"2026","status":"active","created_at":"2026-06-26 00:29:40","updated_at":"2026-06-26 00:29:40","last_synced_at":null,"sync_status":"pending","is_deleted":0,"request_status":"approved","requested_at":"2026-06-25T22:29:40.424Z","approved_by":2,"approved_at":"2026-06-26 00:29:40","rejection_reason":null}
  PASS: request_status=approved, approved_by=2

[4] Teacher uploads evidence/valid.csv (3 rows, all valid)
  HTTP 200 -> {"inserted":3,"updated":0,"errors":[],"total_rows":3}
  PASS: inserted=3, updated=0, errors=[]

[5] Teacher uploads evidence/mixed.csv (4 rows: 2 valid, 2 invalid)
  HTTP 200 -> {"inserted":1,"updated":1,"errors":[{"row":4,"reason":"score is not numeric: not_a_number","data":{"assignment_id":"1","student_id":"10","score":"not_a_number","feedback":"Bad"}},{"row":5,"reason":"score 150 exceeds assignment.max_score 100","data":{"assignment_id":"2","student_id":"7","score":"150","feedback":"Score too high"}}],"total_rows":4}
  PASS: inserted=1, updated=1, errors=2 [score is not numeric: not_a_number | score 150 exceeds assignment.max_score 100]

[6] Student attempts POST /api/marks/bulk (should be 403)
  HTTP 403 -> {"error":"Admin or Teacher access required"}
  PASS: student correctly blocked from /marks/bulk

[7] GET /api/marks?assignment_id=1
  HTTP 200, 2 rows
  PASS: returned 2 submission rows for assignment 1

============================================================
SMOKE: PASS
============================================================
