Face Attendance System
Face-verified clock-in on phone and door terminals.
- Role
- Product design · Full stack
- Year
- 2026
- Platform
- Web dashboard · iOS · Android · Face terminals
- Stack
- Laravel 12 · React 19 · Expo · DeepFace · MariaDB · Docker

Overview
The problem
A public health office tracked attendance across several clinics with a mix of door terminals and manual sign-ins. Punches were duplicated or missing, field staff couldn't clock in at all, and HR had no quick way to tell a genuine punch from a doubtful one.
The idea
One attendance pipeline for every capture method: staff clock in with a selfie and GPS on their phone or at a face terminal, each punch is checked against their enrolled face, and only the doubtful ones land in an HR review queue.
Built for a public health office. Shown anonymised — screens are recreated with sample data.
What I did
Design
- 01Live dashboard: who's in, late, not in yet and what needs triage, per site
- 02Review queue that sorts mismatches first so HR clears the worst cases quickly
- 03Mobile clock-in with a guided face frame, head-turn liveness prompts and location status
- 04Per-office capture policy settings written in plain language, not config flags
Engineering
- 01Laravel 12 API with a strict Form Request → DTO → Service layering and separate web and mobile APIs
- 02Self-hosted DeepFace (Facenet512) service: embeddings are compared in PHP, verdicts sorted into verified / review / unverified
- 03Door-terminal push ingest and phone punches share one dedup and in/out pairing pipeline, with row locks and replay-safe indexes
- 04Multi-office tenancy with per-office capture policy, haversine geofence and per-employee exemptions
How it works
Screens




Under the hood
React dashboard
TanStack Query · Tailwind · shadcn/ui
Expo app
Selfie · GPS · liveness
Laravel 12 API
Sanctum · dedup · pairing
DeepFace service
Facenet512 · internal only
MariaDB
Encrypted selfies · audit trail
3 bands
Verified, review or unverified for every face match
2 sources
Phone and door terminal in one pipeline
Geofence
Flag or enforce per office, exempt per person
Self-hosted
Face data never leaves the server
