Code Studio
Minggu, 13 September 2026
Website Data Mahasiswa - Supabase
Saya seorang lecture web programming. Buatkan studi kasus sederhana full stack dengan backend menggunakan supabase. Terangkan step by step
“Planning Website — Sistem Data Mahasiswa Full Stack + Supabase” dalam format siap ditempel ke Word/Google Docs, mencakup:
- Project Overview
- Problem Statement
- Project Objectives
- Target User
- Functional Requirements
- Non-Functional Requirements
- User Flow
- Information Architecture
- Site Map
- UI/UX Planning
- Database Design / ERD
- Supabase Architecture
- API & CRUD Specification
- Security & RLS
- Folder Structure
- Technology Stack
- Development Roadmap
- Testing Plan
- Deployment Plan
- Assignment/Rubric untuk mahasiswa
Studi Kasus: Sistem Data Mahasiswa
Kita akan membuat aplikasi sederhana CRUD Data Mahasiswa menggunakan:
- Frontend: HTML + CSS + JavaScript
- Backend/Database: Supabase
- API: Supabase JavaScript Client
- Authentication: belum digunakan pada tahap awal
- Deployment: dapat dilanjutkan ke GitHub Pages/Netlify/Vercel
Aplikasi memungkinkan pengguna:
Tambah → Tampilkan → Edit → Hapus → Cari data mahasiswa
1. Tujuan Pembelajaran
Setelah menyelesaikan studi kasus ini, mahasiswa memahami alur:
FULL STACK WEB │ ┌───────────┴───────────┐ │ │ FRONTEND BACKEND │ │ HTML + CSS + JS SUPABASE │ │ └───────────┬───────────┘ │ DATABASE │ PostgreSQL
Mahasiswa belajar bahwa:
HTML ↓ User Interface CSS ↓ Presentation JavaScript ↓ Application Logic Supabase ↓ Backend Service + API PostgreSQL ↓ Data Persistence
Jadi mahasiswa tidak hanya belajar membuat website statis, tetapi memahami bagaimana website berkomunikasi dengan database.
2. Studi Kasus
Sistem Data Mahasiswa
Misalkan sebuah program studi ingin mempunyai aplikasi sederhana untuk mengelola data mahasiswa.
Data yang disimpan:
| Field | Contoh |
|---|---|
| ID | 1 |
| NIM | 2401001 |
| Nama | Budi Santoso |
| Program Studi | Informatika |
| Angkatan | 2024 |
| budi@email.com |
Fitur:
======================================== SISTEM DATA MAHASISWA ======================================== [ + Tambah Mahasiswa ] ---------------------------------------- NIM Nama Prodi ---------------------------------------- 2401001 Budi Informatika 2401002 Siti Sistem Informasi 2401003 Andi Informatika [Edit] [Hapus] ---------------------------------------- Cari mahasiswa: [____________]
3. Arsitektur Aplikasi
Arsitektur sederhananya:
┌─────────────────────────────┐ │ USER │ └──────────────┬──────────────┘ │ ▼ ┌─────────────────────────────┐ │ FRONTEND │ │ │ │ HTML │ │ CSS │ │ JavaScript │ └──────────────┬──────────────┘ │ │ HTTPS / API ▼ ┌─────────────────────────────┐ │ SUPABASE │ │ │ │ API │ │ Authentication │ │ Database │ │ Storage │ └──────────────┬──────────────┘ │ ▼ ┌─────────────────────────────┐ │ PostgreSQL │ │ │ │ mahasiswa │ │ ├── id │ │ ├── nim │ │ ├── nama │ │ ├── prodi │ │ ├── angkatan │ │ └── email │ └─────────────────────────────┘
Hal penting untuk mahasiswa:
Frontend tidak langsung mengakses PostgreSQL.
Frontend berkomunikasi dengan layanan Supabase menggunakan API/client library.
4. Step 1 — Membuat Project Supabase
Buka:
Kemudian:
Login ↓ Dashboard ↓ New Project ↓ Nama project: web-programming-mahasiswa ↓ Buat project
Setelah project selesai dibuat, kita memperoleh:
Project URL + Publishable/Anon Key
Contohnya:
const SUPABASE_URL = "https://xxxxxxxx.supabase.co"; const SUPABASE_KEY = "YOUR_PUBLISHABLE_KEY";
Catatan untuk mahasiswa: jangan memasukkan secret/service-role key ke frontend. Untuk aplikasi browser, gunakan key publik yang memang dirancang untuk client-side access dan atur keamanan melalui Row Level Security (RLS).
5. Step 2 — Membuat Database
Di Supabase buka:
SQL Editor
Kemudian buat tabel:
create table mahasiswa ( id bigint generated by default as identity primary key, nim varchar(20) not null unique, nama varchar(100) not null, prodi varchar(100) not null, angkatan integer not null, email varchar(100), created_at timestamptz default now() );
Struktur database:
mahasiswa │ ├── id ├── nim ├── nama ├── prodi ├── angkatan ├── email └── created_at
6. Step 3 — Memasukkan Data Awal
Masukkan beberapa data:
insert into mahasiswa (nim, nama, prodi, angkatan, email) values ('2401001', 'Budi Santoso', 'Informatika', 2024, 'budi@email.com'), ('2401002', 'Siti Aminah', 'Sistem Informasi', 2024, 'siti@email.com'), ('2401003', 'Andi Wijaya', 'Informatika', 2024, 'andi@email.com');
Sekarang database kita mempunyai data.
7. Step 4 — Memahami CRUD
Ini bagian yang sangat bagus untuk pembelajaran.
CRUD:
C = CREATE R = READ U = UPDATE D = DELETE
Hubungannya dengan database:
CREATE ↓ INSERT READ ↓ SELECT UPDATE ↓ UPDATE DELETE ↓ DELETE
Dalam aplikasi:
Form │ ▼ JavaScript │ ▼ Supabase Client │ ▼ Supabase API │ ▼ PostgreSQL
8. Step 5 — Membuat Struktur Project
Buat folder:
sistem-mahasiswa/ │ ├── index.html ├── style.css └── app.js
Sangat sederhana.
Untuk tahap pertama saya justru menyarankan jangan menggunakan React/Vue/Next.js terlebih dahulu.
Tujuannya supaya mahasiswa memahami:
Apa sebenarnya yang terjadi di balik framework.
9. Step 6 — Membuat HTML
File:
index.html
Isi:
<!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sistem Data Mahasiswa</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="container"> <h1>Sistem Data Mahasiswa</h1> <form id="mahasiswaForm"> <input type="hidden" id="id"> <input type="text" id="nim" placeholder="NIM" required > <input type="text" id="nama" placeholder="Nama Mahasiswa" required > <input type="text" id="prodi" placeholder="Program Studi" required > <input type="number" id="angkatan" placeholder="Angkatan" required > <input type="email" id="email" placeholder="Email" > <button type="submit"> Simpan </button> <button type="button" id="btnBatal"> Batal </button> </form> <hr> <input type="text" id="search" placeholder="Cari mahasiswa..." > <table> <thead> <tr> <th>NIM</th> <th>Nama</th> <th>Prodi</th> <th>Angkatan</th> <th>Email</th> <th>Aksi</th> </tr> </thead> <tbody id="dataMahasiswa"> </tbody> </table> </div> <script src="https://cdn.jsdelivr.net/npm/@supabase/supabase-js@2"></script> <script src="app.js"></script> </body> </html>
10. Step 7 — Membuat CSS
File:
style.css
body { font-family: Arial, sans-serif; background: #f4f6f8; margin: 0; padding: 30px; } .container { max-width: 1000px; margin: auto; background: white; padding: 30px; border-radius: 10px; } h1 { margin-bottom: 25px; } form { display: grid; gap: 10px; } input { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } button { padding: 10px; border: none; border-radius: 5px; cursor: pointer; } table { width: 100%; margin-top: 20px; border-collapse: collapse; } th, td { padding: 10px; border-bottom: 1px solid #ddd; text-align: left; }
11. Step 8 — Menghubungkan JavaScript dengan Supabase
Sekarang bagian yang paling penting.
File:
app.js
Pertama:
const SUPABASE_URL = "https://YOUR_PROJECT.supabase.co"; const SUPABASE_KEY = "YOUR_PUBLISHABLE_KEY"; const supabaseClient = supabase.createClient( SUPABASE_URL, SUPABASE_KEY );
Perhatikan:
Frontend │ ▼ createClient() │ ▼ Supabase
12. Step 9 — READ Data
Buat fungsi:
async function loadMahasiswa() { const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .order("id", { ascending: false }); if (error) { console.error(error); return; } displayMahasiswa(data); }
Kemudian tampilkan:
function displayMahasiswa(data) { const tbody = document.getElementById("dataMahasiswa"); tbody.innerHTML = ""; data.forEach(mahasiswa => { const row = document.createElement("tr"); row.innerHTML = ` <td>${mahasiswa.nim}</td> <td>${mahasiswa.nama}</td> <td>${mahasiswa.prodi}</td> <td>${mahasiswa.angkatan}</td> <td>${mahasiswa.email ?? ""}</td> <td> <button onclick="editMahasiswa(${mahasiswa.id})"> Edit </button> <button onclick="deleteMahasiswa(${mahasiswa.id})"> Hapus </button> </td> `; tbody.appendChild(row); }); }
Kemudian jalankan saat halaman dibuka:
loadMahasiswa();
13. Apa yang Terjadi?
Ketika browser menjalankan:
supabaseClient .from("mahasiswa") .select("*");
secara konsep:
Browser │ │ SELECT mahasiswa ▼ Supabase API │ ▼ PostgreSQL │ │ data ▼ Supabase API │ ▼ JavaScript │ ▼ HTML Table
Ini adalah momen penting untuk menjelaskan kepada mahasiswa:
Database berada di server/cloud, sedangkan HTML berada di browser.
14. Step 10 — CREATE Data
Ketika form disubmit:
document .getElementById("mahasiswaForm") .addEventListener("submit", async function(e) { e.preventDefault(); const id = document.getElementById("id").value; const mahasiswa = { nim: document.getElementById("nim").value, nama: document.getElementById("nama").value, prodi: document.getElementById("prodi").value, angkatan: Number( document.getElementById("angkatan").value ), email: document.getElementById("email").value }; if (id) { await updateMahasiswa(id, mahasiswa); } else { await createMahasiswa(mahasiswa); } resetForm(); loadMahasiswa(); });
Fungsi CREATE:
async function createMahasiswa(mahasiswa) { const { error } = await supabaseClient .from("mahasiswa") .insert(mahasiswa); if (error) { alert(error.message); return; } alert("Data berhasil ditambahkan"); }
15. Step 11 — UPDATE Data
async function updateMahasiswa(id, mahasiswa) { const { error } = await supabaseClient .from("mahasiswa") .update(mahasiswa) .eq("id", id); if (error) { alert(error.message); return; } alert("Data berhasil diperbarui"); }
Konsep SQL-nya:
UPDATE mahasiswa SET nama = 'Budi Baru' WHERE id = 1;
16. Step 12 — Edit Data
async function editMahasiswa(id) { const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .eq("id", id) .single(); if (error) { alert(error.message); return; } document.getElementById("id").value = data.id; document.getElementById("nim").value = data.nim; document.getElementById("nama").value = data.nama; document.getElementById("prodi").value = data.prodi; document.getElementById("angkatan").value = data.angkatan; document.getElementById("email").value = data.email || ""; }
Alurnya:
Klik EDIT ↓ Ambil ID ↓ SELECT database ↓ Data kembali ↓ Isi form ↓ User mengubah data ↓ UPDATE
17. Step 13 — DELETE
async function deleteMahasiswa(id) { const yakin = confirm("Hapus data mahasiswa?"); if (!yakin) return; const { error } = await supabaseClient .from("mahasiswa") .delete() .eq("id", id); if (error) { alert(error.message); return; } alert("Data berhasil dihapus"); loadMahasiswa(); }
Konsepnya:
User ↓ Klik Hapus ↓ Konfirmasi ↓ DELETE ↓ Supabase ↓ PostgreSQL ↓ Refresh data
18. Step 14 — Reset Form
function resetForm() { document .getElementById("mahasiswaForm") .reset(); document .getElementById("id") .value = ""; }
Tombol batal:
document .getElementById("btnBatal") .addEventListener("click", resetForm);
19. Step 15 — Search
Tambahkan:
document .getElementById("search") .addEventListener("input", async function() { const keyword = this.value; const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .or( `nim.ilike.%${keyword}%,nama.ilike.%${keyword}%` ); if (error) { console.error(error); return; } displayMahasiswa(data); });
Sekarang aplikasi sudah mempunyai:
CREATE ✓ READ ✓ UPDATE ✓ DELETE ✓ SEARCH ✓
20. Step 16 — Keamanan dengan RLS
Ini bagian penting untuk materi full stack.
Jangan mengajarkan mahasiswa bahwa:
"Kalau API key ada di JavaScript berarti database aman."
Bukan begitu.
Keamanan database Supabase menggunakan antara lain:
Authentication + Row Level Security + Database Policies
Aktifkan RLS pada tabel:
alter table mahasiswa enable row level security;
Untuk tahap praktikum awal, jika aplikasinya memang sengaja dibuat sebagai aplikasi publik, policy dapat dibuat sesuai kebutuhan pembelajaran.
Contoh policy untuk membaca data:
create policy "Public can read mahasiswa" on mahasiswa for select to anon using (true);
Namun untuk operasi insert, update, dan delete, jangan otomatis membuka akses publik pada aplikasi nyata. Untuk praktik yang lebih aman, tahap berikutnya adalah menambahkan authentication dan policy berdasarkan user/role.
21. Full Code app.js
Setelah semua langkah digabung:
const SUPABASE_URL = "https://YOUR_PROJECT.supabase.co"; const SUPABASE_KEY = "YOUR_PUBLISHABLE_KEY"; const supabaseClient = supabase.createClient( SUPABASE_URL, SUPABASE_KEY ); // ============================= // READ // ============================= async function loadMahasiswa() { const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .order("id", { ascending: false }); if (error) { console.error(error); return; } displayMahasiswa(data); } // ============================= // DISPLAY // ============================= function displayMahasiswa(data) { const tbody = document.getElementById("dataMahasiswa"); tbody.innerHTML = ""; data.forEach(mahasiswa => { const row = document.createElement("tr"); row.innerHTML = ` <td>${mahasiswa.nim}</td> <td>${mahasiswa.nama}</td> <td>${mahasiswa.prodi}</td> <td>${mahasiswa.angkatan}</td> <td>${mahasiswa.email ?? ""}</td> <td> <button onclick="editMahasiswa(${mahasiswa.id})"> Edit </button> <button onclick="deleteMahasiswa(${mahasiswa.id})"> Hapus </button> </td> `; tbody.appendChild(row); }); } // ============================= // CREATE / UPDATE // ============================= document .getElementById("mahasiswaForm") .addEventListener("submit", async function(e) { e.preventDefault(); const id = document.getElementById("id").value; const mahasiswa = { nim: document.getElementById("nim").value, nama: document.getElementById("nama").value, prodi: document.getElementById("prodi").value, angkatan: Number( document.getElementById("angkatan").value ), email: document.getElementById("email").value }; if (id) { await updateMahasiswa( id, mahasiswa ); } else { await createMahasiswa( mahasiswa ); } resetForm(); loadMahasiswa(); }); // ============================= // CREATE // ============================= async function createMahasiswa(mahasiswa) { const { error } = await supabaseClient .from("mahasiswa") .insert(mahasiswa); if (error) { alert(error.message); return; } alert("Data berhasil ditambahkan"); } // ============================= // UPDATE // ============================= async function updateMahasiswa( id, mahasiswa ) { const { error } = await supabaseClient .from("mahasiswa") .update(mahasiswa) .eq("id", id); if (error) { alert(error.message); return; } alert("Data berhasil diperbarui"); } // ============================= // EDIT // ============================= async function editMahasiswa(id) { const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .eq("id", id) .single(); if (error) { alert(error.message); return; } document.getElementById("id").value = data.id; document.getElementById("nim").value = data.nim; document.getElementById("nama").value = data.nama; document.getElementById("prodi").value = data.prodi; document.getElementById("angkatan").value = data.angkatan; document.getElementById("email").value = data.email || ""; } // ============================= // DELETE // ============================= async function deleteMahasiswa(id) { if (!confirm("Hapus data mahasiswa?")) return; const { error } = await supabaseClient .from("mahasiswa") .delete() .eq("id", id); if (error) { alert(error.message); return; } alert("Data berhasil dihapus"); loadMahasiswa(); } // ============================= // SEARCH // ============================= document .getElementById("search") .addEventListener( "input", async function() { const keyword = this.value; const { data, error } = await supabaseClient .from("mahasiswa") .select("*") .or( `nim.ilike.%${keyword}%,nama.ilike.%${keyword}%` ); if (error) { console.error(error); return; } displayMahasiswa(data); } ); // ============================= // RESET // ============================= function resetForm() { document .getElementById("mahasiswaForm") .reset(); document .getElementById("id") .value = ""; } document .getElementById("btnBatal") .addEventListener( "click", resetForm ); // ============================= // INITIAL LOAD // ============================= loadMahasiswa();
22. Cara Menjalankan
Struktur akhirnya:
sistem-mahasiswa/ │ ├── index.html ├── style.css └── app.js
Kemudian buka:
index.html
Browser:
index.html │ ├── style.css │ ├── Supabase JS │ └── app.js │ ▼ Supabase │ ▼ PostgreSQL
23. Peta Konsep Pembelajaran
Saya sarankan menjelaskan kepada mahasiswa menggunakan model berikut:
WEB APPLICATION │ ┌──────────┴──────────┐ │ │ FRONTEND BACKEND │ │ HTML + CSS + JS SUPABASE │ │ │ ┌──────┼──────┐ │ │ │ │ │ API Auth DB │ │ │ │ │ ▼ │ │ PostgreSQL │ │ └─────────────┬───────┘ │ CRUD │ ┌───────────┼───────────┐ │ │ │ CREATE READ UPDATE │ │ └───────────┬───────────┘ │ DELETE
24. Pembagian Pertemuan Kuliah
Studi kasus ini dapat dikembangkan menjadi 5 pertemuan praktikum.
Pertemuan 1 — Konsep Full Stack
Materi:
Frontend Backend API Database HTTP JSON CRUD
Output:
Mahasiswa memahami arsitektur aplikasi.
Pertemuan 2 — Supabase Database
Materi:
Project Supabase PostgreSQL Table Column Primary Key Insert Select RLS
Output:
Mahasiswa mempunyai database
mahasiswa.
Pertemuan 3 — Frontend
Materi:
HTML Form Table CSS DOM JavaScript Event
Output:
Interface aplikasi selesai.
Pertemuan 4 — Integrasi Backend
Materi:
Supabase Client SELECT INSERT UPDATE DELETE
Output:
Frontend terhubung dengan database.
Pertemuan 5 — Pengembangan
Mahasiswa menambahkan:
Search Validation Pagination Loading Error handling Authentication Authorization
25. Level Pengembangan Tugas
Agar cocok untuk mahasiswa, tugas dapat dibuat bertingkat.
Level 1 — Basic
CRUD Mahasiswa
Level 2 — Intermediate
Tambahkan:
Search Filter Prodi Filter Angkatan Sorting Pagination
Level 3 — Advanced
Tambahkan:
Login Register Logout Profile Role
Contoh:
ADMIN │ ├── Create ├── Read ├── Update └── Delete MAHASISWA │ ├── Read └── Update Profile
Level 4 — Full Stack Project
Kembangkan menjadi:
SISTEM AKADEMIK │ ┌────────────────┼────────────────┐ │ │ │ MAHASISWA DOSEN ADMIN │ │ │ ▼ ▼ ▼ KRS NILAI MASTER DATA │ │ └────────────────┘ │ ▼ SUPABASE │ ▼ PostgreSQL
26. Mengapa Studi Kasus Ini Bagus untuk Kuliah?
Yang menarik dari kasus ini adalah mahasiswa dapat melihat evolusi teknologi web secara nyata:
LEVEL 1 HTML │ ▼ Static Website
kemudian:
LEVEL 2 HTML + CSS + JS │ ▼ Interactive Website
kemudian:
LEVEL 3 HTML + CSS + JS + Supabase │ ▼ Full Stack Web Application
dan selanjutnya:
LEVEL 4 Frontend + API + Authentication + Authorization + Database + Deployment ↓
Production Web Application
-
https://www.youtube.com/watch?v=MDdT0WtRniE&list=PLjRBWix725xqEddhpGsg8_VmrIGoaFhs6 https://www.youtube.com/watch?v=FpwcfLHswUo&li...
-
https://chatgpt.com/c/6a977781-74a4-83ec-9398-d58d36d3d82a https://stratoflow.com/web-application-development/?utm_source=chatgpt.com
-
https://www.geeksforgeeks.org/javascript/form-validation-using-javascript/ https://www.geeksforgeeks.org/html/javascript-application-for-e...



