Lewati ke konten

Pola Frontend

Tiap domain bisnis punya folder sendiri di src/features/<domain>/ (±64 folder — lihat daftar lengkap di src/features). Konvensi penamaan berkas yang konsisten di hampir semua folder:

  • supabase-<domain>.ts — fungsi akses data ke Supabase untuk domain itu (query, RPC call, mapping baris ke bentuk yang dipakai UI).
  • <domain>-hooks.ts — React hook (biasanya berbasis React Query) yang membungkus fungsi di atas untuk dipakai komponen halaman.

Halaman di src/pages/<route>/page.tsx meng-import hook dari src/features/<domain>/, bukan memanggil Supabase langsung — menjaga logika data tetap di satu tempat per domain.

  • isSupabaseBackend/selectBackend() (src/lib/backend-provider.ts) menentukan backend aktif di level build — lihat Gambaran Arsitektur.
  • VITE_SUPABASE_CANONICAL_*_READS (satu flag per domain, mis. VITE_SUPABASE_CANONICAL_CONFIG_READS) mengaktifkan pembacaan dari tabel kanonik alih-alih legacy_documents, hanya setelah tabel kanonik untuk domain itu dipastikan siap (jumlah baris sama) — lihat Migrasi & Rollout dan Skema Data & Tabel Kanonik.

Pola ini membuat setiap domain bisa pindah ke tabel kanonik secara independen, tanpa menunggu domain lain selesai, dan bisa dibatalkan sendiri lewat env var tanpa deploy ulang kode aplikasi.

Hampir semua komponen halaman di src/App.tsx di-lazy-load dengan React.lazy() per rute, supaya bundle awal tetap kecil meski jumlah halaman sangat banyak. Rute publik (portal, katalog publik, display, kiosk) sengaja dirender di luar provider aplikasi utama (lihat Gambaran Arsitektur) supaya tidak memuat context yang tidak relevan untuk pengunjung tanpa login.

Error mentah dari Supabase/Postgres (kode PGRST*, nama relasi, detail RLS) tidak langsung ditampilkan ke pengguna. Helper getUserFacingError() (src/lib/user-facing-error.ts) menyaring pesan error sebelum ditampilkan lewat toast:

  • Pesan validasi bisnis yang memang ditulis untuk pengguna (mis. “Stok bahan tidak mencukupi”) diteruskan apa adanya.
  • Pesan yang mengandung istilah teknis (PGRST, postgres, supabase, convex, “relation … does not exist”, dll.) diganti pesan generik: “Layanan sedang tidak dapat dihubungi. Coba lagi beberapa saat.”
  • Pesan terkait hak akses (permission denied, RLS, forbidden) diganti: “Anda tidak memiliki akses untuk melakukan tindakan ini.”
  • Pesan terkait sesi (JWT/token/session tidak valid) diganti: “Sesi login tidak lagi valid. Silakan masuk kembali.”

Pola ini mencegah detail implementasi database bocor ke pengguna akhir lewat pesan error, sekaligus tetap menampilkan pesan validasi bisnis yang memang berguna bagi pengguna.


Sumber: src/lib/backend-provider.ts, src/lib/user-facing-error.ts, src/lib/user-facing-error.test.ts, src/features/hr/supabase-hr.ts, src/App.tsx.