Hospitality Self Check-in & Operations Dashboard
A guest-facing self check-in flow paired with a staff operations dashboard, connected to the property's existing reservation system, with OCR-assisted passport capture and clear status tracking for the front desk.
The problem
- Front-desk check-in relied on manual reservation lookups and passport handling.
- Passport details were typed in by hand: slow and easy to get wrong.
- Staff had no single view of who had checked in, who hadn't, and who needed attention.
- Real reservations don't map cleanly to one guest, so multi-guest and sub-guest cases got messy.
What I built
- A guest self check-in flow: reservation lookup, passport capture, terms agreement, QR step, and completion.
- OCR-assisted passport reading with retries and a manual-entry fallback when a scan fails.
- A staff dashboard showing today's arrivals, live status, and a clear needs-attention list.
- An app-side workflow database kept separate from the PMS, tracking check-in state the reservation system doesn't hold.
- Secure server-side integration so external API keys are never exposed to the browser.
Business value
- Cuts repetitive front-desk verification and manual data entry.
- Makes check-in status visible to staff at a glance.
- Lets guests check in before arrival, smoothing the front desk.
- Surfaces the guests who actually need attention.
- Gives operations clearer, more scalable workflows.
Designed for a target volume of around 3,000 guests/month: a planning estimate used for sizing, not a proven-usage claim.
How the workflow runs
- 1Find reservationLook up by booking number
- 2Capture passportOCR + manual fallback
- 3Agree to termsDigital agreement
- 4Scan QRArrival step
- 5DoneCheck-in complete
- 1Today's arrivalsOne live list
- 2Review & verifyConfirm OCR results
- 3Resolve flagsClear needs-attention
- 4Checked inStatus updated
What made it hard
The interesting problems weren't the screens; they were the business rules underneath them. This is exactly where a naive AI-generated build would have gone wrong.
One reservation ≠ one guest
Multiple guests and sub-guests can belong to a single reservation, and room/bed/guest relationships needed careful modelling. Assuming one-to-one would have caused rework, so I clarified the rules before building.
The PMS data wasn't enough
The reservation system didn't track online check-in progress, OCR results, or staff review state. The app needed its own workflow database alongside it, with clear ownership of each piece of data.
Documents from real phones
Passport photos arrive as HEIC, JPEG or PNG from phone cameras, with glare and odd angles. The flow needed retries, validation, and a manual-entry fallback so a failed scan never blocks a guest.
Production behaves differently than test
A stale CDN cache served old HTML that referenced Next.js build chunks which no longer existed, breaking one route while others worked. I isolated it to that URL, then shipped a cache-control fix so stale HTML can't break deployed pages again.
Before & after
- Guest reads out their reservation number
- Staff look it up by hand
- Passport details typed in manually
- Check-in status lives in someone's head
- Hard to tell who still needs checking
- Guests check in before they arrive
- Reservation matched from the booking number
- Passport captured by OCR, confirmed by staff
- Live status on one shared dashboard
- A needs-attention list makes gaps obvious
Client and property details are anonymized. Optional identity verification (e.g. face match) was explored as a possible future extension, not shipped. The architecture and workflow shown reflect how the system was designed and built.
Have a similar problem to solve?
If something here mirrors a process your team is wrestling with, I'd be glad to talk through what an approach like this could look like for you.
