Problem
Property management in Kenya is largely manual. Rent reconciliation happens by memory or paper, tenants chase landlords for repairs, and owners cannot see the state of their portfolio — arrears, vacancies, maintenance load — in one place.Solution
One system of record for the property business. Every unit has a lifecycle (occupied, vacant, under maintenance); every payment posts against a tenant ledger producing live balances; repair requests, reminders and reports fall out of the same data model.My role
- Defined the product concept from conversations with working landlords.
- Designed the multi-property data model and role-based access architecture.
- Implemented core modules: properties/units, tenants, rent ledger and payment tracking.
- Built notification workflows (SMS reminders for rent and repairs).
- Integrated M-PESA payment flows where implemented and structured reporting on top of the ledger.
Key features
- Property, unit and tenant management
- Rent invoicing, payment tracking and live balances
- Vacancy tracking
- Repair requests and maintenance workflow
- SMS notifications for rent and repairs
- Operational and financial reports
- Role-based access control (owner, manager, tenant-facing views)
- M-PESA / payment integration
- Cloud-based infrastructure
Architecture
apex / system-overview
- Owner / Manager / Tenant
- React frontend
- API layer with authentication
- Role-based authorisation
- Business logic — leases, ledger, maintenance
- PostgreSQL (properties, tenants, payments)
- External services — M-PESA, SMS gateway
- Reports & notifications
Technology stack
The payment ledger is append-only by design: balances are derived from recorded transactions, never edited directly, so reports always reconcile.
Challenges
- Modelling rent arrears, partial payments and adjustments without corrupting balances.
- Making SMS reminders reliable and idempotent when gateways retry.
- Giving multiple staff members correct, scoped visibility without leaking data across properties.
Solutions
- Ledger approach: every payment and adjustment is a transaction row; tenant balance is a derived sum, which makes partial payments and corrections natural and auditable.
- Notification jobs carry idempotency keys so a retried gateway call never double-texts a tenant.
- Access control is evaluated per property membership plus role, enforced in the API layer rather than the UI.