All work
032026Product design, full-stack build & deployment

Site Ledger

Attendance & payroll for a hospital construction site

PHP 8MySQLJavaScriptQR ScanningTOTP 2FAPayroll Engine

Client system · Under NDA

The brief

A private attendance and weekly payroll system for a university hospital construction site. QR badges are scanned at the gate, overtime and lateness go through separate approvals, and every week closes on a signed statement. The real data stays with the client, so this case study runs on placeholder data.

A charitable endowment is building a university hospital, and the site's weekly payroll lived in one hand-typed Excel workbook: more than 5,000 shift rows, four linked sheets, and corrections that overwrote whatever was there before. It worked, but every payday depended on someone typing carefully, and a disputed week could not be traced back to anything.

The rules in that sheet had already survived months of real payroll, so they were carried over exactly: a 10 hour regular cap, overtime paid at 1.5x only once a person approves it, and a Saturday cutoff that moves an afternoon check-in into the following pay week so a shift running into Sunday is never split in two. Lateness became its own approval rather than an automatic deduction, so a foreman can sign off the overtime on a shift while still reviewing the lateness on it.

Workers scan a laminated QR badge at a gate tablet with a USB scanner. The server stamps the time, never the device, and punches are append-only: a correction points back at the row it replaces instead of overwriting it. Each week closes on a signed statement that stores a hash of the document, so if the data underneath ever changes the system flags it, and payroll staff export the same layout they already sign off on.

It runs on plain PHP 8 and MySQL on shared hosting, with no framework and no build step, because that is what the client's hosting runs. That ruled out a few libraries, so the QR encoder and the .xlsx writer are written from scratch. Access is locked down with mandatory TOTP two-factor sign-in, login throttling, CSRF tokens, and a kiosk that only works on a tablet paired through a one-time link.

What shipped

  • QR badge kiosk on a paired gate tablet with a USB scanner
  • Payroll engine that keeps the sheet's rules: 10h cap, approved OT at 1.5x, Saturday cutoff
  • Overtime and lateness approved separately, by role
  • Append-only punches: corrections point back, never overwrite
  • Signed weekly statements with a hash that flags later edits
  • Dependency-free QR encoder and .xlsx writer for shared hosting
  • 5,000+ historical shift rows migrated from Excel
Role
Product design, full-stack build & deployment
Year
2026
The problem

From a hand-typed sheet to one scan at the gate

Payroll for the whole site lived in one Excel workbook. The new system kept every rule that already worked and replaced everything else.

Before
  • 5,000+shift rows typed in by hand
  • 4linked sheets holding the payroll
  • 0audit trail when a row was corrected
After
  • 1 scanto check a worker in at the gate
  • 2separate approvals: overtime and lateness
  • 1 clickto a signed statement or an .xlsx export
How it works

Badge to signed statement

  1. 01QR badgeLaminated, one per worker
  2. 02Gate kioskPaired tablet with a USB scanner
  3. 03Server clockThe device's time is never trusted
  4. 04Append-only logCorrections point back, never overwrite
  5. 05ApprovalsOvertime and lateness, by role
  6. 06Signed statementHashed, then exported to .xlsx
Try it

The kiosk and payroll engine, on placeholder data

Scan a badge, move the times, and approve or hold overtime and lateness. The rules are the real ones. The workers and wages are invented.

Gate kiosk Paired device

Pick a badge, then scan it.

University Hospital ProjectMain gate
07:12:00
Scan your badge
Hold the badge up to the reader
Scan badge here
Supervisor sign-in (lost badge)Dashboard

Time is stamped by the server. The tablet's clock never touches payroll.

Payroll engineDemo wage $3.00/h
Day
Hours on site12.30h
Regular (capped at 10h)10.00h
Overtime at 1.5xPending
Late deductionPending
Day's pay$30.00
Counts toward this week's payroll. Try a Saturday check-in after 12:00 to see the cutoff rule.

Placeholder workers and wages. Same rules as the real engine.

Inside the system

What the admins see

The real screens, translated to English and filled with placeholder rows. The live system runs in Arabic for the site office. Names and amounts stay with the client.

Approving late deductions
A signed weekly statement
Under the hood

Built for shared hosting, hardened like it matters

01

QR encoder from scratch

Badges come from a dependency-free QR encoder, with a self-test that has to pass on the server before a single badge is printed.

02

A real .xlsx writer

The host had no zip extension, so the export builds valid Excel files by hand. Payroll staff get the layout they already sign off on.

03

Tamper-evident statements

Each signed weekly statement stores a hash of the document. If the data underneath drifts later, the system flags it.

04

Locked-down access

Mandatory TOTP two-factor sign-in, login throttling, CSRF tokens, and a kiosk that only works on a tablet paired through a one-time link.

05

Code outside the web root

Application code and config sit beside public_html, not inside it, with a second rule that 404s those paths if they are ever uploaded by mistake.

06

Built to keep changing

40+ database migrations shipped as the site's rules evolved: shift templates, PPE tracking, missed-shift requests, payouts and more.

Next project

Obay Morad

Personal brand & portfolio