Skip to content
android mobile-app featured

Antrian Potong Rambut — Barbershop Queue App (Android + Laravel)

Android barbershop queue app with no customer login: scan the shop QR, fill a short form, take a face photo, and track your number live. Barbers use the same APK to call, serve, and record payment. Kotlin + Jetpack Compose on a Laravel 13 API.

android │ source only · admin-dashboard· android· computer-vision· jetpack-compose
Customer ticket with position and estimated wait
Admin Dashboard Android Computer Vision Jetpack Compose Kotlin Laravel MariaDB PHP Retrofit

An Android queue app for a barbershop. A customer scans the shop's QR code, fills in name and age, takes a face photo, and gets a queue number — no account, no sign-up. The phone then tracks the position and the estimated wait. Barbers use the same APK in a login mode to call, serve, and close each ticket. A university project for Mobile Applications — Android 3 (class TI23).

Highlights

  • No customer login — the QR holds the server address and a shop code, so the app needs no IP setting. A device UUID identifies the phone; one phone can register a group of 1–10 people, each with an own sequential number.
  • Race-safe numbering — taking a number and "call next" run inside a DB transaction that locks the shop row (lockForUpdate), with a unique (date, number) key as a safety net. Measured with 30 concurrent PHP processes against MariaDB: 30/30 succeed with unique numbers 1..30. Negative control (lock removed): only 7/30 succeed.
  • Temporary face photo — the photo helps the barber recognise the customer. It needs explicit consent, the server checks it is a JPEG (≤300 KB), only the barber and the owner's phone can fetch it, and it is deleted when the ticket is finished or cancelled.
  • The server decides everything — numbering, status transitions, and wait estimates live in Laravel models. The phone only sends input and shows results; invalid transitions return 409.

Key Features

  1. Customer flow — scan QR → form (name, age, service) → face photo (manual shutter, enabled only when ML Kit sees the face in position) → ticket with position and "±N minutes" estimate.
  2. Live boards — chair board (who is in each barber's chair) and a waiting-line board, polled while the screen is visible.
  3. Background notifications — a foreground service rings when 2 people are left and when the customer is called.
  4. Barber mode — call next, start, skip, recall, finish + record payment (cash/QRIS), and walk-in tickets for customers without the app.
  5. Owner tools — manage services, barbers, shop settings, regenerate the QR, and a daily report (revenue, customers, ratings).

Tech Stack

  • Kotlin 2.4 + Jetpack Compose (one Activity per screen)
  • CameraX 1.6 + ML Kit barcode scanning and face detection (offline)
  • Retrofit 3 + kotlinx-serialization
  • Laravel 13 + Sanctum (barber tokens)
  • MariaDB 10.4

Status & Maturity

Feature-complete for the course and tested on a real phone (vivo, Android 12) over Wi-Fi: full customer flow, barber flow, walk-ins, notifications, and QR regeneration. Runs on a local network (laptop server + phones on the same Wi-Fi); it is not deployed publicly. A smarter wait estimate based on real service history is planned.

Measured Metrics

Laravel feature tests 67 passing
Android unit tests 14 passing
Concurrent number taking 30/30 unique (no lock: 7/30)
Database tables 6 (4 master, 2 transaction)