C:\ARDI\PROJECTS\HR_ATTENDANCE> type case-study.txt
HR Attendance & Leave System
Sistem Absensi & Cuti HR
How I replaced a hand-made attendance recap and paper leave forms with a system that all 33 employees of a rural bank now use, running on one office server with no internet access.
Bagaimana saya mengganti rekap absensi manual dan formulir cuti kertas dengan sistem yang sekarang dipakai seluruh 33 karyawan sebuah BPR, berjalan di satu server kantor tanpa akses internet.
My role: sole developer and the bank's only IT staff, so requirements, design, code, deployment, training and support. Stack: Python, FastAPI, SQLAlchemy, SQLite, Jinja2, HTMX, APScheduler, openpyxl, pyzk for the ZKTeco terminal. Timeline: first commit 6 August 2026, release candidate 11 September 2026, in daily use since.
Peran saya: developer tunggal sekaligus satu-satunya staf IT bank: kebutuhan, desain, kode, deployment, pelatihan, dan dukungan. Stack: Python, FastAPI, SQLAlchemy, SQLite, Jinja2, HTMX, APScheduler, openpyxl, pyzk untuk mesin ZKTeco. Waktu: commit pertama 6 Agustus 2026, rilis kandidat 11 September 2026, dipakai setiap hari sejak itu.
01 The problemMasalahnya
Before
Sebelum
- Attendance lived on a fingerprint terminal. Every payroll period HR exported a spreadsheet and recapped it by hand: late arrivals, absences, overtime.
- Security guards' night shifts were split across two calendar days, so their records never added up without manual fixing.
- Leave requests were paper forms walking between manager, director and HR, with the yearly quota tracked separately.
- Data absensi ada di mesin sidik jari. Setiap periode payroll HR mengekspor spreadsheet lalu merekapnya manual: terlambat, tidak masuk, lembur.
- Shift malam satpam terpecah di dua tanggal kalender, jadi datanya tidak pernah cocok tanpa diperbaiki manual.
- Pengajuan cuti pakai formulir kertas yang berpindah antara manager, direksi, dan HR, dengan kuota tahunan dicatat terpisah.
After
Sesudah
- Scans arrive by themselves every 90 seconds and land on the right person.
- HR downloads a payroll-ready Excel recap instead of building one, saving hours every payroll period.
- Leave is requested, approved and recorded online, with the quota counted in working days and an audit trail.
- Scan masuk sendiri setiap 90 detik dan tercatat ke orang yang tepat.
- HR mengunduh rekap Excel siap payroll alih-alih menyusunnya sendiri, hemat berjam-jam setiap periode payroll.
- Cuti diajukan, disetujui, dan dicatat online, dengan kuota dihitung dalam hari kerja dan jejak audit.
Constraints: the office server has no internet access, employee data must stay inside the office, fewer than 50 staff, and one IT person to build and run it.
Batasan: server kantor tanpa akses internet, data karyawan harus tetap di dalam kantor, kurang dari 50 staf, dan hanya satu orang IT untuk membangun sekaligus menjalankannya.
02 What I builtYang saya bangun
- Automatic attendance: a background job polls the ZKTeco terminal every 90 seconds. The terminal's user ID is the employee ID, so every account starts from a real fingerprint.
- Leave workflow: leave, permission, sick leave, short trips out, special leave and attendance corrections, routed employee → manager → director → HR. If the manager is absent (detected from attendance), the request goes to the supervisor instead.
- Quota rules: 12 working days a year from the first work anniversary. Sundays and holidays are never charged, and collective-leave days are charged once through a ledger.
- Guard shifts: a shift schedule for security guards, so a night shift from 23:00 to 07:00 counts as one shift, not two broken days.
- Payroll export: an Excel file laid out like the terminal's own export, with per-employee totals, colour marking for what costs pay, and HR's plain-language notes.
- Safety nets: manual corrections only by HR/Admin with an audit note, role-based access for 7 roles, scheduled backups every 6 hours, and a dashboard warning when the fingerprint terminal goes quiet.
- Absensi otomatis: job latar membaca mesin ZKTeco setiap 90 detik. ID pengguna di mesin adalah ID karyawan, jadi setiap akun berawal dari sidik jari asli.
- Alur cuti: cuti, izin, sakit, izin keluar, cuti khusus, dan koreksi absen, dengan alur karyawan → manager → direksi → HR. Kalau manager tidak masuk (terdeteksi dari absensi), pengajuan dialihkan ke supervisor.
- Aturan kuota: 12 hari kerja per tahun sejak ulang tahun kerja pertama. Hari Minggu dan hari libur tidak dipotong, dan cuti bersama dipotong sekali lewat buku besar.
- Shift satpam: jadwal shift satpam, jadi shift malam 23:00–07:00 dihitung satu shift, bukan dua hari yang terpotong.
- Ekspor payroll: file Excel dengan tata letak seperti ekspor bawaan mesin, lengkap dengan total per karyawan, tanda warna untuk yang memotong gaji, dan catatan HR.
- Pengaman: koreksi manual hanya oleh HR/Admin dengan catatan audit, hak akses untuk 7 peran, backup terjadwal tiap 6 jam, dan peringatan di dashboard kalau mesin sidik jari berhenti mengirim data.
03 ArchitectureArsitektur
Everything runs on one office PC on the LAN. Nothing leaves the building.
Semuanya berjalan di satu PC kantor di LAN. Tidak ada data yang keluar gedung.
04 Key decisionsKeputusan penting
Server-rendered pages with HTMX, not a SPA
No build step and no CDN, so it works fully offline and one person can maintain it.
SQLite, with numbered migrations
Fewer than 50 users on one machine. A single file is easy to back up, and 17 SQL migrations apply themselves on startup.
An air-gapped install
Every dependency is bundled with the app, and one script installs it on a PC that has never seen the internet.
Build in-house rather than buy
I wrote a memo to the Board comparing a vendor offer. The rules are specific to this bank, the requirements changed four times in five days once people used it, and the data stays in the office.
Halaman server-rendered dengan HTMX, bukan SPA
Tanpa proses build dan tanpa CDN, jadi berjalan penuh secara offline dan bisa dirawat satu orang.
SQLite, dengan migrasi bernomor
Kurang dari 50 pengguna di satu mesin. Satu file mudah di-backup, dan 17 migrasi SQL berjalan sendiri saat aplikasi menyala.
Instalasi tanpa internet
Semua dependensi dibundel bersama aplikasi, dan satu skrip memasangnya di PC yang tidak pernah terhubung internet.
Bangun sendiri, bukan beli
Saya menulis memo ke Direksi yang membandingkan penawaran vendor. Aturannya sangat khusus untuk bank ini, kebutuhannya berubah empat kali dalam lima hari setelah dipakai, dan data tetap di dalam kantor.
05 Hard problemsMasalah tersulit
Night shifts that crossed midnight
A guard on the night shift scans at 23:00 and again at 07:00 the next morning. Filed by calendar date, that became one day with no exit and a next day whose exit looked like an arrival. I rebuilt guard attendance around shifts instead of dates, with a rotation schedule, so a night shift is one record again.
A login loop nobody reported
While auditing something unrelated, I found that the "change your password" page and the "complete your profile" page each sent users to the other. 22 of 40 accounts were stuck. I fixed it, wrote it up in the audit, and changed how I work: re-audit after every big change instead of trusting an earlier review.
Saying the risks out loud
The system works, but backups sat on the same disk and everything depended on me. I put both in writing to the Board, with fixes: an off-machine backup, a visible "last backup" age, and training a colleague as backup.
Shift malam yang melewati tengah malam
Satpam shift malam scan pukul 23:00 lalu lagi pukul 07:00 besok paginya. Kalau dicatat per tanggal, jadinya satu hari tanpa jam pulang dan hari berikutnya yang jam pulangnya terbaca sebagai jam masuk. Saya membangun ulang absensi satpam berdasarkan shift, bukan tanggal, lengkap dengan jadwal rotasi, sehingga satu shift malam kembali jadi satu catatan.
Login berputar-putar yang tidak dilaporkan siapa pun
Saat mengaudit hal lain, saya menemukan halaman "ganti password" dan "lengkapi profil" saling melempar pengguna ke satu sama lain. 22 dari 40 akun terjebak. Saya memperbaikinya, mencatatnya di laporan audit, dan mengubah cara kerja: audit ulang setiap selesai perubahan besar, bukan mengandalkan review sebelumnya.
Menyampaikan risiko secara terbuka
Sistemnya jalan, tapi backup masih di disk yang sama dan semuanya bergantung pada saya. Keduanya saya sampaikan tertulis ke Direksi, lengkap dengan solusinya: backup di luar mesin, penanda umur backup terakhir yang terlihat, dan melatih satu rekan sebagai cadangan.
06 ResultsHasil
- All 33 employees use it, from staff checking their own attendance to directors approving leave.
- HR no longer builds the attendance recap by hand each payroll period; the export is ready to use.
- Leave has a single source of truth: who asked, who approved, and how much quota is left.
- Delivered as about 60 commits in ~8 weeks (around 10,700 lines of Python), with written spec, status, deploy and audit documents.
- Seluruh 33 karyawan memakainya, dari staf yang mengecek absensinya sendiri sampai direksi yang menyetujui cuti.
- HR tidak lagi menyusun rekap absensi manual setiap periode payroll; hasil ekspornya langsung siap pakai.
- Cuti punya satu sumber data: siapa yang mengajukan, siapa yang menyetujui, dan berapa sisa kuotanya.
- Dikerjakan dalam sekitar 60 commit dalam ~8 minggu (sekitar 10.700 baris Python), lengkap dengan dokumen spesifikasi, status, deployment, dan audit.
07 What I learnedPelajaran
- Real use beats the spec. The best simplifications came from watching people use it in the first week.
- Offline changes everything: no CDN, bundled dependencies, and backups that you can actually check.
- Write it down. A spec, a status log and an audit made it possible to hand over, explain to the Board, and find the bugs nobody reported.
- Pemakaian nyata mengalahkan spesifikasi. Penyederhanaan terbaik datang dari melihat orang memakainya di minggu pertama.
- Offline mengubah segalanya: tanpa CDN, dependensi dibundel, dan backup yang benar-benar bisa dicek.
- Tulis semuanya. Spesifikasi, log status, dan audit membuat sistem bisa diserahterimakan, dijelaskan ke Direksi, dan bug yang tidak dilaporkan siapa pun bisa ditemukan.
Need someone who can build the system and keep the network under it running?
Butuh orang yang bisa membangun sistemnya sekaligus menjaga jaringan di bawahnya?
WhatsApp Email Download CVUnduh CV More projectsProyek lain
