Skip to content

Getting started

  • Bun ≥ 1.3 (bun --version)
  • MariaDB ≥ 10.11 running locally (the prototype uses a dedicated database pms_dev and never touches other databases)
Terminal window
# from the repository root
bun install
# create the pms_dev database, apply the schema,
# generate demo photos and seed the BMyGuest demo tenant
bun run seed

The seed imports the complete live BMyGuest portfolio — 52 real listings (fetched via tools/fetch-bmyguest.ts into packages/db/src/data/bmyguest-live.json): real DTCM permit numbers, geo positions, real photo galleries, the 3 responsible agents (with contact & photo) and the 42 real landlords with their actual unit distribution. On top sits a deterministic fake-booking layer: ~750 bookings / ~6,000 nights from −90 to +150 days including planned future bookings and 12 crafted edge-case scenarios (same-day turnover, arrival-today-unpaid, expiring hold, 45-night long-stay, cancellation with refund, no-show, owner & maintenance blocks, OTA price override with derived invoice, back-to-back stays, security deposits), ~680 payments, invoices with delivery log, website requests (one deliberately conflicting) and the three seasonal regular guests.

Everything date-anchored is built around today: arrivals and in-house guests, a turnover board with checkouts already confirmed clean by the operations manager next to open and overdue ones, and a future book that is well filled for two months and thins out afterwards — while every stay leaves a bookable gap behind it, so the website’s availability teaser always has real offers.

Database credentials are read from .env in the repository root (DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME).

Terminal window
bun run dev:api # REST API → http://localhost:3011
bun run dev:admin # Admin portal → http://localhost:5173
bun run dev:web # Public website → http://localhost:3010
bun run dev:docs # This documentation → http://localhost:4321

Run each in its own terminal (or use a process manager).

Open http://localhost:5173 and use one of the demo accounts (password for all: demo1234):

AccountRoleWhat you’ll see
admin@bmyguest.demoAgency AdminEverything: all units, calendar, requests, legal editor
office@bmyguest.demoBackofficeDaily operations: calendar, bookings, requests
manager@bmyguest.demoManagerOperations without master data: the turnover cleanings in the demo data are confirmed by this account
lead@bmyguest.demoTeam LeadHousekeeping planning and turnover confirmations
display@bmyguest.demoOps DisplayWall display, locked to the operations board
owner@bmyguest.demoLandlordOwner portal view: linked to the real top landlord (3 units), anonymised guests
cleaning@bmyguest.demoCleaning PartnerSigns in on the cleaning portal (not the console): the busiest external company’s jobs, day route and calendar
  1. Dashboard — occupancy, today’s arrivals & departures, new website requests.
  2. Units — browse the real portfolio as photo cards, open one, edit the description in Settings or the price in Prices, save.
  3. Calendar — the heart: scroll the timeline, filter by area or source, click a free day to create a booking (price auto-calculates), click a bar for details, check-in / check-out / cancel.
  4. Requests — convert the seeded website enquiries into confirmed bookings with one click.
  5. Legal & Company — change the Terms text, save, then open http://localhost:3010/legal/terms: your edit is live on the public site.
  6. Sign out and sign in as owner@ — notice how the whole portal shrinks to the landlord’s own units and guests become anonymous.

bun run seed is destructive only for the pms_dev tables and can be run anytime to reset the demo.

A database seeded weeks ago no longer demos anything that depends on the current date — no arrivals today, no open turnovers, holds long expired. bun run reseed replaces only the date-anchored layer (guests, bookings, payments, invoices, payouts, unit costs, website requests, tasks, FX history) and redistributes every use case around today:

  • today — arrivals, in-house guests, checkouts confirmed clean by the operations manager, checkouts still open, and one overdue since three days ago, so the monitor board shows ok, due and overdue side by side
  • future — mixed occupancy (~48 % over the next 30 days, ~37 % in days 30–60, thinner beyond) across four unit profiles from “hot” to “nearly free”
  • free slots — every stay leaves at least the unit’s minimum stay + 1 night open, so the public availability teaser always finds bookable offers

Untouched: the tenant, users, roles and teams, agents, landlords, units and their photos, pricing models, rate seasons, tax templates, legal pages — and the audit trail, which is append-only by design. Audit events written before a reseed stay readable and verifiable; they may reference bookings that no longer exist.

Same day + same portfolio produces the identical result (deterministic seed, vary it with RESEED_SEED=<number>). RESEED_TODAY=2026-12-20 bun run reseed anchors everything on another day, which is handy for demoing high season. If the database is missing a schema change, reseed stops with a pointer to the matching migration instead of running half-way.

For presentations there is no need to reach for a terminal: Demo data sits pinned at the bottom of the admin sidebar (/demo), visible only with the demo.view right — which by default only the agency admin holds. The page shows the day the data is anchored on and how stale that is, next to today’s arrivals, in-house guests, checkouts (cleaned vs. open) and the 30-day occupancy. Re-seed on today runs the same routine in the background (~25 s) with a live log and the resulting figures.

Five guards sit in front of it: the right, an admin base role (even where the right has been delegated), the environment (blocked under NODE_ENV=production unless ALLOW_DESTRUCTIVE_SEED=1), an explicit confirmation in the dialog, and one run at a time. Start, result and failure are written to the audit trail as demo.reseed.* — the one thing a reseed keeps.