Skip to main content

Struktur folder utama

Cara aplikasi ini dibagi

Route groups

  • app/(marketing)/ untuk halaman publik.
  • app/(dashboard)/ untuk area user yang login.
  • app/auth/ untuk alur autentikasi.
Route group memakai tanda kurung, jadi nama foldernya tidak masuk ke URL.

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

  1. User membuka halaman auth.
  2. Form client memanggil Supabase auth.
  3. proxy.ts dan lib/supabase/proxy.ts me-refresh session cookie pada request berikutnya.
  4. Route yang dilindungi seperti /dashboard dan /admin memeriksa user login.
  5. /admin juga memeriksa role admin dari user_roles.

Alur billing dan pembayaran

  1. User memilih plan di dashboard billing.
  2. Client memanggil POST /api/payments.
  3. Server mengambil harga dari config/subscriptions.ts.
  4. Server membuat record payments dengan status PENDING.
  5. Server mengembalikan Snap token Midtrans atau checkout URL Doku.
  6. Webhook provider masuk ke route webhook terkait.
  7. 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 processed atau failed,
  • audit log untuk jejak pemrosesan.
Itu berarti retry provider tidak otomatis membuat data ganda.

Alur profile dan avatar

  1. User meminta signed upload URL ke POST /api/profile/avatar.
  2. File di-upload ke bucket avatars.
  3. User menyimpan referensi avatar lewat POST /api/profile.
  4. 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 ke lib/data/*, misalnya:
  • payments.ts
  • subscriptions.ts
  • profiles.ts
  • admin.ts
  • audit-logs.ts
  • webhook-events.ts
  • user-roles.ts
Pola ini memudahkan testing dan memisahkan logika bisnis dari layer route.

Rate limiting

Public form, payment, dan AI memakai lib/rate-limit.ts.
  • Jika SUPABASE_SERVICE_ROLE_KEY tersedia, 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.