Checkpoint 1 · Related-words data shape

Confirm the data shape — related words

How the words and phrases on a card's Similar/Opposite/Informal/Related-compound lists will be stored — confirm the shape before any build runs.

2 decisions makan worked example 50-word proof plan
Checkpoints Latest →
The design

The shape

Two diagrams: how the words get stored, and what happens the moment a learner taps the + on one.

Each word or phrase on a card (a “target”) is stored once and shared by every sense that mentions it. What’s specific to one sense — its meaning in that context — lives on its own “item” row instead of being copied.

erDiagram
    SENSE_CARD ||--o{ RELATION_ITEM : "owns"
    RELATION_TARGET ||--o{ RELATION_ITEM : "is mentioned by"
    RELATION_TARGET ||--o{ TARGET_GLOSS : "general meaning, one row per language"
    RELATION_ITEM ||--o{ ITEM_GLOSS : "sense-specific meaning, one row per language"
    RELATION_TARGET ||--o{ RELATION_EXAMPLE : "usage, Indonesian"
    RELATION_EXAMPLE ||--o{ EXAMPLE_TEXT : "translation, one row per language"
    RELATION_ITEM ||--o{ ITEM_NOTE : "context note, one row per language"
    RELATION_TARGET }o..o| FULL_CARD : "link when a full card exists"
    RELATION_TARGET }o..o| ENRICH_QUEUE_ROW : "one queue row per target"
    LANGUAGE ||--o{ TARGET_GLOSS : "lang"
    LANGUAGE ||--o{ ITEM_GLOSS : "lang"
    LANGUAGE ||--o{ EXAMPLE_TEXT : "lang"
    LANGUAGE ||--o{ ITEM_NOTE : "lang"
    RELATION_TARGET {
        uuid target_id PK
        text l2_language FK
        text text_norm "unique with l2_language"
        text text_display
        text kind "word | phrase — authored"
        text register_intrinsic "nullable; slang etc. when true of the word itself"
        text ipa
        text respelling
        text audio_normal_url
        text audio_slow_url
        uuid full_card_id FK "nullable"
        text full_card_status "linked | none | queued | refused"
        bigint enrich_queue_id FK "nullable"
        jsonb provenance "model, version, authored_at — opaque, stored whole"
    }
    RELATION_ITEM {
        uuid item_id PK
        uuid source_card_id FK "the owning CT2 sense"
        uuid target_id FK
        text relation_kind "similar | opposite | informal | related_compound"
        int ordinal
        text register "formal | informal | slang | neutral — of the relationship"
        bool is_idiom
        text tag_raw "jenis as authored, kept for the record"
        jsonb provenance
    }
    TARGET_GLOSS {
        uuid target_id FK
        text lang FK
        text text
        text state "machine | llm | human | locked"
    }
    ITEM_GLOSS {
        uuid item_id FK
        text lang FK
        text text
        text state
    }
    RELATION_EXAMPLE {
        uuid example_id PK
        uuid target_id FK
        int ordinal
        text l2_text
    }
    EXAMPLE_TEXT {
        uuid example_id FK
        text lang FK
        text text
        text state
    }
    ITEM_NOTE {
        uuid item_id FK
        text lang FK
        text text
        text state
    }
    

Tapping the + on a word or phrase either adds it to the learner’s list right away (if a full card already exists) or queues it to be authored (if it doesn’t).

flowchart TD
    TAP["Learner taps the standard add chip on an item"] --> Q{"target_status?"}
    Q -- linked --> ADD["POST /api/learning-list/add with sense_id"]
    ADD --> T310["t310 row, user_status = priority: next session"]
    Q -- "no_card" --> ENQ["POST /api/learning-list/add with the item text"]
    ENQ --> QUEUE["t_enrich_queue row: queue_type headword, status pending, requested_by = profile"]
    QUEUE --> ITEM["item.target_status = queued"]
    QUEUE --> DAEMON["enrichment daemon"]
    DAEMON -- word --> CARD["catalog card created"]
    DAEMON -- phrase --> PP{"phrase path: corpus phrase?"}
    PP -- yes --> CARD
    PP -- no --> REF["refused today: eight corpus-grounded steps refuse a non-corpus phrase (desk item G #334)"]
    CARD --> LINK["item.target_card_id filled, status linked"]
    LINK --> AUTO{"auto-add to the requester's list?"}
    AUTO -- "built" --> T310
    AUTO -- "not built today" --> PEND["learner sees pending; must tap again"]
    Q -- queued --> WAIT["chip shows pending"]
    Q -- refused --> HIDE["chip hidden or greyed"]
    
Proof point

Worked example: makan

Here is makan (“to eat” and five other senses) mapped into the new shape, straight from what’s live in the database today. Every cell with no live source yet is marked “to be authored” — those get filled in as part of the build, they aren’t a problem to fix now.

Sense 1 — “to eat”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
informalmamto be authoredto be authoredto be authoredbaby talk for 'eat' used with small children at hometo be authoredNone
informalmamamto be authoredto be authoredto be authoredcute child language for 'eat', common when coaxing toddlersto be authoredNone
informalmknto be authoredto be authoredto be authoredtexting shorthand for 'makan' in chatsto be authoredNone
oppositeberpuasato be authoredto be authoredNoto fast (abstain from eating)to be authoredNone
oppositemenahan laparto be authoredto be authoredNoto hold back hunger (not eat)to be authoredNone
related compoundkasih makanto be authoredto be authoredto be authoredto give food to a person or animalmemberi makan pada orang atau hewanNone
related compoundkereta makanto be authoredto be authoredto be authoreddining cargerbong kereta api yang dipakai sebagai tempat makan; restorasiNone
related compoundmakan malamto be authoredto be authoredto be authoredto have dinnermakan pada malam hariNone
related compoundmakan pagito be authoredto be authoredto be authoredto have breakfastmakan pada waktu pagi; menyarapNone
related compoundmakan siangto be authoredto be authoredto be authoredto have lunchmakan pada waktu siang hariNone
related compoundmakan sirihto be authoredto be authoredto be authoredthe habit of chewing betel leafkebiasaan mengunyah daun sirihNone
related compoundmencari makanto be authoredto be authoredto be authoredto earn a livingmencari nafkahNone
related compoundnafsu makanto be authoredto be authoredto be authoredthe feeling of wanting to eatrasa ingin makanNone
related compoundrumah makanto be authoredto be authoredto be authoredrestaurantkedai tempat makan (menjual makanan)None
related compoundsudah makan?to be authoredto be authoredto be authoreda friendly greeting asking if you have eatensapaan akrab untuk tanya sudah makanNone
similarbersantapto be authoredto be authoredNoto dineto be authoredNone
similarmelahapto be authoredto be authoredNoto devourto be authoredNone
similarmenikmati makananto be authoredto be authoredNoto enjoy a mealto be authoredNone
similarmenyantapto be authoredto be authoredNoto partake (eat formally)to be authoredNone

Sense 2 — “to use up”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
informalmakan waktuto be authoredto be authoredto be authoredcasual speech without prefix me-, same meaning as memakan waktuto be authoredNone
oppositemenghemat biayato be authoredto be authoredNoto save coststo be authoredNone
oppositemenghemat waktuto be authoredto be authoredNoto save timeto be authoredNone
similarmemakaito be authoredto be authoredNoto useto be authoredNone
similarmemerlukanto be authoredto be authoredNoto requireto be authoredNone
similarmenghabiskanto be authoredto be authoredNoto use upto be authoredNone
similarmenguras tenagato be authoredto be authoredNoto drain energyto be authoredNone
similarmenyita waktuto be authoredto be authoredNoto take up timeto be authoredNone

Sense 3 — “to work”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
informalgak makanto be authoredto be authoredto be authoredcolloquial for 'rem tidak makan' in chat and speechto be authoredNone
oppositemacetto be authoredto be authoredNoto jam, to get stuckto be authoredLinked
oppositerem blongto be authoredto be authoredNobrakes failto be authoredNone
oppositetidak berfungsito be authoredto be authoredNoto not functionto be authoredNone
similarbekerja sebagaimana mestinyato be authoredto be authoredNoto work as it shouldto be authoredNone
similarberfungsito be authoredto be authoredNoto functionto be authoredNone
similarberjalanto be authoredto be authoredNoto run properlyto be authoredLinked
similarbisato be authoredto be authoredNoto work, can functionto be authoredLinked

Sense 4 — “to capture”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
similarambil bidakto be authoredto be authoredNoto take a pieceto be authoredNone
similarganyang bidakto be authoredto be authoredNoto wipe out a pieceto be authoredNone
similargasak bidakto be authoredto be authoredNoto snatch a pieceto be authoredNone
similarserang bidakto be authoredto be authoredNoto attack a pieceto be authoredNone

Sense 5 — “to damage”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
informalmakanto be authoredto be authoredto be authoredcasual speech dropping meN- prefix, as in rust already ate through the ironto be authoredLinked
oppositemelindungito be authoredto be authoredNoto protectto be authoredNone
oppositememperbaikito be authoredto be authoredNoto repairto be authoredNone
similarmelukaito be authoredto be authoredNoto injureto be authoredNone
similarmenembusto be authoredto be authoredNoto penetrateto be authoredNone
similarmenggerogotito be authoredto be authoredNoto gnaw away atto be authoredNone
similarmengikisto be authoredto be authoredNoto erodeto be authoredNone
similarmerusakto be authoredto be authoredNoto damageto be authoredNone

Sense 6 — “to embezzle”

RelationItem textKindRegisterIs idiomEng glossInd paraphraseTarget status
informalkorupto be authoredto be authoredto be authoredshort for korupsi, used in casual chat and news headlinesto be authoredNone
oppositemengembalikan danato be authoredto be authoredNoto return funds to their rightful placeto be authoredNone
oppositemenjaga uang kas dengan jujurto be authoredto be authoredNoto guard cash funds honestlyto be authoredNone
similarkorupsito be authoredto be authoredNoto engage in corruptionto be authoredLinked
similarmenggelapkan uangto be authoredto be authoredNoto misappropriate moneyto be authoredNone
similarmenyelewengkan danato be authoredto be authoredNoto misappropriate fundsto be authoredNone
similarrasuahto be authoredto be authoredNocorruption by briberyto be authoredNone

All distinct targets mentioned across makan’s senses

TextKindPhoneticsExample 1Example 2Full card
ambil bidakto be authoredto be authoredto be authoredto be authoredNone
bekerja sebagaimana mestinyato be authoredto be authoredto be authoredto be authoredNone
berfungsito be authoredto be authoredto be authoredto be authoredNone
berjalanto be authored/bər.ˈdʒa.lan/ · buhr-JAH-lahnSaya berjalan pagi ini.
I walked this morning.
Kemarin kami berjalan ke pasar.
Yesterday we walked to the market.
Open card ›
berpuasato be authoredto be authoredto be authoredto be authoredNone
bersantapto be authoredto be authoredto be authoredto be authoredNone
bisato be authored/ˈbi.sa/ · BEE-sahSaya bisa membaca.
I can read.
Kamu bisa berenang?
Can you swim?
Open card ›
gak makanto be authoredto be authoredto be authoredto be authoredNone
ganyang bidakto be authoredto be authoredto be authoredto be authoredNone
gasak bidakto be authoredto be authoredto be authoredto be authoredNone
kasih makanto be authoredto be authoredto be authoredto be authoredNone
kereta makanto be authoredto be authoredto be authoredto be authoredNone
korupto be authoredto be authoredto be authoredto be authoredNone
korupsito be authored/ko.ˈrup.si/ · koh-ROOP-seeKorupsi itu ambil uang negara.
Corruption is taking the country's money.
Dia sudah lawan korupsi baru itu.
He fought that new corruption.
Open card ›
macetto be authored/ˈma.tʃət/ · MAH-chuhtJalan ke pasar sangat macet pagi ini.
The road to the market is very jammed this morning.
Saya beli bumbu kemarin di pasar, lalu saluran air di dapur macet.
I bought spices at the market yesterday, then the kitchen drain got blocked.
Open card ›
makanto be authored/ˈma.kan/ · MAH-kahnSaya makan nasi dan ikan.
I eat rice and fish.
Kami sedang makan di dapur.
We are eating in the kitchen.
Open card ›
makan malamto be authoredto be authoredto be authoredto be authoredNone
makan pagito be authoredto be authoredto be authoredto be authoredNone
makan siangto be authoredto be authoredto be authoredto be authoredNone
makan sirihto be authoredto be authoredto be authoredto be authoredNone
makan waktuto be authoredto be authoredto be authoredto be authoredNone
mamto be authoredto be authoredto be authoredto be authoredNone
mamamto be authoredto be authoredto be authoredto be authoredNone
melahapto be authoredto be authoredto be authoredto be authoredNone
melindungito be authoredto be authoredto be authoredto be authoredNone
melukaito be authoredto be authoredto be authoredto be authoredNone
memakaito be authoredto be authoredto be authoredto be authoredNone
memerlukanto be authoredto be authoredto be authoredto be authoredNone
memperbaikito be authoredto be authoredto be authoredto be authoredNone
menahan laparto be authoredto be authoredto be authoredto be authoredNone
mencari makanto be authoredto be authoredto be authoredto be authoredNone
menembusto be authoredto be authoredto be authoredto be authoredNone
mengembalikan danato be authoredto be authoredto be authoredto be authoredNone
menggelapkan uangto be authoredto be authoredto be authoredto be authoredNone
menggerogotito be authoredto be authoredto be authoredto be authoredNone
menghabiskanto be authoredto be authoredto be authoredto be authoredNone
menghemat biayato be authoredto be authoredto be authoredto be authoredNone
menghemat waktuto be authoredto be authoredto be authoredto be authoredNone
mengikisto be authoredto be authoredto be authoredto be authoredNone
menguras tenagato be authoredto be authoredto be authoredto be authoredNone
menikmati makananto be authoredto be authoredto be authoredto be authoredNone
menjaga uang kas dengan jujurto be authoredto be authoredto be authoredto be authoredNone
menyantapto be authoredto be authoredto be authoredto be authoredNone
menyelewengkan danato be authoredto be authoredto be authoredto be authoredNone
menyita waktuto be authoredto be authoredto be authoredto be authoredNone
merusakto be authoredto be authoredto be authoredto be authoredNone
mknto be authoredto be authoredto be authoredto be authoredNone
nafsu makanto be authoredto be authoredto be authoredto be authoredNone
rasuahto be authoredto be authoredto be authoredto be authoredNone
rem blongto be authoredto be authoredto be authoredto be authoredNone
rumah makanto be authoredto be authoredto be authoredto be authoredNone
serang bidakto be authoredto be authoredto be authoredto be authoredNone
sudah makan?to be authoredto be authoredto be authoredto be authoredNone
tidak berfungsito be authoredto be authoredto be authoredto be authoredNone

Item table: 47 of 216 cells exist today. Target table: 15 of 216 cells exist today. Combined: 62 of 432 cells exist today — the rest are “to be authored”.

Impact

What changes for the learner

Five concrete things a learner will see once this ships.
1
The card shows the meaning of each related word or phrase in both Indonesian and English — never English-only.
2
Each word or phrase gets its own sound: one normal-speed clip and one slow clip.
3
Each word or phrase gets two example sentences, in both languages.
4
Each item can carry a short note explaining why it’s there or how it’s used.
5
Tapping the + on any item queues that word or phrase for authoring if it doesn’t have a full card yet — nothing is ever silently dropped.
Budget

Costs and order

What each part of the build costs to run, and the order things happen in.
UnitCountPer unitDriver
targets28,474one model call (kind, phonetics, example)model price per call
items48,844one model call per language beyond eng (gloss)× languages
examples28,474one translation call per language× languages
notes1,111one translation call per missing languagesmall
translation rows written≈ 214,000 at 2 languages (eng + ind)rows, not money
sound28,474 clip pairs🟡 the expensive line: docket 65 measured ≈1.8 credits per clip, so ≈ 100,000 credits for both speedsElevenLabs plan

Before any of that runs at full scale, the plan is to prove it on 50 words first: migrate their items, write their meanings, translate them, link them to full cards where one exists, and measure the real dollar and credit cost per word — then show Frank the finished card and the real numbers before anything bigger runs.

Decisions

Your decisions

Two calls to make before any build work starts.
1
DS — confirm the data spec
Why it matters: this is the actual design being confirmed before any build work starts.
2
PR — start the 50-word proof now, without the sound step
Why it matters: this is the next concrete action if the spec is confirmed.