Skip to main content

courses

Courses, rosters, enrollment, groups, grades, and their assignments and problems.

πŸ“„οΈGet a course's activity feed

Returns a paginated activity feed for one course: course/assignment/problem/ submission activity plus member logins. Course-content activity by admins (even if not enrolled) and enrolled staff (Faculty/TA) shows any time (so an admin creating or editing a problem before the term is included), while other members' content and all member logins are clipped to the course's start/end dates. Admin logins are never shown (only their course edits). Staff-only to read (see access gate below).

πŸ“„οΈDuplicate an assignment

Duplicate an assignment within the same course. The title/description come from the request; the type (groupSetId), audience (AssignmentAssignee), schedule, and date exceptions (AssignmentOverride) are copied verbatim from the source and are editable afterward. The copy is always created unpublished. Submissions and grades are never copied. Problems are handled by `problemMode`: - none : the copy has no problems. - link : the copy shares the source's Problem records (editing one edits both). - duplicate : each problem is copied to a new Problem (with its own solution file).

πŸ“„οΈBatch set/clear a student's problem grades for an assignment

Batch-saves this student's problem grades for the assignment in a single request; the write counterpart to the GET above (co-located as the same resource). The body maps problemId β†’ grade (a number within [0, maxPoints], or null to clear). Course staff (faculty or TAs) or a system admin. Only problems whose grade actually changed are written: a null for a graded problem deletes it, a number upserts it (existing feedback is left untouched), and unchanged problems are skipped. Every applied change is audited with its previous value, mirroring the single-problem grade route.

πŸ“„οΈGet a student's review data for an assignment

Assembles the grading/review view for one student on one assignment: their submissions (grouped by problem, with evaluation output), the comments about them, and their per-problem grades. Falls back gracefully if the optional `evaluationRaw` column is absent. Access: the student themselves, course staff, or a system admin (`studentId` must be the caller's id unless they are course staff or a system admin). Course membership is also required, except for global admins.

πŸ“„οΈImport an assignment from another course

Imports an assignment from ANOTHER course the caller can manage into this course. Unlike duplicate, audience, group set, and date exceptions are not carried across (they reference records scoped to the source course); the import always lands as an unpublished, individual, assigned-to-everyone assignment. The schedule (due date, available-from, late settings) is copied from the source as a starting point and is editable afterward. Problems are handled by `problemMode`: - none : the imported assignment has no problems. - copy : each problem is copied into THIS course (a new Problem with its own solution file); there is no 'link' mode because problems are course-scoped. Permission is tiered: the wrapper gates the destination course (manage), and the caller must also be able to manage the source course.

πŸ“„οΈDuplicate a course

Creates a new course modeled on an existing one, in a single transaction. The copy's faculty comes from the copied faculty roster and/or an explicit `instructorIds` list; at least one faculty member is required (the caller is NOT added automatically). TAs are copied only when asked. `copyMode` (or the legacy copyAssignments/copyProblems booleans) selects what carries over: assignments only, problems only, or assignments with their problems. The copy always starts unpublished with a fresh registration code. System administrators only. Dates are interpreted in the actor's timezone.

πŸ“„οΈBulk change group-set memberships

Atomically assigns, moves, and removes students within a group set. Each operation sets one student's group (or removes them when groupId is null). A move is a single upsert on the (set, student) unique key, so a student is never transiently in two groups. Assign/move targets must be active STUDENTs; removals are allowed even for inactive members. When expectedBasis is provided and no longer matches the set's current memberships, the change is rejected with 409 so a stale client cannot silently overwrite another staff member's edit. Blocked when the set is locked. Course staff or admin.

πŸ“„οΈImport a problem from another course

Imports a problem from ANOTHER course the caller can manage into this course. The title/description come from the request; the type, state cap, determinism flag, and the solution file (answer key) are copied from the source. The solution file is copied to a fresh name on disk so the two problems never share a file. Permission is tiered: the wrapper gates the destination course (manage), and the caller must also be able to manage the source course.

πŸ“„οΈReset a student's password (course staff)

Course-staff password reset for a student on the roster. This is a stop-gap for small deployments so course staff can help a student who is locked out, without a system administrator. Permission is tiered: the wrapper admits course FACULTY and TAs (and global admins); this handler additionally requires the target to be a STUDENT enrolled in THIS course. It refuses to reset a staff member, a global administrator, or anyone not on this roster, so it can never be used to seize a privileged account. System-wide resets stay on the admin User Accounts page. Not blocked on an archived course: a student may still need to sign in to review past work, and the reset touches the user account, not course content.

πŸ“„οΈDrop or re-enroll a student

Drop or re-enroll a student in a course. A DROPPED student keeps their roster row and all their work (submissions, grades, group membership, audience/override rows) but loses access: `canAccessCourse` denies them, so they can't see or interact with the course, and it disappears from their own lists. Staff review surfaces still show them, marked 'Dropped'. Re-enrolling flips them back to ENROLLED and restores everything. This is distinct from removal (`DELETE .../roster/[userId]`): removal is a hard delete for a student with no work; drop is the reversible action for a student who has work. Only a global admin or a course FACULTY member may do it (TAs may not, matching the other roster mutations), and it applies only to STUDENT rows.

πŸ“„οΈDelete a course

Deletes a course (system admin only). An **empty** course (no assignments, no problems, no student enrollments, and no submissions) is removed permanently (its staff-only roster cascades away; audit logs keep a nulled course pointer). Any course that holds real work or students is **soft-deleted** instead: the row and all its data are retained but `deletedAt` is stamped so the access gates and list queries treat it as gone (recoverable later). The response says which happened via `{ deleted: 'hard' | 'soft' }`.