Booking platformBackend Engineer, sole developerJul 2025 - Mar 2026
Reservation Platform
The API behind a multi-role booking product: conflict-free scheduling, staff rosters, loyalty and management analytics.
- 106
- REST endpoints
- 31
- Sequelize models
- 15
- Domain modules

My contribution
Sole backend engineer, from the data model and API surface through to Dockerised deployment, contract testing and a production security checklist: 106 REST endpoints across 15 domain modules, 93 controllers, 31 Sequelize models and 4 role tiers. It replaced a legacy Laravel backend in place. I reimplemented Laravel's AES-256-CBC payload format and password hashing in Node, so the new API reads and writes the existing MySQL database with no data migration and no downtime for the clients on it.
The hard part
The slot engine had to reconcile six independent sources of unavailability (opening hours, per-staff working hours, full-day leave, mid-day breaks, short absences and live bookings) without ever double-booking. Merging the blocked periods into normalised intervals first keeps it linear, instead of testing every candidate slot against every constraint.
What it is
A production REST API for appointment-based service businesses, powering a mobile app for both clients and staff plus a public website. It covers the whole booking lifecycle: client onboarding, service and product catalogues, staff schedules and leave, real-time booking, loyalty points, promotions, push notifications and management analytics.
Availability engine
- Aggregates multi-service durations into one required block and finds windows that fit the whole booking, so nothing is booked partially or allowed to overflow
- Reconciles opening hours, per-staff weekly hours, full-day leave, breaks, short absences and existing reservations
- Handles recurring and one-off absence patterns, including rules that apply only on certain weekdays
- Merges overlapping blocked periods before generating free windows
- Normalises date comparisons to UTC, which fixed a class of wrong-availability bugs around midnight and same-day bookings
Reservation lifecycle
- Transactional booking covering service validation, price and duration computation, promo-code discounting, reservation creation, line items and QR generation, all atomic across five tables
- A status state machine (pending, accepted, started, completed, cancelled) with role-gated transitions
- QR check-in that looks up an encrypted reservation payload on arrival and awards loyalty points
- An hourly job that closes stale pending reservations, credits points and emits notifications without one failure aborting the batch
Auth and access control
- JWT access and refresh tokens with configurable algorithm, issuer and audience
- OAuth2 social login resolving users by provider account ID, rebuilt after production users hit account-collision cases when switching providers
- Password reset over email OTP
- Role-based middleware on centralised role constants, with account-status checks at the auth layer
- Tiered rate limiting, stricter on auth endpoints than on the rest of the surface
Notifications and analytics
- An event-driven Firebase Cloud Messaging subsystem: an async event bus, business-event triggers, localised templates, multi-device delivery and automatic cleanup of invalid tokens
- Cron-driven reminder and auto-completion jobs, with notifications also persisted for paginated history
- Nine analytics endpoints for the manager dashboard, including per-staff performance with month-over-month deltas on bookings, revenue and rating
Platform work
- Audited the surface against REST semantics, corrected 17 endpoints, and reconciled routes against the spec, which surfaced 16 undocumented endpoints and several method and content-type mismatches
- Standardised every response behind one envelope shape with correlation IDs
- Added ~140 indexes, including FULLTEXT, through a custom idempotent migration runner that inspects the live schema before each run
- Modular OpenAPI 3 spec with generated Postman collections and Dredd contract tests across 93 endpoints, minting JWTs per role
- Multi-stage Dockerfile with a non-root runtime user and container health check, plus compose stacks for MySQL and Redis
- Structured Winston logging with daily rotation, correlation IDs and Sentry
- Full French localisation of API messages, validation errors and notification templates