~/VibeHandbook
PDF Gratis

Bab 17 · 02

Studi Kasus 2: Alat SaaS Kecil dengan Autentikasi + Basis Data

Idenya

Seorang desainer lepas (freelance) ingin dasbor pribadi untuk mencatat jam kerja yang bisa ditagih per klien dan mengekspornya sebagai CSV bulanan (Comma-Separated Values — berkas spreadsheet teks polos yang bisa dibuka aplikasi spreadsheet apa pun). Tidak perlu mewah, tapi butuh akun (agar datanya hanya miliknya sendiri) dan penyimpanan data yang persisten.

Spesifikasinya

Autentikasi dan basis data menaikkan taruhannya, jadi spesifikasi ini menjadi lebih spesifik soal batasan-batasan:

A logged-in web app where a user can: sign up / log in with email,
create clients, log time entries (date, client, hours, note),
see a table of entries filtered by month, and download that month
as CSV. Each user only ever sees their own data. Mobile-friendly.

"Each user only ever sees their own data" (setiap pengguna hanya boleh melihat datanya sendiri) terlihat seperti sekadar kalimat pengalaman pengguna (UX). Padahal itu sebenarnya adalah model keamanan seluruh aplikasi, dipadatkan menjadi sembilan kata. Menuliskannya secara eksplisit di spesifikasi berarti kami bisa merujuk kembali ke situ setiap kali AI melenceng.

Stack-nya

Untuk pembangun solo, langkah yang menang adalah stack di mana autentikasi dan basis data adalah layanan terkelola (managed service), bukan kode yang kamu tulis sendiri. Kami memilih aplikasi Next.js yang di-deploy di hosting , dengan basis data Postgres yang di-hosting, dan penyedia autentikasi siap pakai yang menangani login email, sesi, dan reset kata sandi untuk kami. Lebih sedikit kode yang bisa salah berarti lebih sedikit kode yang bisa dirusak AI atas nama kita. Autentikasi khususnya adalah kategori yang hampir tidak pernah ingin kamu bangun sendiri dengan AI: mode kegagalannya senyap, dampaknya menyeluruh ke akun semua orang, dan penyedia terkelola sudah mengalami jutaan kasus login yang menguji berbagai kasus tepi ( case)-nya.

Bagian-bagian yang terkelola berada di luar; satu aturan yang kamu miliki sendiri ada di tengah — setiap kueri disaring berdasarkan user_id, sehingga satu pengguna tidak pernah bisa membaca baris data pengguna lain:

 ┌──────┐          ┌─────────────┐         ┌──────────────────┐
 │ USER │─ login ─▶│ AUTH        │─ user ─▶│  NEXT.JS APP     │
 └──────┘          │ (managed)   │  id     │                  │
                   └─────────────┘         │  every query:    │
                                           │  WHERE user_id=? ─┼──┐
                                           └──────────────────┘  │
                                                                 ▼
                                                       ┌──────────────────┐
                                                       │ POSTGRES (managed)│
                                                       │ clients · entries │
                                                       └──────────────────┘
            ↑ managed = less to get wrong   ↑ the one boundary YOU enforce

Prompt-prompt kuncinya

Kami membiarkan template dari penyedia autentikasi itu sendiri melakukan pekerjaan berat, lalu mengarahkan AI untuk menumpuk logika di atasnya:

We're using [auth provider]'s Next.js starter. Add a Postgres
schema with two tables: clients (id, user_id, name) and
time_entries (id, user_id, client_id, date, hours, note). Every
query MUST filter by the logged-in user's id from the session.
Generate the migration and the typed data-access functions.

Kalimat "MUST filter by user_id" adalah kalimat paling penting di seluruh proyek ini. Kami mengulangi batasan itu di hampir setiap yang menyentuh data, karena bug paling menakutkan dalam aplikasi multi-pengguna adalah satu pengguna melihat baris data milik pengguna lain. Pengulangan terasa berlebihan saat kamu mengetiknya; justru pengulangan itulah yang menyelamatkanmu, karena model tidak punya ingatan tentang seberapa penting batasan itu antar-prompt yang terpisah.

Untuk fitur ekspornya:

Add a /api/export route that takes a month (YYYY-MM), pulls the
logged-in user's time_entries for that month joined to client
names, and streams a CSV download. Reject the request if there's
no valid session.

Hambatannya

Saat pengujian, kami membuat dua akun dan menemukan akun B bisa melihat data klien milik akun A di sebuah dropdown. Ini persis bug yang kami khawatirkan. Alih-alih meminta AI untuk "memperbaikinya", kami memintanya membuktikan masalah itu dulu:

Account B is seeing Account A's clients. Show me every database
query in the codebase that reads the clients table, and for each
one tell me whether it filters by the session user_id. Don't fix
anything yet — just audit.

Audit itu memunculkan satu kueri — pemuat dropdown-nya — yang ditulis sebelum kami menambahkan batasan itu dan lolos tanpa terdeteksi. Kami meminta AI menambahkan filter yang hilang itu, lalu meminta sebuah pengaman (guard):

Add a single helper that every read goes through, which takes the
session and injects the user_id filter, so no future query can
forget it. Refactor the existing queries to use it.

Itu mengubah perbaikan sekali pakai menjadi jaminan struktural. Lalu kami membuat jaminan itu bisa diuji, karena pengaman yang tidak bisa kamu verifikasi hanyalah sebuah harapan:

Write a test that creates two users, has each create a client,
then asserts that user A's session can never read user B's client
through any of the data-access functions.

Pelajarannya: saat AI memasukkan sebuah bug keamanan, jangan hanya menambal satu kejadiannya saja — arahkan AI untuk menghilangkan kategori kesalahan itu, lalu kunci kategori itu rapat-rapat dengan sebuah tes yang gagal secara nyaring kalau ada yang membukanya kembali.

Peluncurannya

Kami mengisi data uji untuk satu bulan, mengekspor CSV-nya, membukanya di spreadsheet untuk memastikan angka dan enkodingnya benar, lalu mengatur kata sandi basis data yang kuat dan mengganti kredensialnya keluar dari berkas lokal mana pun. Kami men-deploy ke hosting serverless, menambahkan variabel lingkungan produksi di dashboard-nya, dan memberikan URL-nya kepadanya. Dia mendaftar sendiri dengan pendaftaran (signup) yang nyata. Seluruh pembangunan proyek ini memakan waktu satu akhir pekan.

Mau versi offline?

Unduh seluruh buku sebagai PDF atau EPUB — gratis.