Skip to content
Hassan Zayyan
← All work

Case study · Sep 2025 – Feb 2026 · Backend Developer (freelance)

Face-recognition attendance

A Flutter app on a Laravel API that verifies faces in PHP, replacing paper attendance at a village office.

Client
Pemerintah Desa Gedangan
Role
Backend Developer (freelance): backend and deployment, Sep 2025 – Feb 2026
Team
Two people: I built the backend and deployment, my partner built the Flutter app
Stack
Laravel, PHP, MySQL, Docker (PHP-FPM, Nginx with SSL), GitHub Actions
Client app
Flutter (partner)
Status
In production through February 2026

Context

Staff attendance at the village office was recorded on paper, which made recaps slow and sign-ins hard to verify. The replacement was a face-recognition attendance system, built by a two-person team as a Flutter app backed by a Laravel API.

What I built

  • Designed the MySQL schema and the face enrollment and attendance endpoints, replacing manual paper recaps with instant queries for the office's 13 staff.
  • Implemented face verification in PHP, using cosine similarity over MobileFaceNet embeddings with weighted scoring across official and registration photos.
  • Containerized the stack with a multi-stage Docker build covering PHP-FPM, Nginx with SSL, and MySQL, set up a GitHub Actions CI/CD pipeline, and shipped it to the client's server.
  • Maintained the system in production through February 2026.

Architecture

Architecture of Face-recognition attendanceThe Flutter app computes a face embedding on the device with MobileFaceNet (TFLite) and sends it to the Laravel API's enrollment and attendance endpoints. Face verification runs in PHP with cosine similarity, weighted across the official and registration photos, and results are stored in MySQL. The API, PHP-FPM, Nginx with SSL and MySQL run from a multi-stage Docker build on the client's server.Client's serverDocker: PHP-FPM,Nginx (SSL), MySQLFlutter app (partner)Computes a face embedding on thedevice: MobileFaceNet (TFLite)Laravel APIEnrollment endpointsAttendance endpointsFace verification in PHPCosine similarity, weighted acrossofficial and registration photosMySQL

Decisions

  1. 01

    Embeddings on the device, verification on the server in PHP

    An early prototype used a separate Python (Flask) service for verification. It was dropped before production and folded into the Laravel app to keep the system simple, in one ecosystem: one codebase and one deployment.

  2. 02

    Weighted scoring across several photos

    A face is scored against the official photo and the registration photos together, instead of a single reference image.

  3. 03

    The match threshold lives in configuration

    It is kept in sync with the mobile client, because lighting and phone cameras vary in the field.

Outcome

Paper recaps were replaced by instant queries for the office's 13 staff, and I maintained the system in production through February 2026.

Screenshots

Handover at the Gedangan village office: the two developers and a village official holding phones and a laptop running the system.
Handover at the village office.
Admin dashboard in the mobile app: today's summary shows 12 of 13 staff present, 3 late and no pending leave requests. Staff names are hidden.
Admin dashboard: today's attendance.
Staff dashboard in the mobile app: the month's attendance score against a 90% target, with days present, late and on leave. The name and photo are hidden.
Staff dashboard: monthly attendance score.