Langsung ke konten
AFM Studio
  • Halaman

    AFM Studio
  • Karya
  • Lab
  • Tentang
  • CV
  • Kontak
  • Proyek

    AksaraPerpustakaan pengetahuan Otorita IKN yang bisa dicari, dengan server memeriksa akses setiap pembaca di tiga tingkat
  • Daily TaqwaSistem presensi salat anti-manipulasi untuk ~2.000 pegawai OIKN di Masjid Negara IKN
  • Lantara v2Mesin perizinan Otorita IKN tempat administrator menambah jenis izin baru dari layar, tanpa developer
  • eKiosk IKNDua ruang kendali untuk Nusantara: konten kios dan pelacakan bus live dengan estimasi kedatangan yang menilai dirinya sendiri
  • E-Monev IKNPlatform pemantauan pembangunan Nusantara selama 23 tahun, melacak progres triwulan setiap unit terhadap 24 KPI
  • JDIH OIKNPortal dokumen hukum publik OIKN, dengan alur penerbitan terkendali dan ringkasan AI yang tidak pernah keluar dari server
  • Jejak PenanamanAplikasi absen acara penanaman pohon IKN yang membuktikan peserta hadir di lokasi lewat selfie ber-geofence
  • Dashboard SAKTIPipeline malam dan dashboard yang menggantikan unduhan anggaran manual di keenam satker OIKN
  • DoseRxKalkulator dosis untuk 127 obat yang membulatkan dosis ke tablet dan sirup yang dijual apotek Indonesia
  • CubiqPelatih speedcubing dengan timer setara kompetisi dan solver buatan sendiri untuk 8 puzzle utama
  • ScimotionPerpustakaan sains interaktif berisi 86 artikel, masing-masing dijelaskan bersama animasi yang bisa dikendalikan pembaca
  • WA Daily Scrum BotBot WhatsApp yang menagih laporan standup tim 14 orang dan menandai tugas yang macet berhari-hari

↑ ↓ untuk berpindah · Enter untuk membuka · Esc untuk menutup

Daily Taqwa

Sistem presensi salat anti-manipulasi untuk ~2.000 pegawai OIKN di Masjid Negara IKN

Tangkapan layar
pegawai OIKN yang dilayani
~2.000
presensi dalam lima menit, sesuai rancangan
~500
waktu salat dicatat per pegawai
5
papan peringkat, termasuk Subuh dan direktorat
4
Di halaman ini

Masalahnya

Otorita IKN ingin mendorong sekitar 2.000 pegawainya salat di Masjid Negara IKN, dan ingin tahu apakah mereka benar hadir. Daftar hadir kertas bisa diisi belakangan. Presensi digital yang sederhana bisa dipalsukan dari luar masjid. Pimpinan SDM juga ingin melihat tren kehadiran di setiap direktorat, lebih dari sekadar daftar siapa yang datang.

Waktunya membuat masalah ini lebih sulit daripada presensi kantor biasa. Waktu salat singkat, dan presensi menumpuk di beberapa menit sekitar azan. Pengecekan lokasi juga harus tahan terhadap orang yang memang berusaha memalsukannya.

Yang saya bangun

Hanya aplikasi mobile yang bisa presensi

Browser tidak bisa membuktikan bahwa lokasi GPS-nya berasal dari ponsel sungguhan. Aplikasi fake GPS gratisan dan tools browser bisa menembus geofence berbasis web, seketat apa pun server-nya. Jadi saya memisahkan sistemnya. Aplikasi mobile native adalah satu-satunya klien yang boleh mengirim presensi. Aplikasi ini merekam cek liveness dan membaca GPS dengan deteksi lokasi palsu bawaan ponsel. Portal web menampilkan jadwal salat, peringkat, profil, catatan rilis, dan panel admin. Keduanya memakai satu backend yang memegang semua aturan.

Server yang memegang jam

Server menghitung setiap waktu salat, menyimpannya di cache, dan memeriksanya lagi saat presensi masuk. Ponsel tidak pernah mengirim waktu yang ikut dihitung. IKN memakai WITA, delapan jam di depan UTC. Presensi Subuh pukul 05.00 WITA jatuh di hari sebelumnya dalam UTC. Saya membuat semua tanggal di database memakai waktu setempat, supaya Subuh dan Isya tidak tercatat di hari yang salah.

Satu presensi, satu langkah, tanpa duplikat

Presensi mengerjakan semuanya dalam satu langkah: memakai kode sekali pakai, memeriksa waktu salat, geofence, kecepatan perpindahan sejak presensi terakhir, dan hasil liveness, lalu menyimpan catatannya. Kalau satu bagian gagal, tidak ada yang tersimpan. Database menolak catatan kedua untuk orang, hari, dan waktu salat yang sama, jadi dua ketukan bersamaan tidak menghasilkan dua catatan. Rekap harian, bulanan, dan per direktorat ikut diperbarui di langkah yang sama, sehingga selalu cocok dengan catatannya.

Satu login untuk web dan mobile

Kedua aplikasi masuk lewat single sign-on OIKN yang sudah ada. Web memakai redirect browser standar. Aplikasi mobile login langsung, lalu menukar login itu dengan sesi miliknya sendiri di backend. Saya memetakan NIP, unit kerja, dan jenis kelamin dari data login ke profil pegawai. Beberapa sistem kepegawaian mengirim NIP dalam format aneh, dan PPPK serta pegawai militer punya nomor yang tidak standar, jadi saya menerimanya juga.

Peringkat, riwayat, dan alat yang diminta SDM

Ada empat papan peringkat: bulanan per jenis kelamin, tahunan, khusus Subuh, dan per direktorat. Peringkat Anda sendiri tetap tampil di bawah kalau berada di luar sepuluh besar. Kalender bulanan mewarnai kelima waktu salat setiap hari. Setelah peluncuran, muncul kebutuhan yang tidak ada di spesifikasi. Data login tidak membawa jenis kelamin, jadi pegawai bisa mengoreksi jenis kelamin dan direktorat di profilnya, dan login berikutnya tidak menimpa koreksi itu. SDM bisa mengunggah data kertas lama lewat halaman web, dan admin bisa melihat login web dan mobile secara terpisah untuk memantau adopsi aplikasi.

Hasilnya

Daily Taqwa sudah berjalan di produksi di OIKN. Aplikasi mobile-nya live dan menjadi satu-satunya jalur presensi. Portal web menjalankan peringkat dan administrasi di backend yang sama. Sistem ini melayani sekitar 2.000 pegawai dan dirancang untuk sekitar 500 presensi dalam lima menit saat Zuhur. Saya membangunnya antara April dan Juni 2026. Cakupannya tumbuh melampaui spesifikasi awal: single sign-on menggantikan akun lokal, dan alat-alat SDM di atas lahir dari masukan setelah peluncuran.

Di balik layarDetail teknis untuk engineer
  • Waktu salat dihitung dengan library Python praytimes dan di-cache di Redis. Helper get_wita_date() mengubah setiap tanggal presensi ke WITA (UTC+8) sebelum masuk ke constraint berbasis tanggal.
  • Layanan presensi berjalan dalam satu blok @transaction.atomic dengan SELECT FOR UPDATE pada baris user: pemakaian nonce, validasi waktu, geofence Haversine dengan radius yang bisa diatur, cek kecepatan, cek liveness, penyimpanan foto, dan pembaruan rekap.
  • UNIQUE(user_id, date, prayer) menjadi pengaman utama dari race condition. Layanan menangkap IntegrityError dan mengembalikan pesan "sudah presensi". Nonce sekali pakai dengan TTL dua menit.
  • SSO web memakai Keycloak PKCE lewat mozilla-django-oidc. Mobile memakai Direct Access Grant: mendapat id_token Keycloak lalu menukarnya di endpoint backend dengan token SimpleJWT. Klaim (NIP, unit_kerja, gender) dipetakan ke model user dengan pencocokan eselon fuzzy. NIP yang datang sebagai float diubah menjadi string.
  • Flag profile_self_edited mencegah sinkronisasi OIDC menimpa direktorat yang sudah dikoreksi pengguna. last_login_web dan last_login_mobile menggantikan satu field last_login bawaan Django.
  • Pencocokan wajah dengan dlib ditunda menjadi liveness saja. Server memeriksa frame ada dan tidak identik; face-api.js menjalankan tantangan liveness di klien.
  • EXIF foto dihapus dengan Pillow, dan foto hanya disajikan lewat endpoint yang terautentikasi. Presigned URL MinIO mengarah ke hostname Docker internal, jadi endpoint-nya mengalirkan byte foto langsung.
  • import_backfill_csv mengimpor data kertas secara idempoten dengan --append dan menggabungkan akun SSO berdasarkan NIP. Perintah ini juga dibungkus halaman unggah untuk admin.
  • Panel admin punya editor geofence Leaflet, pengaturan waktu per salat, impor user massal dari Excel, log presensi dengan pratinjau foto, dan audit log.
  • Sekitar 15 model, sekitar 30 endpoint API, 23 file halaman frontend, sekitar 18.800 baris Python dan TypeScript, 85 commit.

Tangkapan layar

Beranda
Peringkat
Profil
Pengaturan
Catatan Rilis
Dashboard Admin

Sedang merekrut, atau membangun hal serupa?

Saya terbuka untuk posisi full-time dan proyek freelance tertentu.