All projects

Multi-tenant rental management SaaS: leases, rent collection, reminders, receipts and owner payouts.

Propriyo screenshot
Key result
Per-agency data isolation

Context

Rental agencies run leases, rent collection, reminders and owner payouts across spreadsheets, WhatsApp and paper receipts. Each agency must only ever see its own data, owners want to follow what their property earns, and tenants pay with mobile money.

What I built

A multi-tenant SaaS of about sixty NestJS modules in an Nx workspace, with an Angular app for agencies and a portal for tenants. Every request goes through layered guards: active account, valid subscription, then the modules the agency's plan includes. Rents are collected through a payment gateway with signed, idempotent webhooks, statuses age on their own through scheduled jobs that escalate reminders by email and WhatsApp, and receipts and e-signed leases are rendered as PDF. Delivery runs through GitLab CI to Docker behind Traefik, with documents on MinIO. An AI assistant on a self-hosted Ollama is in testing: it drafts messages and lease contracts and analyses the events of a property, without the data leaving the platform.

Result

Agencies run the whole rental cycle in one place, from the lease to the owner payout, with AI features being tested on a self-hosted model.

Architecture

  1. Tenant isolation in every query

    Every service filters by agency, and an owner only reaches their own properties through a dedicated scope service.

  2. Guards in layers

    Each request re-checks that the account is still active, that the subscription is valid, and that the agency's plan includes the module being called.

  3. Payments through a gateway, idempotent by design

    Webhooks are signed and keyed by the external reference, so a replayed notification never marks a rent as paid twice.

  4. Rent statuses that age on their own

    Scheduled jobs move rents to late and escalate reminders, with a catch-up at startup so a missed night is never lost.

  5. Side effects as event listeners

    Receipts, wallet credits and WhatsApp messages react to domain events, which keeps the payment flow short and each channel independent.

  6. AI on a self-hosted model

    The assistant in testing runs on Ollama, so drafting leases and analysing tenant history never sends agency data to a third party.

Stack

  • NestJS 11
  • Angular 20
  • MongoDB
  • Nx
  • Puppeteer
  • WhatsApp Cloud API
  • MinIO
  • Traefik
  • Docker
  • GitLab CI
  • Next.js 16
  • Ollama