Case · Konreservas

Online booking, secure from the database up.

Konreservas is a booking SaaS for any business that works by appointment, in production since 10 November 2026. It is Bolmia’s own product, and here it is told from the inside: how bookings work, how you sign in, how each business is kept apart, how it takes payments and what it does on its own.

What the customer books onPublic widgetOnly the times that are genuinely free.
Public booking widget: the customer picks a time from the free slots of the day and sees the total before carrying on.
What the customer sees afterwardsCustomer portalTheir bookings, with no password: a link by email.
The Konreservas customer portal: check your bookings by typing your email address, and a link arrives to sign in without a password.
How the business signs inSign-inPassword or passkey, on the web and in the app.
The Konreservas sign-in screen: email and password, or “Sign in with a passkey” using a fingerprint, Face ID, the device PIN or a security key.

Three surfaces of the same product. Underneath, a single core.

What it is

One product for any appointment-based business.

Hair salons, clinics, physios, padel courts, academies, garages or restaurants: each business sets up its own schedule, payments and alerts on the same core, without the product splitting into versions.

Bolmia’s own product · online booking SaaS for appointment-based businesses · web and iOS and Android apps

Where it comes from

A business that works by appointment —hair salons, clinics, physios, padel courts, academies, garages, restaurants…— lives between the phone, the diary and the customers who never turn up. Konreservas was designed for all of them with two requirements from day one: every business kept apart in the database itself, not only in the code, and taking payments that does not depend on everything going right.

What exists today

A SaaS in production since 10 November 2026: a sales website in Spanish and English, an embeddable public booking flow, a business panel, a customer portal, platform administration and apps for iOS and Android. It takes payments through Stripe or the bank’s card terminal, sends alerts by email, WhatsApp and push, and you sign in with a passkey.

What you can open

konreservas.com and its 39 demos by sector, where you can go through the whole booking without being charged or sent anything. The panels are not open: each business has its own inside its account.

Visit konreservas.com
The konreservas.com home page: “An online booking system for appointments, classes, home visits and tables”, with the day’s schedule per professional and the time-picking step on a phone.
konreservas.com, the sales website
applications on a single core
8
Row Level Security policies
69
lock levels with a global order
7
automated tests
6,000+
database migrations
66
public demos by sector
39

The booking

It only offers what is genuinely free.

The customer picks a service, a day and a time on the business’s website. Behind it sits an availability engine written as a pure function —intervals, recurrence and time zones, without touching the database— so every rule is tested on its own and the same answer comes out on the web, in the panel and in the app.

  • Appointments, classes with places, full courses, home visits and tables, on the same engine.
  • Money always in whole cents: not a single floating-point decimal anywhere in the system.
  • A widget that embeds in any website, with a 500 KB ceiling guarded by a test.
  • A password-free customer portal: type your email address and get a link to sign in.
  • A private calendar link to see the schedule in Google Calendar, Outlook or on an iPhone.
  • In Spanish and English, from the website to the emails.
The customer picks a day
Public booking widget for a demo hair salon: step 2 of 4, the month’s calendar with available days and unavailable days struck through.
Free times only
Public booking widget: the customer picks a time from the free slots of the day and sees the total before carrying on.
Customer portal
The Konreservas customer portal: check your bookings by typing your email address, and a link arrives to sign in without a password.

Security

You sign in with a key, not a password.

The password is still there, but the strong way in is a passkey (the WebAuthn standard): the device signs a challenge with a private key that never leaves it. Windows Hello, Face ID, Touch ID or a hardware key all work, on the web and in the app. It is tested and live.

How a passkey signs in

  1. BrowserAsks to sign inNo need to type an email address: the passkey is discoverable and the browser already knows which account it belongs to.
  2. ServerIssues a challengeA random, single-use challenge. Only its hash is stored: stealing it does not help to answer it.
  3. DeviceSignsFace ID, Touch ID, Windows Hello or the hardware key check the person and sign with the private key.
  4. ServerVerifiesSignature, origin and mandatory user verification, all checked on the server. If one is missing, you are not in.
  5. ServerOpens a sessionA 15-minute access token and a refresh token that rotates. Neither is stored in plain form.

There is no password to steal and no code to copy: the signature is bound to konreservas.com, so a site imitating it cannot use it.

Signing in, with a passkey
The Konreservas sign-in screen: email and password, or “Sign in with a passkey” using a fingerprint, Face ID, the device PIN or a security key.

The session

A stolen refresh token gives itself away.

Tokens are opaque, 256 bits long, and only their SHA-256 lives in the database. Each refresh rotates atomically: using it creates a new one and the old one dies. If someone presents one that has already been spent, the system does not guess who the thief is: it revokes the whole family.

  1. access · 15 minAn opaque 256-bit token; the session is re-read from the database on every request.
  2. refresh R1 → R2Atomic rotation: R1 stops working the moment R2 is born.
  3. R2 → R3The family stays alive while it is used properly, for up to 30 days.
  4. R1 againReuse detected: the whole family is revoked and you have to sign in again.
  • Second factorTOTP with replay protection: a code that has been used does not work twice.
  • Recovery120-bit codes, stored as SHA-256: not even the database knows them.
  • Bound secretsTOTP secrets encrypted with AES-256-GCM and bound to their owner: copying the row to another account decrypts nothing. Payment credentials use a separate key.
  • Passwordsbcrypt at cost 12 plus a decoy hash: response times do not reveal which accounts exist.
  • Trusted devices30 days —7 for superadmins— without storing the IP address or a browser fingerprint.
  • Policy and step-upMFA in three states, superadmins required to hold a strong method, and a recent strong proof for every sensitive action.
  • Hand-off between surfacesFrom sign-in to panel with a single-use code: 256 bits, 60 seconds and an exact Origin. No return URL to tamper with.
  • Rate limitsPer network and per identity, with its own store in PostgreSQL, so nobody can guess passwords blindly.

The layers

Seven layers between a request and the data.

Each one holds even if the one before it fails. The ones that matter do not live in application code, which can get things wrong, but in PostgreSQL, which does not skip its own rules.

  1. 01Rate limitsIts own store in PostgreSQL, per network —IPv6 grouped by /56— and per identity. Before anything else.
  2. 02Session re-readEvery request reads the session from the database again: revoking an account takes effect on the very next request.
  3. 03Unprivileged roleThe application connects with a role that is not a superuser, has no BYPASSRLS and does not own the tables.
  4. 04Row Level Security69 policies with FORCE: one business cannot read a single row belonging to another, even if the code gets it wrong.
  5. 05Ordered lockspg_advisory_xact_lock on 7 levels with a global order. Taking them out of order fails in any test, not only in a real race.
  6. 06EXCLUDE constraintsGiST over tstzrange for staff and resources: the database itself rejects two bookings that overlap.
  7. 07Audit ledgersTwo of them, append-only. When support steps into a business, it is read-only and logged before the response goes out.

How it is built

Eight applications, eight packages and one core.

A monorepo where each surface is its own application —with its own deployment and its own security policy— and everything that must not drift apart lives in shared packages: the engine, the money, the data contracts, the session.

Applications

  • apiExpress 5 and Prisma 7: the only one that talks to the database.
  • loginThe single way in: password, passkey and second factor.
  • panelReact: the business’s schedule, payments, team and settings.
  • adminThe platform: sign-ups, plans and support.
  • portalEnd customers see and manage their bookings.
  • publicoThe booking widget, embeddable in any website.
  • webkonreservas.com, in Spanish and English.
  • movilCapacitor 8: iOS and Android on the same panel.

Shared packages

  • motorAvailability as a pure function.
  • dineroWhole cents, always.
  • contratosThe shape of every piece of data, in one place.
  • sesionThe session, the same on every surface.
  • i18nSpanish and English.
  • tokensThe design decisions.
  • uiThe interface components.
  • medicionAnalytics, with consent.

Built on

  • Node 24
  • Express 5
  • Prisma 7
  • PostgreSQL 17
  • 66 migrations
  • Docker Compose
  • Caddy with HSTS
  • Sentry

The apps

A native app that loads nothing from a server.

The iOS and Android app is the same React panel packaged with Capacitor 8 inside the app itself: it is not a website in a frame. Each environment has its own build, and the build refuses to ship if it finds a .map file or an address from another environment.

Native sign-in

  1. The app opens the system browser, not its own web view, with PKCE S256.
  2. There you sign in just as on the web: password, passkey or second factor.
  3. It comes back with a single-use code. On iOS, through a purpose-built Swift plugin on ASWebAuthenticationSession.
  4. The refresh token is stored encrypted in the Keychain or the Keystore, never in web storage.

Push alerts

  1. A booking comes in, another is cancelled or a slot opens up on the waiting list.
  2. The alert is queued inside the same transaction: if the booking is not saved, the alert does not go out.
  3. The server talks directly to APNs (HTTP/2, ES256 JWT) and to FCM, with no third-party SDK.
  4. Tapping it opens that booking in the app.
Konreservas on the App StoreKonreservas on Google Play

The app is for businesses that use Konreservas: you sign in with the same account and the same passkey as on the web.

An alert with every booking
Konreservas app on iPhone: an alert for a new booking arrives on top of the bookings list, with its payment status and amount.
The day’s schedule
Konreservas app on iPhone: a professional’s schedule for the day, with confirmed appointments and the Calendar, Bookings, Payments and Services bar.
The waiting list
Konreservas app on iPhone: the waiting list by service and day, showing who is waiting and the button to offer them a slot.

Payments

The money lands in the business’s own account.

Each business is paid into its own account. It can connect its own Stripe account or use its bank’s card terminal through Redsys, and ask for whatever deposit it wants: a fixed amount, a percentage or full payment, plus a security deposit.

Stripe Connect · direct charges

Built-in payments

  1. The customer pays
  2. The business’s Stripe account
  3. 0.5% to the platform
  • The charge is created on the business’s account: the platform only takes its fee.
  • Refunds through the API, with an idempotency key: a retry never refunds twice.
  • Every Stripe event is verified by signature and time tolerance before it touches a booking.

Redsys · the bank’s card terminal

The bank it already uses

  1. The customer pays
  2. The business’s terminal
  3. No fee
  • HMAC_SHA256_V1 signature over a key derived with 3DES, as Redsys requires.
  • The exact bytes received are signed, without reinterpreting them, and compared in constant time.
  • A notification with an invalid signature does not touch any booking.

The ledger

Every payment, refund and security deposit goes through a ledger with a single writer. And the database does not take its word for it: triggers check that every entry balances when the transaction commits and that nobody rewrites one already made.

  • Session passes
  • Gift cards
  • Full courses
  • Price per person
  • Discount codes
  • Deposits
  • Invoices and credit notes

Automation

What the business no longer has to do by hand.

From the moment a booking comes in until after the appointment, Konreservas confirms, reminds, alerts and asks for the review on its own. Customers get email and WhatsApp; the team gets an alert on their phone.

  1. On bookingConfirmationThe customer gets the confirmation straight away. The team gets a push alert in the app.WhatsAppEmailPush
  2. Before the appointmentRemindersOne the day before by default, and up to five rules per business, in hours or days.WhatsAppEmail
  3. If something changesChanges and cancellationsEvery change of time and every cancellation is announced automatically, to the customer and to the team.WhatsAppEmailPush
  4. If a slot opens upWaiting listIt offers the slot on its own to the first person on the list it fits and holds it for 30 minutes. If they do not take it, it moves on to the next.EmailPush
  5. After the appointmentGoogle reviewTwo hours after a completed appointment it asks for a review with the business’s Google link, at most once every 60 days per customer.Email

The tests

Every guarantee has a test that tries to break it.

Passing tests is not enough. Konreservas has its own sabotage runs: they break the code on purpose, guarantee by guarantee, and require some test to notice. If nothing notices, the guarantee is not proven. There are 252 test files, and while they run the network is closed: nothing leaves the machine.

Konreservas is Bolmia’s own product. We designed it, built it and run it ourselves, with the same standard we hold when the product belongs to a client: every guarantee has to be proven, not just promised.

core tests
3,814
for the website
801
for the panel
640
for the public widget
213
sabotage runs in the core alone
1,700+
tests with sign-in, portal, admin and management
6,000+

Let’s talk

Need a product built with the same rigour?

Konreservas is ours, and we built it the same way we build our clients’ products. Tell us what you want to get off the ground and we will tell you where to start.

Where are things right now?
What investment are you considering?

The total for the project or, if it’s an ongoing service, the first-year investment.

The first thing will be to understand the problem, not to pitch you a service. And if we think it doesn’t make sense for us to do it, we’ll tell you that too.

Privacy policy

Cookie preferences

Choose what you allow. You can change it any time from the link in the footer.