Absensi personel lapangan itu masalah lama yang jarang dibahas serius oleh developer.
Kita sibuk optimasi bundle size. Sibuk debat state management. Sementara di lapangan, satu supervisor masih menghitung kehadiran 60 orang pakai grup WhatsApp dan foto selfie di depan pos jaga.
Dan foto itu bisa diambil di mana saja.
Transformasi digital sektor jasa dan ketenagakerjaan di Indonesia memang bergerak, sebagaimana banyak dilaporkan dalam liputan ekonomi dan ketenagakerjaan Kompas, tapi lapisan operasional paling bawah sering kali tertinggal. Padahal justru di situ datanya paling berantakan. Di situlah geofencing absensi shift lapangan berhenti jadi buzzword dan mulai jadi kebutuhan teknis yang nyata.
Secara teknis, ini bukan hal baru. Riset tentang akurasi location-based attendance, GNSS spoofing detection, dan fencing radius calibration sudah cukup matang — banyak di antaranya terdokumentasi dalam publikasi teknik dan komputasi IEEE Xplore.
Masalahnya bukan teori.
Masalahnya implementasi: sinyal jelek di kawasan industri, HP entry-level, personel yang shift-nya berubah mendadak, dan lokasi kerja yang tersebar di banyak site. Kami mengangkat tema ini karena pengalaman langsung menangani operasional multi-site — di lingkungan seperti kawasan Jababeka, Cikarang — memperlihatkan satu hal: sistem absensi yang gagal bukan karena algoritmanya salah, tapi karena arsiteknya tidak pernah berdiri di pos jaga jam 2 pagi.
Kesimpulan di depan: geofencing yang baik bukan soal seberapa ketat kamu menolak, tapi seberapa jujur kamu mencatat. Sistem yang menolak absen 20% waktu akan diakali. Sistem yang mencatat semua dengan confidence score akan dipercaya.
1. Kenapa Absensi Lapangan Berbeda dari Absensi Kantor
Sebelum masuk ke kode, penting memahami bahwa asumsi yang berlaku di aplikasi absensi kantoran hampir semuanya runtuh saat dibawa ke lapangan. Konteks operasionalnya berbeda total, dan kesalahan paling umum adalah memakai mental model yang sama.
Asumsi yang Runtuh
- Asumsi WiFi stabil. Di gudang dan area pabrik, sinyal seluler saja sering 1 bar.
- Asumsi satu lokasi. Personel bisa dirotasi ke 3 site berbeda dalam seminggu.
- Asumsi device seragam. Realitanya: campuran Android 9 sampai Android 14.
- Asumsi jam kerja normal. Shift malam, shift split, dan pergantian mendadak itu rutin.
Konsekuensi Teknisnya
| Tantangan Lapangan | Dampak Teknis | Mitigasi Arsitektur |
|---|---|---|
| Sinyal lemah / hilang | Absen gagal terkirim | Offline-first + queue sync |
| GPS drift di dalam gedung | False negative check-in | Radius adaptif + confidence score |
| Fake GPS app | Data absensi tidak valid | Mock location detection + device attestation |
| Multi-site rotation | Salah geofence aktif | Assignment-based fence resolution |
| Baterai HP habis | Personel tidak bisa absen | Fallback supervisor override + audit log |
Poin pentingnya: setiap baris di tabel itu adalah keputusan produk, bukan sekadar keputusan teknis.
2. Merancang Model Data yang Tahan Realita
Banyak sistem absensi gagal di level skema, jauh sebelum gagal di level UI. Model data yang terlalu naif akan memaksa kamu menambal logika di aplikasi, dan tambalan itu akan bocor cepat atau lambat.
Entitas Inti
Struktur minimal yang kami pakai kira-kira begini:
-- Site: lokasi fisik penempatan
CREATE TABLE sites (
id UUID PRIMARY KEY,
name TEXT NOT NULL,
center_lat DOUBLE PRECISION NOT NULL,
center_lng DOUBLE PRECISION NOT NULL,
radius_m INTEGER NOT NULL DEFAULT 100,
indoor_bias BOOLEAN DEFAULT FALSE
);
-- Assignment: siapa, di site mana, shift kapan
CREATE TABLE shift_assignments (
id UUID PRIMARY KEY,
personnel_id UUID NOT NULL,
site_id UUID NOT NULL REFERENCES sites(id),
starts_at TIMESTAMPTZ NOT NULL,
ends_at TIMESTAMPTZ NOT NULL,
grace_in_m INTEGER DEFAULT 15,
grace_out_m INTEGER DEFAULT 15
);
-- Attendance event: catat SEMUA, jangan tolak diam-diam
CREATE TABLE attendance_events (
id UUID PRIMARY KEY,
assignment_id UUID NOT NULL REFERENCES shift_assignments(id),
event_type TEXT NOT NULL, -- check_in | check_out
recorded_at TIMESTAMPTZ NOT NULL,
device_lat DOUBLE PRECISION,
device_lng DOUBLE PRECISION,
accuracy_m DOUBLE PRECISION,
distance_m DOUBLE PRECISION,
confidence SMALLINT, -- 0..100
is_mocked BOOLEAN DEFAULT FALSE,
synced_at TIMESTAMPTZ,
raw_payload JSONB
);
Prinsip yang Menyelamatkan Kami
Satu keputusan desain yang paling berdampak:
Jangan pernah menolak absensi secara diam-diam.
Catat event-nya. Beri confidence rendah. Tandai anomalinya. Biarkan supervisor dan HR yang memutuskan.
Kenapa? Karena sistem yang menolak akan menciptakan shadow process — personel akan lapor via WhatsApp lagi, dan kamu kembali ke titik nol.
3. Logika Geofencing yang Tidak Naif
Implementasi geofencing paling sering ditulis sebagai satu baris perbandingan jarak. Itu bekerja di demo, dan gagal di hari ketiga produksi. Bab ini membahas versi yang lebih realistis.
Jarak Saja Tidak Cukup
Versi naif yang harus dihindari:
// ❌ Terlalu naif
const isValid = haversine(userPos, sitePos) <= site.radius_m;
Masalahnya: accuracy dari perangkat diabaikan total. Padahal GPS bisa melaporkan posisi dengan margin error 40 meter dan tetap "yakin".
Versi dengan Confidence Score
const R = 6371000;
function haversine(a, b) {
const toRad = (d) => (d * Math.PI) / 180;
const dLat = toRad(b.lat - a.lat);
const dLng = toRad(b.lng - a.lng);
const lat1 = toRad(a.lat);
const lat2 = toRad(b.lat);
const h =
Math.sin(dLat / 2) ** 2 +
Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLng / 2) ** 2;
return 2 * R * Math.asin(Math.sqrt(h));
}
function evaluateGeofence({ pos, site }) {
const distance = haversine(pos, {
lat: site.center_lat,
lng: site.center_lng,
});
// Radius efektif menyesuaikan kualitas sinyal
const effectiveRadius =
site.radius_m + Math.min(pos.accuracy ?? 0, site.indoor_bias ? 80 : 40);
const inside = distance <= effectiveRadius;
// Confidence turun kalau accuracy buruk atau posisi di tepi fence
let confidence = 100;
if (pos.accuracy > 20) confidence -= Math.min((pos.accuracy - 20) * 1.5, 45);
if (distance > site.radius_m) confidence -= 25;
if (pos.mocked) confidence = 0;
return {
inside,
distance: Math.round(distance),
confidence: Math.max(0, Math.round(confidence)),
flagged: pos.mocked || confidence < 55,
};
}
Deteksi Mock Location
Di Android, Location.isFromMockProvider() masih jadi lapisan pertama yang layak. Tapi jangan berhenti di situ. Kombinasikan dengan:
- Cross-check terhadap cell tower atau WiFi BSSID yang terdaftar di site.
- Deteksi lompatan posisi tidak wajar (teleport detection) antar event.
- Konsistensi sensor fusion: akselerometer diam total selama 8 jam itu anomali.
Untuk pola arsitektur frontend yang menangani kondisi jaringan tidak ideal seperti ini, tulisan Addy Osmani tentang strategi caching dan offline di Dev.to memberi kerangka berpikir yang sangat berguna sebelum kamu menulis service worker sendiri.
4. Offline-First: Bagian yang Paling Sering Diremehkan
Ini bagian yang membedakan prototipe dengan sistem produksi. Personel keamanan di area basement atau gudang tertutup akan kehilangan koneksi, dan sistem harus tetap berfungsi tanpa menyalahkan pengguna.
Antrian Lokal dengan IndexedDB
import { openDB } from 'idb';
const dbPromise = openDB('attendance', 1, {
upgrade(db) {
db.createObjectStore('queue', { keyPath: 'localId' });
},
});
export async function enqueueEvent(event) {
const db = await dbPromise;
await db.put('queue', {
...event,
localId: crypto.randomUUID(),
queuedAt: Date.now(),
});
}
export async function flushQueue(send) {
const db = await dbPromise;
const items = await db.getAll('queue');
for (const item of items) {
try {
// Idempotency key wajib — hindari duplikat saat retry
await send(item, { idempotencyKey: item.localId });
await db.delete('queue', item.localId);
} catch (err) {
if (err.status >= 400 && err.status < 500) {
await db.delete('queue', item.localId); // permanen gagal, jangan loop
}
break; // sisanya coba lagi nanti
}
}
}
Aturan Main Sinkronisasi
- Timestamp dari device, bukan server. Tapi simpan keduanya untuk audit.
- Idempotency key wajib. Retry tanpa ini akan menghasilkan absen ganda.
- Backoff eksponensial. Jangan hammer server saat 200 device online bersamaan setelah sinyal pulih.
- Batas usia antrian. Event yang mengendap lebih dari 48 jam ditandai untuk review manual.
Detail kecil yang menyelamatkan: tampilkan status antrian ke pengguna. "3 absen menunggu terkirim" jauh lebih menenangkan daripada layar yang diam.
5. Panduan Implementasi Bertahap
Bab ini adalah kerangka eksekusi. Urutannya sengaja dibuat agar kamu punya sesuatu yang bisa diuji di lapangan sejak minggu pertama, bukan setelah tiga bulan.
Langkah 1 — Pemetaan Site dan Kalibrasi Radius
Datangi setiap site. Rekam koordinat di beberapa titik (gerbang, pos jaga, area kerja). Tetapkan radius berdasarkan sebaran nyata, bukan tebakan Google Maps.
Langkah 2 — Model Assignment Sebelum Model Absensi
Bangun penjadwalan shift lebih dulu. Tanpa assignment yang benar, sistem tidak tahu geofence mana yang harus aktif untuk personel mana.
Langkah 3 — Client Offline-First
Bangun PWA dengan service worker dan antrian IndexedDB. Uji dengan mode pesawat, bukan hanya dengan throttling DevTools.
Langkah 4 — Lapisan Anti-Fraud
Tambahkan mock detection, teleport detection, dan cross-check BSSID. Jalankan dalam shadow mode selama dua minggu — catat saja, jangan blokir dulu.
Langkah 5 — Dashboard Supervisor
Tampilkan anomali, bukan seluruh data. Supervisor tidak butuh 1.800 baris; dia butuh 12 yang mencurigakan.
Langkah 6 — Evaluasi dan Kalibrasi Ulang
Setelah satu siklus penggajian penuh, tinjau kembali ambang confidence dan radius per site. Sistem geofencing absensi shift lapangan yang baik selalu dikalibrasi ulang, tidak pernah selesai sekali jadi.
6. Kepatuhan, Privasi, dan Batas Etis
Ada dimensi yang tidak bisa diselesaikan dengan kode, dan mengabaikannya adalah risiko hukum sekaligus risiko kepercayaan. Sistem pelacakan lokasi menyentuh wilayah data pribadi secara langsung.
Prinsip Minimisasi Data
- Rekam lokasi hanya pada event absensi, bukan tracking kontinu.
- Simpan koordinat mentah dengan retensi terbatas; agregat untuk laporan jangka panjang.
- Berikan transparansi: personel harus bisa melihat data lokasi dirinya sendiri.
Selaras dengan Sistem Manajemen
Bagi organisasi yang menjalankan sistem manajemen terstandar — ISO 9001, ISO 27001, atau ISO 45001 — data absensi bukan sekadar payroll. Ia jadi bukti audit untuk kontrol akses, jam kerja, dan kepatuhan K3.
Praktik ini yang kami terapkan di PT Bima Indo Garda, penyedia layanan security, cleaning, manpower, dan driver services di kawasan industri, di mana kontrol operasional lintas site harus bisa dipertanggungjawabkan secara dokumen, bukan sekadar terasa rapi.
FAQ
Apakah geofencing bisa akurat di dalam gedung?
Tidak sepenuhnya. Gunakan radius adaptif dan kombinasikan dengan WiFi BSSID atau NFC tag di pos jaga sebagai lapisan verifikasi kedua.
Berapa radius geofence yang ideal?
Tidak ada angka universal. Mulai dari 100 meter, lalu kalibrasi turun berdasarkan data accuracy nyata dari lapangan selama dua minggu pertama.
Bagaimana kalau HP personel tidak mendukung fitur ini?
Sediakan jalur fallback berupa supervisor override yang tercatat penuh di audit log. Jangan biarkan keterbatasan device menciptakan proses bayangan di WhatsApp.
Apakah perlu native app, atau PWA cukup?
PWA cukup untuk mayoritas kasus. Native app baru masuk akal jika kamu butuh background location atau device attestation tingkat lanjut.
Bagaimana menangani personel dengan rotasi multi-site harian?
Selesaikan di level assignment. Geofence yang aktif ditentukan oleh jadwal, bukan oleh site terdekat dari posisi pengguna.
Sistem yang Dipercaya, Bukan Sekadar Sistem yang Ketat
Sebagai penutup, ada satu pergeseran cara pandang yang layak dibawa pulang dari seluruh pembahasan ini. Sistem absensi lapangan bukan proyek untuk menangkap orang curang. Ia proyek untuk menghilangkan ambiguitas — supaya personel yang benar-benar hadir tidak perlu membuktikan diri lewat foto selfie yang meragukan, dan supervisor tidak perlu menebak.
Martin Fowler, arsitek perangkat lunak yang karyanya membentuk cara industri memandang refactoring dan arsitektur aplikasi enterprise, pernah menyatakan bahwa kode yang baik adalah kode yang bisa dipahami manusia, bukan sekadar yang bisa dijalankan mesin.
Relevansinya di sini langsung terasa. Sistem geofencing yang penuh aturan tersembunyi dan penolakan senyap memang "jalan" secara teknis — tapi tidak bisa dipahami oleh orang yang memakainya setiap hari jam 2 pagi. Dan sistem yang tidak dipahami akan selalu diakali.
Bangun yang transparan. Catat semuanya. Beri skor, bukan vonis.
Sisanya adalah kalibrasi.
Top comments (0)