fullstack
Courtsee
Platform livestreaming dan perekaman pertandingan untuk klub padel dan olahraga raket.
- Peran
- Software Engineer
- Durasi
- 2 bulan
- Tanggal
- Juni 2026
Teknologi
- go
- nuxt
- vue
- typescript
- postgresql
- hasura
- graphql
- ffmpeg
- sanity
- gcp
- terraform
- docker
Dampak
Platform tumbuh ke 14.600 pengguna di 3 negara, mencakup 54 klub dan 215 lapangan.
Masalah
Klub olahraga raket merekam pertandingan pakai ponsel, kalau sempat. Rekamannya berpencar di banyak perangkat, jarang dibagikan, dan turnamen baru disiarkan kalau kebetulan ada yang membawa peralatan yang benar. Tidak ada satu tempat untuk menjalankan semuanya secara berulang.
Sebagian besar pekerjaannya justru ada di sisi lain: portal admin tempat klub, lapangan, perangkat, langganan, dan pembayaran dikelola, dan tempat aturan platformnya ditegakkan. Komponennya dibangun tanpa pernah dilihat lintas resolusi, dan tagihannya datang sebagai rentetan perbaikan layout, satu breakpoint demi satu; viewport yang belum pernah dicek, banner yang tombolnya menumpuk alih-alih berdampingan, nama organisasi kepanjangan untuk kolomnya, kartu lapangan rusak di tablet, nomor seri terpotong. Yang lebih buruk dari urusan kosmetik adalah sekelas bug yang menyesatkan orang: analytics masih menghitung klub yang konfigurasi pembayarannya sudah dimatikan, pencarian perangkat menampilkan empty state yang meyakinkan padahal organisasinya belum dipilih, memilih semua cabang olahraga malah menyembunyikan hasilnya, pencarian pengguna admin case-sensitive, dan popup verifikasi tidak pernah menyebut alamat email tujuannya.
Dua lapis lagi dari masalah yang sama. Validasinya tipis tepat di tempat yang paling penting: kode kupon menerima tanda hubung dan spasi, sehingga duplikat bisa lolos dari aturan keunikannya; identifier klub tidak pernah dicek sebagai UUID sebelum sampai ke handler Go; gambar watermark diunggah tanpa batas ukuran maupun format, dan unggah ulang tidak mem-bust cache CDN-nya; tanggal event tidak wajib diisi. Dan bagian yang melintasi domain justru bagian yang tidak dimiliki siapa pun dari ujung ke ujung; sesi pembayaran yang kedaluwarsa per gateway alih-alih berdasarkan aturan, pembayaran yang terbuka di tab baru dan meninggalkan penggunanya di sana, tidak ada loading state saat kembali dari pembayaran sukses, dan sesi livestreaming yang bisa dibuat dua kali. Sementara itu fitur utuhnya masih belum ada: manajemen event, halaman subscription, portal analytics, dan section pricing, about, serta roadmap di situs marketingnya.
Solusi
Courtsee menyatukannya jadi satu platform: pertandingan direkam dan dipublikasikan dari tempat yang sama dengan tempat penyiarannya, sehingga klub bisa menggelar acara mingguan tanpa tim media khusus. Bagian depan memakai Nuxt dengan TypeScript, API-nya Go, dan pembacaan data lewat GraphQL supaya klien hanya meminta field yang dibutuhkan satu layar: papan skor dan daftar pertandingan tetap responsif di wifi klub.
Responsnya bergeser dari menambal gejala ke menghilangkan kondisi yang memproduksinya. Breakpoint disepakati sekali di config styling dan theme, bukan diputuskan per komponen; nilai rem yang di-hardcode diganti max-width dan token warna; dan logika tampilan pindah keluar dari komponen ke composable (salah satunya disentuh lima belas kali seiring fiturnya tumbuh), dan itulah intinya: ia punya rumah untuk tumbuh. Validasi dipindah ke batas, tempat ia bisa dipercaya: aturan alfanumerik dan sanitasi spasi untuk kupon di handler Go, pengecekan UUID sebelum identifier klub dipakai, pemeriksaan ukuran dan format di uploader sebelum apa pun dikirim, serta aturan tanggal di schema repository. Filternya pindah ke lapisan query alih-alih view: pengguna belum terverifikasi keluar dari statistik, lapangan yang sudah dihapus keluar dari daftar livestreaming, bypass pembayaran dibatasi hanya untuk system admin, dan empty state-nya dibuat informatif, sehingga “tidak ada data” dan “belum memilih filter” berhenti terlihat sama.
Bagian yang melintasi domain ditangani dengan memberi masing-masing satu pemilik. Kedaluwarsa sesi pindah ke balik abstraksi payment provider, sehingga aturan spesifik gateway berhenti merembes ke alurnya; pembayaran kini mengalihkan di dalam aplikasi alih-alih membuka tab baru, dan jalur kembalinya mendapat loading state yang tadinya hilang; guard di paling atas fungsi livestreaming menolak sesi kedua. Fitur yang belum ada dibangun sebagai irisan vertikal, bukan lapisan horizontal (schema, lalu query, lalu server, lalu composable, lalu halamannya), begitulah manajemen event datang lengkap dengan soft delete, unggah gambar, dan validasi tanggal, dan begitulah watermark per lapangan berjalan dari migrasi database ke endpoint API ke komponen yang ditarik keluar dari sebuah slot lalu dibuat utuh, termasuk cache busting-nya. Sepanjang tujuh bulan itu menjadi 271 commit substantif dan sekitar 28.000 baris ditambahkan melawan 5.000 dihapus, tersebar di aplikasi Nuxt, backend Go, server Nuxt, dan schema CMS. Rasio itu adalah bentuk dari membangun alih-alih menambal, dan alasan perbaikan berikutnya cukup berupa penyesuaian kecil, bukan penulisan ulang, adalah karena komponen bersama dan fondasi internasionalisasinya sudah ada.
Galeri
Tangkapan layar

Halaman depan
Kontak
Tertarik untuk bekerja sama?
Ceritakan apa yang sedang Anda bangun dan apa yang dibutuhkan. Catatan singkat sudah cukup.