資料模型
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 標準(變動長度、首字大寫):Gen、1Sam、1John。不是 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 已設計,尚未建立對應資料集或目錄:
| 實體 | 維度 | 狀態 |
|---|---|---|
| Event | 事 | Theographic 有資料,尚未 normalize |
| Period | 時 | Theographic 有資料,尚未 normalize |
| Item | 物 | TIPNR 有部分資料,尚未 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-apostle、mt-sinai) - 撞名加 disambiguator 後綴:
john-the-apostle/john-the-elder - 章節引用格式:
Gen.1(書卷.章),節引用:Gen.1.1