Kolpa Adventures Booking
Online rafting booking platform for a Slovenian outfitter, with Stripe payments and FURS-compliant fiscal receipts.

Overview
Kolpa Adventures Booking is an online reservation platform for a Slovenian river-rafting outfitter. Guests pick a date and time slot, pay online with Stripe, and receive a confirmation email together with a FURS-verified fiscal receipt as required by Slovenian tax law. Staff manage bookings, schedules, pricing, and promo codes from a dedicated admin panel.
It's live in production, taking real payments and filing a real fiscal invoice on every booking. I built it solo — owning both the engineering and the product — in about 10 weeks, with Claude Code as my development and research partner.
Key Features
- Bilingual booking flow (SL/EN) with URL-prefixed locales and a 6-step guided checkout.
- Slot-based capacity with race-safe seat allocation under concurrent checkouts.
- Stripe payments via the embedded Payment Element with 3DS/SCA handled automatically.
- Slovenian fiscal receipts issued through Minimax and verified by FURS, attached as a PDF to the confirmation email.
- Admin panel for bookings, walk-in entry, calendar, schedule overrides, promo codes, versioned pricing, and GDPR marketing exports.
Technical Implementation
- Framework: Next.js (App Router) with Server Actions, React Server Components, and TypeScript in strict mode.
- Styling: Tailwind CSS with shadcn/ui primitives and custom brand tokens.
- i18n:
next-intlwith URL-prefixed Slovenian and English locales. - Database & Auth: Supabase Postgres with Row Level Security and magic-link auth for staff.
- Payments: Stripe Payment Element backed by a server-created Checkout Session, with an idempotent webhook for paid-state transitions.
- Fiscalization: Minimax REST API (FURS ZOI/EOR signing) driven by an event-based pipeline — a paid booking fans out through Postgres triggers to background workers, with pg_cron sweepers retrying any failures.
- Email: Resend with React Email templates in both languages.
- Observability & Hosting: Sentry for error tracking; deployed on Vercel.
Challenges & Solutions
The hardest part was guaranteeing that two guests racing for the last seat in a slot can't both succeed. Solved with a Postgres advisory lock keyed on activity + date + hour, taken inside the capacity-recheck function so the check and the booking commit are atomic across instances.
Fiscal issuance is fragile by nature — Minimax or FURS can be momentarily unavailable. A paid booking starts an event-driven pipeline where background workers issue the receipt and send the email independently, each guarded by a lease so a retry can never double-issue an invoice or double-send an email. If the receipt is slow, the confirmation email goes out without the PDF and a follow-up email delivers it once it's ready.
How It Was Built
I worked solo, using Claude Code as a development partner and a team of specialized agents — frontend, backend, code review, and QA. The first lesson was that parallel agents need a deep spec: my early attempt, built from a shallow one, produced a sloppy MVP that took days to untangle. So I built a system around the agents — settle the spec first, write tests as the spec, run a review agent on every handoff, and let QA agents drive the real booking flow in a browser and end-to-end before launch. The result is a production app that handles real money and real tax compliance, built fast without cutting corners.
