2.1
Alur Permintaan Roast
Satu permintaan roast berjalan dari form di browser, masuk ke endpoint POST /llama, lalu kembali sebagai teks yang dirender oleh komponen SvelteMarkdown src/routes/+page.svelte:104-1111. Di antaranya ada dua persinggahan data: tabel roasts pada binding D1 DB dan dua API eksternal, GitHub dan OpenAI. Kontrak endpoint dijelaskan di Endpoint POST /llama, sedangkan bentuk tabelnya di Model Data Tabel roasts.
Siklus Satu Request
Fungsi handleRoast mengirim POST /llama dengan header Content-Type: application/json dan body { username, language: selectedLanguage } src/routes/+page.svelte:39-452. Selama loading bernilai true, input username dan select bahasa dinonaktifkan src/routes/+page.svelte:74-943, dan tombol submit dinonaktifkan bila loading atau username kosong src/routes/+page.svelte:96-1024. Daftar pilihan bahasa berasal dari array languages src/routes/+page.svelte:12-285.
sequenceDiagram
autonumber
participant B as Browser (+page.svelte)
participant S as POST /llama
participant D as D1 roasts
participant G as GitHub API
participant O as OpenAI
B->>S: fetch /llama dengan username dan language
S->>S: cek validLanguages
alt language tidak valid
S-->>B: 400 error invalid language specified, please pass a valid language.
else language valid
S->>D: SELECT * FROM roasts WHERE gh_username = ? AND language = ?
alt row ditemukan
D-->>S: history.response
S-->>B: roast, username, language
else cache miss
S->>G: GET /users/{username}
G-->>S: profileResponse
Note over S,G: response.ok false langsung 500 Our roast machine is in trouble
S->>G: GET /users/{username}/repos?sort=updated
G-->>S: repoResponse
S->>G: GET raw README.md main lalu master
G-->>S: readmeResponse
S->>S: susun prompt lewat switch language
S->>O: chat.completions.create gpt-4o-mini
O-->>S: choices[0].message.content
S->>D: INSERT INTO roasts di dalam try catch kosong
S-->>B: roast
end
end
%% fig: Siklus satu request roast
%% desc: Browser memanggil /llama, handler memeriksa cache D1, lalu mengambil data GitHub, memanggil OpenAI, dan menyimpan hasil sebelum membalas.Di sisi server, handler POST membaca username dan language dari request.json() lalu membalas 400 bila bahasa tidak ada di validLanguages src/routes/llama/+server.js:31-386. Pemeriksaan cache dijalankan sebelum satu pun request ke GitHub: baris hasil query langsung dipakai sebagai response, dengan history.response dikirim sebagai roast bersama username dan language src/routes/llama/+server.js:40-477.
Pada cache miss, handler menyiapkan headers dengan User-Agent: github-roast.pages.dev dan menambahkan Authorization berisi GITHUB_API_KEY bila variabel itu ada. Profil diambil dari https://api.github.com/users/${username}; bila response.ok false, handler langsung membalas 500 dengan error bernilai Our roast machine is in trouble, sedangkan jalur catch mengulang fetch yang sama src/routes/llama/+server.js:49-718. Setelah itu handler mengambil repos?sort=updated dan README profil dari branch main, dengan percobaan kedua ke master src/routes/llama/+server.js:78-1089.
Objek datas lalu dirakit dari name, bio, company, location, followers, following, public_repos, profile_readme, dan last_15_repositories; prompt dasar berbahasa Inggris kemudian diganti oleh switch (language) src/routes/llama/+server.js:111-17610. Panggilan client.chat.completions.create memakai model gpt-4o-mini dengan stream: false, dan isi completion.choices[0].message.content disimpan sebagai roast src/routes/llama/+server.js:180-19311.
Penyimpanan berjalan di dalam try tersendiri: INSERT INTO roasts diikuti catch {} kosong dan return json({ roast }). Kegagalan pada blok luar dibalas 500 dengan error bernilai Failed to generate roast src/routes/llama/+server.js:194-21212. Di browser, kegagalan HTTP apa pun memicu throw new Error('Failed to fetch roast'), dan roast diisi kalimat fallback Oops! Looks like our roasting machine is on a coffee break. Try again later! src/routes/+page.svelte:47-5813.
Percabangan dan Kegagalan
graph TD
A["handleRoast() di +page.svelte"] --> B{"validLanguages.includes(language)"}
B -->|"tidak"| C["400 invalid language specified"]
B -->|"ya"| D{"row roasts ditemukan"}
D -->|"ya"| E["200 roast, username, language"]
D -->|"tidak"| F["GET api.github.com/users/{username}"]
F --> G{"response.ok"}
G -->|"tidak"| H["500 Our roast machine is in trouble"]
G -->|"ya"| I["GET repos dan README.md"]
I --> J["susun prompt lewat switch(language)"]
J --> K["chat.completions.create gpt-4o-mini"]
K -->|"error"| M["500 Failed to generate roast"]
K --> L["INSERT INTO roasts"]
L --> N["200 roast"]
L -.->|"catch {} kosong"| N
style B fill:#f59e0b,color:#000
style G fill:#f59e0b,color:#000
style D fill:#8b5cf6,color:#fff
style L fill:#336791,color:#fff
style E fill:#2d7d46,color:#fff
style N fill:#2d7d46,color:#fff
style C fill:#dc2626,color:#fff
style H fill:#dc2626,color:#fff
style M fill:#dc2626,color:#fff
%% fig: Percabangan validasi, cache, dan kegagalan
%% desc: Setiap keputusan di handler /llama berakhir pada satu response: 400, 500, atau roast dari cache maupun hasil generate.Ada dua jalur pintas yang perlu diingat. Cache hit mengembalikan history.response tanpa menyentuh GitHub maupun OpenAI src/routes/llama/+server.js:40-477, sedangkan validasi bahasa menutup request sebelum query dijalankan src/routes/llama/+server.js:31-386. Nilai created_at yang ditulis pada INSERT dihitung dari Math.floor(new Date().getTime() / 1000) src/routes/llama/+server.js:194-21212.
⚠️ Daftar bahasa di select dan daftar di server tidak sama. Array
languagesmenawarkan 15 pilihan src/routes/+page.svelte:12-285, sedangkanvalidLanguageshanya memuat 11 nilai yaituenglish,indonesian,indian,chinese,japanese,korean,french,polish,vietnamese,arabic, dantraditionalChinesesrc/routes/llama/+server.js:15-2714. Memilihitalian,german,finnish, atauportuguesemenghasilkan 400, dan pengguna melihat kalimat fallback, bukan roast.
⚠️
INSERT INTO roastsmenulis kolomip_addresssrc/routes/llama/+server.js:194-21212, padahaldatabase.sqlmendefinisikan tabel tanpa kolom tersebut src/routes/llama/+server.js ... lihat database.sql:2-1115. Nilai kolom itu berasal darisha256(...)yang mengembalikan Promise, bukan string src/routes/llama/+server.js:215-22116. Karena kegagalan ditelancatch {}kosong, response tetap 200 walau tidak ada baris baru tersimpan; cache pun tidak pernah terisi dan setiap request mengulang panggilan ke GitHub dan OpenAI.
Bahan Rujukan per Langkah
| # | Langkah | Kode | Perilaku |
|---|---|---|---|
| 1 | Input pengguna | src/routes/+page.svelte:74-943 | username dan selectedLanguage di-bind ke input dan select; keduanya nonaktif selama loading. |
| 2 | Kirim request | src/routes/+page.svelte:39-452 | fetch('/llama') dengan method POST dan body JSON. |
| 3 | Gagal di browser | src/routes/+page.svelte:47-5813 | throw new Error('Failed to fetch roast'), lalu roast diisi kalimat fallback. |
| 4 | Validasi bahasa | src/routes/llama/+server.js:31-386 | Balasan 400 untuk bahasa di luar validLanguages. |
| 5 | Cek cache | src/routes/llama/+server.js:40-477 | SELECT * pada roasts dengan gh_username dan language. |
| 6 | Data profil | src/routes/llama/+server.js:49-718 | Profil dari api.github.com/users/{username}, dengan fallback di jalur catch. |
| 7 | Repos dan README | src/routes/llama/+server.js:78-1089 | repos?sort=updated, README branch main lalu master. |
| 8 | Prompt | src/routes/llama/+server.js:111-17610 | Objek datas dan switch (language). |
| 9 | OpenAI | src/routes/llama/+server.js:180-19311 | Model gpt-4o-mini, stream: false. |
| 10 | Simpan hasil | src/routes/llama/+server.js:194-21212 | INSERT INTO roasts di dalam try dengan catch {} kosong. |
| 11 | Render | src/routes/+page.svelte:104-1111 | <SvelteMarkdown source={roast} /> dengan transisi fade. |