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

Jejak Penanaman

Aplikasi absen acara penanaman pohon IKN yang membuktikan peserta hadir di lokasi lewat selfie ber-geofence

Tangkapan layar
radius absen, diatur per acara
50–5.000 m
jalan masuk, termasuk tamu tanpa akun
3
layar untuk peserta dan admin
28
angka desimal GPS di setiap foto
7
Di halaman ini

Masalahnya

Otorita IKN rutin menggelar acara penanaman pohon di Nusantara, untuk pegawainya sendiri dan untuk masyarakat umum. Dulu kehadiran dicatat di formulir kertas dan spreadsheet. Tidak ada yang bisa memastikan peserta memang ada di lokasi. Tidak ada catatan terpusat tentang siapa datang ke acara mana, tidak ada catatan jenis pohon yang ditanam, dan tidak ada foto.

Tiga jenis peserta harus masuk ke satu sistem. Pegawai login dengan akun pemerintah mereka. Masyarakat umum mendaftar dengan email. Di acara terbuka, sebagian orang datang begitu saja tanpa akun. Admin perlu membuat acara, menaruhnya di peta, memantau pendaftaran, dan mengekspor laporan kehadiran.

Yang saya bangun

Absen butuh selfie di lokasi acara

Untuk absen, peserta mengambil selfie dan membagikan lokasinya. Lokasi itu harus berada di dalam radius yang diatur admin untuk setiap acara, antara 50 sampai 5.000 meter dari pin di peta. Ponsel mengecek jaraknya lebih dulu dan memberi tahu peserta seberapa jauh ia dari lokasi. Server mengecek sekali lagi, jadi absen tidak bisa dipalsukan lewat API. Foto dikompres di ponsel supaya ukurannya di bawah 1 MB.

Setiap foto membawa buktinya sendiri

Sebelum diunggah, ponsel mencetak tanggal, jam WITA, dan koordinat GPS sampai tujuh angka desimal di setiap selfie dan foto tanaman. Lokasi yang sama juga ditulis ke metadata foto. Server tidak mengolah gambar sama sekali. Buktinya ikut di dalam file, jadi foto yang diunduh belakangan tetap menunjukkan kapan dan di mana foto itu diambil.

Satu catatan kehadiran, tiga jalan masuk

Pegawai login lewat single sign-on pemerintah. Nama dan unit kerja mereka datang dalam format yang tidak seragam, jadi saya merapikannya saat login. Peserta umum mendaftar dengan email dan menerima kata sandi yang dibuat otomatis. Di acara terbuka, peserta yang datang langsung bisa absen tanpa mendaftar. Sistem membuat akun tamu ringan saat itu juga, dan hak akses pengguna lain tidak berubah.

Catatan tanaman saya tambahkan di tengah jalan

Pencatatan spesies tidak ada di spesifikasi awal. Saya menambahkannya di tengah proyek untuk mendukung data penghijauan IKN, tanpa merusak data yang sudah ada. Setiap absen bisa mencatat beberapa spesies, lengkap dengan jumlah, umur bibit dalam bulan, dan fotonya. Halaman pribadi "Jejak Hijau" menampilkan semua yang pernah ditanam seorang peserta di semua acara.

Acara publik punya tiket dan kuota per instansi

Acara publik menerbitkan tiket QR untuk setiap pendaftaran. Admin memindai tiket di pintu masuk dengan kamera ponsel, dan setiap hasil pindaian mengeluarkan bunyi. Awalnya kuota hanya satu angka per acara. Ketika instansi pemerintah mulai meminta jatah sendiri, saya membuat kuota dan ukuran kaos per instansi sebagai opsi di setiap acara. Acara yang lebih sederhana tetap memakai satu kuota. Peserta juga bisa berfoto dengan bingkai twibbon IKN, lalu mengunduhnya untuk dibagikan.

Admin bisa membereskan kendala di lapangan

Di acara luar ruang, sinyal sering hilang. Admin bisa mencatat kehadiran atas nama peserta, mengatur jam kehadirannya, dan menambahkan foto tanaman ke catatan yang sudah ada. Peran superadmin mengelola para admin dan bisa mengubah status pengguna umum menjadi pegawai. Data unit kerjanya lalu dikunci, supaya login berikutnya tidak menimpa koreksi itu.

Hasilnya

Jejak Penanaman sudah berjalan di produksi dan dipakai di acara penanaman pohon IKN sejak pertengahan 2026. Saya membangunnya antara April dan Juli 2026, dan versi produksinya sudah jalan sejak Juni. Satu codebase menangani dua jenis acara. Acara internal hanya lewat login, tanpa pendaftaran. Acara publik punya pendaftaran, kuota, tiket QR, dan tamu yang datang langsung. Dashboard admin memecah kehadiran per direktorat dan kedeputian, lengkap dengan tabel peringkat untuk laporan internal. Aplikasinya punya 28 layar untuk peserta dan admin.

Di balik layarDetail teknis untuk engineer
  • API Django REST Framework dengan single-page app React (Vite), memakai token JWT akses dan refresh. Tiga service Docker Compose: PostgreSQL, Django di Gunicorn, dan React di Nginx.
  • Geofence: pengecekan jarak Haversine di klien untuk umpan balik instan ("kamu berjarak 340m"), diulang di view pengiriman absen terhadap koordinat acara yang tersimpan.
  • CameraCapture memakai MediaDevices API, menggambar frame ke canvas tersembunyi, lalu mengompresnya ke maksimal 1024px dengan kualitas JPEG 0,7. iOS Safari hanya mengizinkan getUserMedia() dari gestur pengguna, jadi kamera menyala saat tombol ditekan, tidak saat halaman dimuat.
  • Cap foto digambar di canvas sebelum diunggah. GPS ditulis ke EXIF di sisi klien dengan piexifjs.
  • Login pegawai memakai Keycloak OIDC lewat mozilla-django-oidc dan OIDCAuthenticationBackend kustom yang merapikan nama berhuruf kapital semua dan unit kerja yang tersebar di beberapa field klaim. Konfigurasi OIDC diambil dari endpoint backend saat aplikasi dibuka, jadi satu image Docker bisa dipakai di dev dan prod tanpa build ulang.
  • Email pendaftaran publik dikirim lewat SendGrid. Reset kata sandi mandiri memakai token berbatas waktu yang dikirim lewat email.
  • Absen tamu ("absen tanpa login") adalah endpoint pendaftaran anonim yang membuat pengguna tamu saat dibutuhkan.
  • Kode tiket berformat JP-YYMMDD-NNN dan diberikan secara atomik supaya tidak bentrok. Pemindai di pintu masuk memakai html5-qrcode; tiket dirender dengan qrcode.react dan diunduh lewat html2canvas.
  • Segmentasi per instansi bersifat opsional lewat flag institution_enabled dan tshirt_enabled di Event. Setiap baris EventInstitution punya kuota yang boleh null (null berarti tanpa batas) dan daftar ukuran kaosnya sendiri.
  • Satu bingkai twibbon bawaan berlaku di semua acara, kecuali acara itu punya bingkai sendiri. Bingkai digabungkan di sisi klien dengan canvas.
  • Form acara di admin memakai react-leaflet dengan pin yang bisa digeser dan slider radius.
  • 5 Django app (accounts, events, attendance, flora, twibbon), 13 model, sekitar 90 pola URL API, dan 28 halaman frontend. Sekitar 11.200 baris JSX/JS dan 3.400 baris Python, 78 commit dari 1 April sampai 3 Juli 2026.

Tangkapan layar

Beranda
Jejak Hijau
Riwayat
Event Detail
Admin Dashboard

Sedang merekrut, atau membangun hal serupa?

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