Lompat ke konten
dokumentasi.id
Commit d59d965
v3
Star763

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

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-111. 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-45. Selama loading bernilai true, input username dan select bahasa dinonaktifkan src/routes/+page.svelte:74-94, dan tombol submit dinonaktifkan bila loading atau username kosong src/routes/+page.svelte:96-102. Daftar pilihan bahasa berasal dari array languages src/routes/+page.svelte:12-28.

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.
Fig. 1: Siklus satu request roastBrowser 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-38. 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-47.

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-71. Setelah itu handler mengambil repos?sort=updated dan README profil dari branch main, dengan percobaan kedua ke master src/routes/llama/+server.js:78-108.

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-176. 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-193.

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-212. 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-58.

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.
Fig. 2: Percabangan validasi, cache, dan kegagalanSetiap 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-47, sedangkan validasi bahasa menutup request sebelum query dijalankan src/routes/llama/+server.js:31-38. Nilai created_at yang ditulis pada INSERT dihitung dari Math.floor(new Date().getTime() / 1000) src/routes/llama/+server.js:194-212.

⚠️ Daftar bahasa di select dan daftar di server tidak sama. Array languages menawarkan 15 pilihan src/routes/+page.svelte:12-28, sedangkan validLanguages hanya memuat 11 nilai yaitu english, indonesian, indian, chinese, japanese, korean, french, polish, vietnamese, arabic, dan traditionalChinese src/routes/llama/+server.js:15-27. Memilih italian, german, finnish, atau portuguese menghasilkan 400, dan pengguna melihat kalimat fallback, bukan roast.

⚠️ INSERT INTO roasts menulis kolom ip_address src/routes/llama/+server.js:194-212, padahal database.sql mendefinisikan tabel tanpa kolom tersebut src/routes/llama/+server.js ... lihat database.sql:2-11. Nilai kolom itu berasal dari sha256(...) yang mengembalikan Promise, bukan string src/routes/llama/+server.js:215-221. Karena kegagalan ditelan catch {} 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

#LangkahKodePerilaku
1Input penggunasrc/routes/+page.svelte:74-94username dan selectedLanguage di-bind ke input dan select; keduanya nonaktif selama loading.
2Kirim requestsrc/routes/+page.svelte:39-45fetch('/llama') dengan method POST dan body JSON.
3Gagal di browsersrc/routes/+page.svelte:47-58throw new Error('Failed to fetch roast'), lalu roast diisi kalimat fallback.
4Validasi bahasasrc/routes/llama/+server.js:31-38Balasan 400 untuk bahasa di luar validLanguages.
5Cek cachesrc/routes/llama/+server.js:40-47SELECT * pada roasts dengan gh_username dan language.
6Data profilsrc/routes/llama/+server.js:49-71Profil dari api.github.com/users/{username}, dengan fallback di jalur catch.
7Repos dan READMEsrc/routes/llama/+server.js:78-108repos?sort=updated, README branch main lalu master.
8Promptsrc/routes/llama/+server.js:111-176Objek datas dan switch (language).
9OpenAIsrc/routes/llama/+server.js:180-193Model gpt-4o-mini, stream: false.
10Simpan hasilsrc/routes/llama/+server.js:194-212INSERT INTO roasts di dalam try dengan catch {} kosong.
11Rendersrc/routes/+page.svelte:104-111<SvelteMarkdown source={roast} /> dengan transisi fade.