Skip to main content

Database Schema — IllustrateTheWord & SermonWise

Knowledge > Architecture > Database Schema > ITW & SermonWise Tables


Database Schema — IllustrateTheWord & SermonWise

All tables owned or primarily used by sermon-illustrations/ (IllustrateTheWord) and the SermonWise feature in churchwiseai-web/src/app/sermons/. All tables live in the shared Supabase instance (wrwkszmobuhvcfjipasi), public schema.

Content Retrieval Pipeline

CRITICAL Safety Rules

  • unified_rag_content has ~326K rows — NEVER bulk delete. To hide content, set is_active = false or curation_status = 'rejected'. Never use DELETE or TRUNCATE.
  • sai_scripture has ~31K verses — read-only reference data. Never modify.
  • scripture_word_analysis has ~439K rows — word-level morphological data. Read-only in production.
  • All writes go to the ONE shared production Supabase instance. There is no staging database.

Row Count Summary

TableEst. RowsNotes
unified_rag_content~326,000CRITICAL — never bulk delete
scripture_word_analysis~439,000Read-only morphological data
sai_scripture_access_log~244,000Usage telemetry
sai_generated_content~23,700AI-generated sermon content
theological_rag_documents~5,500Theological commentary
word_study_lexicon~14,300Hebrew/Greek lexicon
sai_strongs_concordance~14,200Strong's numbers
pericope_lens_perspectives~18,600Lens-specific sermon angles
sai_scripture~31,000Bible verses (multi-translation)
bible_passages~6,984Canonical passage registry
bible_passages_canonical~3,727Deduplicated canonical passages
bible_passages_id_mapping~3,492Old-to-new passage ID map
theological_lens_positions~578Per-lens doctrinal positions
content_passage_links~9,908Content-to-passage associations
content_chunks~1,456Legacy chunked content
sai_lectionary_calendar~208Liturgical calendar entries
sai_lectionary_readings~712Lectionary passage assignments
narrative_units~167Narrative groupings in scripture
pericope_thematic_links~107Cross-pericope thematic links
theme_pericope_connections~73Theme-to-pericope mapping
lens_affinity~68Lens compatibility scores
bible_book_lens_perspectives~133Per-book lens emphases
sai_bible_book_overviews~132Book-level overviews
bible_book_metadata~66Extended book metadata
theological_contradictions~124Per-lens doctrinal guardrails
sai_people_in_story~237Biblical characters
sai_sermon_methods~4Sermon structure methods
method_lens_guidance~187Method × lens adaptations
sai_theological_lenses~18The 18 theological lenses
profiles~6User profiles (ITW/SermonWise)
user_subscriptions~1Stripe subscription records
user_theological_preferences~11Per-user lens preferences
illustrations~93Legacy illustration table
unified_rag_content_staging~3,312Staging before production promotion

1. Content Core

unified_rag_content

The primary content store for all ITW illustrations, sermon starters, commentaries, and AI-generated content. ~326K rows. Queried by the ITW frontend, SermonWise RAG pipeline, and chatbot.

ColumnTypeNullableNotes
iduuidNOT NULLPK, gen_random_uuid()
legacy_tabletextYESSource table before migration
legacy_idtextYESSource row ID before migration
content_categorytextNOT NULLe.g. illustration, commentary, sermon_starter
content_typetextNOT NULLSub-type within category
content_formattextYESDefault 'full_text'
titletextYESDisplay title
contenttextNOT NULLThe full content body
summarytextYESShort summary for search results
word_countintegerYES
canonical_pericope_idintegerYESFK → bible_passages_canonical.id
pericopetextYESHuman-readable pericope label
scripture_referencestext[]YESArray of reference strings
scripture_startjsonbYES{book, chapter, verse}
scripture_endjsonbYES{book, chapter, verse}
scripture_hierarchyjsonbYESNested book/chapter/verse metadata
theological_lens_idintegerYESFK → sai_theological_lenses.lens_id
lens_tagsint[]YESAdditional lens IDs
lens_variationsjsonbYESPer-lens content variants
denominational_focustextYES
themestext[]YES
topicstext[]YES
keywordstext[]YES
emotionstext[]YES
human_needstext[]YES
doctrinestext[]YES
spiritual_disciplinestext[]YES
application_pointstext[]YES
source_typetextYESoriginal, public_domain, fair_dealing, etc.
source_attributiontextYESDisplay attribution string
primary_sourcetextYESPublication or work title
primary_authortextYES
copyright_statustextYES
fair_dealing_compliantbooleanYESDefault true
quality_scorenumericYES0–1 composite score
appropriateness_ratingintegerYESDefault 5 (1–10 scale)
canadian_compliantbooleanYESDefault true
curation_statustextYESpending, approved, rejected — Default 'pending'
auto_approvedbooleanYESDefault false
moderation_notestextYES
audience_primarytextYES
audience_suitabilitytext[]YES
app_compatibilitytext[]YESWhich apps can surface this content
usage_typestext[]YES
sermon_sectionstext[]YES
embeddingvectorYESpgvector embedding
embedding_modeltextYESDefault 'text-embedding-3-small'
ai_model_usedtextYES
generation_prompttextYES
generation_costnumericYES
tokens_usedintegerYES
parent_content_iduuidYESFK → self (versioning)
related_content_idsuuid[]YES
organization_iduuidYES
created_byuuidYESFK → profiles.id
approved_byuuidYES
import_batch_idtextYES
import_sourcetextYES
metadatajsonbYESDefault {}
search_vectortsvectorYESFull-text search index
view_countintegerYESDefault 0
use_countintegerYESDefault 0
last_used_attimestamptzYES
created_attimestamptzYESDefault now()
updated_attimestamptzYESDefault now()
is_universalbooleanYESDefault false
creative_approachvarcharYES
pericope_unlinkablebooleanYESDefault false
contributor_user_iduuidYES
rag_contribution_iduuidYES
is_activebooleanYESDefault trueuse this to hide content, never DELETE
slugtextYESURL slug for public pages
teasertextYESShort preview for paywalled content
visibility_tiertextYESfree, premium, etc.
image_urltextYES
tonetextYES

Safety: Never bulk delete. To unpublish: UPDATE unified_rag_content SET is_active = false WHERE ...


unified_rag_content_staging

Mirrors the schema of unified_rag_content exactly (plus 3 migration columns). Used to stage content before promoting to production. ~3,312 rows.

Additional columns (not in production table):

  • migration_status text — Default 'pending'
  • migrated_at timestamptz
  • migration_batch_id text

illustrations

Legacy illustration table — predates unified_rag_content. ~93 rows. New content goes to unified_rag_content. Kept for backward compatibility.

ColumnTypeNotes
iduuid PK
titletext NOT NULL
contenttext NOT NULL
source_typetext
source_attributiontext
themestext[]
appropriateness_ratinginteger
audience_suitabilitytext[]
embeddingvectorpgvector
created_attimestamptz
organization_iduuid
theological_lens_idinteger
fair_dealing_purposetext
copyright_statustext
usage_rightstext
educational_contexttext
content_typetext
legal_review_statustext
six_factor_analysisjsonbCanadian fair dealing 6-factor test
canadian_compliantboolean
primary_passage_iduuid
lens_compatibilitytext[]
method_compatibilitytext[]
theological_emphasistext[]
sermon_section_fittext[]
content_warningstext[]
cultural_sensitivity_notestext
ai_generatedbooleanDefault false
ai_modelvarchar
generation_costnumeric
generation_tokens_usedinteger
account_iduuid
app_suitabilityjsonbDefault {}
usage_typestext[]Default ['sermon_illustration']
user_iduuid

sai_generated_content

AI-generated sermon content (starters, outlines, reflections). ~23,700 rows. Separate from unified_rag_content — these are AI outputs tied to a specific lens + scripture reference.

ColumnTypeNotes
iduuid PKgen_random_uuid()
typetext NOT NULLContent type (sermon_starter, outline, etc.)
titletext NOT NULL
contenttext NOT NULL
summarytext
theological_lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
scripture_referencetextHuman-readable ref
scripture_booktext
scripture_chapterinteger
scripture_verse_startinteger
scripture_verse_endinteger
generation_sourcetext NOT NULLDefault 'ai'
ai_model_usedtext
prompt_template_usedtext
generation_parametersjsonbDefault {}
statustext NOT NULLDefault 'pending'
relevance_scorenumeric
theological_accuracy_scorenumeric
readability_scorenumeric
usage_countintegerDefault 0
embedding_createdbooleanDefault false
embedding_iduuid
created_byuuid
organization_iduuid
reviewed_byuuid
reviewed_attimestamptz
review_notestext
approved_byuuid
approved_attimestamptz
tagstext[]Default {}
audiencetext
difficulty_leveltext
language_codetextDefault 'en'
metadatajsonbDefault {}
version_numberintegerDefault 1
parent_content_iduuid
is_current_versionbooleanDefault true
generated_attimestamptzDefault now()
created_attimestamptzDefault now()
updated_attimestamptzDefault now()
embeddingvectorpgvector
embedding_updated_attimestamptz

2. Scripture & Bible

sai_scripture

The full Bible text in multiple translations. ~31,000 rows (one per verse). Read-only reference data.

ColumnTypeNotes
verse_idbigint PKNumeric verse ID
book_nametext NOT NULLe.g. 'Genesis'
book_numberinteger NOT NULL1–66 (OT 1–39, NT 40–66)
chapterinteger NOT NULL
verseinteger NOT NULL
text_kjvtext
text_amptext
text_nettext
text_nasbtext
text_webtext
text_originaltextHebrew/Greek original
text_translittextTransliteration
original_languagetext'Hebrew' or 'Greek'
text_esvtext
text_nivtext
verse_numbering_metadatajsonbCross-translation verse number notes
translation_sourcesjsonbSource tracking per translation
language_familytext
canonical_pericope_idintegerFK → bible_passages_canonical.id
narrative_unit_idintegerFK → narrative_units.id

scripture_word_analysis

Word-level morphological analysis for every verse. ~439,000 rows. One row per word per verse. Used by SermonWise word study feature.

ColumnTypeNotes
iduuid PK
verse_idbigint NOT NULLFK → sai_scripture.verse_id
word_positioninteger NOT NULLWord order within verse (1-indexed)
original_wordtext NOT NULLHebrew/Greek original
transliterationtext
strong_numbertexte.g. H1234, G5678
morphologytextFull morphology code
part_of_speechtext
stemtextVerbal stem (Hebrew: Qal, Niphal, etc.)
persontext1st/2nd/3rd
gendertextmasculine/feminine/neuter
numbertextsingular/plural/dual
tensetext
voicetextactive/passive/middle
moodtextindicative/subjunctive/imperative/etc.
case_typetextnominative/genitive/dative/accusative/vocative
statetextabsolute/construct (Hebrew)
english_glosstextShort English gloss
contextual_translationtextContextual rendering
created_attimestamptzDefault now()

word_study_lexicon

Hebrew/Greek lexicon with full definitions. ~14,300 entries. The primary lexicon used by SermonWise word study.

ColumnTypeNotes
iduuid PK
strong_numbertext NOT NULLe.g. H1, G1
original_wordtext NOT NULL
transliterationtext NOT NULL
pronunciationtext
languagetext NOT NULL'Hebrew' or 'Greek'
part_of_speechtext
definitionjsonb NOT NULLStructured definition with glosses and extended senses
etymologytext
usage_notestext
frequencyintegerDefault 0 — occurrence count in Bible
created_attimestamptzDefault now()
updated_attimestamptzDefault now()

sai_strongs_concordance

Strong's Concordance entries. ~14,200 rows. Parallel to word_study_lexicon — older/simpler structure, used for concordance lookup.

ColumnTypeNotes
strongs_numbervarchar PKe.g. H1234
languagevarchar NOT NULL'Hebrew' or 'Greek'
lemmatextBase lexical form
transliterationtext
pronunciationtext
definitiontextPlain text definition
kjv_definitiontextKJV-specific gloss
derivationtextEtymological note
created_attimestamptzDefault CURRENT_TIMESTAMP
updated_attimestamptzDefault CURRENT_TIMESTAMP

bible_passages

All named Bible passages. ~6,984 rows. The working passage registry. May contain duplicates (see bible_passages_canonical).

ColumnTypeNotes
idinteger PK
book_numberinteger NOT NULL1–66
book_namevarchar NOT NULL
passage_referencevarchar NOT NULLe.g. John 3:16
full_text_referencevarchar NOT NULLVerbose form

bible_passages_canonical

Deduplicated canonical passage registry. ~3,727 rows. The preferred table for passage lookups — duplicates from bible_passages have been resolved here.

ColumnTypeNotes
idinteger PK
book_numberinteger NOT NULL
book_namevarchar NOT NULL
passage_referencevarchar NOT NULL
full_text_referencevarchar NOT NULL
created_attimestampDefault now()
migrated_from_idsint[]Old bible_passages IDs this replaced
book_number_startinteger
chapter_startinteger
verse_startinteger
book_number_endinteger
chapter_endinteger
verse_endinteger
narrative_unit_idintegerFK → narrative_units.id
pericope_themestext[]

bible_passages_id_mapping

Migration map from old bible_passages IDs to canonical IDs. ~3,492 rows. Used to resolve foreign key references that used pre-deduplication IDs.

ColumnTypeNotes
old_idinteger NOT NULLOld bible_passages.id
new_canonical_idinteger NOT NULLFK → bible_passages_canonical.id
book_numberinteger NOT NULL
passage_referencevarchar NOT NULL
mapping_reasonvarcharDefault 'deduplication'
created_attimestamp

bible_book_metadata

Extended metadata for each Bible book. ~66 rows (one per book).

ColumnTypeNotes
idinteger PK
book_numberinteger NOT NULL
book_nametext NOT NULL
theme_statementtext
jesus_lenstextChristological interpretation
historical_contexttext
authortext
date_writtentext
audiencetext
key_themestext[]
testamenttext'OT' or 'NT'
genretext
created_attimestamptz
updated_attimestamptz
book_outlinejsonbChapter-by-chapter structure
key_passagestext[]
literary_featurestext[]
popular_sermon_passagestext[]
sermon_series_ideasjsonb
difficulty_levelinteger
common_misconceptionstext[]
related_bookstext[]
nt_quotes_otjsonbNT quotations from this OT book
parallel_passagestext[]
thematic_connectionstext[]
chapter_countinteger
verse_countinteger
reading_time_minutesinteger

sai_bible_book_overviews

Sermon-focused book overviews (simpler than bible_book_metadata). ~132 rows (2 rows per book — OT + NT sets).

ColumnTypeNotes
book_numberinteger NOT NULL
book_namevarchar NOT NULL
authorvarchar
time_writtenvarchar
language_writtenvarcharHebrew/Greek/Aramaic
main_theme_god_activetextGod's primary action in this book
detailed_themetext
short_summarytext
detailed_summarytext
jesus_lenstextChristological connection
cultural_contexttext
main_characterstext
genrevarchar
audiencevarchar
canonical_divisionvarcharTorah, Prophets, Writings, Gospels, etc.
key_versevarchar

3. Theological Framework

sai_theological_lenses

The 18 theological lenses — the core taxonomy that shapes all content and user experience in ITW and SermonWise.

ColumnTypeNotes
lens_idinteger PK
lens_namevarchar NOT NULLe.g. 'Reformed', 'Wesleyan', 'Charismatic'
core_focustextOne-sentence focus statement
key_questiontextThe lens's central interpretive question
principle_authoritytextView of Scripture authority
principle_christologytextChristological emphasis
principle_soteriologytextView of salvation
principle_ecclesiologytextView of church
principle_ethical_missiontextEthical and missional emphasis
is_visibleboolean NOT NULLDefault true — hides deprecated lenses

theological_rag_documents

Theological commentary and source documents for RAG. ~5,500 rows. Pre-embedding theological content used to enrich sermon preparation.

ColumnTypeNotes
iduuid PK
pericopetextAssociated pericope label
lens_tagsint[] NOT NULLFK array → sai_theological_lenses.lens_id
content_typetext NOT NULLType of theological content
base_contenttext NOT NULLThe main content body
lens_variationsjsonbPer-lens content adaptations
quality_score_iduuidFK → quality scoring table
curation_statustext NOT NULLDefault 'pending'
primary_sourcetext NOT NULL
primary_authortext NOT NULL
license_typetext NOT NULL
attribution_texttext NOT NULL
source_urlstext[]
embeddingvectorpgvector
tokensinteger NOT NULLDefault 0
last_scrapedtimestamptz
scrape_versionintegerDefault 1
enhancement_leveltextDefault 'raw'
ai_enhancement_notestext
organization_iduuid
created_byuuid
reviewed_byuuid
approved_byuuid
created_attimestamptz
updated_attimestamptz
scripture_scope_typetext'verse', 'pericope', 'chapter', 'book'
scripture_startjsonb
scripture_endjsonb
canonical_pericope_idintegerFK → bible_passages_canonical.id
scripture_hierarchyjsonb

theological_lens_positions

Per-lens doctrinal positions on contested questions. ~578 rows. Used by the chatbot and voice agent to ensure lens-consistent answers.

ColumnTypeNotes
iduuid PK
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
question_categorytext NOT NULLe.g. 'soteriology', 'eschatology'
lens_specific_answertext NOT NULLWhat this lens teaches on this question
confidence_scorenumericDefault 1.0
created_attimestamptz
updated_attimestamptz
contrary_positionsjsonbDefault {} — positions this lens rejects

theological_contradictions

Guardrails defining what each lens must NOT say. ~124 rows. Validation rules that prevent theologically inconsistent content generation.

ColumnTypeNotes
iduuid PK
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
doctrine_categorytext NOT NULL
doctrine_subcategorytext
primary_positiontext NOT NULLThe correct position for this lens
contrary_positionstext[] NOT NULLPositions that contradict this lens
must_include_termstext[]Terms required in valid content
must_exclude_termstext[]Terms that invalidate content
severitytext NOT NULLDefault 'error' ('error' or 'warning')
validation_regextextOptional regex for automated checks
explanationtextHuman-readable rationale
biblical_referencestext[]
historical_contexttext
created_attimestamptz
updated_attimestamptz
created_byuuid

theological_documents

Full theological source documents (creeds, confessions, academic papers). Rarely queried directly — chunked into theological_document_chunks for RAG.

ColumnTypeNotes
iduuid PK
titletext NOT NULL
authortext
categorytext NOT NULL
subcategorytext
denominationtext
year_writteninteger
contenttext NOT NULLFull document text
content_hashtextDeduplication hash
embeddingvectorDocument-level embedding
theological_traditiontext
primary_topicstext[]
scripture_referencestext[]
theological_weightnumericDefault 1.0
usage_countintegerDefault 0
last_accessedtimestamp
source_urltext
copyright_infotext
is_public_domainbooleanDefault false
languagetextDefault 'en'
metadatajsonbDefault {}
created_attimestamp
updated_attimestamp
created_byuuid
search_texttsvectorFull-text index

theological_document_chunks

Chunked segments of theological_documents for RAG retrieval. Schema is present; row count shows empty (not yet populated in production).

ColumnTypeNotes
iduuid PK
document_iduuidFK → theological_documents.id
chunk_indexinteger NOT NULLChunk order within document
chunk_texttext NOT NULL
chunk_embeddingvectorpgvector
section_titletext
subsection_titletext
paragraph_numberinteger
word_countinteger
start_positionintegerCharacter offset
end_positioninteger
created_attimestamp

method_lens_guidance

How each sermon method should be adapted per theological lens. ~187 rows (method × lens pairs).

ColumnTypeNotes
idinteger PK
method_idinteger NOT NULLFK → sai_sermon_methods.method_id
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
adaptation_summarytext NOT NULLBrief adaptation description
section_adaptationsjsonb NOT NULLPer-section guidance, Default {}
adjusted_length_minutesinteger
adjusted_word_countsjsonbPer-section word count targets
theological_emphasistext NOT NULLWhat to emphasize for this lens
authority_sourcestext[] NOT NULLRecommended sources for this lens
vocabulary_overridesjsonbLens-specific terminology substitutions
tone_guidancetext NOT NULL
fit_scorenumeric NOT NULLDefault 3.0 (1–5 scale)
fit_notestext
is_recommendedbooleanDefault false
created_attimestamptz

lens_affinity

Compatibility scores between pairs of lenses. ~68 rows. Used to suggest complementary secondary lenses.

ColumnTypeNotes
idinteger PK
source_lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
target_lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
affinity_scorenumeric NOT NULL0–1 compatibility score
affinity_categorytext'complementary', 'contrasting', etc.
notestext
created_attimestamptz

4. Sermon Structure

pericope_lens_perspectives

The core sermon preparation data. ~18,600 rows. One row per (pericope × lens) pair — provides theological interpretation, preaching angles, and sermon starters for every passage through every lens.

ColumnTypeNotes
idinteger PK
canonical_pericope_idinteger NOT NULLFK → bible_passages_canonical.id
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
theological_emphasistext NOT NULLCore theological angle for this lens
interpretive_notestextExegetical observations
doctrinal_connectionstext[]
application_themestext[]
preaching_anglestext[]Distinct angle options for a sermon
sermon_startersjsonbPre-written opening hooks
key_commentatorstext[]Recommended commentators
textual_pointstext[]Key textual observations
show_dont_telljsonbNarrative illustration prompts
imagery_elementstext[]Visual/sensory elements
cautionstext[]Theological pitfalls to avoid
liturgical_connectionstextConnection to liturgical season/calendar
source_attributiontext
quality_scorenumericDefault 0.85
review_statustextDefault 'pending'
reviewed_bytext
reviewed_attimestamptz
created_attimestamptz
updated_attimestamptz

Cross-pericope connections by theme or type. ~107 rows.

ColumnTypeNotes
idinteger PK
source_pericope_idinteger NOT NULLFK → bible_passages_canonical.id
target_pericope_idinteger NOT NULLFK → bible_passages_canonical.id
link_typetext NOT NULL'typological', 'thematic', 'narrative', etc.
shared_themestext[]
link_strengthinteger1–5
source_attributiontext
created_attimestamptz
updated_attimestamptz

narrative_units

Narrative groupings spanning multiple pericopes. ~167 rows. Groups passages into larger narrative arcs (e.g., "The Passion Narrative", "The Exodus").

ColumnTypeNotes
idinteger PK
nametext NOT NULLe.g. 'The Sermon on the Mount'
referencetext NOT NULLHuman-readable range
descriptiontext
book_number_startinteger NOT NULL
chapter_startinteger NOT NULL
verse_startinteger NOT NULL
book_number_endinteger NOT NULL
chapter_endinteger NOT NULL
verse_endinteger NOT NULL
unit_typetext'narrative', 'discourse', 'poem', etc.
testamenttext
parent_unit_idintegerFK → self (nested units)
themestext[]
created_attimestamptz
updated_attimestamptz

bible_book_lens_perspectives

Book-level lens emphasis (macro view). ~133 rows (books × lenses). Complements pericope_lens_perspectives for book-level preaching plans.

ColumnTypeNotes
idinteger PK
book_numberinteger NOT NULL1–66
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
lens_emphasistext NOT NULLHow this lens reads this whole book
key_passagestext[]
key_commentatorstext[]
interpretation_notestext
common_sermon_themestext[]
hermeneutical_approachtext
doctrinal_connectionstext[]
source_attributiontext
quality_scorenumericDefault 0.85
created_attimestamptz
updated_attimestamptz

theme_pericope_connections

Links themes to pericopes. ~73 rows. Maps curriculum-level thematic entries to canonical passages.

ColumnTypeNotes
connection_iduuid PK
theme_iduuid NOT NULL
canonical_pericope_idinteger NOT NULLFK → bible_passages_canonical.id
connection_strengthvarcharDefault 'secondary' ('primary', 'secondary')
teaching_notestext
curriculum_levelintegerDefault 101
lens_specific_notesjsonbDefault {}
display_orderinteger
is_exemplarbooleanDefault false
created_attimestamptz
updated_attimestamptz
created_byuuid

Association table linking content chunks to Bible passages. ~9,908 rows. Bridges content_chunks (and unified_content_id) to bible_passages.

ColumnTypeNotes
iduuid PK
content_chunk_iduuidFK → content_chunks.id
passage_idintegerFK → bible_passages.id
relevance_scorefloatDefault 0.8
link_typetextDefault 'thematic'
created_attimestamptz
user_iduuid
unified_content_iduuidFK → unified_rag_content.id

content_chunks

Legacy chunked content table — predates unified_rag_content. ~1,456 rows. New content goes to unified_rag_content.

ColumnTypeNotes
iduuid PK
contenttext NOT NULL
embeddingvectorpgvector
metadatajsonb
source_typetext
denominationtext
scripture_referencestext[]
themestext[]
created_attimestamptz
organization_iduuid
theological_lens_idinteger
account_iduuid
app_compatibilitytext[]Default ['sermon-companion']
content_typevarcharDefault 'sermon_starter'
usage_contextstext[]
user_iduuid
commentary_typetext
authortext
work_titletext
publication_yearinteger
scripture_booktext
scripture_chapterinteger
scripture_verse_startinteger
scripture_verse_endinteger

sai_passage_lens_data

Structured sermon outline data per (passage × lens × method). Row count: ~0 in production estimates but schema exists. May be populated by scripts.

ColumnTypeNotes
passage_lens_data_idinteger PK
passage_idinteger NOT NULLFK → bible_passages.id
lens_idinteger NOT NULLFK → sai_theological_lenses.lens_id
method_idinteger NOT NULLFK → sai_sermon_methods.method_id
sermon_titlevarchar
outline_data_jsonjsonbFull sermon outline
show_dont_tell_prompttextNarrative illustration prompt

sai_sermon_methods

Sermon structure methods (e.g., expository, topical, narrative). ~4 rows.

ColumnTypeNotes
method_idinteger PK
method_namevarchar NOT NULL
method_descriptiontext
structure_templatejsonbOutline template
ai_generation_prompttextLLM prompt for this method
section_definitionsjsonbWhat each section does
time_allocationjsonbSuggested time per section
best_for_passagestext[]Passage types this method suits best
prompt_variablesjsonbTemplate variable definitions
example_sermonsjsonb
method_strengthstext[]
ideal_length_minutesintegerDefault 20
requires_greek_hebrewbooleanDefault false
complexity_leveltextDefault 'intermediate'
usage_countintegerDefault 0
avg_user_ratingnumeric
last_updatedtimestamp
is_custombooleanDefault false
created_byuuid

sai_people_in_story

Biblical characters and persons referenced in sermon content. ~237 rows.

ColumnTypeNotes
idinteger PK
person_nametext NOT NULL
person_typetext NOT NULL'biblical_figure', 'historical', etc.
descriptiontext
biblical_roletext
key_attributestext[]
testamenttext'OT', 'NT', 'both'
created_attimestamptz
updated_attimestamptz

5. Lectionary

The lectionary system covers the Revised Common Lectionary (RCL) and tracks the 3-year cycle of liturgical readings.

sai_lectionary_years

The three lectionary years. 3 rows.

ColumnTypeNotes
idinteger PK
year_namevarchar NOT NULL'Year A', 'Year B', 'Year C'

sai_lectionary_sundays

All Sundays and special days within each lectionary year.

ColumnTypeNotes
idinteger PK
year_idintegerFK → sai_lectionary_years.id
sort_orderintegerDisplay/sort order within year
seasonvarchar'Advent', 'Christmas', 'Epiphany', 'Lent', 'Easter', 'Ordinary'
sunday_namevarchare.g. 'Second Sunday of Advent'

sai_lectionary_calendar

Calendar date to lectionary Sunday mapping. ~208 rows. Ties calendar dates to lectionary positions.

ColumnTypeNotes
idinteger PK
calendar_datedate NOT NULL
liturgical_yearchar NOT NULL'A', 'B', or 'C'
liturgical_seasonvarchar NOT NULL
sunday_namevarchar NOT NULL
week_numberintegerWeek within season
is_special_daybooleanDefault false (feast days, holy days)
notestext
created_attimestampDefault now()
lectionary_typetext NOT NULLDefault 'rcl'

sai_lectionary_readings

The four assigned readings per lectionary Sunday. ~712 rows (typically 4 per calendar entry: OT, Psalm, Epistle, Gospel).

ColumnTypeNotes
idinteger PK
calendar_idinteger NOT NULLFK → sai_lectionary_calendar.id
reading_typevarchar NOT NULL'OT', 'Psalm', 'Epistle', 'Gospel'
passage_referencevarchar NOT NULLHuman-readable ref (e.g. Romans 8:1-11)
liturgical_yearvarchar NOT NULL'A', 'B', 'C'
passage_texttextCached passage text
created_attimestampDefault now()
lectionary_typetext NOT NULLDefault 'rcl'

6. Lookup Tables (15 tables)

Fifteen sai_lookup_* tables provide controlled vocabulary for tagging and search filtering across illustration and sermon content. All follow a simple 2-column pattern: id (integer or bigint PK) + a name column.

TableName ColumnRow CountPurpose
sai_lookup_themestheme_name171Thematic tags (Covenant, Redemption, Grace, …)
sai_lookup_doctrinesdoctrine_name21Doctrinal categories
sai_lookup_emotionsemotion_name17Emotional tone of content
sai_lookup_spiritual_disciplinesdiscipline_name14Spiritual discipline focus
sai_lookup_theological_emphasesemphasis_name14Theological accent
sai_lookup_human_strugglesstruggle_name13Human struggle type (grief, doubt, …)
sai_lookup_trivia_categoriescategory_name12Bible trivia categories
sai_lookup_human_needsneed_name12Human need addressed
sai_lookup_sermon_series_ideasseries_title11Series title ideas
sai_lookup_apologetic_objectionsobjection_name9Apologetic objections addressed
sai_lookup_applicational_pointspoint_tag9Application point tags
sai_lookup_gospel_elementselement_name9Gospel narrative elements
sai_lookup_seeker_audiencesaudience_name8Target audience type
sai_lookup_illustrative_anecdotesanecdote_tag8Anecdote/story type tags
sai_lookup_insight_typestype_name7Insight classification

These tables are referenced by unified_rag_content array columns (themes, doctrines, emotions, etc.) as controlled vocabulary values.


7. Users & Subscriptions

profiles

User profile table for ITW and SermonWise. ~6 rows. Shared auth table — users authenticated via Supabase Auth have a corresponding profile here.

Key columns:

ColumnTypeNotes
iduuid PKMatches auth.users.id
emailtext NOT NULL
full_nametext
denominationtext
church_nametext
roletextDefault 'pastor'
subscription_tiertextDefault 'free' ('free', 'sermon_pro'). Set to 'sermon_pro' by Stripe webhook on free→Pro upgrade; reset on customer.subscription.deleted.
preferencesjsonbDefault {}
stripe_customer_idtext
account_typetextDefault 'individual'
theological_lens_idintegerPrimary lens preference
free_tier_sermon_limitintegerDefault 3
onboarding_completedboolean NOT NULLDefault false
app_sourcetextDefault 'churchwiseai'. Set by the handle_new_user() trigger from auth.users.raw_user_meta_data->>'app_source' (migration 2026-05-11-handle-new-user-app-source.sql). SermonWise signups write 'sermon_starter'. Never write normalizePlanTier() output here.
first_app_visit_attimestamptzNULL until user's first /sermons/app load. Set via POST /api/sermons/log-first-visit (atomic UPDATE-WHERE-NULL). Gates the PostHog first_app_visit funnel event so it fires once per user (replaces broken localStorage gate that persisted across user accounts in same browser). Migration add_profiles_first_app_visit_at 2026-05-09.
pro_welcome_email_sent_attimestamptz (in user_metadata)Idempotency flag for sendSermonProWelcomeEmail(). Stored in auth.users.raw_user_meta_data, not directly on profiles row. Set on first welcome-Pro email send.
created_attimestamptz
updated_attimestamptz

Realtime subscription enabled 2026-05-09 (enable_realtime_on_profiles_for_sermonwise_upgrade migration). Required for the useProfileTierRealtime client hook in src/hooks/useProfileTierRealtime.ts — both the SermonWise dashboard page (one-shot subscribe on ?upgraded=1) and SermonAppHeader (long-lived subscribe) listen for UPDATE events on this row to refresh usage data live when the Stripe webhook flips subscription_tier.

Additional gamification/social columns: total_xp, current_level, xp_to_next_level, follower_count, following_count, is_verified, is_moderator, privacy_settings (jsonb), social_links (jsonb) — these are legacy B2C features from ai-sermon-assistant/, currently unused in production.


user_subscriptions

Stripe subscription records for ITW/SermonWise users. ~1 row (founder test).

ColumnTypeNotes
iduuid PK
user_iduuid NOT NULLFK → profiles.id
pricing_tier_iduuid NOT NULLFK → pricing tier
stripe_subscription_idvarchar
stripe_customer_idvarchar
statusvarchar NOT NULLDefault 'active'
current_period_starttimestamptz
current_period_endtimestamptz
trial_starttimestamptz
trial_endtimestamptz
cancel_at_period_endboolean NOT NULLDefault false
canceled_attimestamptz
ended_attimestamptz
created_attimestamptz
updated_attimestamptz
is_founder_memberboolean
founder_enrolled_attimestamptz
locked_price_centsintegerFounder price lock
founder_member_numberinteger

user_favorites

User-saved illustration favorites. ~0 rows.

ColumnTypeNotes
iduuid PKgen_random_uuid()
user_iduuid NOT NULLFK → profiles.id
illustration_iduuid NOT NULLFK → unified_rag_content.id (or illustrations.id)
created_attimestamptz NOT NULLDefault now()

user_theological_preferences

Per-user theological lens preferences. ~11 rows.

ColumnTypeNotes
iduuid PK
user_iduuid NOT NULLFK → profiles.id
primary_lens_idintegerFK → sai_theological_lenses.lens_id
secondary_lensesint[]Default []
per_app_preferencesjsonbDefault {} — per-app lens overrides
content_appropriateness_minintegerDefault 5
preferred_sourcestext[]Default []
created_attimestamptz
updated_attimestamptz

sai_scripture_access_log

Usage telemetry: scripture lookups. ~244,000 rows. Tracks which passages were accessed, by whom, and how fast.

ColumnTypeNotes
iduuid PKgen_random_uuid()
scripture_referencetext NOT NULL
analysis_typetext NOT NULLType of analysis performed
was_cachedbooleanDefault false
access_time_msintegerDefault 0 — response time
user_iduuidFK → profiles.id
created_attimestamptzDefault now()

8. Backup / Staging Tables

These are read-only artifacts. Never write to them.

TableEst. RowsNotes
unified_rag_content_backup_20251210~20,600Snapshot from Dec 10 2025 before a major migration. Same schema as unified_rag_content.
scripture_word_analysis_orphaned_backup~84,800Word analysis rows that lost their verse_id FK during a re-import. Same schema as scripture_word_analysis.
content_passage_links_backup~9,908Pre-migration backup of content_passage_links. Same schema minus NOT NULL constraints.
quality_scores_backup_20250918unknownBackup of quality scoring data from Sep 2025 before quality score schema changed. Columns: id, theological_accuracy, practical_value, scholarly_depth, accessibility, scripture_alignment, overall, confidence, scoring metadata.
sai_passage_lens_data_backupunknownBackup of sai_passage_lens_data before a schema migration.
staging_lexiconunknownStaging table for word_study_lexicon imports. Mirrors lexicon schema.
staging_word_analysisunknownStaging table for scripture_word_analysis imports.

Key Relationships

sai_theological_lenses (18 lenses)
└── pericope_lens_perspectives (18,600 rows: passage × lens)
└── sai_generated_content (per-lens generated content)
└── theological_lens_positions (doctrinal positions)
└── theological_contradictions (guardrails)
└── method_lens_guidance (method × lens adaptation)
└── lens_affinity (lens compatibility)
└── bible_book_lens_perspectives (book-level lens view)
└── unified_rag_content.theological_lens_id

bible_passages_canonical (3,727 passages)
└── pericope_lens_perspectives.canonical_pericope_id
└── theme_pericope_connections.canonical_pericope_id
└── pericope_thematic_links (cross-passage links)
└── unified_rag_content.canonical_pericope_id
└── theological_rag_documents.canonical_pericope_id

sai_scripture (31K verses)
└── scripture_word_analysis (439K word rows)
└── sai_scripture.canonical_pericope_id → bible_passages_canonical

sai_lectionary_calendar
└── sai_lectionary_readings (4 readings per calendar entry)

profiles
└── user_subscriptions
└── user_favorites → unified_rag_content
└── user_theological_preferences → sai_theological_lenses
└── sai_scripture_access_log