Summary
A new backend for a residential property manager, built from scratch alongside its existing platform. It keeps a clean, reliable copy of the company’s AppFolio data in step through webhooks, and runs maintenance intake on top of it: urgency triage, technician matching and dispatch.
Context
The property manager runs on AppFolio, and its maintenance operation depends on the data in it: properties, units, tenants, leases, vendors and work orders. The company already had a platform built by another team.
N-Thesis was asked to build a stable data foundation and to re-implement maintenance intake on top of it, without stopping the operation that depends on it.
What N-Thesis delivered
N-Thesis built a new backend from scratch, running alongside the existing platform during the transition.
- Signed AppFolio webhooks received, verified and queued, covering 17 of AppFolio’s event types
- A cleaned, normalised copy of the AppFolio data, from properties and tenants to work orders, bills and ledger details
- Bulk and historical backfills, plus scheduled synchronisation for data AppFolio does not announce by webhook
- Maintenance intake: AI-assisted urgency scoring and repair matching, technician matching, then an emergency or a scheduled path
- Dispatch into the field-service platform, with SMS, phone calls and staff alerts where a person is needed
- An admin console to run and monitor sync jobs and trigger intake for a work order
- AppFolio events
Signed webhooks verified, de-duplicated and queued.
- Clean data
Coalesced fetches written idempotently into a normalised copy of the data.
- Intake and triage
AI-assisted urgency scoring and repair matching for a maintenance request.
- Matching and dispatch
Qualified or on-call technician, scheduled in the field-service platform.
- Follow-up
SMS, calls and staff alerts where a person needs to act.
The difficult problem
Most of the difficulty is in making someone else’s API dependable. AppFolio sends the same event more than once and many events for the same record in quick succession. The service records each event by its id so a redelivery is ignored, collapses a burst of updates into a single fetch, and writes idempotently, so a retry can never duplicate data.
The API has its own limits: a request-rate ceiling, endpoints that accept only one property at a time, and ledger data that can only be read in three-month windows. Every call goes through one rate-aware client that backs off when told to, and the slow scans are scheduled rather than run on demand. The data model was rebuilt from what the live API actually returns, because the published specification did not match it.
Maintenance intake had to stay safe while the old and new systems ran side by side. Intake runs outside the synchronisation transaction, so a slow dispatch call cannot undo a sync. Each step is idempotent and can be restarted, and in production staff decide when intake runs for a work order.
Results and delivered capability
A reliable, queryable copy of the property manager’s AppFolio data, and an intake flow that takes a maintenance request from triage to a dispatched job, built so that the legacy platform can be retired step by step.