DesignDevelopmentBackendMobileIntegrationsMaintenance
02
PMS SaaS

BookBed

A multi-platform property management system for owners managing short-stay, vacation, and long-stay lets — built solo across six months.

See live website

Introduction

BookBed is a multi-platform property management system I built for myself — iOS, Android, Web, macOS, Linux, and Windows from a single Flutter codebase, backed by Firebase and Stripe. It targets the gap between enterprise PMS tools and raw Airbnb direct bookings: owners managing one to twenty units who need a real calendar, real iCal sync, and a real embeddable booking widget without paying hospitality-SaaS enterprise prices.

Background

I'm the sole founder, designer, developer, and maintainer of BookBed. No co-founder, no team, no contractors. The project started on October 16, 2025 and has been in active development for six months — published to both Apple App Store and Google Play, with a marketing site live at bookbed.io.

The market gap was specific. Smoobu specializes in vacation rentals. Lodgify and Hostaway target mid-to-enterprise property managers. Airbnb and Booking.com are fine for individual listings but offer nothing for owners running several units across different stay types — short-stay nightly rentals, week-long vacation rentals, long-stay three-month lets. BookBed covers all three stay patterns under one platform at €9 per month for up to twenty units per tenant.

The Challenge

iCal sync with overbooking detection. Booking.com, Airbnb, and Adriagate each export iCal calendars in subtly different formats. Timezone semantics get messy fast when bookings stored at 22:00 UTC represent midnight in Zagreb CEST. An early version of the overbooking detection logic was normalizing these dates with setUTCHours(0,0,0,0) plus toISOString(), which produced the wrong date for anything stored late-evening UTC — triggering false-positive overbooking warnings on bookings that didn't actually overlap.

One calendar UI across six platforms. The timeline view (Gantt-style booking calendar) had to render consistently on phones, tablets, desktop Web, and native macOS — not break at weird breakpoints, not mis-measure drag distances, not flicker when switching screens.

An embeddable widget that survives every host site's CSS. The widget lives on owner marketing sites via <iframe>. Arbitrary hosts means arbitrary stylesheets, arbitrary scroll containers, arbitrary viewport constraints. Early versions had a scroll-trap bug where the iframe caught scroll intent and never released it back to the parent page.

Stripe LIVE mode with cross-tab checkout. Checkout typically opens in a new tab. The original tab needs to know when payment completes without polling. Webhooks are authoritative but browser state has to catch up too, or the UI lies to the owner for a few seconds after success.

Sustained solo iteration. Six months of active development means six months of bugs, regressions, and edge cases without a second pair of eyes. Discipline had to be structural: versioned changelogs, path-scoped code rules, deliberate "DO NOT REFACTOR" markers on code that had been stabilized through painful testing.

Our Solution

Timezone-correct iCal sync with echoDetection. Rewrote the date normalizer to use toLocaleDateString('en-CA', {timeZone: 'Europe/Zagreb'}) with a fallback, iterating at noon UTC to stay DST-safe. A new save_trimmed recommended action handles the case where an aggregator event has partial overlap with an existing booking — imports only the genuinely-new date ranges instead of flagging the whole event for manual review. Eight dedicated tests cover real-world Adriagate imports, 100% containment, 0% overlap, multiple contiguous ranges, turnover days, and action priority.

Fixed-dimension timeline calendar. Cells are locked at 50/42/100/60 pixels across every platform — no responsive breakpoints reshaping the drag math. Z-index is disciplined: cancelled bookings at base level drawn first, confirmed bookings on top. The underlying repository (989 lines, firebase_booking_calendar_repository.dart) carries deliberate duplication marked "do not refactor without unit tests" — because the duplication came from real bugs we solved incrementally, and collapsing the code would resurrect them.

Scroll overlay v5 in bookbed-overlay.js. Universal iframe scroll-trap fix that works across any owner site. Detects scroll intent at iframe boundaries and releases it back to the parent. Deployed alongside the main widget bundle via CI pipeline with an explicit copy step (earlier deploys had missed the overlay asset entirely).

Cross-tab Stripe with BroadcastChannel + Firestore fallback. When checkout opens in a new tab, the original tab subscribes to a BroadcastChannel and a Firestore listener. Either source can fire — BroadcastChannel is instant when the browser permits it, Firestore is authoritative via webhook. Webhook writes sync accountType in lockstep with subscription status; no orphaned "active" accounts with cancelled subscriptions.

Versioned discipline across 66+ changelog entries. v4.6 through v6.66+ with detailed changelogs for every release. Path-scoped code rules in .claude/rules/ (per-directory linting guidance for calendar, widget, admin, auth, stripe, firestore, fcm, hosting). AI-branch audits (Jules/Sentinel/Bolt contributions) integrated selectively — real fixes cherry-picked, regressions rejected.

Outcome

BookBed is live on the Apple App Store and Google Play, with the marketing site deployed at bookbed.io. Core features are shipped and stable: timeline calendar, bidirectional iCal sync with overbooking detection, embeddable owner widget with scroll-trap fix, Stripe LIVE mode with cross-tab communication, Apple and Google Sign-In, email verification, eighteen-plus Resend email templates, Firebase Cloud Messaging push notifications, AI chat with dispose-safe streaming, and a separate admin entry point with its own navigation.

Subscription infrastructure is wired and tested — Stripe LIVE, webhook handlers, trial lifecycle, €9/month for up to twenty units — but not yet activated for paid traffic. The platform is in its early adoption phase.

Conclusion

Six months, one person, six platforms, 66+ versioned releases. BookBed isn't a demo — it's in the App Store and Play Store, running daily on real devices, backed by a test suite and documented architecture. The PMS category doesn't need another enterprise tool. It needs something solo owners can actually afford to run. That's what BookBed is.

More live work

More live work