Back to CV

case_study_02 · skvass-gate-access

Selected build · remote hardware · live

Skvass Gate Access - remote gym access automation

A full-circle access system for a squash gym: memberships and bookings in the third-party booking platform become QR or wallet credentials, biometric scanners read them at the door, and a Raspberry Pi decides whether the gate should open.

Role
Solo build · architecture, implementation, deployment and remote debugging
Scope
Booking sync, QR/NFC access, local rules engine, biometric-scanner WebSocket integration, admin UI, Raspberry Pi deployment
Scale
Live gym install · 2 biometric scanners · 177 members bound in recovery push · changed-only normal sync
Stack
Python · FastAPI · SQLAlchemy · SQLite · React · Vite · aiohttp WebSockets · systemd · Raspberry Pi · third-party booking API · biometric-scanner WebSocket protocol
Fig. 01 Live install — booking → credential → scan → gate, in motion.

01

The problem was not the door

Opening a door is easy. The hard part is knowing, at the exact moment someone is standing in front of a scanner, whether that person has a valid membership, a live booking, a single-use access right, or no right to enter at all.

This project had to close that loop for a squash gym without depending on front-desk staff. The booking and membership system lived in a third-party API. The scanners spoke their own WebSocket protocol. The gate was physical hardware on-site. I was building from another country, with no direct access to the devices when something behaved strangely.

That changes the engineering shape. You do not just build endpoints. You build the ability to see, reason about and recover a physical system from a terminal somewhere else.

02

The local bridge

The Raspberry Pi at the venue became the bridge between software truth and physical reality. It runs the Python service, serves the admin UI, keeps the local SQLite state, accepts scanner WebSocket connections, and decides whether to open the gate.

The result is not a scheduling integration and not a gate controller. It is the glue in the middle, where operational truth becomes hardware behaviour.

Architecture loop showing third-party bookings and members flowing into the Raspberry Pi, local SQLite rules engine, biometric scanners, gate hardware, customer credentials and admin observability
Fig. 02 — The access loop. Booking and membership state on the left, scanner and gate behaviour on the right, the Pi and the local rules engine in between.

03

Synchronisation became the product

The first version of any access system can push users. The useful version knows when not to. The biometric scanners hold device-side state — face templates, palm prints, enrolment IDs — so normal sync cannot casually delete and recreate everyone just because the booking platform changed one field.

The production path became deliberately frugal. A booking-platform sync inserts new clients, updates changed records, preserves field-derived values, soft-disables missing users, and marks only affected clients pending for the scanners. The scanner sync then hashes the canonical payload and sends only new, changed or newly inactive users. Inactive users are disabled, not deleted.

There is still a manual force-all button. It exists for device reset and recovery, not as the normal operating mode. That distinction matters in hardware systems. Routine work should be quiet; recovery tools should be explicit.

04

Bridging bookings and biometrics

The booking platform identifies members by software identifiers: client IDs, booking IDs, membership IDs. Numbers issued at signup, mutated by every renewal and cancellation. The biometric scanners at the door identify members by something else entirely — a face print, a palm print, an enrolment ID stored on the device. Two identity systems looking at the same person from opposite sides: one ledger of bookings, one ledger of bodies.

The job of this gate is not to read a face. It is to make those two ledgers agree on the same person, every time, without anyone at the gym fixing it by hand.

Binding happens at enrolment. A member registers online and the booking platform issues them a client ID. Some time later they visit the gym, present a face or a palm to a scanner, and the device captures a biometric template against an enrolment ID. The bridge has to bind those two events: this client_id is this enrolment, the same human being. After that, the two sides evolve independently. A member extends their membership online — their face has not changed, but their access rights have. A member re-enrols their face after some change in appearance — their bookings have not changed, but their template has. Both kinds of change have to flow to the gate without breaking the binding.

The architecture follows from that:

  • A canonical mapping from booking identifier ↔ scanner enrolment ID, owned by the bridge — neither external system is authoritative on its own.
  • Field-level binding for contact data — email, phone, ID number — pushed to the scanners so they have enough context to operate without continuously reading back to the booking platform.
  • Sync that touches only the records that have actually changed, so device biometric state is not blown away on every refresh.
  • Force-all recovery as a separate, explicit tool — used after a mapping has drifted, never as the normal path.

The result is a member walking up to a scanner. Face matches. The bridge resolves face → enrolment ID → client ID → "valid membership today". Gate opens. The two identity systems were aligned three steps before the member ever got there.

Admin view of 177 members fully bound and present on both biometric scanners — booking-platform identities reconciled with scanner enrolments
Fig. 03 — After full reconciliation. 177 members bound across both scanners: every booking-platform identity matched to a biometric enrolment, every drift resolved.

05

How AI carried the ambiguous parts

AI was not a chatbot bolted onto the product. It was used as an engineering accelerator around documentation, protocol analysis, remote debugging and implementation. The system itself still makes deterministic access decisions. AI helped build the system that makes those decisions reliably.

01

Third-party API integration agent

AI analysed the third-party booking API surface and helped turn booking, client and membership data into a local sync model. That included preserving local credentials, enriching missing fields only when needed, and designing the access rules around real booking and membership states. Build-time only.

02

Scanner protocol integration agent

The scanner side was built from protocol descriptions and observed device messages. AI helped map scanner registration, QR scan events, user-management commands (create, update, enable, query), profile fields, password fields and privilege levels into a working WebSocket command layer. Build-time only, with production-facing outputs.

03

Spec-to-installation planning

AI was given the components available: a Raspberry Pi, the third-party booking platform, biometric scanners, a physical gate and API/protocol documentation. From that, it helped plan the architecture, database shape, admin UI, sync flow, deployment script and installation assumptions. Build-time only.

04

Remote hardware debugging partner

When a scanner stopped opening the gate, the investigation had to happen through logs, command traces and observed device responses. AI helped rule through the software path and point the investigation toward what turned out to be a wiring issue. One-off incident support. The fix was twenty centimetres of cable, identified from a country away.

Gate hardware open during debugging, internal wiring exposed, hand reaching into the cabling area
Fig. 04 — Where the investigation ended up. The trace started in software logs and ended at exposed cabling on-site. AI ruled out the software path quickly enough that the on-site time went straight to the wiring.

05

Regression and release assistant

AI added tests around sync behaviour, access decisions, payload hashes, profile metadata and admin privilege tagging, then used the deploy script to push releases to the Pi and verify the scanners through live read-back commands. Build-time and release-time.

06

What this proves

This is the shape of a useful AI-assisted build: not a demo, not a prompt trick, but a working physical system where the software has to survive third-party APIs, undocumented device behaviour, remote deployment and hardware faults.

The bet is simple: with AI as an engineering partner, one person can own the full booking-to-gate loop and still keep enough discipline in the system to repair it when reality disagrees.