2
1 Comment

How I built an auto check-in system that eliminates meeting room no-shows

Hey IH 👋

Post #3 of my build in public journey with SpotBooker. Today I'm breaking down the feature that makes the whole product work: automated check-in.

## The problem

In most offices, 30-40% of booked meeting rooms are never actually used. People book "just in case," meetings get cancelled last minute, or someone just forgets. The room stays blocked all day while others wander around looking for a free space.

I lived this in every company I worked with. The calendar shows zero availability, but half the rooms are empty. It's absurd.

## The solution

Simple concept: if you book a room, you have to prove you're there. If you don't, the room frees itself.

When someone makes a booking, they get a check-in window (configurable per company — usually 10-15 minutes after the booking starts). They can confirm their presence three ways:

1. QR code scan — each room has a unique QR code posted on the door

2. NFC tap — for offices with NFC tags

3. Email confirmation — one-click link for remote-first teams

If nobody checks in before the window closes, the booking is automatically cancelled and the room appears as available again.

## The technical implementation

QR codes are signed, not just random IDs.

Each QR code is generated with HMAC-SHA256 using a secret key + spot ID + timestamp. When scanned, the server validates the signature before accepting the check-in. This prevents someone from just guessing room IDs or reusing old codes.

Rate limiting prevents abuse.

Each spot is limited to 10 check-in attempts per minute. This stops brute-force attacks and also catches edge cases like a broken scanner repeatedly hitting the endpoint.

The release job runs on a queue.

A scheduled Laravel command runs every minute, looking for bookings that:

- Started more than X minutes ago (configurable check-in window)

- Have no check-in recorded

- Haven't been manually cancelled

These bookings are marked as "no-show" and the room status flips to available. A notification goes to the original booker so they know what happened.

Real-time updates via broadcasting.

When a room is released, other users see it instantly without refreshing. I use Laravel's event broadcasting with a simple polling fallback for older browsers. The calendar UI (FullCalendar 6) refetches events when it receives the "room released" event.

## Edge cases I had to handle

Multiple bookings in sequence. If Room A has a 9am and 10am booking by different people, and the 9am person doesn't check in, the room should only be released until 10am, not the whole day.

Timezone hell. Companies have offices in different timezones. The check-in window has to respect the local time of the room, not the server time. I store everything in UTC and convert on display.

Partial attendance. What if 3 people are invited but only 1 shows up? For now, one check-in is enough to hold the room. Some customers asked for a minimum attendance threshold — it's on the roadmap but adds complexity.

Grace period after release. If a room is released at 9:15, I block new bookings for that slot for 2 minutes. This prevents a race condition where someone books it the exact moment the original person finally arrives.

## Results

For the companies using this feature actively, the impact is real:

- Rooms that used to show "fully booked" now have 20-30% more actual availability

- No-show bookings dropped significantly once people knew their rooms would disappear

- Facility managers finally have accurate data on real usage vs. booked usage

## What I learned

The check-in feature is what sells SpotBooker. Every other feature (search, recurring bookings, approvals) exists elsewhere. But "your rooms free themselves" is the hook that makes people pay attention.

Sometimes one well-executed feature beats ten mediocre ones.

What's the one feature that defines your product?

https://spot-booker.com

posted toAvatar for product SpotBooker
SpotBooker
  1. 1

    Congrats on the launch, looks solid. How are you currently thinking about acquiring early users and gathering feedback?