Skip to content

DRAFT CLUE-610: make classWide the kind, move slot identity to a variant - #2963

Closed
scytacki wants to merge 1 commit into
CLUE-610-store-class-wide-titlesfrom
CLUE-610-class-wide-kind-variant
Closed

DRAFT CLUE-610: make classWide the kind, move slot identity to a variant#2963
scytacki wants to merge 1 commit into
CLUE-610-store-class-wide-titlesfrom
CLUE-610-class-wide-kind-variant

Conversation

@scytacki

Copy link
Copy Markdown
Member

Draft, stacked on #2962 (which is stacked on #2949) — not meant to merge. It answers the second half of the review question: if classWide were the kind and a new field held each document's identity, what would actually change?

It is stacked on the stored-titles PR deliberately. Both changes delete some of the same code, so measuring each against #2949 would let them both claim the same savings.

The change

classWide is a built-in kind carrying the axis values every class-wide document shares (class owner, classUnit container, concurrent). A new stored variant says which one a document is. The unit config declares { variant, title } instead of { kind, title }.

What actually gets simpler

Real, and worth naming precisely: the registry stops being dynamic. Kinds are all written in code, so a kind name resolves the same in every session and for every document.

  • registerClassWideDocumentKind is gone, along with the try/catch-and-skip registration path at startup.
  • getKindDefinitionFor and IDocumentKindInfo.unit are gone. With one definition that is always present, there is no question of which definition applies.
  • getDocumentOwner's rule that a document may only be created for a kind the current unit defines is gone, along with its rationale.
  • The "Static and dynamic kinds" section of axes.md — two rules and a bound on what a unit may declare — collapses to a shorter section about variants.

That is a genuine reduction in conceptual load, more than in code.

What does not get simpler

The dynamic string survives with its constraints intact. Everything the authored kind had to satisfy, variant now satisfies:

  • It is still a Firestore path segment (the canonical slot label), so it still needs isValidDocumentKind's camelCase check before a document is created from it.
  • It still has to be unique, or two entries contend for one slot — the check just moved from "registry rejects a duplicate" to an explicit seen set.
  • It still has to be interpretable in a session where its unit's config is not loaded, so it is still stamped on the document rather than looked up.

Two sites were forced to move from kind to variant, because the kind no longer distinguishes anything:

  • The workspace title bar's stylesheet hook. Styling from the kind would style every class-wide document alike.
  • The last-resort display label. getDocumentKindLabel(kind) would render every untitled class-wide document as "Class Wide".

A new stored field costs plumbing: IDocumentMetadata, DocumentMetadataModel, DocumentModel and its metadata view, the create path, and the open path.

Net

+194 / −238 across 17 files. The deletions are real, and concentrated in the registry and its documentation. The additions are the variant and its plumbing.

The honest summary is that this relocates the dynamism rather than removing it. A unit config still declares an open-ended set of runtime strings; they are just called variants and no longer key a registry. What is removed is the registry's dynamism — one definition, always present, centrally enumerable — which is a genuine benefit, and the one the "confidence that all axis combinations are supported" argument actually rests on.

What did not happen

No axis-based read was forced to become a kind lookup. hasClassOwner, concurrent, isInClassUnitContainer, and isAboutUnitOnly all still answer their questions from stored fields, and Sort Work's sectioning and the edit gate are untouched.

But doc.kind === "classWide" is now a correct, cheap, registry-free one-liner at the two Sort Work sectioning sites that currently ask hasClassOwner, and at the edit gate that composes concurrent with isInClassUnitContainer. Nothing forces the substitution; nothing discourages it either. Whether that matters depends on how much weight the axes design puts on kind never being branched on.

Not included

  • A migration. Existing class-wide documents carry kind: "<slot>" and no variant. They would need kind rewritten to classWide and variant set from the old kind. It is a straightforward script — the documents are selectable by type == "group" && !groupId, the same way the existing backfill selects them — but it is worth noting that this migration is exactly the kind of thing the "it would be hard to migrate class-wide documents" argument was concerned about, and it is not hard.
  • Firestore rules changes. None were needed: the rules build the pointer path from the stored canonical field, and never look at kind.

…nt [CLUE-610]

Every class-wide document now shares the built-in classWide kind, which carries
the axis values they all have. A new stored `variant` says which one a document
is: it labels the canonical slot, hooks the stylesheet, and names the document
when nothing else can.

Kinds are all written in code again, so the registry resolves the same in every
session and getKindDefinitionFor has nothing left to 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

❌ Patch coverage is 90.90909% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.96%. Comparing base (78ea6a7) to head (4c53384).

Files with missing lines Patch % Lines
src/components/document/document.tsx 0.00% 1 Missing ⚠️
src/lib/db.ts 93.75% 1 Missing ⚠️
Additional details and impacted files
@@                         Coverage Diff                          @@
##           CLUE-610-store-class-wide-titles    #2963      +/-   ##
====================================================================
- Coverage                             69.98%   69.96%   -0.03%     
====================================================================
  Files                                   973      973              
  Lines                                 55838    55839       +1     
  Branches                              14736    14738       +2     
====================================================================
- Hits                                  39076    39065      -11     
- Misses                                16728    16740      +12     
  Partials                                 34       34              
Flag Coverage Δ
cypress-smoke 41.68% <81.81%> (-0.02%) ⬇️
jest 56.72% <81.81%> (+<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 #19836

Run Properties:  status check passed Passed #19836  •  git commit 4c533848be: experiment: make classWide the kind and move slot identity to a variant [CLUE-61...
Project collaborative-learning
Branch Review CLUE-610-class-wide-kind-variant
Run status status check passed Passed #19836
Run duration 03m 38s
Commit git commit 4c533848be: experiment: make classWide the kind and move slot identity to a variant [CLUE-61...
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