Modern HRIS Dashboard for attendance management with GPS geofencing, AI-powered face recognition, shift scheduling, and real-time monitoring
Keywords: HRIS, Attendance System, GPS Tracking, Face Recognition, AI, Employee Management, Next.js, PostgreSQL, FastAPI, InsightFace
Aplikasi HRIS (Human Resource Information System) untuk manajemen absensi karyawan menggunakan GPS geolocation dan AI face recognition dengan validasi radius kantor dan verifikasi identitas berbasis wajah.
- β Dashboard monitoring real-time
- π₯ Manajemen karyawan (CRUD)
- πΈ Registrasi wajah karyawan (saat create/edit)
- π Manajemen shift (CRUD)
- π Penjadwalan shift karyawan (per minggu)
- π Data absensi lengkap dengan filter tanggal
- π Statistik absensi (total, hadir, terlambat, alpha)
- π₯ Export laporan ke CSV dengan shift schedule yang benar
- π Pengaturan multi-lokasi kantor
- βοΈ Pengaturan sistem
- π Role-based access control
- β Check-in dengan validasi GPS + Face Recognition
- β Check-out dengan validasi GPS + Face Recognition
- π€ Deteksi wajah otomatis dengan countdown
- π― Verifikasi identitas real-time (similarity > 85%)
- π Validasi radius multi-lokasi kantor (100m)
- π Lihat status absensi hari ini
- π Lihat jadwal shift bulanan
- π Statistik absensi bulanan pribadi
- β° Deteksi keterlambatan otomatis
- π Timezone WIB (Asia/Jakarta)
- Next.js 16 (App Router, JavaScript, Turbopack)
- React 19 dengan Server Components
- TailwindCSS 4 untuk styling modern
- PostgreSQL 16 (Dockerized)
- Drizzle ORM dengan camelCase schema
- FastAPI 0.115 (Python web framework)
- InsightFace 0.7.3 (buffalo_l model, 512-dim embeddings)
- ONNX Runtime 1.19 untuk inference
- OpenCV 4.10 untuk image processing
- JWT session-based cookies (HTTP-Only)
- bcrypt untuk password hashing
- Face verification dengan cosine similarity (threshold 0.5)
- Docker Compose multi-container setup
- PostgreSQL container dengan persistent volume
- Face Recognition API container terpisah
- Node.js 18+ dan npm
- Docker dan Docker Compose
- Python 3.9+ (untuk face recognition service)
- Browser dengan GPS dan Camera support
- 4GB RAM minimum (untuk ML model)
git clone https://github.com/shadowanon46-maker/hris-attendance-system.git
cd hris-attendance-systemnpm installBuat file .env.local dengan konfigurasi berikut:
# PostgreSQL Configuration (for Docker Compose)
POSTGRES_USER=hrisadmin
POSTGRES_PASSWORD=hrispass123
POSTGRES_DB=hris_db
POSTGRES_PORT=5432
# Database Configuration
DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:${POSTGRES_PORT}/${POSTGRES_DB}
# Session Secret (generate random string in production)
SESSION_SECRET=hris_secret_key_change_in_production_2024
# Face Recognition API URL
NEXT_PUBLIC_FACE_API_URL=http://localhost:8000
# Application Settings
NODE_ENV=development
NEXT_PUBLIC_APP_URL=http://localhost:3000docker-compose up -dIni akan menjalankan:
- PostgreSQL di port 5432
- Face Recognition API (FastAPI + InsightFace) di port 8000
Note: Pertama kali menjalankan, face recognition akan download model buffalo_l (~300MB). Tunggu hingga selesai (cek logs: docker logs -f hris_face_recognition)
npm run db:pushnpm run db:seednpm run devAplikasi akan berjalan di: http://localhost:3000
curl http://localhost:8000/health
# Response: {"status":"healthy","model":"buffalo_l"}# Upload gambar untuk deteksi
curl -X POST "http://localhost:8000/detect" -F "file=@path/to/photo.jpg"- Email: admin@hris.com
- Password: admin123
- Email: employee1@hris.com
- Password: employee123
- id, nip, email, password (hashed)
- full_name, role (admin/employee)
- shift_id, is_active
- face_embedding (JSON, 512-dim vector)
- face_registered_at (timestamp)
- created_at, updated_at
- id, name, start_time, end_time
- tolerance_late, description
- created_at, updated_at
- id, user_id, date
- check_in_time, check_out_time
- check_in_lat, check_in_lng
- check_out_lat, check_out_lng
- check_in_face_verified (boolean)
- check_in_face_similarity (decimal)
- check_out_face_verified (boolean)
- check_out_face_similarity (decimal)
- status, notes, created_at
- id, name, latitude, longitude
- radius, is_active
- created_at, updated_at
- id, user_id, shift_id
- schedule_date, notes
- created_by, created_at, updated_at
- id, user_id, action
- description, ip_address
- user_agent, created_at
- id, key, value
- description, updated_at
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Next.js App βββββββΆβ FastAPI Server βββββββΆβ InsightFace β
β (Frontend/API) ββββββββ (Port 8000) ββββββββ (buffalo_l) β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β β
β β
βΌ βΌ
βββββββββββββββββββ ββββββββββββββββββββ
β PostgreSQL β β Face Embeddings β
β (Port 5432) β β (512-d vector) β
βββββββββββββββββββ ββββββββββββββββββββ
- Admin membuka form create/edit karyawan
- Klik "Daftar Wajah" untuk membuka camera
- Sistem deteksi wajah secara real-time (brightness-based)
- Countdown 3 detik setelah wajah terdeteksi
- Auto-capture dan kirim ke FastAPI
- InsightFace ekstrak embedding 512-dimensi
- Simpan embedding ke database (JSON format)
- Karyawan klik tombol Clock In/Out
- Camera terbuka, sistem deteksi kehadiran wajah
- Countdown 3 detik, auto-capture
- Kirim foto + stored embedding ke FastAPI
- FastAPI:
- Ekstrak embedding dari foto baru
- Hitung cosine similarity dengan embedding tersimpan
- Return verified=true jika similarity > 0.5 (50%)
- Jika verified=true: Lanjut proses absensi
- Jika verified=false: Tampilkan error 403 (Forbidden)
- Model: buffalo_l (InsightFace)
- Embedding Size: 512 dimensions
- Similarity Threshold: 0.5 (cosine similarity)
- Typical Accuracy: 85-95% untuk wajah terdaftar
- Detection Method: Brightness-based presence (60% center area)
- Password Hashing: bcrypt dengan salt rounds 10
- Session Management: JWT-based secure cookies (HTTP-Only)
- Role-based Access: Middleware untuk authorization
- Face Recognition Security:
- Embedding disimpan sebagai JSON (tidak reversible ke gambar)
- Verifikasi mandatory untuk user dengan wajah terdaftar
- Threshold similarity 50% (adjustable)
- Reject attendance jika wajah tidak cocok (403 Forbidden)
- GPS Geofencing: Multi-location support dengan radius validation
- Activity Logging: Semua aksi penting dicatat
- Timezone Consistency: Semua timestamp menggunakan WIB (UTC+7)
- Menggunakan Geolocation API browser
- Validasi jarak menggunakan Haversine formula
- Multi-location support: Bisa tambah lebih dari 1 lokasi kantor
- Default radius: 100 meter dari koordinat (adjustable per lokasi)
- Koordinat disimpan di
office_locationstable
Semua operasi menggunakan WIB (Asia/Jakarta, UTC+7):
- Clock In/Out timestamp
- Query attendance by date
- Export laporan
- Dashboard statistics
Implementasi:
function getWIBDate() {
const now = new Date();
const wibOffset = 7 * 60; // WIB is UTC+7
const utcTime = now.getTime() + (now.getTimezoneOffset() * 60000);
return new Date(utcTime + (wibOffset * 60000));
}- Filter berdasarkan range tanggal
- Format UTF-8 dengan BOM (Excel compatible)
- Kolom: Tanggal, NIP, Nama, Shift (dari schedule), Check In, Check Out, Status
- Perbaikan: Shift diambil dari
shift_schedule, bukan user default shift - Auto-calculate status (present/late/absent)
npm run dev # Start Next.js development server
npm run build # Build for production
npm run start # Start production server
npm run db:push # Push Drizzle schema to database
npm run db:seed # Seed initial data (admin + employees)docker-compose up -d # Start semua services
docker-compose up -d postgres # Start PostgreSQL saja
docker-compose up -d face-recognition # Start Face API sajadocker-compose down # Stop semua services
docker-compose stop postgres # Stop PostgreSQL sajadocker-compose logs -f # All services
docker logs -f hris_postgres # PostgreSQL logs
docker logs -f hris_face_recognition # Face API logsdocker-compose build face-recognition # Rebuild face API (jika ubah code)
docker-compose up -d face-recognition # Restart dengan image baru# Masuk ke PostgreSQL console
docker exec -it hris_postgres psql -U hrisadmin -d hris_db
# Backup database
docker exec hris_postgres pg_dump -U hrisadmin hris_db > backup.sql
# Restore database
docker exec -i hris_postgres psql -U hrisadmin hris_db < backup.sqlproject/hris/
βββ src/
β βββ app/
β β βββ api/ # API Routes
β β β βββ admin/ # Admin endpoints
β β β β βββ attendance/ # Attendance management
β β β β βββ dashboard/ # Dashboard stats
β β β β βββ employees/ # Employee CRUD
β β β β βββ export/ # CSV export
β β β β βββ settings/ # System settings
β β β β βββ shift-schedules/ # Schedule management
β β β β βββ shifts/ # Shift CRUD
β β β βββ auth/ # Authentication
β β β β βββ login/ # Login endpoint
β β β β βββ logout/ # Logout endpoint
β β β β βββ me/ # Get current user
β β β β βββ register/ # Register endpoint
β β β βββ attendance/ # Employee attendance
β β β β βββ clock-in/ # Clock in with GPS+Face
β β β β βββ clock-out/ # Clock out with GPS+Face
β β β β βββ status/ # Attendance status
β β β β βββ today/ # Today attendance
β β β βββ employee/ # Employee endpoints
β β β βββ monthly-stats/ # Monthly statistics
β β β βββ my-schedule/ # Employee schedule
β β βββ dashboard/ # Dashboard pages
β β β βββ admin/ # Admin dashboard
β β β β βββ attendance/ # Attendance view
β β β β βββ employees/ # Employee management
β β β β βββ reports/ # Reports & export
β β β β βββ settings/ # Settings page
β β β β βββ shift-schedule/ # Schedule management
β β β β βββ shifts/ # Shift management
β β β βββ page.js # Employee dashboard
β β βββ login/ # Login page
β β βββ register/ # Register page
β β βββ layout.js # Root layout
β β βββ globals.css # Global styles
β βββ components/ # React components
β β βββ AdminNavbar.js # Admin navigation
β β βββ FaceCapture.js # Face capture component
β βββ lib/ # Libraries & utilities
β βββ db.js # Drizzle database connection
β βββ schema.js # Drizzle schema (camelCase)
β βββ session.js # Session management
β βββ geolocation.js # GPS utilities (Haversine)
β βββ seed.js # Database seeder
β βββ faceApi.js # Face API utilities
βββ face-recognition-service/ # FastAPI Face Recognition
β βββ main.py # FastAPI application
β βββ requirements.txt # Python dependencies
β βββ Dockerfile # Docker build config
βββ docker-compose.yml # Multi-container setup
βββ drizzle.config.js # Drizzle ORM configuration
βββ next.config.mjs # Next.js configuration
βββ tailwind.config.js # TailwindCSS configuration
βββ package.json # Node dependencies
βββ README.md # This file
# Cek logs face recognition container
docker logs -f hris_face_recognition
# Tunggu hingga muncul: "β
Face Recognition models loaded successfully"
# Download model ~300MB, butuh waktu 1-5 menit tergantung koneksi# Cek apakah container berjalan
docker ps | grep face
# Restart container
docker-compose restart face-recognition
# Rebuild jika ada perubahan code
docker-compose build face-recognition
docker-compose up -d face-recognition- Pastikan FormData terkirim dengan benar
- Cek parameter FastAPI menggunakan
Form()bukan default parameter - Lihat debug logs:
docker logs hris_face_recognition | grep "stored_embedding"
- Pastikan pencahayaan cukup saat registrasi dan verifikasi
- Hindari backlight atau cahaya terlalu gelap/terang
- Minta user registrasi ulang wajah di kondisi pencahayaan normal
- Pastikan menggunakan HTTPS atau localhost
- Izinkan akses lokasi di browser
- Cek apakah device mendukung Geolocation API
- Test di mobile untuk GPS lebih akurat
- Cek koordinat
office_locationstable - GPS mobile bisa error Β±20-50 meter
- Pertimbangkan naikkan radius jadi 150-200 meter
- Gunakan Google Maps untuk cek koordinat akurat
# Cek container berjalan
docker ps
# Restart PostgreSQL
docker-compose restart postgres
# Cek DATABASE_URL di .env.local
echo $env:DATABASE_URL# Push schema ulang
npm run db:push
# Atau drop database dan recreate
docker-compose down -v
docker-compose up -d
npm run db:push
npm run db:seed- Clear browser cookies
- Cek SESSION_SECRET di
.env.local - Logout dan login ulang
- Semua API sudah menggunakan WIB helper
- Jika masih error, cek fungsi
getWIBDate()di setiap API route - Refresh browser untuk fetch data dengan tanggal WIB
- Model inference butuh ~500ms-1s per request
- Pastikan container dapat alokasi memory cukup (min 2GB)
- Jangan restart container saat model loading
-- Tambah index untuk performa
CREATE INDEX idx_attendance_user_date ON attendance(user_id, date);
CREATE INDEX idx_shift_schedule_user_date ON shift_schedule(user_id, schedule_date);- β Face Recognition: AI-powered identity verification
- β Multi-location GPS: Support multiple office locations
- β Timezone WIB: Consistent timezone across all operations
- β Shift Schedule Fix: Export CSV shows correct shift from schedule
- β Auto-capture: Face detection dengan countdown otomatis
- β Security: Mandatory face verification untuk user terdaftar
- β GPS-based attendance
- β Shift management
- β Employee CRUD
- β Dashboard & reports
Built with β€οΈ by Fitrah Andre
Tech Stack: Next.js 16 β’ PostgreSQL 16 β’ FastAPI β’ InsightFace β’ Docker
MIT License - feel free to use for personal or commercial projects.
Contributions are welcome! Please open an issue or submit a pull request.
- GitHub: @shadowanon46-maker
- Project: hris-attendance-system
β Star this repo if you find it useful!