Clock-in dan clock-out
Karyawan mencatat satu clock-in dan satu clock-out per hari. Status tepat waktu sampai 08.00 WIB dan terlambat sesudahnya ditentukan otomatis.
PROYEK 01 · APLIKASI FULL-STACK
Attenda adalah aplikasi absensi karyawan full-stack. Frontend React terhubung ke REST API Go dengan database MySQL. Karyawan melakukan clock-in dan clock-out dari dashboard, sedangkan administrator mengelola akun dan meninjau data absensi.
Overview
01 / LATAR BELAKANG
Mencatat absensi hanyalah sebagian dari kebutuhan. Karyawan memerlukan cara sederhana untuk mencatat waktu kerja, dan admin memerlukan satu tempat untuk mengelola akses serta meninjau data. Saya membangun Attenda untuk berlatih autentikasi, akses berbasis peran, dan pemisahan yang rapi antara frontend dan backend.
02 / FITUR
Karyawan mencatat satu clock-in dan satu clock-out per hari. Status tepat waktu sampai 08.00 WIB dan terlambat sesudahnya ditentukan otomatis.
Persentase tepat waktu, absensi terbaru, dan riwayat absensi yang bisa dicari.
Admin membuat akun karyawan dan mengaktifkan atau menonaktifkannya. Akun nonaktif langsung kehilangan akses.
Admin melihat ringkasan hari ini dan menelusuri semua data, dengan pencarian nama karyawan dan filter status.
Password bcrypt, JWT HS256, middleware peran, validasi input, dan pembatasan laju pada login dan register.
Tes Go untuk JWT, aturan terlambat, validasi, dan middleware admin. GitHub Actions menjalankan format, vet, test, lint, dan build.
TANGKAPAN LAYAR
ENDPOINT API
| METHOD | PATH | AKSES | CATATAN |
|---|---|---|---|
| GET | /health | Publik | Memeriksa kesehatan API dan database. |
| POST | /register | Publik | Membuat akun karyawan. Peran tidak bisa dipilih oleh klien. |
| POST | /login | Publik | Mengembalikan JWT. Dibatasi per IP. |
| GET | /profile | Perlu login | Pengguna yang sedang login. |
| POST | /clock-in | Perlu login | Mencatat clock-in hari ini. Status on_time atau late ditentukan oleh server. |
| POST | /clock-out | Perlu login | Mencatat clock-out hari ini. |
| GET | /attendance/history | Perlu login | Riwayat absensi milikmu, terbaru lebih dulu. |
| GET | /admin/employees | Khusus admin | Daftar karyawan. |
| POST | /admin/employees | Khusus admin | Membuat akun karyawan. |
| PATCH | /admin/employees/:id/status | Khusus admin | Mengaktifkan atau menonaktifkan karyawan. |
| GET | /admin/attendances | Khusus admin | Semua data absensi. |
KEPUTUSAN DESAIN
Middleware autentikasi memuat pengguna dari database setiap kali. Akun yang dinonaktifkan, atau yang perannya berubah, langsung kehilangan akses dan tidak menunggu JWT kedaluwarsa.
Unique index pada pengguna dan tanggal menolak clock-in kedua di hari yang sama, bahkan ketika dua request datang bersamaan. Handler mengubah error duplicate-entry MySQL 1062 menjadi respons yang jelas.
Pendaftaran publik selalu membuat karyawan. Akun admin hanya berasal dari perintah seed, dan route admin berada di balik middleware autentikasi sekaligus middleware admin.
Clock-in setelah pukul 08.00 WIB dianggap terlambat. Batas waktu dihitung di server dengan zona Asia/Jakarta, jadi tidak bergantung pada jam perangkat, dan aturannya dicakup unit test.
Password memakai bcrypt. Token harus HS256 dan ditolak jika tidak, server menolak autentikasi tanpa secret JWT, login dan register dibatasi lajunya, dan server memiliki timeout baca, tulis, serta idle.
03 / PERBAIKAN BERIKUTNYA
Menyimpan JWT di cookie httpOnly dengan refresh token, bukan di localStorage; menambahkan pagination pada daftar admin; memakai migrasi berversi, bukan AutoMigrate; dan menambah tes integrasi yang berjalan di database sungguhan.