I Vibe Coded an Internal Family App with Next.js, Supabase, and WhatsApp Notifications
Website Development

Saya vibe coding Membangun Aplikasi Keluarga Internal dengan Next.js, Supabase, dan Notifikasi WhatsApp

Semenjak anak saya masuk sekolah dasar, ada satu hal yang pelan-pelan saya sadari: dia sudah punya dunianya sendiri. Padahal baru kelas 1 SD. Rasanya baru kemarin saya yang menentukan hampir semua hal untuk dia, sekarang dia punya jadwal, punya teman, punya kesibukan, dan punya prioritasnya sendiri.

Harinya sekarang penuh. Ada sekolah, ada mengaji, ada PR yang harus dikerjakan, ada waktu bermain dengan teman-temannya di kompleks, dan tentu saja ada Roblox — game kesukaannya yang kalau tidak dibatasi bisa memakan waktu sore sampai malam. Saya dan istri juga mulai memberi dia beberapa tugas kecil di rumah seperti merapikan tempat tidur dan membereskan mainannya sendiri.

Masalahnya sederhana tapi nyata: kami bertiga sering tidak sinkron. Istri saya mengingatkan hal yang berbeda dengan yang saya ingat, dan anak saya punya alasan klasik “tadi nggak ada yang bilang”. Dari situ saya mulai berpikir untuk membuat satu sistem super mini yang mengatur jadwal dan tugasnya, dan bersifat internal — hanya kami bertiga yang bisa mengaksesnya.

Artikel ini adalah cerita jujur tentang proses itu. Bukan tutorial step-by-step, lebih ke apa yang saya coba, apa yang gagal, dan apa yang akhirnya saya pelajari sebagai developer sekaligus sebagai ayah.

Awalnya Saya Pakai Notion, dan Sampai Sekarang Masih Suka

Saya harus jujur di awal: Notion itu favorit saya, dan sampai hari ini masih saya pakai untuk kerjaan. Jadi wajar kalau percobaan pertama saya adalah membangun semuanya di Notion. Saya buat database jadwal, database tugas, beberapa view yang rapi, filter per hari, dan relasi antar tabel.

Untuk saya pribadi, hasilnya bagus. Untuk anak saya, hasilnya kacau. Waktu saya minta dia membuka halaman jadwalnya sendiri, dia bingung harus klik apa. Ada terlalu banyak tombol, terlalu banyak view, dan terlalu banyak hal yang bisa tidak sengaja dia ubah atau hapus.

Waktu saya cek ulang dengan kepala dingin, saya sadar saya membangun sesuatu yang kompleks untuk pengguna yang butuh sesederhana mungkin. Anak kelas 1 SD tidak butuh database view, dia butuh satu layar yang bilang “hari ini kamu ngapain aja”.

Dan satu hal lagi yang jadi penentu: saya tidak menemukan cara push notifikasi yang benar-benar bekerja untuk kebutuhan kami di notion, mungkin anda bisa tahu, tolong tinggalkan komen? Padahal seluruh premis sistem ini adalah pengingat yang datang sendiri tanpa kami harus ingat membukanya.

Rencana Bikin Mobile App yang Batal karena iPhone Istri Saya

Karena sudah terlanjur kepikiran, saya lanjut ke rencana berikutnya: migrasi dari Notion ke mobile app pakai Expo. Saya sudah cukup familiar dengan React, jadi Expo terasa seperti jalan yang masuk akal. Saya bahkan sempat membayangkan tampilan tab bar-nya seperti apa.

Lalu saya berhenti di satu kenyataan yang sangat tidak teknis: istri saya pakai iPhone. Artinya kalau saya mau dia bisa memakai aplikasinya secara normal, saya harus masuk ke ekosistem distribusi Apple. Dan untuk sekarang saya tidak berminat berlangganan Apple Developer hanya untuk aplikasi yang penggunanya tiga orang di rumah yang sama. Hahaha.

Saya sempat mempertimbangkan jalur-jalur alternatif, tapi semuanya terasa terlalu ribet untuk skala masalah yang sedang saya selesaikan. Ini bukan produk, ini alat rumah tangga.

Akhirnya saya ambil keputusan yang belakangan terbukti paling benar: bikin saja versi web. Semua orang di rumah punya browser, tidak ada yang perlu install apa pun, dan saya bisa update kapan saja tanpa menunggu proses review siapa pun.

Pelajaran pertama dari sini: batasan non-teknis sering kali yang paling menentukan arsitektur. Bukan performa, bukan skalabilitas — tapi biaya langganan dan HP yang dipakai istri.

Fitur yang Saya Putuskan untuk Dibangun

Fitur yang Saya Putuskan untuk Dibangun

Setelah keputusan platform selesai, saya paksa diri saya menulis daftar fitur sependek mungkin. Saya tahu kebiasaan buruk saya: kalau tidak dibatasi di awal, side project ini tidak akan pernah selesai.

Untuk saya dan istri saya sebagai orang tua, ada dua kemampuan utama. Pertama, mengelola jadwal agenda yang sifatnya repetitif — sekali dibuat, dia berulang sendiri. Contoh nyatanya adalah jadwal mengaji setiap Senin sampai Jumat jam 15.30 WIB, yang cukup saya input satu kali.

Kedua, mengelola tugas yang sifatnya sekali selesai. Tugas tidak berulang, dia punya deadline tanggal dan jam, punya prioritas, lalu selesai. Merapikan lemari, menyelesaikan PR matematika halaman sekian, hal-hal seperti itu.

Untuk anak saya, perannya sengaja saya buat sesempit mungkin: dia hanya bisa melihat jadwal dan agendanya. Tidak ada tombol tambah, tidak ada tombol hapus, tidak ada form yang bisa dia rusak tanpa sengaja. Ini keputusan desain yang saya ambil setelah gagal di Notion.

Di luar itu ada tiga syarat wajib. Harus ada push notifikasi untuk semua peran, login harus pakai Google ID supaya tidak ada yang perlu mengingat password, dan sistem hanya boleh diakses oleh tiga akun Google — saya, istri saya, dan anak saya.

Tech Stack yang Saya Pilih dan Alasannya

Saya memilih Next.js karena itu framework React yang paling sering saya pakai dan saya paling nyaman dengannya. App Router-nya membuat saya bisa memisahkan halaman publik seperti login dengan halaman yang butuh sesi dengan rapi, dan middleware-nya sangat membantu untuk urusan proteksi rute.

Untuk database saya pakai Supabase. Alasan utamanya adalah saya tidak mau mengurus backend terpisah untuk aplikasi tiga pengguna. Supabase memberi saya Postgres, autentikasi Google OAuth, dan Row Level Security dalam satu paket. Struktur data saya juga tidak rumit — pada dasarnya hanya tabel anggota keluarga, jadwal, kemunculan jadwal, dan tugas.

Untuk notifikasi, saya memutuskan pakai API WhatsApp milik Fonnte. Ini keputusan yang paling saya syukuri. Kami sekeluarga sudah membuka WhatsApp puluhan kali sehari tanpa disuruh, jadi tidak ada kurva belajar sama sekali. Pengingat jadwal dan tugas datang ke tempat yang memang sudah kami lihat setiap hari.

Untuk deploy dan menjalankan aplikasinya saya pakai Netlify. Sederhana, cepat, terhubung langsung ke repo, dan lebih dari cukup untuk beban kerja yang penggunanya bisa dihitung dengan jari satu tangan.

Bagian yang Ternyata Paling Rumit: Jadwal Berulang

Waktu menulis daftar fitur, saya pikir bagian tersulit adalah notifikasi. Ternyata bukan. Bagian tersulit adalah jadwal berulang.

Awalnya saya membayangkan cukup menyimpan satu baris jadwal dengan pola pengulangan, lalu tampilkan saja. Tapi begitu masuk ke kasus nyata, muncul pertanyaan yang tidak bisa dijawab dengan satu baris: bagaimana kalau hari Rabu ini mengajinya libur? Bagaimana cara menandai bahwa jadwal Senin kemarin sudah selesai, tapi Selasa belum?

Solusi yang akhirnya saya pakai adalah memisahkan definisi jadwal dari kemunculannya. Jadwal menyimpan pola berulang berupa daftar pasangan hari dan jam, sementara setiap kemunculan pada tanggal tertentu punya statusnya sendiri. Jadi jadwal mengaji tetap satu entri, tapi Senin, Selasa, dan Rabu bisa punya status yang berbeda-beda.

Pola ini membuat banyak hal jadi jauh lebih mudah setelahnya. Kalender jadi tinggal membaca rentang tanggal, notifikasi tinggal melihat kemunculan yang akan datang, dan halaman anak tinggal menampilkan kemunculan hari ini.

Pelajaran kedua: kalau sebuah fitur terasa aneh saat dikoding, biasanya masalahnya bukan di kode, tapi di model datanya. Saya menghabiskan setengah malam mengakali logika sebelum sadar bahwa saya cuma salah memodelkan satu tabel.

Notifikasi WhatsApp yang Harus Tahu Diri

Bagian notifikasi punya pelajarannya sendiri, dan pelajaran itu datang dari istri saya.

Versi pertama saya terlalu bersemangat. Setiap jadwal mendekat, kirim pesan. Tugas mendekati deadline, kirim pesan. Tugas lewat deadline, kirim pesan lagi. Hasilnya, dalam dua hari pertama grup keluarga kami penuh notifikasi dan istri saya bilang aplikasi saya berisik. Itu feedback paling jujur yang pernah saya terima soal side project.

Jadi saya rombak pendekatannya. Sekarang tipe pengingatnya terbatas dan punya maksud yang jelas: pengingat jadwal sebelum waktunya, pengingat deadline tugas, penanda tugas yang terlambat, serta ringkasan pagi dan ringkasan malam. Ringkasan ini yang paling berguna — satu pesan di pagi hari yang merangkum hari ini, bukan sepuluh pesan sepanjang hari.

Satu hal teknis yang wajib saya sebut karena sempat membuat saya malu: idempotensi. Sebelum saya menambahkan kunci unik per periode untuk setiap pesan, ada satu pengingat yang terkirim berkali-kali karena job-nya berjalan ulang. Anak saya sampai bertanya kenapa HP ibunya bunyi terus. Sejak setiap pesan punya kunci dedup, masalah itu hilang.

Untuk pemetaan nomor, saya sengaja tidak menyimpannya di database. Karena penggunanya hanya tiga, nomor WhatsApp masing-masing peran saya baca dari environment variable. Lebih aman, lebih sederhana, dan tidak ada tabel tambahan yang harus saya urus.

Login Google dan Akses yang Benar-Benar Tertutup

Untuk login, saya pakai Google OAuth lewat Supabase. Alasannya praktis: tidak ada yang perlu mengingat password, termasuk anak saya yang jelas tidak akan mau berurusan dengan reset password.

Tapi login dengan Google saja tidak cukup, karena secara teknis siapa pun yang punya akun Google bisa mencoba masuk. Jadi saya tambahkan lapisan berikutnya: setelah autentikasi berhasil, email yang masuk dicocokkan dengan daftar anggota keluarga yang tersimpan di database. Kalau tidak ada di daftar itu, sesi ditolak sebelum mencapai halaman mana pun.

Middleware Next.js menangani pengecekan ini di level rute, jadi tidak ada halaman internal yang bisa diakses tanpa sesi valid. Di sisi database, Row Level Security memastikan data keluarga kami tidak bisa dibaca dari sesi yang tidak berhak.

Pembagian perannya juga saya jaga di dua tempat sekaligus. Di UI, anak saya diarahkan ke dashboard khusus yang tidak punya tombol edit sama sekali. Di server, aksi membuat dan mengubah jadwal maupun tugas tetap divalidasi ulang. Saya belajar untuk tidak pernah menganggap UI sebagai pengaman.

Soal Vibe Coding dan Pengalaman 10 Tahun WordPress

Saya membangun ini dengan cara yang sekarang orang sebut vibe coding — banyak bekerja bersama AI, iterasi cepat, tidak menulis semuanya dari nol. Dan saya mau jujur soal ini karena banyak yang menganggapnya jalan pintas.

Menurut pengalaman saya, vibe coding itu efektif justru karena saya sudah punya latar belakangnya. Sepuluh tahun lebih di dunia WordPress mengajarkan saya cara memecah masalah, cara menamai sesuatu, dan cara membaca kode orang lain dengan cepat. Pengalaman di React membuat saya tahu kapan sebuah komponen mulai terlalu banyak tanggung jawab.

Yang saya rasakan, AI sangat cepat menghasilkan kode yang jalan, tapi tidak otomatis menghasilkan kode yang benar untuk konteks saya. Beberapa kali saya menerima solusi yang terlalu umum dan terlalu banyak abstraksi untuk aplikasi tiga pengguna. Di situ pengalaman berperan — saya tahu kapan harus bilang “ini kebanyakan, sederhanakan”.

Jadi kalau ada yang bertanya apakah vibe coding menggantikan pengalaman, jawaban saya dari proyek ini adalah tidak. Dia melipatgandakan pengalaman yang sudah ada. Kalau fondasinya belum ada, yang berlipat ganda adalah kebingungannya.

Apa yang Saya Pelajari dari Membangun Aplikasi untuk Keluarga Sendiri

Apa yang Saya Pelajari dari Membangun Aplikasi untuk Keluarga Sendiri

Pelajaran terbesarnya bukan soal teknologi. Membangun untuk keluarga sendiri itu berbeda karena penggunanya tidak akan sungkan bilang aplikasi saya membingungkan, dan mereka tinggal di rumah yang sama dengan saya.

Saya belajar bahwa kesederhanaan itu mahal. Halaman anak saya adalah halaman yang paling sedikit elemennya, tapi paling banyak saya revisi. Menghapus sesuatu ternyata butuh lebih banyak pertimbangan daripada menambahkannya.

Saya juga belajar bahwa notifikasi adalah fitur yang paling mudah disalahgunakan oleh developernya sendiri. Kalau kita bisa mengirim pesan kapan saja, godaannya besar untuk mengirim terlalu sering. Sekarang standar saya sederhana: kalau pesan itu tidak mengubah apa yang akan seseorang lakukan dalam satu jam ke depan, pesan itu tidak perlu dikirim.

Dan yang paling penting, saya belajar bahwa side project terbaik adalah yang menyelesaikan masalah yang saya alami setiap hari. Saya tidak perlu mencari motivasi untuk merawatnya, karena setiap bug langsung terasa dampaknya di meja makan.

Apakah Sistem Ini Benar-Benar Dipakai?

Apakah Sistem Ini Benar-Benar Dipakai?

Ini pertanyaan yang saya tanyakan ke diri sendiri sebelum menulis artikel ini, karena banyak side project yang berhenti dipakai setelah minggu pertama.

Jawabannya iya, dan yang membuatnya bertahan justru bagian WhatsApp-nya. Karena pengingat datang ke aplikasi yang sudah kami buka setiap hari, tidak ada kebiasaan baru yang perlu dibentuk. Istri saya bahkan tidak perlu membuka aplikasinya untuk tahu agenda hari ini.

Anak saya sendiri sekarang punya kebiasaan mengecek layarnya sepulang sekolah untuk tahu urutan harinya. Bukan karena sistemnya canggih, tapi karena halamannya cuma menampilkan apa yang perlu dia lihat hari itu.

Masih banyak yang bisa diperbaiki, dan saya masih rutin menambal hal-hal kecil. Tapi untuk sebuah sistem super mini yang lahir dari kebingungan seorang ayah dengan anak kelas 1 SD, saya rasa ini sudah lebih dari cukup.

Kalau kamu sedang mempertimbangkan membangun sesuatu yang serupa, saran saya cuma satu: mulai dari masalah yang paling mengganggu di rumahmu, bukan dari tech stack yang paling ingin kamu coba.

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *