Skip to content

HRIS Dashboard - GPS-based Attendance System with geofencing validation, shift management, and real-time monitoring. Built with Next.js 16, PostgreSQL, and Drizzle ORM.

Notifications You must be signed in to change notification settings

shadowanon46-maker/hris-attendance-system

Repository files navigation

HRIS Attendance System | GPS-Based Employee Tracking with Face Recognition

Modern HRIS Dashboard for attendance management with GPS geofencing, AI-powered face recognition, shift scheduling, and real-time monitoring

Next.js PostgreSQL FastAPI InsightFace Docker License

Keywords: HRIS, Attendance System, GPS Tracking, Face Recognition, AI, Employee Management, Next.js, PostgreSQL, FastAPI, InsightFace


HRIS Dashboard - Sistem Absensi GPS & Pengenalan Wajah

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.

πŸš€ Fitur Utama

Untuk Admin:

  • βœ… 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

Untuk Karyawan:

  • βœ… 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)

πŸ› οΈ Teknologi Stack

Frontend & Backend

  • Next.js 16 (App Router, JavaScript, Turbopack)
  • React 19 dengan Server Components
  • TailwindCSS 4 untuk styling modern

Database & ORM

  • PostgreSQL 16 (Dockerized)
  • Drizzle ORM dengan camelCase schema

AI & Face Recognition

  • 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

Authentication & Security

  • JWT session-based cookies (HTTP-Only)
  • bcrypt untuk password hashing
  • Face verification dengan cosine similarity (threshold 0.5)

DevOps

  • Docker Compose multi-container setup
  • PostgreSQL container dengan persistent volume
  • Face Recognition API container terpisah

πŸ“‹ Prerequisites

  • 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)

πŸ”§ Instalasi & Setup

1. Clone Repository

git clone https://github.com/shadowanon46-maker/hris-attendance-system.git
cd hris-attendance-system

2. Install Dependencies

npm install

3. Setup Environment Variables

Buat 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:3000

4. Start All Services dengan Docker Compose

docker-compose up -d

Ini 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)

5. Push Database Schema

npm run db:push

6. Seed Data Awal

npm run db:seed

7. Run Next.js Development Server

npm run dev

Aplikasi akan berjalan di: http://localhost:3000

πŸ§ͺ Testing Face Recognition

Cek Face API Status

curl http://localhost:8000/health
# Response: {"status":"healthy","model":"buffalo_l"}

Test Face Detection

# Upload gambar untuk deteksi
curl -X POST "http://localhost:8000/detect" -F "file=@path/to/photo.jpg"

πŸ‘€ Default Credentials

Admin

Employee Sample

πŸ—„οΈ Database Schema

Tabel: users

  • 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

Tabel: shift

  • id, name, start_time, end_time
  • tolerance_late, description
  • created_at, updated_at

Tabel: attendance

  • 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

Tabel: office_locations

  • id, name, latitude, longitude
  • radius, is_active
  • created_at, updated_at

Tabel: shift_schedule

  • id, user_id, shift_id
  • schedule_date, notes
  • created_by, created_at, updated_at

Tabel: activity_log

  • id, user_id, action
  • description, ip_address
  • user_agent, created_at

Tabel: company_settings

  • id, key, value
  • description, updated_at

πŸ€– Face Recognition System

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Next.js App   │─────▢│  FastAPI Server  │─────▢│  InsightFace    β”‚
β”‚  (Frontend/API) │◀─────│   (Port 8000)    │◀─────│   (buffalo_l)   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        β”‚                        β”‚
        β”‚                        β”‚
        β–Ό                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   PostgreSQL    β”‚      β”‚  Face Embeddings β”‚
β”‚   (Port 5432)   β”‚      β”‚   (512-d vector) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Face Registration Flow

  1. Admin membuka form create/edit karyawan
  2. Klik "Daftar Wajah" untuk membuka camera
  3. Sistem deteksi wajah secara real-time (brightness-based)
  4. Countdown 3 detik setelah wajah terdeteksi
  5. Auto-capture dan kirim ke FastAPI
  6. InsightFace ekstrak embedding 512-dimensi
  7. Simpan embedding ke database (JSON format)

Face Verification Flow (Clock In/Out)

  1. Karyawan klik tombol Clock In/Out
  2. Camera terbuka, sistem deteksi kehadiran wajah
  3. Countdown 3 detik, auto-capture
  4. Kirim foto + stored embedding ke FastAPI
  5. FastAPI:
    • Ekstrak embedding dari foto baru
    • Hitung cosine similarity dengan embedding tersimpan
    • Return verified=true jika similarity > 0.5 (50%)
  6. Jika verified=true: Lanjut proses absensi
  7. Jika verified=false: Tampilkan error 403 (Forbidden)

Model Details

  • 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)

πŸ” Security Features

  1. Password Hashing: bcrypt dengan salt rounds 10
  2. Session Management: JWT-based secure cookies (HTTP-Only)
  3. Role-based Access: Middleware untuk authorization
  4. 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)
  5. GPS Geofencing: Multi-location support dengan radius validation
  6. Activity Logging: Semua aksi penting dicatat
  7. Timezone Consistency: Semua timestamp menggunakan WIB (UTC+7)

🌍 GPS Geofencing

  • 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_locations table

⏰ Timezone Management

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));
}

πŸ“Š Fitur Laporan

Export CSV

  • 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 Scripts

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 Commands

Start Services

docker-compose up -d              # Start semua services
docker-compose up -d postgres     # Start PostgreSQL saja
docker-compose up -d face-recognition  # Start Face API saja

Stop Services

docker-compose down               # Stop semua services
docker-compose stop postgres      # Stop PostgreSQL saja

View Logs

docker-compose logs -f            # All services
docker logs -f hris_postgres      # PostgreSQL logs
docker logs -f hris_face_recognition  # Face API logs

Rebuild Services

docker-compose build face-recognition  # Rebuild face API (jika ubah code)
docker-compose up -d face-recognition  # Restart dengan image baru

Database Management

# 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.sql

πŸ“ Struktur Project

project/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

🚨 Troubleshooting

Face Recognition Issues

Model tidak ter-download

# 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

Face API tidak merespon

# 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

Error "stored_embedding not received"

  • Pastikan FormData terkirim dengan benar
  • Cek parameter FastAPI menggunakan Form() bukan default parameter
  • Lihat debug logs: docker logs hris_face_recognition | grep "stored_embedding"

Similarity terlalu rendah (< 50%)

  • Pastikan pencahayaan cukup saat registrasi dan verifikasi
  • Hindari backlight atau cahaya terlalu gelap/terang
  • Minta user registrasi ulang wajah di kondisi pencahayaan normal

GPS Issues

GPS tidak berfungsi

  • Pastikan menggunakan HTTPS atau localhost
  • Izinkan akses lokasi di browser
  • Cek apakah device mendukung Geolocation API
  • Test di mobile untuk GPS lebih akurat

Selalu di luar radius padahal di lokasi

  • Cek koordinat office_locations table
  • GPS mobile bisa error Β±20-50 meter
  • Pertimbangkan naikkan radius jadi 150-200 meter
  • Gunakan Google Maps untuk cek koordinat akurat

Database Issues

Connection error

# Cek container berjalan
docker ps

# Restart PostgreSQL
docker-compose restart postgres

# Cek DATABASE_URL di .env.local
echo $env:DATABASE_URL

Schema tidak sinkron

# 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

Session/Login Issues

Token expired atau invalid

  • Clear browser cookies
  • Cek SESSION_SECRET di .env.local
  • Logout dan login ulang

Timezone salah (tanggal tidak match)

  • Semua API sudah menggunakan WIB helper
  • Jika masih error, cek fungsi getWIBDate() di setiap API route
  • Refresh browser untuk fetch data dengan tanggal WIB

Performance Issues

Face API lambat

  • Model inference butuh ~500ms-1s per request
  • Pastikan container dapat alokasi memory cukup (min 2GB)
  • Jangan restart container saat model loading

Database query lambat

-- 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);

πŸ“ Changelog

Version 2.0 (Current)

  • βœ… 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

Version 1.0

  • βœ… GPS-based attendance
  • βœ… Shift management
  • βœ… Employee CRUD
  • βœ… Dashboard & reports

Built with ❀️ by Fitrah Andre

Tech Stack: Next.js 16 β€’ PostgreSQL 16 β€’ FastAPI β€’ InsightFace β€’ Docker


πŸ“„ License

MIT License - feel free to use for personal or commercial projects.

🀝 Contributing

Contributions are welcome! Please open an issue or submit a pull request.

πŸ“§ Contact


⭐ Star this repo if you find it useful!

About

HRIS Dashboard - GPS-based Attendance System with geofencing validation, shift management, and real-time monitoring. Built with Next.js 16, PostgreSQL, and Drizzle ORM.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published