Six kinds of study card exist in the database today, but the code only fully knows how to handle some of them, and two of them — "concept" and "passage" — got tangled up with each other along the way. This checkpoint settles the core list, untangles concept/passage, and proposes one habit that would keep this from drifting again: schemas generated straight from the live database instead of written by hand and left to go stale.
Audit finding D15 + the archetype map (§2)
The database holds six different kinds of study card. The code that builds and manages them recognizes four by name, treats a fifth ("rule") as a bolt-on rather than its own type, and has never heard of the sixth ("concept") at all — even though 120 concept cards already exist and are visible to learners today.
| Card type | Roughly how many | Status today |
|---|---|---|
| Vocabulary | ~2,100 words | Fully supported — this rebuild's main focus |
| Grammar rules | 194 | Built by the old system; carried as a bolt-on, not its own first-class type |
| Script / alphabet | 32 | Built by the old system; recognized |
| Phrases | 28 | Built by the old system; recognized |
| Concept | 120 | Cards exist and are visible to learners — the code doesn't officially know this type exists |
| Passages | 12 | Cards exist, mostly incomplete/flagged; no code has ever been written to build or manage them |
Underneath this, every card type stores its extra, type-specific details in one shared "extras" field — but four of the six types use it one way (a labeled bucket, e.g. {rule: …}) while vocabulary uses it a completely different way (a flat grab-bag with no label). Whatever the final list of types turns out to be, that inconsistency needs to be resolved the same time the list is ratified — it's the same underlying "no shared shape" problem as the family-storage checkpoint.
Quoted from your response to Decision 6 — lightly cleaned up from voice dictation, your words
"At this point in time, I see the core for language learning as vocabulary, grammar rules, script/alphabet, and phrases. These will be pre-built and be the master repository of information available to people learning a language.
Now, the ability to have a concept or passages is supposed to be really one card archetype, or maybe two. I'm kind of leaning toward: concept is more like cluster learning, and passages is basically like phrases. I think there was a bit of misunderstanding when I was creating the card archetypes — that phrases and passages kind of came together. Phrases are good — it could be idioms, or passages from a text, or short sentences, or phrases you should know in a language. Sort of like the things TripAdvisor would have in their dictionary of handy phrases you need to know. For the card archetype, the phrase might be at CT1, but the definition of all the data would be at CT2 in the t070 table.
So the schema should be better defined. Actually for all of these — somewhere there should be a canonical schema that we're enriching to, and the schema should exist in the database and be self-documenting. Like a query, sort of what we did for taxonomy.ts — if we want to know the schema for vocabulary, we'd call vocabulary-schema.ts and it would pull it, self-documented. Not a living document that someone maintains by hand — something generated based on the schema that actually exists in Supabase."
taxonomy.ts pattern, applied to every card typetaxonomy.ts file already uses. It's always accurate because it's pulled from what's actually there, not typed up once and left to drift.
vocabulary-schema.ts), built from the live database — this becomes the one source of truth every enrichment pass writes to.