Sistem Manajemen & Reservasi Fasilitas Olahraga
Platform booking lapangan olahraga berbasis normalisasi basis data relasional dan resolusi konflik jadwal otomatis.
Sistem Manajemen & Reservasi Fasilitas Olahraga
Aplikasi web manajemen pemesanan fasilitas olahraga yang dibangun untuk menyelesaikan permasalahan operasional reservasi multi-venue (seperti lapangan futsal, badminton, dan basket) yang sebelumnya dilakukan melalui pencatatan manual via chat dan buku agenda fisik.
1. Permasalahan Utama yang Diselesaikan
- Konflik Jadwal (Double-Booking): Dua pelanggan sering memesan jam yang sama di lapangan yang sama karena lambatnya konfirmasi manual admin.
- Rekapitulasi Keuangan yang Rentan Selisih: Manajemen kesulitan melacak status uang muka (DP), pelunasan sewa, dan riwayat pembatalan jadwal.
- Visibilitas Ketersediaan Lapangan: Pelanggan tidak memiliki cara mandiri untuk melihat jam kosong tanpa harus bertanya satu per satu kepada pengelola.
2. Arsitektur Basis Data & Pencegahan Konflik
Kunci keberhasilan sistem ini terletak pada perancangan skema database MySQL dengan normalisasi tingkat ketiga (3NF) dan integritas transaksi:
┌───────────────────────┐ ┌────────────────────────┐
│ Venues │ │ Field_Courts │
│ (ID, Name, Location) │ 1──────* │ (ID, Venue_ID, Type) │
└───────────────────────┘ └───────────┬────────────┘
│ 1
│
▼ *
┌───────────────────────┐ ┌────────────────────────┐
│ Users │ 1 * │ Reservations │
│ (ID, Name, Phone, Role│ ──────── │ (ID, Court_ID, Slot_ID,│
└───────────────────────┘ │ Status, Booking_Date) │
└───────────┬────────────┘
│ *
▼ 1
┌────────────────────────┐
│ Time_Slots │
│ (ID, Start_Time, End) │
└────────────────────────┘
Mekanisme Penguncian Jadwal (Transactional Lock):
Untuk mencegah dua pengguna memesan slot yang sama pada milidetik yang berdekatan, proses checkout dibungkus dalam transaksi database dengan composite unique constraint:
ALTER TABLE reservations
ADD CONSTRAINT unique_court_schedule
UNIQUE (field_court_id, booking_date, time_slot_id);
Sebelum reservasi disimpan, aplikasi menjalankan query locking sementara:
DB::transaction(function () use ($courtId, $date, $slotId, $userId) {
$existing = Reservation::where('field_court_id', $courtId)
->where('booking_date', $date)
->where('time_slot_id', $slotId)
->lockForUpdate()
->first();
if ($existing) {
throw new ScheduleCollisionException("Slot jadwal ini baru saja diambil pengguna lain.");
}
return Reservation::create([...]);
});
3. Hasil & Pembelajaran Rekayasa
- Nol Tabrakan Jadwal: Penerapan integritas database dan pessimistic lock sepenuhnya mengeliminasi kasus booking ganda.
- Pembelajaran: Memahami bahwa validasi frontend hanyalah kenyamanan antarmuka (user experience), sedangkan pertahanan kebenaran data mutlak harus ditegakkan di layer skema database relasional.