Skip to content

Show a student which class each text belongs to - #1235

Merged
mircealungu merged 3 commits into
masterfrom
wt/class-attribution
Aug 31, 2026
Merged

mircealungu merged 3 commits into
masterfrom
wt/class-attribution

Conversation

@mircealungu

Copy link
Copy Markdown
Member

Needs zeeguu/api#719 deployed first. Without it from_classes is absent and the tag simply doesn't render.

Why

Our pilot teacher joined a second class and asked whether he had to delete his enrolment in the first one to see its texts. He didn't — but the app never told him that, because the classroom is a merged list with no provenance. A student with two classes sees one pile and can't tell whose lesson is whose.

What

Each text carries its class as a tag in the metadata strip:

War Near Cyprus Stops People Coming for Holidays
CUT Language Centre · LCE 103 · example.com · ~5min

Suppressed for the 2,484 students who have exactly one class and would otherwise see the same answer on every row. Only 18 students are in two classes, so this is deliberately invisible to almost everyone.

Note for review: ArticlePreview renders two layouts — the interactive card and the preview/headlines teaser — and each has its own MetaStrip. The tags are built once beside the other tag slots (savedTag, publishedTimeSlot) rather than inside either branch. I put them in the previewMode strip first, which is a silent no-op for the classroom feed, since interactive defaults to true and that branch is never taken there. Worth knowing before adding anything else to those strips.

Also: telling the teacher what their class hides

The class Texts tab now says when the class holds texts in a language its students aren't learning:

3 texts here are not in English — 2 in Danish, 1 in Greek. Your students only ever see the texts in the language they are learning, so nobody in this class can open them.

7 classes are in that state today, holding 32 texts, affecting 54 students (none active since June). The teacher is the only person who can fix it — a student's only "fix" would be to abandon the language they chose — so the count goes to them rather than into the student's feed.

Verified

Both variants in the browser: tags render for a multi-class student, suppressed for a single-class one; the teacher warning renders with a realistic mix.

48 tests, build clean.

A student in more than one class gets one merged classroom list, and until now
it was a pile of texts with no way to tell whose lesson was whose. Each text
now carries its class as a tag in the metadata strip, suppressed for the 2,484
students who have exactly one class and would see the same answer on every row.

ArticlePreview renders two layouts and both have their own MetaStrip, so the
tags are built once next to the other tag slots rather than inside either
branch. Putting them in only one is a silent no-op for the classroom, which is
exactly what happened first time.

The class page also tells the teacher when it holds texts in a language its
students are not learning -- those texts are invisible to the whole class, and
the teacher is the only person who can do anything about it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@netlify

netlify Bot commented Aug 31, 2026

Copy link
Copy Markdown

Deploy Preview for voluble-nougat-015dd1 ready!

Name Link
🔨 Latest commit 81b029e
🔍 Latest deploy log https://app.netlify.com/projects/voluble-nougat-015dd1/deploys/6a955ba54adcfb000899f342
😎 Deploy Preview https://deploy-preview-1235--voluble-nougat-015dd1.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Review follow-ups.

- `cohort.language` is null for a class whose language was never set, and every
  language then failed the "is this off-language?" test, so the banner claimed
  the whole list was unreachable and left a hole in its own sentence where the
  language name should be. Both halves were false: the student filter compares
  the *article's* language to the *student's* learned language and never
  consults the class's. Six such classes exist; none holds a text yet, which is
  the only reason this was not already visible.

- The classroom waited for getStudent before choosing an empty-state message
  but not before rendering the list, so the class tags -- which need to know
  whether the student has more than one class -- rendered absent and then
  appeared when that request landed. It waits in both paths now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mircealungu

Copy link
Copy Markdown
Member Author

Two review fixes pushed (586e725), plus one behaviour change I should have called out in the description.

A class with no language warned that all its texts were hidden. cohort.language is null when a class's language was never set, so every language failed the off-language test and the banner claimed the whole list was unreachable — with a hole in the sentence where the language name belongs. Both halves were false: the student filter compares the article's language to the student's learned language and never consults the class's. Six such classes exist; none holds a text yet, which is the only reason it wasn't already visible.

The class tags popped in a beat late. The classroom waited for getStudent before choosing an empty-state message, but not before rendering the list — and the tags need to know whether the student has more than one class. It waits in both paths now.

Behaviour change worth knowing (zeeguu/api#719): a text shared with two of a student's classes used to be appended once per class and therefore rendered twice. It now appears once, tagged with both class names. That's the better behaviour and there's a test for it, but it changes what an existing student sees and arrived as a side effect of adding attribution rather than as a stated goal.

The cohort id is a number in every payload now (api#719), but useParams()
always hands back a string, so the two places that matched one against the
other were relying on the API's odd stringification to work at all.

Adds the regression this closes: a class shared during a session (ids from
/cohorts_info) and the same class after a reload (ids from /teacher_texts)
used to build two separate filter chips.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@mircealungu
mircealungu merged commit fdd3979 into master Aug 31, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant