Overview
HeliCar aggregates helicopter, car, and bus bookings behind one flow. Guests can complete a reservation without an account; operators get a role-based admin UI for inventory, pricing windows, and cancellations.
Problem
The business needed a single pipeline for three vehicle classes with different pricing rules, validation, and capacity limits. Shipping quickly with ad-hoc controllers would have made auth, reporting, and auditing inconsistent.
Architecture
- Modular domain services in Node/Express: bookings, vehicles, pricing, notifications. HTTP layer stays thin—validation in, DTOs out.
- PostgreSQL + Sequelize: relational model for inventory and schedules; explicit migrations for every schema change.
- React + Tailwind admin: tables and forms optimized for staff workflows (bulk edits, filters), not marketing polish.
- Docker for repeatable deploys across staging and production.
Traffic-sensitive paths (OTP send, search) sit behind queues where rate limits apply, so spikes don’t hammer SMTP or third-party APIs.
Technical challenges
| Challenge | Approach |
|---|---|
| Dynamic pricing by vehicle + season | Pricing resolved in a dedicated service; cached per window with explicit invalidation |
| Guest vs staff permissions | JWT for staff; short-lived tokens for guest session where needed; admin routes gated by role middleware |
| Email deliverability for OTP | Retry with backoff; structured logging of provider responses for debugging |
Performance
- List endpoints use pagination + selective columns; N+1 avoided via Sequelize
includediscipline. - Heavy reads (availability calendars) use bounded query windows and indexes on vehicle + date columns.
Tradeoffs
- Monolith over microservices: faster iteration for a small team; bounded contexts still enforced in folder structure.
- Sequelize vs raw SQL: ORM for velocity; raw SQL only where explain plans proved it necessary.
Results (directional)
Concrete numbers depend on deployment—replace this block with measured P95 latency, conversion, or error-rate deltas from your production monitoring.
- OTP verification path designed for < 3s perceived round-trip under normal SMTP latency.
- Admin bulk actions batched to avoid long transactions on hot rows.
Lessons learned
- Treat email as an unreliable channel: idempotent tokens, resend caps, and visible UX when providers throttle.
- Invest early in migration hygiene; booking systems accumulate edge cases fast.