feat(assignments): Full assignment management system#265
Conversation
…m into lib/features
fix(auth): persist and return user role on signup
…orts Each feature under lib/features/ now exposes a public surface via index.ts so routes import from `$lib/features/<feature>` instead of deep component paths. Covered: admin, auth, channel, legal, playground, student, workspace. Routes using chat/avatar barrels (already existing) also migrated off direct component paths (Messages, PairedResponses, SettingsModal).
Scans requirements*.txt and ui/package-lock.json against the OSV database on manifest changes and weekly. Detection-only: findings land in the Security tab without blocking merges.
Replace Black with Ruff (format + lint) across pre-commit, CI, and requirements. Ruff config lives in pyproject.toml with E/F/I rules. Cleanup of the 103 pre-existing lint findings: unsorted/unused imports auto-fixed, SQLAlchemy boolean filters converted to .is_() (the E712 autofix would have broken the queries), test asserts switched to 'is True/False', one dead mock binding removed. Full pytest suite passes (210 tests).
'vitest --passWithNoTests' enters watch mode outside CI (GitHub Actions sets CI=true, which is why CI never hung) and leaks worker processes locally — 'make test' never returned. Use 'vitest run' explicitly; watch mode stays available via test:watch.
- CONTRIBUTING: English-only, required local setup (pre-commit + commit-msg hook), Make targets table, and the mandatory feature workflow (issue -> architecture -> TDD -> docs -> PR) - Issue/PR templates: required Architecture section (OpenWebUI-first, DDD boundary, API contract, test plan) and matching PR checklist - AGENTS.md: Known Pitfalls, graduated proof standards, change-detector test anti-patterns, git discipline, feature workflow - SECURITY.md: private vulnerability reporting via GitHub advisories - Normalize end-of-file newlines flagged by pre-commit across remaining files; repo links point to the canonical Open-TutorAi org
- Teacher space: sidebar, navbar, dashboard with quick actions - Student detail page: header, stats, parents/guardians tab - Invite modal: form triggered by button click - Guardian backend: ORM model, repository, service, 4 REST endpoints - Fix: teacher signup now correctly redirects to /teacher - Tests: 9 passing tests for guardian endpoints
- Classroom & enrollment management (create, enroll students by email) - Assignment CRUD with file attachments (PDF, images, etc.) - Student submission with text answer and/or file attachment - Teacher grading modal with score, feedback, and student attachment download - Per-student status tracker: submitted / late / returned / missed / not_submitted - Student assignments list with tabs (To Do / Submitted / Late / Missed) - Enrolled students now display full name + email instead of UUID - Protected file download via fetch + Authorization Bearer header - API docs in docs/assignments.md
- Display full student name (from enrolled list) in submissions table, status tracker, and grade modal instead of truncated UUID - Change "Return Grade" button from emerald to indigo to match app palette - Update getClassroomStudents type to include name and email fields
Replace old screenshots with new captures that reflect: - Student full name (Lucas Dupont) in submissions table, status tracker, and grade modal - "Return Grade" button in indigo instead of green
…ubmission
Teacher:
- PUT /api/v1/assignments/{id} — edit title, instructions, due date, max score
- DELETE /api/v1/assignments/{id} — delete assignment + all its submissions
- DELETE /api/v1/classrooms/{id}/students/{student_id} — unenroll a student
- Edit modal on assignment detail page (pencil button in header)
- Delete button in header with confirmation dialog
- Remove button (user-minus icon) next to each enrolled student
Student:
- DELETE /api/v1/assignments/{id}/my-submission — cancel own submission
- "Cancel Submission" button shown when submission exists and not yet graded
…mission New captures showing all new features: - teacher-assignment-detail: Edit + Delete buttons in header - teacher-edit-modal: edit assignment form - classroom-students: remove student button per row - student-submit: Cancel Submission + Update Submission buttons
|
Documentation Review — Assignments Feature Hi @BOUKAR-Nadia! 👋 I've reviewed both documentation files. Overall good work, but there are some issues to fix: assignments.mdMissing endpoints (present in your changelog, absent from the table):
Path mismatch with your own changelog (please confirm which one is correct):
assignments-user-guide.mdMissing sections:
Screenshots issue:Screenshots are in SummaryPlease fix these issues before I can approve the PR. Let me know if you need any clarification! 🚀 |
| onMount(async () => { | ||
| try { | ||
| [assignment, submission] = await Promise.all([ | ||
| getAssignment(localStorage.token, assignmentId), |
There was a problem hiding this comment.
Hi 👋,BOUKAR-Nadia
[HIGH – CWE-523 / OWASP A02] Authentication tokens are currently stored in localStorage throughout the Svelte application.
Storing sensitive tokens in localStorage exposes them to any JavaScript running in the browser. In the event of an XSS vulnerability, compromised third-party script, or malicious browser extension, the token could be extracted and used to gain unauthorized API access.
Recommendation: Store authentication tokens in HttpOnly, Secure, and SameSite=Strict cookies managed by the server. This prevents client-side JavaScript from accessing the token and significantly reduces the impact of XSS attacks. Remove all frontend references to localStorage for authentication data.
|
Security Review Thank you for this contribution. The assignment management system is a significant addition to the platform and covers the complete workflow from classroom management and assignment creation to submission tracking and grading. While reviewing the implementation from a security perspective, I identified a few concerns that should be considered before merging or releasing this feature: Critical Findings1. Missing Authorization Checks (CWE-862 / OWASP A01)GET /guardians/student/{student_id} exposes guardian PII (name, email, relationship) without verifying whether the authenticated user is authorized to access data for the requested student. Risk: Any authenticated user can enumerate guardian information for unrelated students. Recommendation : Enforce object-level authorization and verify that the caller owns the resource or has a legitimate administrative/teaching relationship with the student. 2. IDOR Vulnerabilities (CWE-639 / OWASP A01) Endpoints using guardian_id (/contact, /resend) retrieve or modify resources directly from user-controlled identifiers without validating ownership or authorization. Risk: Unauthorized disclosure of guardian data and abuse of email invitation functionality. Recommendation: Implement resource ownership validation before returning data or performing actions.High Severity Findings3. Missing Authorization Re-Validation (CWE-285) Assignment operations rely on enrollment checks performed during listing but do not consistently re-validate authorization during subsequent actions. Risk: Users may continue interacting with assignments after losing access rights. Recommendation: Perform authorization checks on every state-changing operation (submit, cancel_submission, etc.). 4. Authentication Token Stored in localStorage (CWE-922) Frontend authentication relies on localStorage.token. Risk: Any XSS vulnerability or malicious third-party script can exfiltrate authentication tokens and fully compromise user accounts. Recommendation: Store session tokens in HttpOnly, Secure, SameSite=Strict cookies and implement short-lived access tokens with rotating refresh tokens. Thanks again for the contribution. These improvements would significantly strengthen the security of the project and help prevent common access control and authorization issues. Feel free to reach out if you have any questions about the findings or need assistance implementing the recommended fixes. I'd be happy to help review the changes so that the pull request can move forward toward a successful merge. |
|
Hi, |
…fied-ai-context-spec chore: add unified AI agent context and shared skills workflow & CI pipelines fix
Database schemas
docs: add current and target backend architecture sequence diagrams
Merge upstream/main into assignments branch. Kept all assignment management features (classrooms, guardians, assignments routers) while integrating upstream's refactored imports, api_routes, and UI fixes.
65ea445 to
2f1b7e0
Compare
…and screenshots
- Teachers can paste external URLs (Google Drive, Docs, YouTube, etc.)
when creating or editing an assignment, in addition to uploading files
- Students can paste external URLs when submitting work
- External links open in a new tab ("Open Link" button); internal file
URLs continue to download with auth ("Download Attachment" button)
- Fix: 204 No Content response on cancel submission no longer throws
JSON.parse error
- Fix: Overview tab now activates automatically after editing, so the
updated attachment link is immediately visible
- Docs: update assignments.md with all endpoints (PUT, DELETE, cancel)
and attachment_url semantics; update user guide with URL link steps
and cancel/unenroll instructions
- Screenshots: replace all captures with fresh ones showing the new
URL fields, Open Link buttons, and student link display
Merge upstream import style refactor (split router imports into one block per router) while keeping Guardian, Classroom, and Assignment models and routers added by the assignments feature branch.
- PUT /api/v1/classrooms/{id} to update name, subject, description
- DELETE /api/v1/classrooms/{id} to permanently delete a classroom
- Frontend: edit modal pre-filled and delete confirmation modal
- Fix apiFetch to handle 204 No Content responses
What does this PR do?
This PR adds a complete assignment management system for OpenTutorAI:
submitted,late,returned,missed, ornot_submitted.Why is this needed?
The platform had no structured way for teachers to assign work and for students to hand it in. This feature closes that gap with a complete end-to-end submission and grading loop integrated into both the teacher and student portals.
How to test?
Setup
python -m uvicorn --factory gateway.http.app:create_app --host 0.0.0.0 --port 8080cd ui && npm run devTeacher flow
Student flow
user) → go to Assignments → see the assignment in the To Do tab.Late submission
Screenshots
Teacher — Assignments list

Teacher — New Assignment modal with file upload and URL link field

Teacher — Assignment detail (Overview tab with Open Link button)

Teacher — Edit assignment modal with attachment link field

Teacher — Grade modal showing student's link ("Open student's link")

Teacher — Classroom with enrolled students and remove button

Student — My Assignments (tabs)

Student — Submission form: teacher's Open Link + student's submitted link

Student — Returned grade with score and feedback

Checklist
maindocs/assignments.md(API reference) anddocs/assignments-user-guide.md(user guide)featChangelog Entry
Added
DELETE /api/v1/classrooms/{id}/students/{student_id})PUT /api/v1/assignments/{id}), delete (DELETE /api/v1/assignments/{id})POST /api/v1/assignments/{id}/submit)DELETE /api/v1/assignments/{id}/my-submission)POST /api/v1/assignments/{id}/submissions/{sub_id}/grade)GET /api/v1/assignments/{id}/status)GET /api/v1/users/lookup?email=)docs/assignments.mddocs/assignments-user-guide.mdChanged
nameandemailalongsidestudent_idfetch()+Authorization: Bearerheaderattachment_urlnow accepts both internal file URLs and any external URLFixed
<a href>)Breaking Changes
Additional Information
assignmentsfrom forkBOUKAR-Nadia/open-tutor-ai-CE