Skip to content
Rafi Akmal Widikta

fullstack

Kopsp

Platform koperasi simpan pinjam di mana uang hanya bergerak lewat persetujuan terverifikasi, dengan jejak audit di balik setiap perubahan.

Peran
Fullstack
Tanggal
Januari 2026

Teknologi

  • go
  • gin
  • nuxt
  • vue
  • typescript
  • postgresql
  • drizzle
  • better-auth
  • zod
  • unocss
  • jose

Masalah

Koperasi memegang uang orang lain, dan bagian tersulitnya bukan daftar fitur, melainkan kebenarannya. Dua staff menyetujui setoran yang sama. Anggota membayar simpanan Pokok dua kali. Pinjaman cair gara-gara tombol diklik dua kali. Dan karena tidak ada payment gateway di sini, setiap rupiah datang lewat transfer manual yang harus dikaitkan dengan bukti yang diunggah anggota dan dengan staff yang bersedia menjaminnya.

Solusi

Tiga lapis dengan aturan masing-masing. Browser bicara ke Nuxt, Nuxt bicara ke API Go, dan hanya Go yang menulis tabel domain. Drizzle dibatasi pada tabel autentikasi saja; BFF tidak pernah meng-query tabel simpanan atau pinjaman. Browser juga tidak pernah melihat token Go: yang dipegangnya cookie sesi, dan server Nitro yang membuat HS256 JWT berumur pendek untuk diteruskan. Field identitas (siapa yang memverifikasi, siapa yang menyetujui, anggota yang mana) di-inject dari sesi itu dan diabaikan dari body request, sehingga klien tidak bisa mengaku sebagai orang lain. Anggota hanya melihat barisnya sendiri, dijaga oleh scope WHERE member_id, bukan oleh UI yang menyembunyikan tautan.

Di bagian yang menyangkut uang, pengecekannya sengaja dibuat membosankan. Saldo hanya berubah saat persetujuan, dalam satu transaksi atomic. Perpindahan status memakai compare-and-set terhadap status saat itu, sehingga request yang diulang mengembalikan konflik alih-alih diterapkan dua kali. Aturan bahwa simpanan Pokok hanya boleh dibayar sekali berupa partial unique index, bukan if di dalam handler: aturan itu tetap berlaku meski nanti ada yang menulis endpoint baru dan lupa. Dan audit log ditulis di dalam transaksi yang sama dengan aksinya: kalau log-nya gagal ditulis, aksinya dibatalkan. Buku besar yang bisa diubah tanpa jejak bukanlah buku besar.

Uangnya tidak pernah menyentuh float. Nominalnya DECIMAL(15,2) di Postgres, dikirim sebagai string desimal di JSON, dan dihitung di Go memakai big.Rat. Angka-angkanya sendiri (bunga flat bulanan, denda harian beserta batasnya, pengali plafon pinjaman, tanggal jatuh tempo) tersimpan di tabel settings, jadi mengubah kebijakan adalah perubahan data, bukan deploy ulang. Berkasnya privat: bukti transfer dan KTP hanya dilayani lewat endpoint ber-autentikasi, dan bukti verifikasi milik admin disimpan terpisah dari unggahan anggotanya, sehingga keduanya tidak mungkin tertukar.

Kontak

Tertarik untuk bekerja sama?

Ceritakan apa yang sedang Anda bangun dan apa yang dibutuhkan. Catatan singkat sudah cukup.

Back to top