Weekly Blog: Building Booknix Beyond a Single Booking Category

By: Muhammad Faisal

One platform, five different experiences

This week, Booknix moved closer to becoming a unified marketplace for real-world experiences. The focus was not on transportation; it was on the other categories that make booking behavior more diverse and technically interesting: cinema, events, parties, seminars, and dinners.

At first glance, these categories appear similar. A customer discovers something interesting, selects a date or time, provides attendee information, and confirms a booking. Underneath that simple flow, however, each category has different rules. A cinema needs assigned seats. An event must protect limited inventory. A party may have both capacity and venue requirements. A seminar needs attendee registration. A dinner reservation depends on party size, dining area, arrival time, and the overlap between existing reservations.

The engineering challenge was therefore not just to add five screens. It was to create shared foundations without erasing the business rules that make each category different.

A shared marketplace with category-aware behavior

Booknix now presents cinema, event, party, seminar, and dinner listings through a consistent customer marketplace. Customers can identify the organization, understand the offering, inspect availability, and continue into a focused booking flow.

Cinema, event, party, and seminar offerings share scheduled inventory. Their common booking experience includes:

  • Offering title, description, venue, start and end time.
  • Organization details and support contacts.
  • Price, currency, capacity, and remaining availability.
  • Assigned seating where seat selection is configured.
  • Reserved-seat rules and occupied-seat visibility.
  • Booking for the authenticated customer or another attendee.
  • A generated customer ticket after confirmation.

Dinner reservations intentionally use a separate interaction. Customers search first by arrival time, expected stay, party size, and party type. Booknix then returns restaurants that can actually serve that request. This avoids showing a restaurant as available when its capacity is already consumed by overlapping reservations.

The result is a familiar interface across categories without pretending that every booking follows the same domain model.

Assigned seating for scheduled experiences

For cinema, events, parties, and seminars, availability is not only a number. Customers often care about the exact seat they will occupy.

The shared seat map supports:

  • Available and occupied seats.
  • Permanently reserved seat numbers.
  • Configurable seat-column layouts.
  • Gender-aware occupied-seat display.
  • Multiple attendee selections without duplicate seats.

Seat availability is checked when the customer views the offering, but that view is never treated as a guarantee. The backend validates capacity and seat conflicts again during booking. This matters because two customers can view the same available seat at nearly the same time. The successful booking must be decided by the authoritative write, not by whichever browser loaded first.

This is one of the most important lessons from the implementation: displayed availability improves the customer experience, while transactional validation protects the business.

Dinner capacity is a time problem

Dinner reservations required a different way of thinking. A restaurant seat is not occupied for an entire day, and capacity cannot be represented by a single sold quantity. Each reservation has an arrival and expected end time.

Two reservations overlap when:

existing arrival < requested end

AND existing end > requested arrival

Booknix calculates the diners already occupying the requested area during that period and compares the result with the area’s capacity. The restaurant can define common, family, and special areas, each with independent availability.

This approach supports realistic dinner discovery. A restaurant may be unavailable at 8:00 PM for a large group but available at 9:30 PM after earlier reservations finish. It also gives the organization a clear operational view of when and where capacity is committed.

Images became part of the booking contract

Experiences are visual products. Customers often decide whether to book a cinema, venue, celebration, seminar, or restaurant based on how it looks. This week added image galleries for all five categories covered in this blog.

Organization admins can upload three or four JPEG, PNG, or WebP images. The backend validates each source file, limits size and pixel count, corrects orientation, resizes the image, converts it to WebP, and stores it as a data-URL string in PostgreSQL JSONB.

The customer interface renders compact thumbnails without forcing neighboring cards to match the tallest gallery. Selecting an image opens a responsive modal with previous and next controls, keyboard navigation, mobile swipe, an image counter, and safe dismissal behavior.

One subtle issue appeared at the database boundary. Passing a JavaScript array directly to PostgreSQL caused the driver to encode it as a PostgreSQL array literal, which is not valid JSONB. Explicitly applying JSON.stringify() before persistence corrected the contract. This was a useful reminder that valid JavaScript data is not automatically valid database input; serialization must match the destination type.

One ticket view for every experience

After booking, customers receive a consistent ticket card across cinema, events, parties, seminars, and dinners. Scheduled-experience tickets show the offering, venue, start and end time, attendees, seats, price, organization, and support contacts. Dinner tickets show the reservation time, expected end, diner count, venue address, reservation status, and Pay at restaurant guidance.

The same normalized ticket model also made downloadable images possible. Every active and historical ticket now has a Download ticket image action. The browser generates a category-themed PNG using Canvas, so no additional image generation service or screenshot dependency is required.

The downloaded image contains the booking reference, organization, category, venue, schedule, attendees or diner count, payment information, address, and ticket status. Remote gallery images are intentionally excluded from the generated PNG, avoiding cross-origin failures and keeping the artifact deterministic.

Notifications that survive application restarts

Customers need timely information before and during an experience. Booknix now stores notification plans in the database rather than relying on timers inside the application process.

A normal scheduled experience can produce confirmation, 30-minute reminder, start-time, and completion messages. Dinner reservations use the same lifecycle based on arrival and expected end time. Due notifications appear in the customer notification center, while email delivery can be processed separately with retry information.

Database-backed scheduling was selected because application instances may restart, scale horizontally, or sleep. An in-memory timer would lose its state under those conditions. Durable notification rows make delivery observable, retryable, and independent from one server process.

Cancellation reasons that belong to the organization

Organizations do not all receive the same cancellation requests. A cinema may commonly see schedule conflicts, whereas a restaurant may see changes in party size or plans. Each organization can now maintain up to five cancellation reasons, control their order, and enable or disable individual choices.

Customers see only the active reasons belonging to the organization that owns their booking. A final Other option always allows manual text. The backend verifies that a selected preset belongs to the correct organization and stores the final reason text as an immutable snapshot.

This snapshot protects history. If the organization later renames or deletes a preset, the original cancellation request still explains what the customer selected at that moment.

Cancellation, refunds, and operational review

A customer can submit a cancellation request until 30 minutes before the booking starts. Submission does not immediately cancel the booking or release inventory. Instead, an organization admin reviews the request and chooses to reject it or approve it with no refund, a partial refund, or a complete refund.

Approval occurs transactionally. The service locks the pending request and booking, verifies ownership and current status, calculates the permitted refund, changes the booking status, removes obsolete future notifications, records the reviewer and decision, and commits the changes together.

Refunds are currently manual accounting records. Booknix does not yet call a payment provider. This limitation is made explicit in both the interface and engineering documentation so an audit record is not mistaken for transferred money.

Rescheduling across different inventory models

Rescheduling uses one customer experience but category-specific availability adapters.

For cinema, events, parties, and seminars, the replacement must be a compatible future inventory unit from the same organization and category. The customer selects replacement seats, and the backend rechecks those seats when the admin approves the request.

For dinners, replacement options are future time slots with enough area capacity for the existing diner count. No seat map is required, but overlap validation remains essential.

When an admin approves a request, Booknix transfers the booking, replaces notification times, and calculates the financial difference. Equal prices complete automatically. A higher replacement price creates a manual customer payment requirement, while a lower price creates a manual customer credit. Settlement status, reference, note, actor, and timestamp remain available for operational follow-up.

The hardest engineering lessons this week

The biggest lesson was that reuse should happen at the correct layer. Cinema, events, parties, and seminars can share scheduled inventory, seat selection, ticket display, and booking-change interfaces. Dinner can share authentication, organizations, tickets, notifications, cancellation review, and settlement—but not assigned-seat or capacity logic.

Other lessons included:

  • Never trust availability that was calculated earlier in a customer session.
  • Store historical snapshots when mutable configuration explains an irreversible decision.
  • Keep financial state explicit even when payment is manual.
  • Use durable database jobs for time-based behavior.
  • Normalize read models for shared interfaces without forcing source tables into one oversized schema.
  • Treat image conversion, serialization, ownership, and delivery as one end-to-end contract.
  • Make platform limitations visible in documentation rather than presenting future controls as completed work.

What comes next

The next stage is less about adding more category screens and more about proving reliability:

  • Run complete end-to-end booking tests for cinema, events, parties, seminars, and dinners on Neon.
  • Add concurrency tests for assigned seats and overlapping dinner capacity.
  • Test cancellation and rescheduling while competing booking writes are occurring.
  • Integrate a payment provider for charges, refunds, additional payment, and customer credit.
  • Add signed, expiring QR verification to downloaded ticket images.
  • Add organization reports for sales, attendance, cancellations, refunds, settlements, and capacity utilization.
  • Move gallery assets to object storage and CDN when database payload size becomes operationally expensive.
  • Add structured monitoring for notification delivery, image processing, and settlement aging.

Closing reflection

Supporting multiple booking categories is not primarily a UI expansion. It is an exercise in finding the right boundaries: what should be shared, what must remain category-specific, and where the database must protect decisions that the browser cannot safely make.

This week established those boundaries for cinema, events, parties, seminars, and dinners. Customers now have a more complete experience from discovery to booking, ticket ownership, notifications, cancellation, rescheduling, and image download. The next week should turn that breadth into confidence through automated verification, operational visibility, security hardening, and real payment settlement.

Leave a Reply

Your email address will not be published. Required fields are marked *