Central Station / YPM-ARCHIVE-STUDENT-DETAILS-POPOUT-BY-ASSIGNMENT

Student details popout organized by assignment

archive/student-details-popout-by-assignment.md · Updated 2026-05-24
GET /api/tickets/YPM-ARCHIVE-STUDENT-DETAILS-POPOUT-BY-ASSIGNMENT

Summary

Group student work by Assignment in the View Details popout, with an at-a-glance average grade; gated on dashboard cleanup and assignments-unification landing

2Questions 0Links 0Comments 0PRs
Open questions 2 items
  1. 1 Does the current popout query return assignment data, or just raw submissions? (Bryant — quick lookup)
  2. 2 How does this interact with `released-grades-organization`? Coordinate the visual treatment of released grades across surfaces so a teacher sees the same badge/state in both views.
Spec body Markdown
# Student details popout organized by assignment

Reorganize the right-side student details popout (opened from "View details" on a student in the teacher's class view) so a student's papers are grouped by Assignment rather than presented as a flat, undifferentiated list, and surface an average released grade so the teacher gets an immediate health-check.

## Problem

When a teacher is looking at a class roster and clicks "View details" next to a student's name, a panel slides in from the right showing that student's work. Today it's a flat list of papers — every Document and Submission the student has, with no grouping or hierarchy. This isn't actually useful for the teacher: they're usually trying to answer a question like "how is this student doing on the thesis essay?" or "did they submit the daily pages this week?" — questions that are framed by *which assignment*, not by paper-as-individual-artifact.

The flat list forces the teacher to scan, remember which paper goes with which assignment, and reconstruct context the system already knows. It also offers no aggregate signal — a teacher has to click into individual submissions to assemble a sense of how the student is doing overall. With the assignments-unification work landing (`AssignmentType` + `Assignment` are now first-class), the system has the structure to organize this view properly and to compute an average grade against released submissions.

## Goals

- A teacher opening a student's details popout sees the student's work grouped by Assignment, not as a flat paper list.
- For each Assignment, the teacher can see status at a glance (in progress, submitted, graded, released) without drilling in.
- Surface an average released grade as a quick health-check at the top of the popout.
- The popout reflects the same vocabulary and hierarchy as the redesigned My Classes dashboard — Assignments are the organizing unit on both surfaces.
- Faster answers to "how is this student doing on X?" without leaving the class view.

## Non-goals

- Changing the trigger (still "View details" on a student row, still slides in from the right).
- Bulk actions across a student's assignments (regrade all, re-release all, etc.).
- Inline grading from this popout — clicking a submission still navigates to the submission view.
- Replacing the gradebook. This is a snapshot, not a spreadsheet.
- Changing student-side views. This is teacher-only.
- Cross-student comparison inside this popout. That's the dashboard's job.

## Domain notes

Entities involved:
- **Student** (the user the popout is about).
- **Course** (the class the teacher is viewing — bounds which Assignments are relevant).
- **Assignment** — instances of an AssignmentType assigned to this student in this course. The new top-level grouping inside the popout.
- **AssignmentType** — labels each Assignment (e.g., "Thesis-Driven Essay," "Daily Pages").
- **Document** — the student's working surface for a given Assignment.
- **Submission** — snapshots submitted to the teacher; possibly graded, possibly released.

The popout should scope to the course the teacher is currently viewing. A student in multiple courses should not see assignments from other courses leak into this view.

Average grade is computed client-side from released grades on that student's submissions within the course. Only released grades count toward the average — unreleased grades are not visible to the student and shouldn't appear in any teacher-facing aggregate either (consistency, avoid confusion). If no grades are released yet for the student in this course, show "No grades released yet" rather than `0` or a blank.

This spec depends on the assignments-unification refactor (so Assignments exist as first-class entities) and on the teacher My Classes dashboard cleanup (so the popout's framing matches the surface it's launched from).

## UX sketch

Today (flat list):

```
+----------------------------------+
| Jordan Rivera          [x close] |
+----------------------------------+
| Papers                           |
|   • Untitled draft   (in prog)   |
|   • Thesis essay v2  (submitted) |
|   • Daily pages 4/29 (graded)    |
|   • Daily pages 4/28 (released)  |
|   • Thesis essay     (released)  |
|   • Daily pages 4/27 (released)  |
+----------------------------------+
```

Proposed (grouped by Assignment, with average grade header):

```
+--------------------------------------------+
| Jordan Rivera                    [x close] |
| Period 1 English                           |
|                                            |
| Average grade: 84%             (released)  |
+--------------------------------------------+
| Thesis-Driven Essay                        |
|   Submitted · awaiting grade               |
|   • Thesis essay v2     (submitted)        |
|   • Thesis essay        (released)         |
+--------------------------------------------+
| Daily Pages                                |
|   3 of 5 released                          |
|   • Daily pages 4/29    (graded)           |
|   • Daily pages 4/28    (released)         |
|   • Daily pages 4/27    (released)         |
+--------------------------------------------+
| Untitled work (no assignment)              |
|   • Untitled draft      (in progress)      |
+--------------------------------------------+
```

Each Assignment section header shows the *specific* Assignment name (e.g., "Macbeth essay," not just the AssignmentType "Thesis-Driven Essay") plus a one-line status summary. Assignments are ordered chronologically by most-recent activity — the Assignment with the most recent submission or document update sits at the top of the popout, oldest at the bottom — so the teacher's attention lands first on what's currently happening with this student. Within an Assignment, the Documents and Submissions are also ordered most-recent-first. A trailing "no assignment" group catches student-owned Documents not tied to any Assignment (free writing, drafts the student started independently).

Submission state markers should be visually distinguishable so a teacher can scan status at a glance:

- **In progress** — student is still working on the Document.
- **Submitted** — submitted to the teacher, not yet graded.
- **Graded · not released** — teacher has graded but the student can't see it yet. Show the grade with a lock or other "teacher-only" cue so the teacher knows visibility status.
- **Released** — student can see the grade.
- **Not started** — Assignment exists but no Document yet.

Visual treatment of "released" specifically should mirror whatever pattern the released-grades view lands on (see open question on coordination with `released-grades-organization`).

Empty state: if the student has no Assignments in this course yet, show "No assignments yet" with a hint to assign one from the AssignmentType detail page. If the student has Assignments but no released grades, show "No grades released yet" in place of the average.

## Data model implications

No new fields or tables required for v1. The popout is a read-only view assembled from existing `Submission`, `Assignment`, and `AssignmentType` records. Documents and Submissions need to be queryable by `(student, course, assignment)` so the popout can group them; if there isn't already a clean join from Document → Assignment, engineering may need to surface that relationship (likely already present after assignments-unification).

If average-grade computation becomes expensive at scale (a teacher with 150+ students all opening popouts), a denormalized `average_released_grade` field on `Enrollment` or a similar join table could be added later. Design that as a read-replica or event-sourced aggregate — not a write-path concern for v1.

## File paths in `yawp-2.0` likely to change

Best-guess; engineering to confirm:

- `services/web-app/app/routes/app.my-classes.$courseId/components/student-details-popout.tsx` (or wherever the existing popout/panel lives — currently rendering name, email, and the flat paper list)
- The loader that hydrates the popout — needs to return data shaped as `Assignment[] → (Documents, Submissions)` rather than a flat paper list, and should join through `Assignment` so assignment context arrives with each submission
- Shared Assignment status summary component (likely reusable from the AssignmentType detail page in `teacher-my-classes-dashboard-cleanup`)
- Possibly a new or expanded query in `packages/db/` if the current query doesn't return assignment context alongside submissions

## Open questions

- [ ] Does the current popout query return assignment data, or just raw submissions? (Bryant — quick lookup)
- [ ] How does this interact with `released-grades-organization`? Coordinate the visual treatment of released grades across surfaces so a teacher sees the same badge/state in both views.

## v2 ideas (deferred)

Once v1 (Assignment grouping + average grade) lands, candidates for a richer student snapshot. Flag each one for design before pulling into v2.

- **Last active date** — when did this student last touch a Document in this course? Cheap to compute, high signal for "is this student engaged?"
- **On-time submission rate** — fraction of Assignments submitted by their due date. Useful for flagging students drifting on deadlines without opening every Assignment.
- **Paste alert count** — how many times the paste detector has fired for this student in this course. Currently broken (see `bugs/paste-alert-detection-broken.md`); gated on that fix.
- **Feedback request count** — how often this student has asked for AI feedback. Reads as engagement on the high end and over-reliance on the very high end; teachers may want to see both.
- **Revision count per Assignment** — how many drafts the student went through before submitting. Pairs naturally with `revision-flow`.
- **Time-on-document** — total active editing time per Assignment, if we track it. Helps distinguish "wrote it in 20 minutes" from "iterated for hours."
- **Trend arrow on the average** — is the student's average released grade trending up, down, or flat over the last N submissions? Cheap visualization, more informative than a single number.
- **Last teacher action** — when did *you* last grade, comment, or release for this student? Flags students who've been waiting on you.
- **Outstanding action count** — number of submitted-but-not-graded items for this student. Personal to-do for the teacher.

Don't ship all of these. Pick the two or three with highest signal-to-noise and design them deliberately so the popout doesn't become a dashboard.

## Edge cases

- Student has zero Assignments in this course → empty state.
- Student has Documents not attached to any Assignment → grouped under a "no assignment" trailing section.
- Student has an Assignment but hasn't started a Document yet → show the Assignment with a "not started" status row.
- Long assignment lists (e.g., daily pages over a semester) → each Assignment group may need internal collapsing or "show older" behavior. Decide based on density.
- Teacher opens popout for a student with 50+ submissions → the popout should be scrollable internally without affecting main page scroll.
- Submissions in an Assignment that has since been deleted or archived → still show the submission, label the assignment as "(removed)".
- Legacy submissions with no associated Assignment (predate the Assignment model) → fall into the "no assignment" trailing group.
- Student dropped from the course mid-semester → past Assignments still appear, marked appropriately.
- Multi-course students → popout shows only Assignments from the course the teacher is currently viewing.
- Average grade with a mix of numeric and letter grades → defer to v2; v1 assumes numeric grades and skips non-numeric ones in the average.

## Test plan

- Unit:
  - Assignment-grouping logic correctly partitions a student's Documents and Submissions.
  - Average-grade calculation: released-only, excludes unreleased, handles zero-grade case, handles no-released-grades case.
- Integration: loader returns submissions correctly grouped by assignment in the expected shape and order for a student with mixed assignment states.
- Manual QA:
  - Student with multiple Assignments across different AssignmentTypes — verify grouping, order, and grades.
  - Student with one Assignment and no submissions yet — verify "not started" row.
  - Student with no submissions at all — verify empty state.
  - Student with free-write Documents not tied to any Assignment — verify "no assignment" group.
  - Student with one released and one unreleased grade — verify only the released one counts toward the average.
  - Student in multiple courses — confirm scoping to the current course.
  - Verify popout scroll is independent of main page scroll.

## Rollout

Feature-flag the new layout. Pilot with UA first (highest-volume teacher — stress test for list length and average-grade computation), then Washington and Birmingham City after a week with no issues, then broader. The flat-list view stays available behind the flag during rollout in case teachers want to fall back.

## Engineering handoff checklist

- [ ] Domain context covered
- [ ] File paths in `yawp-2.0` listed
- [ ] Data model implications spelled out, including backward-compat plan
- [ ] UX sketch in prose
- [ ] Edge cases enumerated
- [ ] Test plan written
- [ ] Rollout plan decided
Repo sync Not recorded

No repo sync metadata recorded yet.