Booking and capacity
Itineraries, departure dates, capacity and waiting list; deposits with remaining balance tracking. Capacity for recurring tours is now calculated per date.
A booking platform for women-only group tours: occupancy-driven tiered pricing, cash and token refunds and authorisation audited across 38 tables. 57k lines of code, two locales, pre-rendered SEO.
| Stack | React 18 + TypeScript, Vite, Tailwind CSS, Framer Motion |
|---|---|
| Backend | PostgreSQL with edge functions and row-level security |
| Codebase | ~57,000 lines · 351 files |
| Interface | 145 components · 34 pages |
| Database | 38 tables · 74 versioned migrations |
| Server functions | 23 (payments, refunds, email, automated blog) |
| Locales | TR · EN via a dictionary-based translation layer |
| Payments | 3-D Secure card payments, deposits and balance tracking |
| SEO | Pre-rendered pages served to search bots |
Itineraries, departure dates, capacity and waiting list; deposits with remaining balance tracking. Capacity for recurring tours is now calculated per date.
Prices rise as occupancy grows. Virtual sales entered by an administrator do not count towards the ladder, and leaving the last tier empty no longer pins the price to the first tier.
Separate functions for cash and token refunds; cancellation tiers and the token deduction rate were consolidated into one settings hub and are calculated dynamically at refund time.
The free-ticket gap was closed with a trigger, and the role-check function's public grant was revoked. Row-level authorisation was verified across all 38 tables.
A bottom ticket sheet with a fixed mobile action bar, scroll-to-error warnings, a day-by-day itinerary in tabs, inline editing of included/excluded services, and corrected currency formatting.
The whole site was opened up in English through a translation dictionary, and the loading order that froze the header on language switch was fixed.
Most of the problems we solved on Kızkıza Heryerde repeat across sectors. Tell us about yours and we will scope it together.
We load nothing beyond the cookies required for the site to work. If you let us measure which pages get attention, we can make the site better. Details