My Bible

資料模型

Schema 設計與資料分層架構

一、譯本檔 Schema(已實作)

一卷一檔 + _index.json,目錄名稱為來源 ID(如 youversion_cunp)。實際定義在 src/lib/bible.ts

ts
type Verse = {
  verse: number
  text: string
  merged?: true          // 被合併到前一節,text 為空
  headingBefore?: string // pericope 小標題
}

type Chapter = {
  chapter: number
  verses: Verse[]
}

type Book = {
  book: string       // OSIS 書卷 ID,例:'Gen'
  bookNameZh: string
  bookNameEn: string
  translation: string
  chapters: Chapter[]
}

// _index.json
type IndexEntry = {
  id: string          // OSIS,例:'Gen'
  nameZh: string
  nameEn: string
  testament: 'OT' | 'NT'
  order: number       // 1–66
  chapters: number    // 該卷章數
}

書卷 ID:真 OSIS 格式

採用 OSIS 標準(變動長度、首字大寫):Gen1Sam1John。不是 USFM 的 GEN/MAT。理由:OpenBible、Theographic 等資料集多用 OSIS,跨資料集 join 零摩擦。

二、人物 Schema(已實作)

來源:Theographic(TIPNR 合併已延後)。實際定義在 src/lib/people.ts,資料在 src/data/people.json

ts
type Person = {
  id: string            // Theographic slug,例:'adam', 'john-the-apostle'
  name: string          // 英文名
  displayTitle: string  // 中文顯示名(經文對齊推導)
  alphaGroup: string    // 英文首字母,用於分組瀏覽
  gender: string | null
  birthYear: number | null  // 負數 = BC
  deathYear: number | null
  verseCount: number
  verses: { osis: string; readable: string }[]
  chapters: string[]    // 出現章節,格式 'Gen.1'
  summary: string | null
  status: 'publish' | 'wip'
}

三、地點 Schema(已實作)

來源:OpenBible Geocoding × CUNP 標注。定義在 src/lib/place-annotations.ts,正規化資料在 src/data/place-meta.json(地點元資料)和 src/data/cunp-place-annotations.json(字元位置索引)。

ts
type PlaceEntry = {
  id: string          // OpenBible hex ID(7 碼,如 aea17b7)
  label: string       // 英文地名(friendly_id)
  types: string[]     // settlement | region | mountain | river | valley | campsite | special | other
  lat?: number
  lng?: number
  verseCount: number  // 出現節數
}

type AnnotationSpan = {
  placeId: string     // 同 PlaceEntry.id
  start: number       // 節文字元起始位置(UTF-16 index)
  end: number         // 節文字元結束位置(不含)
}

四、資料目錄結構(實際現況)

text
data/
├── raw/                          # 原始下載(不可刪)
│   ├── tipnr/
│   ├── theographic/              # 8 個 JSON 檔
│   ├── openbible-geocoding/
│   ├── openbible-cross-references/
│   ├── openscriptures/
│   ├── youversion_cunp/          # 1189 章 JSON
│   ├── youversion_ccbt/
│   ├── youversion_niv/
│   ├── biblegateway_ccbt/
│   ├── biblegateway_niv/
│   └── github_cuv/
├── translations/                 # 正規化譯本(可 commit)
│   ├── youversion_cunp/          # 66 卷 + _index.json
│   ├── youversion_ccbt/
│   ├── youversion_niv/
│   ├── biblegateway_ccbt/
│   ├── biblegateway_niv/
│   └── github_cuv/               # 66 卷,備用(未列入 AVAILABLE_TRANSLATIONS)
└── normalized/                   # 實體資料(可 commit)
    ├── people.json
    ├── cunp-place-annotations.json  # OSIS → [{placeId, start, end}]
    ├── place-meta.json              # hexId → {label, types, lat, lng}
    ├── places-comparison.json    # 三資料集地點比對
    ├── translation-diff.json     # 譯本章節差異
    └── niv-diff-detail.txt       # NIV 跨來源逐節比對

五、規劃中(未實作)

以下 schema 已設計,尚未建立對應資料集或目錄:

實體維度狀態
EventTheographic 有資料,尚未 normalize
PeriodTheographic 有資料,尚未 normalize
ItemTIPNR 有部分資料,尚未 normalize
Edge(關係)跨維度schema 已設計,資料層尚未建立

規劃中的 Edge 格式

ts
type Edge = {
  id: string     // 例:'abraham--parent-of--isaac'
  from: { type: 'person' | 'place' | 'event' | 'period' | 'item'; id: string }
  to:   { type: 'person' | 'place' | 'event' | 'period' | 'item'; id: string }
  type: 'parent-of' | 'spouse-of' | 'born-in' | 'occurred-at' | 'within-period' | string
  sources: string[]
}

六、ID 命名規則

  • 實體 ID:全部 lowercase + hyphen,沿用 Theographic slug(如 john-the-apostlemt-sinai
  • 撞名加 disambiguator 後綴:john-the-apostle / john-the-elder
  • 章節引用格式:Gen.1(書卷.章),節引用:Gen.1.1