Baku Heritage Tours
Full-stack development
A tour-booking and operations platform for a heritage-tour operator, built solo. It handles the whole lifecycle: a visitor books a tour online, and staff scan the QR ticket at the gate. Under the hood it's a Next.js Turborepo monorepo with a microservices backend.
The problem
Small tour operators run on a patchwork. A booking form here, a spreadsheet there, paper tickets at the door, and no single view of what's actually happening. Double-bookings slip through, walk-ins are hard to price, and nobody can say who really showed up. Baku Heritage Tours puts all of that in one place. Sell online, check people in at the gate, and see everything from one dashboard, so a small team can run more tours without more overhead.
What it does
Capability | What it means |
|---|---|
QR ticketing & check-in | Issue a scannable ticket on booking, and validate it at the door |
Reservations & dynamic pricing | Manage availability and adjust prices by demand and season |
Content CMS | Staff manage tours, media and pages without a developer |
Audit logging | Every sensitive action is recorded for accountability |
Scheduled jobs | Reminders, cleanup and reporting run on their own |
How it works
A Next.js app serves both the public site and the staff admin. Behind it, a set of Elysia.js services own separate slices of the domain over typed contracts. PostgreSQL (through Prisma) is the source of truth, and Redis handles anything fast and disposable like rate limits, job queues and caching. A booking moves through the system like this:
- Book. A visitor picks a tour and slot. The service checks availability and prices it.
- Issue. A QR ticket is generated and a confirmation email goes out.
- Scan. At the gate, staff scan the QR and the service validates it and checks the visitor in.
- Record. The check-in is logged, and scheduled jobs handle reminders and reporting.
Highlights
- Built solo, end to end: data model, services, UI and deployment
- Covers the full lifecycle, from booking to payment to ticket to gate scan
- Microservices on a shared-types monorepo, so client and services never drift
- Operations kept honest by audit logs and scheduled jobs
Stack
Next.js ·
Turborepo ·
Bun · Elysia.js ·
Prisma ·
PostgreSQL · Redis
Why this stack
Choice | Why | Instead of |
|---|---|---|
Next.js (App Router) | Server components render tour pages fast for SEO, and one framework covers both the public site and the admin | a separate SPA plus a standalone API |
Turborepo monorepo | Web and services share types and UI from one install, so the client can't drift from the API | a polyrepo with duplicated, hand-synced types |
Elysia.js on Bun | Tiny, end-to-end-typed services with first-class performance | a monolithic Express app with untyped routes |
PostgreSQL | Bookings and tickets need relational integrity and hard constraints | a document store like MongoDB |
Redis | Fast, disposable state for rate limits, job queues and caching | hammering Postgres for every transient read |
Biggest thing I've built solo. A whole business running end to end on one system. Ambitious, sure, but that's exactly why I took it on.