Cloud & platform · maint.keyholdCI passing

Property Management SaaS

Maintenance triage that gets a Friday-night emergency to someone in hours, and a rent ledger that never piles fees on tenants who paid.

Open the live demo View the code Evaluation report Demo tour Run it ›_ last push 1 day ago

97% vs 51%of emergencies attended within 4 hours, triage vs inbox order, on phrasings written after the freeze

90% vs 15%of emergency messages caught on unseen wording, triage vs keyword rules (19% false alarms)

0 vs 1,756late fees charged while all rent was paid: rent-first vs oldest-first allocation

The maintenance board after a weekend: requests sent to on-call, urgent jobs to dispatch, routine jobs to schedule
The maintenance board after a weekend: requests sent to on-call, urgent jobs to dispatch, routine jobs to schedule. Screenshot from the project's demo (synthetic data).

demo Demo tour

Screenshots from the running application, with its synthetic demo data. Select one to enlarge.

The maintenance board after a weekend: what went to on-call, what to dispatch today, what to schedule.
The maintenance board after a weekend: what went to on-call, what to dispatch today, what to schedule.
One request: the hazard and words that drove the triage, and when on-call was alerted.
One request: the hazard and words that drove the triage, and when on-call was alerted.
A tenant ledger: rent paid in full every month, late fees kept separate instead of eating into rent.
A tenant ledger: rent paid in full every month, late fees kept separate instead of eating into rent.
An owner statement: rent collected, the management fee on it, maintenance and the payout.
An owner statement: rent collected, the management fee on it, maintenance and the payout.
Evaluation: triage on fresh phrasings, simulated months per policy, and a year of rent through two ledgers.
Evaluation: triage on fresh phrasings, simulated months per policy, and a year of rent through two ledgers.

01 The problem

Tenants report problems in their own words at any hour, and the office reads the inbox on weekdays. Keyword rules follow the tenant's tone, not the problem, so a burst pipe described calmly waits until Monday. On the money side, applying payments strictly oldest first lets one unpaid late fee eat into every later month's rent, so a tenant who pays in full is charged a fee every month and shown owing rent.

02 How it works

  1. Tenant message
  2. Hazard screen
  3. Urgency + trade model
  4. On-call or inbox
  5. Rent ledger
  6. Owner statement

03 What I built

  • Triage of each request into urgency and trade: a hazard lexicon (water escaping, heat or fire, gas, no power, security, structure, cold) as a screen and as features for numpy logistic regressions, with settings chosen by cross-validation that holds out whole phrasings.
  • A dispatch simulation of a portfolio's month (inbox read three times each weekday, on-call call-backs for flagged requests) to measure how long emergencies wait under each policy.
  • A rent ledger in whole cents: proration by days let, one late fee per month after grace, payments to rent before fees, credit carried forward, and owner statements; plus a FastAPI console and an optional Claude second reading that may raise urgency but never lower it.

04 What I learned

A word model was perfect on new messages that reused its training sentences and caught 30% of emergencies on new phrasings; splitting by phrasing, not by message, exposed it.

A fresh phrasing set written after the freeze commit is the test; one limit set in advance (night false alarms 3.0 a week) was missed at 3.1 and reported, not tuned away.

The console caught 'smoke alarm battery chirps' flagged as fire; equipment names are now ignored by the screen, every bank was rerun and the change is in the ADR.

05 Known limitations

Every repository documents what it doesn't do yet. The main ones:

  • Synthetic messages by one author; real tenant messages would be the real test.
  • The dispatch simulation assumes contractors are always available; Claude's reading is not measured.

06 Stack

PythonFastAPINumPyClaude APIDocker

The repository has the design document, operations runbook, full evaluation report and known limitations. All data is synthetic, generated by code in the repository.

run Run it yourself

Every project runs on a laptop: no cloud account and no paid API needed.

git clone https://github.com/codeROCK-IZZY/property-management-saas.git
cd property-management-saas
pip install -e ".[dev]" && pytest
propman evaluate --gate                    # writes eval/reports/report.html

↑↓ to move · Enter to open · Esc to close