1
Ringkasan Proyek
github-roast adalah aplikasi web berukuran kecil dengan dua bagian: satu halaman yang meminta username GitHub dan bahasa, serta satu endpoint POST /llama yang mengambil profil publik lalu meminta gpt-4o-mini menulis roast singkat. README menyebut tumpukannya dalam satu baris: SvelteKit, Cloudflare Pages, Cloudflare D1, OpenAI gpt-4o-mini (README.md:1-31). Proyek di-build memakai @sveltejs/adapter-cloudflare (svelte.config.js:102), sehingga hasil build berjalan sebagai Pages Function dan bukan server Node biasa.
Halaman utama berupa form sederhana yang di-prerender menjadi aset statis (src/routes/+page.js:33). Form itu mengirim POST /llama dengan body { username, language } (src/routes/+page.svelte:39-454). Seluruh logika produk berada di satu berkas endpoint src/routes/llama/+server.js.
Peta modul
Satu request roast melewati empat titik: halaman, cache di tabel roasts, GitHub REST API, lalu OpenAI.
graph TD
UI["+page.svelte<br/>input username + select language"] -->|"POST /llama"| API["llama/+server.js"]
API --> CACHE{"roasts lookup<br/>gh_username + language"}
CACHE -->|"cache hit"| OUT["response roast"]
CACHE -->|"cache miss"| GH["GitHub REST API"]
GH --> DATAS["datas: profil + README + 15 repo"]
DATAS --> PROMPT["prompt sesuai language"]
PROMPT --> LLM["OpenAI gpt-4o-mini"]
LLM --> STORE["INSERT INTO roasts"]
STORE --> OUT
OUT --> UI
D1[("D1 binding DB")] --- CACHE
D1 --- STORE
ENV["OPENAI_API_KEY<br/>GITHUB_API_KEY"] -.-> API
style D1 fill:#336791,color:#fff
style STORE fill:#336791,color:#fff
style CACHE fill:#8b5cf6,color:#fff
style DATAS fill:#8b5cf6,color:#fff
style PROMPT fill:#8b5cf6,color:#fff
style API fill:#f59e0b,color:#000
style ENV fill:#f59e0b,color:#000
style GH fill:#2d7d46,color:#fff
style LLM fill:#2d7d46,color:#fff
style OUT fill:#2d7d46,color:#fff
%% fig: Peta modul github-roast
%% desc: Satu request roast berpindah dari halaman SvelteKit ke endpoint, cache tabel roasts, GitHub REST API, lalu gpt-4o-mini, dan kembali ke pengguna.Berkas yang menyusun aplikasi
| Berkas | Peran | Dibahas di |
|---|---|---|
src/routes/+page.svelte | form username, pemilih bahasa, render hasil roast | Antarmuka Pengguna |
src/routes/llama/+server.js | handler POST, cache, GitHub fetch, prompt, OpenAI | Endpoint POST /llama |
database.sql | CREATE TABLE roasts dan gh_username_idx | Model Data Tabel roasts |
wrangler.toml | nama Pages, pages_build_output_dir, binding D1 | Konfigurasi Environment dan Binding |
.env.example | daftar variabel environment yang dibutuhkan | Memulai |
svelte.config.js | pemilihan @sveltejs/adapter-cloudflare | Deployment ke Cloudflare Pages |
Tumpukan dan nilai konfigurasi
| Lapisan | Nilai di repository | Sumber |
|---|---|---|
| Framework | @sveltejs/kit ^2.0.0, svelte ^4.2.7 | package.json:13-275 |
| Adapter | @sveltejs/adapter-cloudflare ^4.7.0 | package.json:156 |
| Nama Pages dan output | githubroast, .svelte-kit/cloudflare | wrangler.toml:2-47 |
| Database | D1 dengan binding DB, database_name = "githubroast" | wrangler.toml:28-318 |
| Tabel | roasts: id, gh_username, response, created_at, country, language | database.sql:2-99 |
| Klien LLM | openai ^4.54.0, model gpt-4o-mini | package.json:30-3410 |
| Render markdown | svelte-markdown ^0.4.1 | package.json:30-3410 |
Variabel environment yang ada di .env.example adalah OPENAI_API_KEY, GITHUB_API_KEY, dan TELEGRAM_API_KEY (.env.example:1-311). Endpoint hanya mengimpor dua yang pertama (src/routes/llama/+server.js:1-712).
Satu request, empat langkah
- Endpoint memeriksa
languageterhadapvalidLanguagesyang berisi 11 nilai, lalu menjalankanSELECT * FROM roasts WHERE gh_username = ? AND language = ?; kalau ada baris cocok, roast lama langsung dikembalikan tanpa memanggil GitHub (src/routes/llama/+server.js:29-4713). - Pada cache miss, endpoint mengambil profil dan daftar repo dari GitHub REST API, membaca
README.mddari branchmainataumaster, lalu merakit objectdatasberisiname,bio,company,location,followers,following,public_repos,profile_readme, dan 15 repo terakhir (src/routes/llama/+server.js:111-13114). datasdisisipkan ke prompt sesuai bahasa, lalu dikirim keclient.chat.completions.createdenganmodel: 'gpt-4o-mini'danstream: false(src/routes/llama/+server.js:180-19115).- Hasil roast dikembalikan sebagai
{ roast }dan dicoba disimpan ke tabelroasts; halaman menampilkannya lewatSvelteMarkdown(src/routes/llama/+server.js:195-20816, src/routes/+page.svelte:104-11117).
⚠️ Pemilih bahasa di UI memuat 15 pilihan, termasuk
german,italian,finnish, danportuguese, sedangkanvalidLanguagesdi endpoint hanya menerima 11 nilai. Memilih bahasa di luar daftar itu berakhir dengan status 400 dan pesaninvalid language specified, please pass a valid language.(src/routes/+page.svelte:12-2818, src/routes/llama/+server.js:15-2719, src/routes/llama/+server.js:33-3820). Rinciannya ada di Prompt Multibahasa.
⚠️
INSERTdi endpoint menyebut kolomip_address, tetapidatabase.sqltidak membuat kolom itu. Kegagalan insert ditelan blokcatch {}kosong, sehingga response roast tetap terkirim ke pengguna meski barisnya tidak tersimpan (src/routes/llama/+server.js:195-20816, database.sql:2-99). Rinciannya ada di Model Data Tabel roasts.