Skip to content

Repository files navigation

🛏️ BunkBoard

Real-time bed & housekeeping operations for hostels — with a local-AI ops layer.

A multi-property platform that runs the daily housekeeping operation of a hostel: a mobile app for cleaners on the floor, a live reception board, a manager analytics dashboard, a maintenance ticket system, and an AI ops copilot — all over a multi-tenant data model that syncs two-way with the Cloudbeds PMS.

The AI runs on a local Ollama model — free, private, no external API, no keys — and degrades gracefully to deterministic logic when it's offline, so nothing ever hard-depends on it.

Built with
Next.js 16 (App Router) · TypeScript · Tailwind CSS v4 · Supabase (Postgres + Realtime + RLS) · Cloudbeds API v1.3 · Ollama

Portfolio project. It runs fully standalone on generated demo data for a fictional hostel chain (“Driftwood Hostels”) — npm install && npm run dev, no database, no API keys. The Supabase + Cloudbeds integration is real and documented; live mode is opt-in via env. No real PMS data is ever written.

BunkBoard


Why it's interesting

Most housekeeping tools are room-centric. Hostels run on beds — each capsule or bunk is its own unit, with same-day dorm turnover, continuous (long-stay) guests that shouldn't be re-cleaned, and female/mixed/private dorm rules. BunkBoard is built bed-first, and layers on the workflows real products ship (inspection QA, maintenance tickets, credit-based assignment, productivity analytics) — plus an AI layer that reasons over the live board instead of bolting on a generic chatbot.

The feature set is grounded in how leading housekeeping/PMS tools actually work (Flexkeeping, Sweeply, Optii, hotelkit, Cloudbeds Housekeeping).


Surfaces

📱 Housekeeping — the floor app

Mobile-first, built for speed and one-handed use. Priority-sorted beds, predicted clean times, dorm-type badges, the four muscle-memory actions (Ext / Flag / NS / Done) with a two-tap guard on the destructive one, per-bed notes that turn into maintenance tickets, and an AI cleaning order that explains how to attack the shift.

Housekeeping floor app with AI cleaning plan

🖥️ Reception — the live board

Read-only, at-a-glance bed state for the front desk — who cleaned what and when, clean/dirty/ready, KPI strip, an AI shift briefing, and a manager inspection (pass / re-clean) QA loop.

Reception board

📊 Manager dashboard

Completion %, average clean time, occupancy-based staffing forecast, a per-cleaner productivity leaderboard with one-click credit-based load balancing, clean-time anomaly detection, and an open-issue feed.

Manager dashboard

🔧 Maintenance

Report an issue → AI triage classifies category + severity and suggests an action → it becomes a ticket on an Open / In progress / Resolved board. Blocking issues automatically take the bed out of order until resolved.

Maintenance board

🤖 Ops copilot

Ask the board anything in natural language — “What should we prioritise before the 15:00 check-ins?” — answered from a compact live-board digest, entirely on a local model.

Ops copilot


The AI layer (local, free, private)

Everything runs on a local Ollama model (llama3.2 by default). Each feature has a deterministic rule-based fallback, so the product works with AI off too (the status pill in the nav shows which is active).

Feature What it does Endpoint
Shift briefing A duty-manager briefing — priorities, risks, staffing POST /api/ai/briefing
Cleaning order An explained, priority-ranked plan for the floor POST /api/ai/prioritize
Maintenance triage Free text → {category, severity, action} (JSON mode) POST /api/ai/triage
Ops copilot Q&A grounded in a live-board digest POST /api/ai/chat

The board is pre-aggregated into a tight text digest (lib/ai/context.ts) before it reaches the model — small local models reason far better over the few facts a question needs than over raw rows.


Domain logic worth a look

  • Bed-level turnover — full-clean vs stayover-light vs continuous (no re-clean), per bed.
  • Predicted clean time — explainable formula: base minutes by unit type × occupancy effort (lib/ops.ts).
  • Cleaning priority — combines turnover/arrival signal, cleanliness, and time until check-in.
  • Inspection QAclean → inspected on pass; → dirty / re-clean on fail.
  • Credit-based assignment — greedy load balancing (pod = 1, deluxe = 2, DP2 = 3 credits).
  • Staffing forecast — remaining predicted work ÷ time to the check-in peak → cleaners needed.
  • Anomaly flag — serviced beds that took ≥2× their predicted time.

Architecture

Cloudbeds (PMS)  ──webhooks──▶  sync engine  ──▶  Supabase (Postgres)
   ▲  reservations + housekeeping        bed_states / bed_assignments / tickets
   │  (source of truth)                            │  RLS + Realtime
   └──── housekeeping write-back ◀── BFF ◀─────────┤
                                                   ▼
                          Next.js surfaces ──▶ local Ollama (AI ops layer)
  • Multi-tenant from day one — every operational row carries property_id; per-property isolation via real RLS policies keyed off a minted Realtime token.
  • Cloudbeds is the source of truth for reservations + guests; this DB owns only bed↔state, timing, housekeeping, tickets, and the sync audit trail (no guest PII).
  • One bed == one Cloudbeds roomID (each capsule/bunk is its own room).
  • Safe by construction — a Supabase-backed mock Cloudbeds (/api/mock-cloudbeds) lets the full client → sync → board pipeline run end-to-end against fake data; the dev sync + mock routes 404 on a real Cloudbeds base URL.
  • Standalone demo — surfaces read/write a single in-memory ops store (lib/demo/store.ts) seeded by a deterministic generator, so a change on the housekeeper phone shows up on the reception board and dashboard. The same OpsSnapshot shape comes from Supabase + Cloudbeds in live mode.

Full design record + the Cloudbeds quirks that shape it: docs/architecture.md.


Quick start

npm install
npm run dev          # http://localhost:3007 — fully working on demo data

That's it — no database, no API keys. Open / and explore every surface.

Enable the AI (recommended)

# install Ollama from https://ollama.com, then:
ollama pull llama3.2     # ~2 GB, runs locally

With Ollama running, the AI features produce live output. Without it, they fall back to deterministic logic and the app still works end to end.

Live mode (optional)

Copy .env.example.env.local and fill Supabase + Cloudbeds keys to swap the in-memory store for real persistence + PMS sync. See docs/architecture.md and docs/pseudo-cloudbeds.md.

Regenerate the screenshots

npm run build && npm run start    # terminal 1
npm run shots                     # terminal 2 → docs/screenshots/*

Project structure

app/
  page.tsx              portfolio hub
  housekeeping/         mobile floor app (priority sort, AI order, report issue)
  reception/            live board + KPIs + AI briefing + inspection QA
  dashboard/            KPIs, leaderboard, staffing forecast, anomalies
  maintenance/          ticket kanban + AI triage + report form
  copilot/              natural-language ops chat
  api/
    ai/                 briefing · prioritize · triage · chat · status
    board/ tickets/     in-memory store mutations
    mock-cloudbeds/     pseudo-PMS for safe end-to-end testing
    dev/sync/           dev-only Cloudbeds → bed_states sync trigger
lib/
  ops.ts               domain: predicted time, priority, tickets, assignment
  metrics.ts           KPIs, per-cleaner stats, anomalies, staffing forecast
  ai/                  Ollama client, board digest, AI ops functions (+ fallbacks)
  demo/                deterministic generator + in-memory ops store
  cloudbeds/           API client, rate limiter, sync engine (live mode)
  supabase/ db/ auth/ realtime/   live-mode data + auth + RLS plumbing
supabase/migrations/   multi-tenant schema · RLS + realtime · mock-PMS schema
scripts/               migrate · seed · register-webhooks · screenshots

Tech & engineering notes

  • Next.js 16 App Router with server components reading the store and client components persisting through small route handlers.
  • TypeScript strict, ESLint (flat config) and a clean production build.
  • Rate-limited Cloudbeds client (~4 req/s with 429 backoff) and idempotent webhook handling — built around real Cloudbeds API quirks.
  • No secrets in the repo; all keys are env-only and gitignored.

BunkBoard is an independent portfolio project and is not affiliated with Cloudbeds or Ollama. All hostels, guests, and PMS IDs in the demo data are fictional.

About

BunkBoard — real-time bed & housekeeping operations for hostels, with Cloudbeds (PMS) sync and a local-AI ops layer (Ollama). Next.js 16 portfolio project.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages