← All work

Hotel Property Management System

Room operations, housekeeping, payroll and staff workflows across five role-based views.

In productionReactTypeScriptPocketBaseRBACWeb PushExpress
Overview

The problem, and what I built

The problem

Housekeeping ran on paper. A supervisor walked the floors with a clipboard, wrote down which rooms were dirty, handed slips to housekeepers and collected them back. Front desk had no way to know a room was ready without asking someone. Payroll was reconstructed at month-end from attendance scribbled in a register. The failure mode was always the same: a guest checked into a room nobody had confirmed was clean, or a clean room sat empty because the news had not travelled.

What I built

One application covering room state, housekeeping assignment, tasks, leave requests, attendance-derived payroll and an activity log — with the view adapting to whoever logs in. Sole engineer, from on-site requirements through deployment onto hotel hardware.

Engineering

Decisions worth defending

And why the alternative was worse.

Room status is a state machine with a previous-status field

Clean, occupied, checkout, dirty, cleaning, with maintenance and damaged as off-path states. The previous-status field exists because maintenance is an interruption, not a transition: a room coming back from repair needs to return to whatever it was before. One column that removes a whole class of “what was this room before someone flagged the broken AC?” bugs.

Reporting derived from the log, not stored as aggregates

Staff performance counts action entries in the activity log for the current day. There is no performance table to drift out of sync; the log is the single source of truth and every number is re-derived on view. The trade-off is that the report depends on the log’s string conventions — a renamed action silently produces a zero rather than an error, and a typed enum would have made that coupling explicit.

Payroll figures masked by default

Salary, deductions and net pay render hidden behind a per-row reveal. The admin terminal sits at a front desk where staff and guests walk past; a manager opening payroll should not broadcast what everyone earns to whoever is standing there.

Screenshot protection as a product feature

The interface blurs itself on PrintScreen, on window blur and when the pointer leaves the page. It is a deterrent against casual capture of guest details, not a defence against a determined attacker, and I would not claim otherwise.

Hardware-bound installation licensing

Activation ties an install to a specific machine and is validated server-side on boot. A pragmatic answer to how a solo developer prevents a system being copied to a second property — with a real ongoing cost, since a hardware change becomes a support call.

Interface

What it looks like

Captured against a locally seeded demo database. Every name, figure and identifier shown is invented.

End to end — sign in, live room board, housekeeping’s scoped view, tasks, payroll, reporting.
End to end — sign in, live room board, housekeeping’s scoped view, tasks, payroll, reporting.
Front desk. Live occupancy with guest names, stay day counts and checkout markers.
Front desk. Live occupancy with guest names, stay day counts and checkout markers.
Housekeeping. The same rooms, scoped to what this person is responsible for.
Housekeeping. The same rooms, scoped to what this person is responsible for.
Payroll derived from recorded attendance — figures masked by default behind a per-row reveal.
Payroll derived from recorded attendance — figures masked by default behind a per-row reveal.
Reporting. Live duty status and per-person daily performance, computed from the activity log.
Reporting. Live duty status and per-person daily performance, computed from the activity log.
Task assignment with priority and due date, delivered to a phone rather than a paper slip.
Task assignment with priority and due date, delivered to a phone rather than a paper slip.
Capability

Features

Five role-based views

Housekeeping, supervisor, front desk, manager and admin — one build, five different systems.

Live room board

Occupancy counters and colour-coded state across every floor.

Housekeeping assignment

Work assigned to a named person, delivered by push notification.

Guest add-ons

Requested, delivered, pending collection, returned — so items that went out come back.

Attendance-derived payroll

Working days, absences, deductions, bonuses and advances, with payment vouchers and PDF export.

Leave workflow

Type, date range, reason and an approval trail visible to both sides.

Immutable activity log

Every status change attributed to a person and a room, with photographs where relevant.

Honest assessment

Known limitations

What I would fix next, stated plainly.