Struktur folder utama
| Path | Fungsi |
|---|---|
app/ | Route App Router, layout, dan API route |
components/ | Komponen reusable aplikasi |
components/ui/ | Primitive shadcn/ui |
config/ | Konfigurasi terpusat untuk site, navigasi, pricing, preset desain, roadmap, status, dan open startup |
content/blog/ | Postingan blog MDX |
emails/ | Template React Email |
hooks/ | Hook client seperti auth, payment, subscription, dan AI chat |
lib/ | Helper bersama, integrasi, SEO, validations, rate limit |
lib/data/ | Data access layer untuk profile, payments, subscriptions, admin, audit, webhook events |
lib/payments/ | Integrasi Midtrans dan Doku |
lib/ai/ | Provider, middleware, dan usage tracking AI |
lib/storage/ | Avatar storage helpers |
supabase/migrations/ | SQL migration |
tests/ | Unit test, DOM test, dan route test |
e2e/ | Playwright smoke test |
Cara aplikasi ini dibagi
Route groups
app/(marketing)/untuk halaman publik.app/(dashboard)/untuk area user yang login.app/auth/untuk alur autentikasi.
Model rendering
- Server components adalah default.
- Client components dipakai untuk form interaktif, switcher tema, design switcher, chart, dan hook browser.
- Supabase browser client dibuat di
lib/supabase/client.ts. - Supabase server client dibuat per request di
lib/supabase/server.ts.
Alur auth
- User membuka halaman auth.
- Form client memanggil Supabase auth.
proxy.tsdanlib/supabase/proxy.tsme-refresh session cookie pada request berikutnya.- Route yang dilindungi seperti
/dashboarddan/adminmemeriksa user login. /adminjuga memeriksa role admin dariuser_roles.
Alur billing dan pembayaran
- User memilih plan di dashboard billing.
- Client memanggil
POST /api/payments. - Server mengambil harga dari
config/subscriptions.ts. - Server membuat record
paymentsdengan statusPENDING. - Server mengembalikan Snap token Midtrans atau checkout URL Doku.
- Webhook provider masuk ke route webhook terkait.
- Route webhook memverifikasi signature, mencatat event, lalu mengaktifkan subscription saat pembayaran sukses.
Alur webhook yang tahan retry
Webhook Midtrans dan Doku tidak langsung mengubah data tanpa pengaman. Repo ini memakai:- tabel
webhook_events, - RPC claim idempotent,
- status
processedataufailed, - audit log untuk jejak pemrosesan.
Alur profile dan avatar
- User meminta signed upload URL ke
POST /api/profile/avatar. - File di-upload ke bucket
avatars. - User menyimpan referensi avatar lewat
POST /api/profile. - Jika avatar lama diganti, object lama ikut dibersihkan.
Data access layer
Repo ini tidak menaruh semua query langsung di route file. Banyak akses data dipisah kelib/data/*, misalnya:
payments.tssubscriptions.tsprofiles.tsadmin.tsaudit-logs.tswebhook-events.tsuser-roles.ts
Rate limiting
Public form, payment, dan AI memakailib/rate-limit.ts.
- Jika
SUPABASE_SERVICE_ROLE_KEYtersedia, repo memakai backend rate limit persisten di Supabase. - Jika tidak, repo fallback ke in-memory store lokal.
- Response membawa header
X-RateLimit-*.
Kapan halaman ini berguna
Halaman ini penting saat kamu:- ingin refactor folder,
- ingin menambah route baru,
- ingin memahami mengapa session auth tetap sinkron,
- ingin men-debug billing atau webhook.