Resolve null bibleTextId for verses in the Record tab (sync/lookup gap)
Summary / context
The Record tab can't start a recording when getBibleTextId(...) returns null for the selected verse. Recording is keyed on bible_text_id, so a null value leaves the record button silently inert. PR #158 (Record tab, #49) ships a TEMP Android toast ("No bible text id for this verse yet.") to surface the state instead of a dead button, and #49 is waived for a real fix. This ticket owns diagnosing the root cause and making the lookup reliable so every assigned verse resolves a bible_text_id.
Current vs expected
Current
- Open a chapter → Record tab → select a verse.
RecordTab (src/app/tabs/RecordTab.tsx) calls getBibleTextId(bibleId, bookId, chapterNumber, verseNumber); for some verses it resolves null.
- Tapping record shows the TEMP toast and does nothing (
src/app/tabs/drafting/record/RecordTab.tsx L131–145).
Expected
- Every verse the user is assigned to and can open in the Record tab resolves a valid
bible_text_id, so recording starts normally.
- If a row genuinely cannot exist yet (e.g. sync not finished), the UI communicates a real, non-TEMP state (e.g. "source text still syncing") rather than a debug toast — and the record button's disabled/enabled state reflects it.
Scope
In scope
- Root-cause why
bible_texts has no matching row for (bible_id, book_id, chapter_number, verse_number) — investigate sync timing/ordering, missing rows in syncBibleTexts, or an API contract gap.
- Fix the lookup and/or sync so assigned verses always have a
bible_text_id after sync completes.
- Replace the TEMP
ToastAndroid debug path with the settled behavior.
Out of scope
Acceptance criteria
Verification / test plan
npm run format:check · npm run lint · npm run typecheck · npm test -- --ci
- Manual (Android): sign in, wait for sync, open an assigned chapter → Record tab, step through verses; confirm each resolves a
bible_text_id and record starts. Confirm mid-sync state shows the real "still syncing" UX, not the debug toast.
File pointers & approach
src/db/queries.ts — getBibleTextId() (L461–481): SELECT id FROM bible_texts WHERE bible_id/book_id/chapter_number/verse_number; returns null on no-row or error.
src/app/tabs/RecordTab.tsx (L27–49, L73) — resolves bibleTextId in an effect and passes bibleTextIdForSelectedVerse down.
src/app/tabs/drafting/record/RecordTab.tsx (L131–145) — TEMP toast to remove.
src/services/sync.ts — syncBibleTexts() (L299+), invoked at L493/L574/L577/L585; check ordering vs chapter-assignment sync and whether all assigned verses are fetched/inserted.
src/db/repository.ts — insertBibleTexts write path.
Approach: (1) reproduce and capture which (bible_id, book_id, chapter_number, verse_number) combos miss a row; (2) determine whether the row is absent (sync/API) or the query keys are wrong; (3) fix at the correct layer; (4) swap the TEMP toast for real disabled/status UX and gate the record button.
Links
Resolve null
bibleTextIdfor verses in the Record tab (sync/lookup gap)Summary / context
The Record tab can't start a recording when
getBibleTextId(...)returnsnullfor the selected verse. Recording is keyed onbible_text_id, so a null value leaves the record button silently inert. PR #158 (Record tab, #49) ships a TEMP Android toast ("No bible text id for this verse yet.") to surface the state instead of a dead button, and #49 is waived for a real fix. This ticket owns diagnosing the root cause and making the lookup reliable so every assigned verse resolves abible_text_id.Current vs expected
Current
RecordTab(src/app/tabs/RecordTab.tsx) callsgetBibleTextId(bibleId, bookId, chapterNumber, verseNumber); for some verses it resolvesnull.src/app/tabs/drafting/record/RecordTab.tsxL131–145).Expected
bible_text_id, so recording starts normally.Scope
In scope
bible_textshas no matching row for(bible_id, book_id, chapter_number, verse_number)— investigate sync timing/ordering, missing rows insyncBibleTexts, or an API contract gap.bible_text_idafter sync completes.ToastAndroiddebug path with the settled behavior.Out of scope
Acceptance criteria
bibleTextIdis identified and documented (sync timing vs missing row vs API gap).bible_text_id.ToastAndroiddebug message inRecordTab.tsx(L131–145) is removed and replaced with real UX (disabled state + clear "still syncing"/error messaging as appropriate).bible_text_idis available.getBibleTextId/syncBibleTexts.Verification / test plan
npm run format:check·npm run lint·npm run typecheck·npm test -- --cibible_text_idand record starts. Confirm mid-sync state shows the real "still syncing" UX, not the debug toast.File pointers & approach
src/db/queries.ts—getBibleTextId()(L461–481):SELECT id FROM bible_texts WHERE bible_id/book_id/chapter_number/verse_number; returnsnullon no-row or error.src/app/tabs/RecordTab.tsx(L27–49, L73) — resolvesbibleTextIdin an effect and passesbibleTextIdForSelectedVersedown.src/app/tabs/drafting/record/RecordTab.tsx(L131–145) — TEMP toast to remove.src/services/sync.ts—syncBibleTexts()(L299+), invoked at L493/L574/L577/L585; check ordering vs chapter-assignment sync and whether all assigned verses are fetched/inserted.src/db/repository.ts—insertBibleTextswrite path.Approach: (1) reproduce and capture which
(bible_id, book_id, chapter_number, verse_number)combos miss a row; (2) determine whether the row is absent (sync/API) or the query keys are wrong; (3) fix at the correct layer; (4) swap the TEMP toast for real disabled/status UX and gate the record button.Links