refactor(types): eliminate all explicit any types (45 → 0)#8
Conversation
Category A — useNavigation<any>() (15 screens):
All replaced with proper ScreenNavProp<Stack, Screen> types.
ProphecyDetailScreen: removed unnecessary (navigation as any) cast.
Category B — component/screen prop and state types (13 files):
ChapterSkeleton: style → ViewStyle, width → DimensionValue
ScholarInfoSheet + ScholarBioScreen: bio → ScholarBio | null
useBookIntro: intro → ParsedBookIntro | null
BookIntroScreen: section/outline/plan items properly typed
SectionBlock: onRefPress → ParsedRef
ThreadViewerSheet: steps → CrossRefStep[]
DebatePanel: entries → DebateEntry[]
ReceptionPanel: entries → RecEntry[]
TranslationPanel: data → string | TransPanel
ChapterScreen: bookData → Book | null
GenealogyTreeScreen + MapScreen: proper route/nav prop types
Category C — utility types (5 files):
SearchScreen: Person, WordStudy, Verse casts replace `as any`
BookListScreen: removed unnecessary `as any` on useScrollToTop
typography.ts: result typed as Record<keyof typeof presets, ...>
treeBuilder.ts: d3 HierarchyPointNode<HierNode> replaces `any`
types/index.ts: SectionWithPanels.panels → Record<string, unknown>
New types added to types/index.ts:
ScholarBio, ParsedBookIntro, BookIntroSection,
BookIntroOutlineItem, BookIntroPlanItem, BookIntroAuthorship
Nav types updated:
GenealogyTree: accepts optional { personId }
Map: accepts optional { placeId }
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 94bf7dc85d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const heading = e.title ?? ''; | ||
| const body = e.quote ?? ''; |
There was a problem hiding this comment.
Preserve legacy
who/text keys in ReceptionPanel
This change drops support for the existing legacy reception shape (who/text) and only reads title/quote, so chapters with legacy panel data now render blank entries instead of content. The repository still contains legacy rec entries (for example content/proverbs/2.json), and the content normalizer leaves dict-form rec entries as-is (_tools/shared.py), so this is a real runtime regression for current data rather than just a type-only cleanup.
Useful? React with 👍 / 👎.
| const label = p.scholar ?? 'Scholar'; | ||
| const body = p.position ?? ''; |
There was a problem hiding this comment.
Preserve legacy debate position keys when rendering
The renderer now reads only p.scholar/p.position, but existing debate data uses legacy position fields like name, argument, and proponents (for example content/proverbs/2.json). Since there is no runtime normalization in the app for these keys, debate rows lose their labels/body text and degrade to placeholder output, which removes substantive chapter content for users.
Useful? React with 👍 / 👎.
All P3 items from UI_UX_AUDIT.md resolved: ACCESSIBILITY (#8): - 21 accessibilityRole additions (headers on all screen/section titles, buttons on all interactive elements) - 38 accessibilityLabel additions (meaningful descriptions for screen reader users on all list items, buttons, inputs, badges) - 4 accessibilityHint additions (gesture hints on tree viewport, map viewport, timeline scroll, chapter navigator) - 4 accessibilityState additions (EraFilterBar selected state) MINOR POLISH (#9): - ChapterHeader 'About This Book →' → Lucide ArrowRight icon - ChapterListScreen 'About This Book →' → Lucide ArrowRight icon - PersonDetailScreen 'See on Family Tree →' → Lucide ArrowRight icon - ParallelPassageScreen: added LoadingSkeleton for initial data load - PlanListScreen: 'Active' text → BadgeChip for visual consistency - BookmarkListScreen: regex hardened \S+ instead of \w+ - ReadingHistoryScreen: push('Chapter') within MoreStack instead of cross-tab navigate('ReadTab') — stays in current navigation context - PlanDetailScreen: same ReadTab → push fix - MoreStack: added Chapter + BookIntro screens so push() works Files: 20 changed, +93/-27
Blockers: #1 userDatabase.ts v6 migration — add prominent SQL-quoting warning comment explaining why JSON.stringify + single-quoted SQL literal is safe, so future edits don't break it #2 review.ts / userMutations.ts — spaced repetition was pre-creating all 4 interval rows (1/3/7/30d) up front, causing users to see 3 copies of each prompt between day 7 and day 30. Now schedules ONE row at interval 1; completeGuidedReviewItem inserts the next-interval row in the same transaction via new nextIntervalAfter() helper #3 build_sqlite_loaders.py — proof_text_guards loader was silently falling back to guard's own book/chapter on missing suggested_chapter. Now raises ValueError with the offending guard ref. (Note: self-reference itself is valid — it's the UX for 'read in full chapter context' — so equal values are allowed, only missing/malformed values fail) #4 guidedStudy.test.ts — fixture used 'at_a_glance: [...] as any' which disabled TS checking. Replaced with correctly-typed ParsedBookIntro containing a full BookIntroAtAGlance object, so the bookIntro code path in buildConceptChips is now actually exercised #5 userDatabase.ts — new migration v20 adds partial unique index on guided_study_sessions(chapter_id) WHERE status='active' to prevent session leaks from crashes between insert and status flip. Migration dedupes any existing duplicates to the most recently updated row first Nits: #7 types/user.ts — export GUIDED_STUDY_STEPS const; derive GuidedStudyStep type from it; add GUIDED_STUDY_STEP_LABELS map in guidedStudy/types.ts; StudySessionStepper consumes both. Migration SQL CHECK gets a comment pointing at the const as single source of truth #8 plan.ts — CONCEPT_WORDS and genrePrompt refactored; concepts gets TODO(#1584); genrePrompt switched from label.includes(...) substring match to exact Record<label,prompt> lookup (with fallback for unknown genres). Filed #1584 to migrate concepts to content/meta/concepts.json #9 ChapterScreen.tsx + navigation/types.ts — added TODO(#1585) comments around the nav escape hatch. Filed #1585 to track typed CrossTabNavProp #10 StudySessionScreen.tsx — Amicus seed query fields now truncated to 200 chars with ellipsis sentinel so long syntheses don't blow past the peek sheet or Amicus's seed-query limit #12 .gitattributes — added '* text=auto eol=lf' + binary asset list. Normalized CRLF → LF on translations.json and db-manifest.json Deferred (filed/noted separately): #6 EraTimeline RAF cleanup — legit scope creep, but splitting now is more ceremony than benefit for a solo-dev PR. Kept bundled #11 GoldStripeListItem primitive — real refactor opportunity touching 5 components; out of scope for a review-response commit Tracking issues: #1584 (concepts from meta), #1585 (typed CrossTabNavProp)
Category A — useNavigation() (15 screens):
All replaced with proper ScreenNavProp<Stack, Screen> types.
ProphecyDetailScreen: removed unnecessary (navigation as any) cast.
Category B — component/screen prop and state types (13 files):
ChapterSkeleton: style → ViewStyle, width → DimensionValue
ScholarInfoSheet + ScholarBioScreen: bio → ScholarBio | null
useBookIntro: intro → ParsedBookIntro | null
BookIntroScreen: section/outline/plan items properly typed
SectionBlock: onRefPress → ParsedRef
ThreadViewerSheet: steps → CrossRefStep[]
DebatePanel: entries → DebateEntry[]
ReceptionPanel: entries → RecEntry[]
TranslationPanel: data → string | TransPanel
ChapterScreen: bookData → Book | null
GenealogyTreeScreen + MapScreen: proper route/nav prop types
Category C — utility types (5 files):
SearchScreen: Person, WordStudy, Verse casts replace
as anyBookListScreen: removed unnecessary
as anyon useScrollToToptypography.ts: result typed as Record<keyof typeof presets, ...>
treeBuilder.ts: d3 HierarchyPointNode replaces
anytypes/index.ts: SectionWithPanels.panels → Record<string, unknown>
New types added to types/index.ts:
ScholarBio, ParsedBookIntro, BookIntroSection,
BookIntroOutlineItem, BookIntroPlanItem, BookIntroAuthorship
Nav types updated:
GenealogyTree: accepts optional { personId }
Map: accepts optional { placeId }