A full restaurant platform for several venues, from the booking to the returning guest
A hospitality group's venues run on it. It started as a booking system; today it also carries the table plans, the guest list, automatic emails and reminders, the review after a visit, the newsletter, campaigns and coupons, with roles for the staff.
What the team needed solved
One system for several venues that keeps everything in one place, from the booking to the returning guest.
Some venues take bookings on a website we do not run, and booking has to work regardless.
Keeping in touch with guests, from confirmation, reminder and review to campaigns, has to run on its own, and staff should see only what their job needs.
What we built
Bookings for several venues
One system carries the bookings of all the group's venues. Guests get the same rules, messages and confirmation whichever venue and whichever site they book on.
An embedded booking form on another site
Two venues take bookings on another of the group's websites, which we do not run. That site loads one element and one script from us, without an iframe, and takes the language from the page.
Table plans made for restaurants
Each venue has its own table map, with a floor plan and areas. Staff move, rotate and resize tables on the same map they use to see the evening’s bookings, so the editor and the live map cannot disagree.
Waitlist
When no table is free, guests can join a waitlist. When a place opens up, staff send an offer, which the guest accepts or declines from the email.
Automatic emails and reminders
Guests get a confirmation with a cancellation link and a calendar file, and a reminder before the booking. The wording and look of the emails can be edited in the workspace.
Reviews and return visits
After the visit the system asks the guest for a review by email, and sends an offer for next time so they come back.
Newsletter and campaigns
Newsletters and campaigns go out to the guest list from the workspace. A campaign’s wording, image and validity can be changed without a new release.
Coupons and re-targetable QR codes
The card is printed once; where it leads can be changed in the workspace at any time. From the card a guest can claim a coupon, one per email address.
A staff workspace with roles
Per venue: the day's bookings, arrivals, free tables, the guest list and statistics. Sign-in and roles: the group admin sees everything, a venue admin their own venues, staff the day's work, and the statistics role only the numbers.
How it works
One booking
- Form or embedded booking. The guest books on the venue's site or on another of the group's websites.
- A free table. The system looks for a table within opening hours and reserves it in one step. If there is none, the waitlist.
- Confirmation and reminder. An email with a cancellation link and a calendar file, and a reminder before the booking.
- Staff. The booking appears on the venue's day list and on the table map.
- After the visit. An email that asks for a review and sends an offer for next time.
From card to coupon
- Printed card. The code carries one fixed address that does not change.
- Campaign. Behind the address, the campaign set in the workspace: code, image, wording, validity.
- Coupon. One coupon per e-mail address, sent by e-mail.
How we built it
Limits on the public booking form
Only approved sites can book. Each address may make five bookings in ten minutes, a hidden field and the time taken to fill the form filter out bots, and there are caps per email address, per venue per night and overall.
It stops on a fault
If the counter or a cap cannot be read, the booking does not go through, and the guest is told to call the venue.
No stored IP addresses
The limits are keyed on a salted hash of the address; no raw address reaches the database.
Seating in one step
Assigning a free table is a single atomic database function that only the server can call, so the public key cannot get around the checks.
Map saves without collisions
A save takes the same per-venue lock as a booking, writes in one transaction, and writes nothing if someone else saved in between. Tables are never deleted: a retired table stays for the bookings it already had.
A tested booking flow
The unit tests run the real sequence of steps against a fake database, and check that every rejection happens before anything is written.
The project in brief
- System: Restaurant platform: bookings, guests, campaigns
- Period: Since October 2025
- Status: Live · Extended continuously, most recently in October 2026
- Technology: Next.js, TypeScript, PostgreSQL, Konva, Resend
Several venues, and one system for all of them?
Write down where your guests book today and what your team sees of it. We start from what you write.