Komuvo
Estate & community management platform: estate operations, residents, payments, visitors and communication.
- Environment
- Production SaaS
- Primary constraint
- Reliability + low operational cost
- Architecture style
- Modular application
- Data
- Relational
- External dependencies
- Payments · Notifications
- My role
- Architecture · Backend · Technical direction
01Overview
Komuvo runs the day-to-day operations of residential estates and gated business parks: who can enter, who has paid, and what needs fixing. It is a Scalefort product, and I led its architecture and backend.
02Problem
Estates need access verification for thousands of visitors, staff and residents every day. In suburban developments the telecom backhaul is intermittently unstable — and if the access service is down or lagging, vehicles queue onto public roads.
At the same time the platform collects service charges and utility payments across disjointed bank transfers. The ledger must be exact: no double-charging residents, no lost or unreconciled deposits.
03Constraints
- Unreliable connectivity at the gate. Entry checks are validated by the server today, so working without a connection is the next goal.
- Financial correctness. Every payment recorded exactly once, even when providers time out.
- Low operational cost. A small team operating the system, on a modest hosting budget.
04My role
Architecture, backend engineering and technical direction — from module boundaries and data model to the reliability patterns described below.
05Architecture
A single application split into modules with enforced boundaries. Modules communicate through in-process interfaces and domain events; no module queries another module's tables directly. Select a component to see what it does and how it fails.
- Component
- Payment Providerexternal
- Type
- External payment API
- Purpose
- Processes resident payments.
- Failure mode
- Timeout / unavailable / ambiguous response.
06Engineering decisions
Visitor access
Residents create timed visitor passes. At the gate, guards check the QR code or PIN in the mobile app, the server validates it, and check-in is recorded as a separate step.
Offline gate verificationPLANNED
Not built yet. This is the intended design.
- When a resident creates a visitor pass, the server would sign a payload (timestamp, duration, estate) with a private key.
- Gate devices would cache the public keys and verify the signature locally, with no round-trip to the cloud API.
- Entry events would be spooled to local storage on a barrier controller and flushed to the backend once connectivity resumes.
Transactional outbox for side effects
An operation often has to save a record and send a message. Calling messaging providers inside the database transaction risks dual writes — the change commits but the notification throws. Instead, the change and an outbox message are written in the same transaction, and a background worker delivers the message.
begin transaction record the change record the outbox message commit # background worker delivers pending outbox messages
07Trade-offs & hindsight
- What we chose
A modular application rather than independently deployed microservices.
- Why we chose it
Microservices would have added RPC serialization, partial network failures and distributed sagas — failure modes the product had no requirement to take on.
- What it gave us
One deployment to operate. Less infrastructure to maintain, and hosting that stayed under $40/month.
- What it cost us
Read-heavy dashboards queried the same normalized tables the ledger wrote to. Past roughly 40 estates, end-of-month reconciliation caused database CPU spikes.
- What I would change today
Introduce read replicas and materialized read models about six months earlier — while keeping the single deployment until operational requirements justify extracting a service.
08Reliability
- Repeated payment requests
- Payment requests carry idempotency keys, so a retry can't be recorded twice.
- Payment provider degradationPLANNED
- Not built yet. A circuit breaker would open after 5 failures in 30 seconds, and the API would return
202 Acceptedand fall back to webhook reconciliation instead of holding request threads. - Transient database failures
- Transient database failures are retried automatically. If they still fail, the transaction rolls back cleanly.
- Double-entry ledgerPLANNED
- Not built yet. Today payments are kept as wallet and transaction records; a double-entry ledger would make every movement of money balance by construction.