Lompat ke konten
dokumentasi.id
Commit d59d965
v3
Star763

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

2.2

Model Data Tabel roasts

Tabel roasts adalah satu-satunya tabel yang dibuat repository ini, dan tabel itu merangkap dua peran: menyimpan hasil roast dan berlaku sebagai cache per pasangan username dan language. Skemanya lahir dari berkas database.sql yang diimpor ke D1 lewat npx wrangler d1 import, baik ke database remote maupun lokal database.sql:2-11 README.md:7-9. Di runtime, kode mengakses tabel ini lewat binding DB yang dideklarasikan sebagai d1_databases bernama githubroast wrangler.toml:28-31; rincian binding dan variabel lain ada di Konfigurasi Environment dan Binding.

Struktur tabel

erDiagram
  roasts {
    integer id PK
    text gh_username
    text response
    text created_at
    text country
    text language
  }
  style roasts fill:#336791,color:#fff
%% fig: Kolom tabel roasts
%% desc: Enam kolom yang dideklarasikan database.sql; id adalah primary key AUTOINCREMENT, sisanya menyimpan isi roast dan metadata permintaan.
Fig. 1: Kolom tabel roastsEnam kolom yang dideklarasikan database.sql; id adalah primary key AUTOINCREMENT, sisanya menyimpan isi roast dan metadata permintaan.
KolomTipeConstraintNilai yang di-bind POST /llama
idintegerPRIMARY KEY AUTOINCREMENTtidak pernah di-bind kode; diisi D1
gh_usernametextNOT NULLusername dari body request
responsetextNOT NULLcompletion.choices[0].message.content
created_attextNOT NULLMath.floor(new Date().getTime() / 1000)
countrytextNOT NULLrequest.cf.country, string kosong bila cf tidak ada
languagetextNULLlanguage dari body request

Nama dan tipe seluruh kolom diambil apa adanya dari database.sql:2-9. Nilai username dan language berasal dari body request src/routes/llama/+server.js:31; nilai roast diambil dari completion.choices[0].message.content src/routes/llama/+server.js:193; empat nilai berikutnya di-bind berurutan sebagai epoch detik, country dari request.cf, hash sha256(...), dan language src/routes/llama/+server.js:198-205.

database.sql adalah hasil dump, bukan rangkaian migration: baris pertamanya PRAGMA defer_foreign_keys=TRUE dan baris kesepuluh mengosongkan sqlite_sequence database.sql:1 database.sql:10. Tidak ada direktori migration di repository; satu-satunya sumber skema adalah berkas itu.

Peran tabel sebagai cache

Sebelum menyentuh OpenAI, handler menjalankan SELECT * FROM roasts WHERE gh_username = ? AND language = ? lalu .first(). Bila ada baris, history.response langsung dikembalikan sebagai roast dan model tidak dipanggil src/routes/llama/+server.js:40-47. Pasangan gh_username dan language karena itu berperan sebagai kunci cache, bukan gh_username saja: satu username yang di-roast dalam bahasa berbeda menempati baris berbeda.

Nilai language yang tersimpan selalu salah satu dari 11 entri validLanguages, karena request dengan bahasa lain ditolak lebih dulu dengan status 400 src/routes/llama/+server.js:15-27 src/routes/llama/+server.js:33-38. Kolom language dideklarasikan text NULL database.sql:2-9, tetapi jalur tulis di endpoint ini selalu mengisinya; kolom itu nullable hanya secara deklarasi. Daftar bahasa dan prompt tiap bahasa dibahas di Prompt Multibahasa, sedangkan urutan penanganan request dibahas di Endpoint POST /llama.

Index gh_username_idx

index di tabel ini hanya satu: CREATE INDEX gh_username_idx ON roasts (gh_username) database.sql:11. Query cache memfilter dua kolom sekaligus, gh_username dan language src/routes/llama/+server.js:40-47, sehingga index hanya mempersempit pencarian pada bagian username; language disaring setelah baris kandidat dibaca.

index itu juga tidak unik. Tidak ada constraint UNIQUE pada pasangan gh_username dan language di database.sql:2-11, jadi satu pasangan bisa punya beberapa baris, dan .first() mengembalikan baris pertama menurut rencana eksekusi, bukan baris terbaru. Cache bisa menyajikan roast lama meski baris baru sudah tersimpan.

Ketidakcocokan kolom dengan kode

graph LR
  stmt["INSERT INTO roasts: gh_username, response, created_at, country, ip_address, language"] --> cek{"cocok dengan schema?"}
  cek -->|"lima kolom"| ok["baris tersimpan"]
  cek -->|ip_address| gagal["statement gagal dijalankan"]
  gagal --> telan["catch kosong membuang error"]
  style cek fill:#f59e0b,color:#000
  style ok fill:#2d7d46,color:#fff
  style gagal fill:#dc2626,color:#fff
  style telan fill:#dc2626,color:#fff
%% fig: INSERT yang tidak cocok dengan schema
%% desc: INSERT menyebut enam kolom, tetapi ip_address tidak ada di database.sql, sehingga kegagalan penulisan berhenti tanpa jejak.
Fig. 2: INSERT yang tidak cocok dengan schemaINSERT menyebut enam kolom, tetapi ip_address tidak ada di database.sql, sehingga kegagalan penulisan berhenti tanpa jejak.
HalSchema di database.sqlKode di src/routes/llama/+server.js
ip_addresstidak dideklarasikanikut di-bind pada INSERT
created_attextbilangan bulat epoch detik
nilai hash IPtidak ada kolomnyahasil sha256(...) tidak di-await

Kolom ip_address muncul di daftar kolom INSERT src/routes/llama/+server.js:195-206, padahal skema tidak memuatnya database.sql:2-11. Nilai yang di-bind untuk kolom itu adalah hasil sha256(request.headers.get('cf-connecting-ip')) src/routes/llama/+server.js:203, dan pemanggilan itu tidak memakai await, sehingga argumen yang masuk ke .bind bukan string hash. sha256 sendiri memanggil hex(hash) yang tidak pernah didefinisikan di repository, sehingga Promise hasilnya berakhir reject src/routes/llama/+server.js:215-221.

⚠️ Kegagalan INSERT ditelan oleh catch {} kosong src/routes/llama/+server.js:207. Tidak ada log dan tidak ada respons error: pengguna tetap menerima roast, tetapi baris cache tidak pernah tersimpan selama ip_address belum ada di skema, sehingga setiap request untuk pasangan yang sama memanggil ulang model.

Memperbaiki ketidakcocokan ini berarti menambahkan kolom ip_address ke skema atau menghapusnya dari daftar INSERT. Keduanya tidak mengubah jalur baca, karena history.response hanya bergantung pada gh_username dan language src/routes/llama/+server.js:40-47. Alur permintaan lengkap yang memakai tabel ini dijelaskan di Alur Permintaan Roast.