Skip to content

DRAFT CLUE-610: store class-wide document titles instead of resolving them by kind - #2962

Closed
scytacki wants to merge 1 commit into
masterfrom
CLUE-610-store-class-wide-titles
Closed

DRAFT CLUE-610: store class-wide document titles instead of resolving them by kind#2962
scytacki wants to merge 1 commit into
masterfrom
CLUE-610-store-class-wide-titles

Conversation

@scytacki

Copy link
Copy Markdown
Member

Draft, built on #2949 — not meant to merge as-is. It exists to answer a review question concretely: if class-wide documents stored their titles instead of resolving them from the kind registry, what would actually change?

What it does

A class-wide document's authored title is stamped onto it at creation and read back like any other stored title. IDocumentKindInfo.title is gone; registerClassWideDocumentKind no longer takes one. The unit config is unchanged — authors still write { kind, title }.

The plumbing was mostly already there: createDocument accepted a title and threaded it into the Firestore metadata, and openDocumentFromFirestoreMetadata read it back. The only gap was that getOrCreateCanonicalDocument never passed one.

What this buys

  • A document from another unit shows its real authored title ("Our Big Questions") instead of a label reconstructed from its kind ("Driving Question Board"). The same document now reads the same wherever it is listed.
  • The registry has no read-time consumer left at all. Every remaining lookup is creation-side.

What it costs

Changing a title in a unit config now renames only documents created afterwards. Today an author fixing wording fixes it for every class immediately. This is the one genuine regression, and existing class-wide documents would need a backfill to pick up their titles. Until then they fall back to the kind label — visible, not broken, but wrong wording. Note the backfill can't simply be done client-side: the write-back would be made by the signed-in user, and the Firestore rules would have to allow a class member to set title on a class-owned document.

getKindDefinitionFor(doc) is now exercised only by its own tests. It is deliberately kept. Scoping a dynamic kind's definition to the configuration that declared it is a constraint we expect to need again — copy/publish templates are the case with no graceful-degradation option, since a document cannot be created without deciding its axes, so a wrong template writes wrong stored axes that need a migration to fix. Titles were the only thing exercising that constraint; storing them makes the mechanism unused rather than unnecessary. Reviewers should read the unused mechanism as the point of this PR, not as an oversight.

The suffix rule

A stored title alone cannot tell two documents apart — two units may each author a "Driving Question Board" — so a title authored at unit scope is shown with its unit code when the document is not from the unit being viewed: "Our Big Questions (other)". The unit code rather than its name, because nothing loads another unit's config.

The general rule, which the new isAboutUnitOnly guard implements one case of:

A title identifies a document only within the scope its author controlled. Displayed outside that scope, it needs the coordinate that restores identification.

This already explains behavior that exists. A student-authored personal document title is unique within nothing, and is disambiguated by creation time instead — same rule, different coordinate.

Problem documents follow the same rule by a different mechanism, and this PR does not change them. A problem document from another problem in the same unit shows its own title with no decoration; one from another unit shows "Problem doc from sas-1.2". That second string is not a decorated title — it is a substitute for a title that cannot be resolved, because only the current unit's curriculum is loaded. Same rule, degraded implementation.

That inconsistency is worth deciding on rather than inheriting: either problem documents should store their titles too, or class-wide documents should not store theirs. Both are defensible. What is hard to defend is two kinds of document whose names are unique within a unit resolving that name by two different mechanisms with two different failure modes.

The authored title is stamped at creation instead of being resolved from the
kind registry at display time, so it travels with the document and names it in
units whose config does not declare its kind.

A stored title still needs its unit shown alongside it when the document is not
from the unit being viewed: a title is authored to be unique within one unit's
config, and two units may each author a "Driving Question Board". The new
isAboutUnitOnly guard recognizes a name authored at unit scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.98%. Comparing base (018a5b2) to head (78ea6a7).

❗ There is a different number of reports uploaded between BASE (018a5b2) and HEAD (78ea6a7). Click for more details.

HEAD has 14 uploads less than BASE
Flag BASE (018a5b2) HEAD (78ea6a7)
cypress-regression 14 0
Additional details and impacted files
@@                        Coverage Diff                         @@
##           CLUE-610-class-wide-documents    #2962       +/-   ##
==================================================================
- Coverage                          85.88%   69.98%   -15.91%     
==================================================================
  Files                                978      973        -5     
  Lines                              55859    55838       -21     
  Branches                           14737    14736        -1     
==================================================================
- Hits                               47977    39076     -8901     
- Misses                              7864    16728     +8864     
- Partials                              18       34       +16     
Flag Coverage Δ
cypress-regression ?
cypress-smoke 41.70% <90.00%> (+0.01%) ⬆️
jest 56.72% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cypress

cypress Bot commented Aug 14, 2026

Copy link
Copy Markdown

collaborative-learning    Run #19835

Run Properties:  status check passed Passed #19835  •  git commit 78ea6a71d4: feat: store a class-wide document's title on the document [CLUE-610]
Project collaborative-learning
Branch Review CLUE-610-store-class-wide-titles
Run status status check passed Passed #19835
Run duration 03m 47s
Commit git commit 78ea6a71d4: feat: store a class-wide document's title on the document [CLUE-610]
Committer Scott Cytacki
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 4
View all changes introduced in this branch ↗︎

@scytacki

Copy link
Copy Markdown
Member Author

We decided not to go in this direction.

@scytacki scytacki closed this Aug 25, 2026
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