CLUE-550: auto-generate a class-wide Driving Question Board per unit - #2890
CLUE-550: auto-generate a class-wide Driving Question Board per unit#2890lbondaryk wants to merge 4 commits into
Conversation
Add a class-wide shared document (the Driving Question Board) that is auto-created once per (class, unit) when group documents are enabled. It is editable by every class member, appears in Sort Work under "No Group"/"No Name", and its title is authorable on the Document Settings page (default "Driving Question Board"). - New drivingQuestionBoard document type + unit-keyed synthetic storage uid - get-or-create on opening any lesson; always-on Sort Work listener so the single board shows under every lesson and filter scope - Edit opens it in the main workspace (read-only in Sort Work); also fixes the resources-pane Edit button to show for any document the current user can edit (own docs, the user's group doc, and the DQB) - Class-wide tile presence: a class-scoped activity channel (broadcaster + listener) so all editors see each other's tile focus, not just group-mates - Concurrent history manager + workspace title bar wired for the new type Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new class-wide “Driving Question Board” (DQB) document that is automatically created once per class per unit (when group documents are enabled), appears in Sort Work under “No Group” / “No Name”, supports class-wide tile-focus presence, and can have its title authored via Document Settings.
Changes:
- Adds a new
drivingQuestionBoarddocument type with unit-keyed synthetic storage uid, plus get-or-create/guarantee logic. - Extends Sort Work sorting/listening to always include the unit’s DQB across filter scopes and supports opening/editing it from the main workspace.
- Adds a class-scoped presence channel (broadcaster + listener) so DQB tile focus badges reflect all class members, not just group-mates.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/models/stores/unit-configuration.ts | Adds a unit-level authored title field for the DQB. |
| src/models/stores/stores.ts | Adds dqbActivity store to hold class-wide DQB presence activity. |
| src/models/stores/sorted-documents.ts | Adds an always-on Firestore metadata listener for DQB docs and merges into Sort Work results. |
| src/models/stores/documents.ts | Uses concurrent history manager for DQB docs (like group docs). |
| src/models/stores/document-group.ts | Places DQB under “No Group” / “No Name” sections in Sort Work grouping. |
| src/models/stores/configuration-manager.ts | Exposes drivingQuestionBoardTitle from unit configuration. |
| src/models/stores/base-stores-types.ts | Extends base store typing to include dqbActivity. |
| src/models/stores/app-config-model.ts | Surfaces drivingQuestionBoardTitle via appConfig. |
| src/models/document/document.ts | Adds isDrivingQuestionBoard convenience view. |
| src/models/document/document-utils.ts | Uses authored DQB title for display; makes DQB accessible to all students. |
| src/models/document/document-types.ts | Adds new document type constant + enum membership + sortable/type helpers. |
| src/lib/logger-types.ts | Adds a log event for DQB creation. |
| src/lib/firebase.ts | Adds RTDB path helpers for class-scoped DQB activity presence. |
| src/lib/driving-question-board-activity-broadcaster.ts | New broadcaster for class-wide DQB tile-focus presence. |
| src/lib/db.ts | Implements DQB creation, get-or-create, metadata stamping, synthetic uid, and RTDB activity write helpers. |
| src/lib/db-types.ts | Extends DB document metadata types to include DQB. |
| src/lib/db-listeners/index.ts | Wires DQB activity listener/broadcaster into DB listeners lifecycle. |
| src/lib/db-listeners/db-driving-question-board-activity-listener.ts | New listener mirroring class-scoped RTDB presence into dqbActivity. |
| src/components/tiles/tile-activity-badges.tsx | Shows tile-focus badges for both group docs and the class-wide DQB. |
| src/components/document/sort-work-document-area.tsx | Shows Edit button when user can edit DQB or their group doc (not only owned docs). |
| src/components/document/document.tsx | Adds a DQB-specific title bar (authored title + styling hook). |
| src/components/document/document-workspace.tsx | Ensures the unit’s DQB exists when group documents are enabled. |
| src/clue/clue.scss | Styles the DQB title bar like other teal titlebars. |
| src/authoring/types.ts | Adds DQB title to authoring unit config type. |
| src/authoring/components/workspace/document-settings.tsx | Adds UI for authoring the DQB title with a default value. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // The class-wide Driving Question Board belongs to no group. | ||
| if (doc.type === DrivingQuestionBoardDocument) { | ||
| return `No ${groupTerm}`; | ||
| } |
There was a problem hiding this comment.
Good catch — fixed in e0c6383. sortGroupSectionLabels now sorts numeric group labels first (ascending) and places non-numeric labels like "No Group" last deterministically, instead of producing NaN sort keys.
| // The class-wide Driving Question Board belongs to no group. | ||
| if (doc.type === DrivingQuestionBoardDocument) { | ||
| return `No ${groupTerm}`; | ||
| } | ||
| if (doc.type === GroupDocument) { |
There was a problem hiding this comment.
Added in e0c6383 — new tests in document-group.test.ts assert the DQB lands under "No Group" (by Group) and "No Name" (by Name).
| // Ensures the unit's Driving Question Board exists (creating it on first open of any | ||
| // lesson). Does not open it as the primary document — access is only via Sort Work. | ||
| public async guaranteeDrivingQuestionBoard() { | ||
| await this.getOrCreateDrivingQuestionBoard(); | ||
| } |
There was a problem hiding this comment.
Agreed — fixed in e0c6383. guaranteeDrivingQuestionBoard() now only creates the document if missing (via the extracted findDrivingQuestionBoardMetadata()) and no longer opens it, so users don't start DQB content/history listeners on workspace mount. It still appears in Sort Work via the always-on Firestore metadata listener, and content/history load only when a user actually opens it.
- Reuse group document thumbnail styling (purple border + corner icon) for the Driving Question Board - Center the DQB workspace title across the full bar width - Make the content-drift check tolerant of an empty remote history: an empty chain has nothing to contradict the content, so surface the document instead of hard-failing it. Fixes the DQB being bricked when its first-session history uploads race the lazy metadata creation; the board self-heals on the next edit. Genuine corruption (a non-empty chain missing the saved id) still errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #2890 +/- ##
==========================================
- Coverage 86.06% 84.23% -1.83%
==========================================
Files 909 911 +2
Lines 52012 52226 +214
Branches 13719 13777 +58
==========================================
- Hits 44763 43995 -768
- Misses 7234 8214 +980
- Partials 15 17 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- guaranteeDrivingQuestionBoard now creates-if-missing WITHOUT opening the
document, so users don't start DQB content/history listeners on workspace
mount unless they actually open it (it still appears in Sort Work via the
metadata listener). Extracted findDrivingQuestionBoardMetadata.
- Make sortGroupSectionLabels deterministic for non-numeric labels: numeric
group labels sort first ascending, "No Group" (NaN) goes last instead of
producing NaN sort keys.
- Add unit tests for DQB grouping ("No Group" by Group, "No Name" by Name).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Place the class-wide Driving Question Board in a dedicated "Whole Class" section in the by-group sort instead of the "No Group" bucket, and sort it ahead of the numbered groups. Also gitignore the local OSEMagnets demo copy (the real unit lives in the clue-curriculum repo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
scytacki
left a comment
There was a problem hiding this comment.
Thanks for getting this feature working, Leslie. I did a detailed engineering review and found a number of issues that should be worked through before this can merge — they range from a blocking correctness regression to a larger design question about whether the Driving Question Board should be its own document type.
Full write-up, with code references and a triage summary:
https://gist.github.com/scytacki/01ae500953533bb955018583cab31729
Highlights:
- Blocking: the content-drift check was relaxed in a way that weakens a shared corruption guard used by group documents and the playback path, not just the DQB (#6). Separately, auto-creating on every unit launch widens an existing duplicate-document race, and the DQB has no primary-document pointer to recover, so users can silently end up in different boards (#1).
- Design decision: the DQB is introduced as a whole new document type that nearly duplicates the group document, producing a lot of parallel code (duplicate listeners/broadcaster, a separate Firestore query, and many two-type conditionals). It may be better modeled as a group/collaborative document with a class-wide scope (#3).
- Plus several follow-up/cleanup items (#2, #4, #5, #7), some pre-existing.
Because several of these involve architecture and shared infrastructure rather than local fixes, I'd suggest assigning the revision to a full-time developer who can review the write-up and work through the right solutions with me.
|
|
||
| # Local demo copy of OSEMagnets — the real unit lives in the clue-curriculum repo | ||
| src/public/demo/units/OSEMagnets/ |
There was a problem hiding this comment.
Rather than making an exception to one particular unit. It'd be better to have a folder that is always ignored perhaps drafts or tmp and then any local temporary units can be stored there.
Add a class-wide shared document (the Driving Question Board) that is auto-created once per class, per unit when group documents are enabled. It is editable by every class member, appears in Sort Work under "No Group"/"No Name", and its title is authorable on the Document Settings page (default "Driving Question Board").