# Data Model Documentation — Throne of Fractured Fates Novel Manager

Dokumen ini adalah data dictionary lengkap: seluruh tabel, field, tipe data, constraint, dan relasi. Untuk daftar endpoint API, lihat `api-documentation.md`.

## Konvensi Tipe Data

| Tipe di dokumen | Keterangan |
|---|---|
| `id` | Primary key, auto increment integer |
| `string` | Teks pendek (nama, judul, label) |
| `text` | Teks panjang (paragraf, deskripsi, konten) |
| `int` | Bilangan bulat |
| `float` | Bilangan desimal |
| `enum` | Pilihan tetap, nilai dijabarkan di kolom Keterangan |
| `timestamp` | Tanggal & waktu |
| `FK → Tabel` | Foreign key merujuk ke primary key tabel lain |

---

## 1. Chapters

Tabel inti — menyimpan metadata chapter. Isi tulisan (outline/konten) **tidak** disimpan di sini, tapi di `Chapter_Versions` supaya histori edit tidak hilang.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| title | string | required | Judul chapter |
| position | float | required, unique | Menentukan urutan; nomor tampilan ("Chapter 7") dihitung dari rank field ini, bukan disimpan |
| status | enum | required | `draft` \| `dirapikan` \| `final` |
| current_version_id | FK → Chapter_Versions | nullable | Versi yang sedang aktif/ditampilkan |
| updated_at | timestamp | auto | Waktu terakhir metadata/versi berubah |

**Relasi:** 1—N ke Chapter_Versions · N—N ke Characters (via Chapter_Links) · N—N ke Locations (via Chapter_Links) · N—N ke Tags (via Chapter_Tags) · N—N ke Plot_Threads (via Plot_Mentions) · 1—N ke Timeline_Events · 1—N ke Lore_Entries (first_revealed)

---

## 2. Chapter_Versions

Snapshot isi chapter tiap kali disimpan — histori penuh, tidak pernah ditimpa.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| chapter_id | FK → Chapters | required | |
| version_number | int | required | Auto increment per chapter (1, 2, 3, ...) |
| outline | text | | Poin-poin garis besar |
| content | text | | Naskah penuh |
| word_count | int | auto | Dihitung dari `content` |
| note | string | nullable | Catatan singkat perubahan, misal "revisi plot setelah diskusi lore" |
| created_at | timestamp | auto | |

**Relasi:** N—1 ke Chapters

---

## 3. Characters

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | |
| alias | string | nullable | |
| race_id | FK → Races_Species | nullable | |
| family_id | FK → Families | nullable | |
| faction_id | FK → Factions | nullable | |
| tier_sublevel_id | FK → Tier_Sublevels | nullable | Level kekuatan saat ini |
| status | enum | required | `hidup` \| `mati` \| `tidak diketahui` |
| description | text | nullable | |
| first_appearance_chapter_id | FK → Chapters | nullable | |

**Relasi:** N—1 ke Races_Species, Families, Factions, Tier_Sublevels · 1—N ke Skills, Aetherial_Traits, Items (owner) · N—N ke Characters (via Relationships, self-referencing) · N—N ke Chapters (via Chapter_Links) · 1—N ke Character_Positions

---

## 4. Families

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | Misal "Valerius", "Valcaryn" |
| family_type | enum | required | `bangsawan` \| `rakyat biasa` \| `klan` \| `suku` — makna berbeda tergantung `race_id` |
| race_id | FK → Races_Species | required | Struktur keluarga beda antar ras (bangsawan manusia vs klan beastkin vs hierarki elf) |
| faction_id | FK → Factions | nullable | Kerajaan/organisasi asal keluarga |
| parent_family_id | FK → Families | nullable, self-reference | Untuk cabang keluarga/garis keturunan |
| notes | text | nullable | |

**Relasi:** 1—N ke Characters · N—1 ke Races_Species, Factions · self 1—N ke Families (cabang keluarga)

---

## 5. Factions

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | |
| type | enum | required | `kerajaan` \| `organisasi` \| `sindikat` |
| leader_id | FK → Characters | nullable | |
| base_location_id | FK → Locations | nullable | |

**Relasi:** 1—N ke Characters, Families, Faction_Positions · 1—N ke Locations (controlling_faction)

---

## 6. Faction_Positions

Definisi jabatan dalam suatu faksi (bukan siapa pemegangnya — itu di `Character_Positions`).

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| faction_id | FK → Factions | required | |
| title | string | required | Misal "Raja", "Putra Mahkota", "Duke" |
| hierarchy_level | int | required | Angka kecil = tingkat lebih tinggi |

**Relasi:** N—1 ke Factions · 1—N ke Character_Positions

---

## 7. Character_Positions

Junction dengan histori — satu karakter bisa punya banyak baris (riwayat jabatan dari waktu ke waktu).

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| character_id | FK → Characters | required | |
| position_id | FK → Faction_Positions | required | |
| start_chapter_id | FK → Chapters | nullable | Chapter mulai menjabat |
| status | enum | required | `aktif` \| `mantan` \| `dicabut` |

**Relasi:** N—1 ke Characters, Faction_Positions, Chapters

---

## 8. Tiers

Tabel referensi tetap — level kekuatan utama.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required, unique | Embers, Sprouts, Adepts, Practitioners, Ascendants, Sovereigns/Saint, Vessel, Transcendent, Primordials |
| level_order | int | required, unique | Urutan 1-9 |

**Relasi:** 1—N ke Tier_Sublevels

---

## 9. Tier_Sublevels

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| tier_id | FK → Tiers | required | |
| name | enum | required | `Beginner` \| `Advanced` \| `Grandmaster` — Grandmaster adalah batas atas sebelum naik ke Tier berikutnya |
| sub_order | int | required | 1-3 |

**Relasi:** N—1 ke Tiers · 1—N ke Characters

---

## 10. Skills

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| character_id | FK → Characters | required | |
| name | string | required | |
| description | text | nullable | |
| type | enum | required | `generic` \| `aetherial` |
| aetherial_trait_id | FK → Aetherial_Traits | **wajib diisi jika type = aetherial**, harus kosong jika type = generic | Skill generik tidak butuh trait; skill aetherial bergantung pada jenis & sifat trait induknya |
| first_used_chapter_id | FK → Chapters | nullable | |

**Relasi:** N—1 ke Characters, Aetherial_Traits, Chapters

---

## 11. Aetherial_Traits

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| character_id | FK → Characters | required | |
| form_name | string | required | Misal "Valkyrie" |
| nature | text | nullable | Deskripsi sifat/jenis trait — menentukan arah skill turunannya |
| grade_id | FK → Trait_Grades | nullable | Sistem grading belum final, boleh kosong |
| awakening_chapter_id | FK → Chapters | nullable | |

**Relasi:** N—1 ke Characters, Trait_Grades · 1—N ke Skills (type=aetherial)

---

## 12. Trait_Grades

Tabel referensi — kriteria tingkatan Aetherial Trait (disusun belakangan, saat sistem grading fix).

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| code | string | required, unique | Misal S, SS, SSS |
| criteria_description | text | nullable | |

**Relasi:** 1—N ke Aetherial_Traits

---

## 13. Items

Mencakup senjata, artefak, dan barang bersihir.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | Misal "Sol Aria" |
| type | enum | required | `senjata` \| `artefak` \| `consumable` |
| tier_rank | string | nullable | Misal "Divine" |
| description | text | nullable | |
| owner_id | FK → Characters | nullable | Kepemilikan saat ini |
| origin_note | text | nullable | Asal-usul/histori singkat |

**Relasi:** N—1 ke Characters (owner)

---

## 14. Locations

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | |
| parent_region | string | nullable | Benua/wilayah induk |
| description | text | nullable | |
| controlling_faction_id | FK → Factions | nullable | |

**Relasi:** N—1 ke Factions · 1—N ke Races_Species (origin) · 1—N ke Factions (base_location)

---

## 15. Races_Species

Mencakup ras utama, monster, maupun makhluk mitos.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | Manusia, Elf, Dwarf, Beastkin, dll |
| category | enum | required | `ras utama` \| `monster` \| `mitos` |
| traits_description | text | nullable | Ciri fisik & kekuatan khas |
| origin_location_id | FK → Locations | nullable | |

**Relasi:** N—1 ke Locations · 1—N ke Characters, Families

---

## 16. Relationships

Junction many-to-many antar Characters (self-referencing).

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| character_a_id | FK → Characters | required | |
| character_b_id | FK → Characters | required | |
| relation_type | string | required | keluarga, rival, mentor, romance, dll |
| status | string | nullable | Status hubungan saat ini |
| notes | text | nullable | Catatan perubahan histori bila perlu |

**Relasi:** N—1 ke Characters (dua arah)

---

## 17. Chapter_Links

Junction many-to-many Chapters ↔ Characters. Composite primary key.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| chapter_id | FK → Chapters | PK (composite) | |
| character_id | FK → Characters | PK (composite) | |
| role_in_chapter | string | nullable | Misal "POV", "cameo" |

---

## 18. Timeline_Events

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| description | text | required | |
| chrono_order | int | required | Urutan kronologis in-universe — bisa beda dari urutan chapter karena flashback |
| chapter_id | FK → Chapters | nullable | |
| in_universe_date | string | nullable | Format bebas |

**Relasi:** N—1 ke Chapters

---

## 19. Plot_Threads

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| name | string | required | Misal "Identitas pelaku kutukan Aria" |
| status | enum | required | `aktif` \| `terselesaikan` \| `menggantung` |
| resolution_notes | text | nullable | |

**Relasi:** N—N ke Chapters (via Plot_Mentions)

---

## 20. Plot_Mentions

Junction many-to-many Chapters ↔ Plot_Threads. Composite primary key.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| chapter_id | FK → Chapters | PK (composite) | |
| plot_thread_id | FK → Plot_Threads | PK (composite) | |

---

## 21. Lore_Entries

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| category | enum | required | `sistem kekuatan` \| `sejarah` \| `ras` \| `geografi` |
| title | string | required | |
| content | text | required | |
| first_revealed_chapter_id | FK → Chapters | nullable | |

**Relasi:** N—1 ke Chapters

---

## 22. Tags

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| id | id | PK | |
| label | string | required, unique | |

**Relasi:** N—N ke Chapters (via Chapter_Tags)

---

## 23. Chapter_Tags

Junction many-to-many Chapters ↔ Tags. Composite primary key.

| Field | Tipe | Constraint | Keterangan |
|---|---|---|---|
| chapter_id | FK → Chapters | PK (composite) | |
| tag_id | FK → Tags | PK (composite) | |

---

## Ringkasan Relasi Antar Tabel

| Dari | Ke | Tipe Relasi | Lewat |
|---|---|---|---|
| Chapters | Chapter_Versions | 1—N | langsung |
| Chapters | Characters | N—N | Chapter_Links |
| Chapters | Locations | N—N | Chapter_Links |
| Chapters | Tags | N—N | Chapter_Tags |
| Chapters | Plot_Threads | N—N | Plot_Mentions |
| Chapters | Timeline_Events | 1—N | langsung |
| Chapters | Lore_Entries | 1—N | first_revealed_chapter_id |
| Characters | Races_Species | N—1 | langsung |
| Characters | Families | N—1 | langsung |
| Characters | Factions | N—1 | langsung |
| Characters | Tier_Sublevels | N—1 | langsung |
| Characters | Skills | 1—N | langsung |
| Characters | Aetherial_Traits | 1—N | langsung |
| Characters | Items | 1—N | owner_id |
| Characters | Characters | N—N | Relationships |
| Characters | Faction_Positions | N—N | Character_Positions |
| Families | Families | 1—N | parent_family_id (self) |
| Factions | Faction_Positions | 1—N | langsung |
| Factions | Locations | 1—N | base_location_id / controlling_faction_id |
| Tiers | Tier_Sublevels | 1—N | langsung |
| Skills | Aetherial_Traits | N—1 | aetherial_trait_id (nullable) |
| Aetherial_Traits | Trait_Grades | N—1 | langsung |
| Races_Species | Locations | N—1 | origin_location_id |
