collection - bitcobblers/wod-wiki GitHub Wiki
[!info] Review status Current State describes the legacy
ScriptCollectioncorpus adapter. Future State proposes a distinct query-composed collection page, not a Catalog rename or adopted Page-store migration. See todo#Datatype review guide.
- Store: none — derived at read, never persisted
-
Builder:
apps/playground/src/repositories/script-collections.ts(+groupings.ts) -
Corpus:
markdown/collections/(seed content, IndexedDB-backed via theseedContentseam)
A Collection is a grouping of named items from the seed corpus — static, bundled workout content. It is not a database row: buildScriptCollections() derives the list fresh from each corpus snapshot and memoizes until a new seed lands.
| Knob | Where | Effect |
|---|---|---|
| Directory name | markdown/collections/{dir}/ |
The collection. One level deep; root-level files ignored. Also the id and (humanized) name
|
| Member files | {dir}/{file}.md |
One item per file (except README.md); day-NN- prefixes stripped from the display name |
README.md frontmatter category
|
{dir}/README.md |
categories — lowercased slug list (the only README field parsed) |
README.md body |
{dir}/README.md |
readme — collection description prose |
| Item frontmatter | each item file | Card badges: Category, Type, Difficulty; link widgets; ## Description (or first line) as the card snippet |
Derived, not configured: IDs/display names come from slugs (crossfit-girls → "Crossfit Girls"); items and collections sort name-ascending. README.md is collected as description, not an item. This adapter reads category metadata, not the canvas layout configuration.
| Field | Type | Notes |
|---|---|---|
id |
string | Directory name, e.g. crossfit-girls
|
name |
string | Humanized directory name |
count |
number | Workout files, excluding README |
items |
ScriptCollectionItem[] |
{ id, name, content, path } — filename stem, display name, raw markdown, canonical path key |
readme? |
string | README.md content when present |
categories |
string[] | From README frontmatter category
|
- Seed import materializes collection items as Note rows with
seedOrigin: 'seed'andcatalog= the collection directory id - Their blocks index into BlockIndexRow with
isStatic: trueandsourceId= source path - Import checkpoint lives in Configuration (
metakv store, proposed rename toconfiguration) - Bundled source is protected, but a read-only source does not imply inert UI. Feed detail deliberately persists separate local scratch edits; syntax examples may be ephemeral.
- Library lists Catalog content; existing collection/feed detail routes and WQL discovery remain compatibility constraints, not redesign targets.
- Library routes preserve the Note UUID for ownership. Collection landings
resolve
page:collection:<catalog>to/c/<catalog>; workouts resolvecollection:<catalog>/<item>or their importedsourcePathto/c/<catalog>/<item>. UUID-keyed workouts do not become catalog landings. Block results use the same owning route with a section anchor. - Sibling root: feeds (
markdown/feeds/{feed}/{YYYY-MM-DD}/{file}.md) — same builder, dated items
| Aspect | Page | Note | Collection |
|---|---|---|---|
| Store |
page table |
notes table |
none — derived at read |
| Role | Grouping / addressing | Content container | Grouping of bundled static content |
| Identity |
id; addressed by unique date or slug
|
id UUID; routed by slug
|
directory name |
| Holds | Membership only — no content | Authored source + occurrence map; saved block states in BlockRevision | Items = seed markdown files |
| Flavors | Calendar (date) / custom (slug) |
note / template / playground / journal
|
collections / feeds |
| Membership | Notes point in via pageId
|
Belongs to ≤ 1 page | File location decides |
pageId fan-out |
Copied onto segments, results, attachments, events | Source of the copied value | n/a |
| Source writes | No content field on row | Depends on source ownership and action | Seed source protected; explicitly separate scratch/copy actions may be editable |
Proposed distinction: a collection page is a Page presentation configured by an authored Note containing prose and a WQL listing. A Catalog retains the glossary's bundled-source meaning. The legacy ScriptCollection is an adapter over that source, not proof that query-page membership should become a stored entity.
Do not replace Catalog/Library terminology or rename its existing routes in this effort. Adopting “collection page” in the shared glossary remains part of Note#Wayfinder questions and proposed answers.
Owner: Decide collection-page membership: WQL segment vs pageId.
-
Live query, stored membership or hybrid? Recommended answer: live query-derived display.
Note.pageIdremains owned placement, especially journal dates; it does not record all queries that happen to include a note. No membership backfill or second writable list is needed. -
Where do non-query segments live? Recommended answer: ordinary prose/headings/metadata in the configuration note's
rawContent. Do not addPage.body, duplicate category fields, or copy every member's source into the page. - How do feeds fit? Recommended answer: the same composition with explicit date selection, grouping and ordering. Preserve source/post dates; do not treat a seed-build timestamp as the publication date or rewrite source dates to the journal day.
-
What WQL behavior is needed? Use existing
find:notefilters for type/text/content/source/catalog/tags where supported. Require a navigable result preview, empty/error states and deterministic order. Decide exact ordering/limit/date requirements before declaring a grammar extension; this draft does not invent unsupported query syntax. -
Does this replace the corpus builder or
catalog? No. Retain current source loading, Library filters and deep links; add query-composed presentation without requiring a Page-store roll-up. The earlier mandatorykind: collection/by-pagemigration is not the recommendation. -
Feed convergence: feeds are transitional collections with dates rather than an independent storage or routing family. Posts are notes in a dated collection; they open in the universal editor at
/notes/:noteId. The feed stream (/feeds) and detail paths merge into dated collection routes (/c/:slugand/c/:slug/:date). -
Canonical collection routes: browsing all collections lives at
/collections(find:note{source:collections} by {tag}); collection landing lives at/c/:slug(specialized view of/p/:slug); date-scoped view lives at/c/:slug/:date; named workout editor lives at/c/:slug/:page-slug(disambiguated by shape:YYYY-MM-DDindicates date, other strings indicate page slug). Persisted collection items open directly at/notes/:noteId.
- Editing the listing query edits the configuration note. Opening a result identifies its owning note; rendering the result does not grant write access to that note.
- Read presentation may inspect filters and follow results. Source authoring follows Page#Mode and write destinations, including explicit local scratch/copy actions instead of a universal disabled state.
- Show previews rather than nested editable documents by default. Recursive embedding needs a defined bound/cycle behavior before it is enabled.
- Counts derive from results; query membership is not copied to tags or relationship rows. BlockIndexRow owns derived-search identity and deletion consistency.
- Which date is used for each source, how are undated notes handled, and what deterministic tie-breaker/order should a dated collection use?
- Do any collections need manual curation or pinned order, rather than a live query? That concrete requirement would justify revisiting membership, not prebuilding a hybrid.
- Should embedded results be links, summaries or expanded read-only content? Define recursion/expansion limits if expanded content is required.
- Which sort/limit/date operations are missing in the actual query path? Verify against a representative listing before extending WQL.
Feedback case: the same dated source item appears in two collections and is copied into today's journal. Both listings retain its source identity/date; the journal copy owns its edits/results. A feed scratch persists without modifying the bundled item.
- Collection adapter; grouping builder; static identity/date projection.
- Feed scratch ownership; query vocabulary; result presentation.
!