9 Featured WorksProjects
  1. Home
  2. /Projects
  3. /HomeFlow
full stack2026Featured

HomeFlow

Property Management

Start a project
rohith-a.me/projects/proj-10
01

The challenge

Indian landlords track rent, bills, leases and repairs across notebooks and chat threads, with no safe way to let someone else handle part of the work.

02

The approach

Built a server-component-first Next.js 15 app with MongoDB/Mongoose, Auth.js v5 sessions, Zod validation at the service boundary and edge middleware for routing and session gating, plus a super-admin delegation model for scoped sub-accounts.

03

The outcome

Properties, units, tenants, leases, rent cycles, utility bills, payments, receipts and maintenance in one place, with parts of the workload delegated to sub-accounts without sharing the owner's account.

At a glance

Year
2026
Type
full stack
Stack
6 technologies

Built with

Next.js 15TypeScriptMongoDBAuth.jsZodVitest
System design

How HomeFlow is put together

A server-component-first Next.js 15 app on Vercel. Requests pass a cookie-only edge gate, then a strict route → action → service → repository → model stack, with authorisation, property scoping and audit enforced in the service layer. Reads are designed around a slow serverless cold connect.

domain modules
29
invariants held by unique indexes
10
cold DB connect kept off the hot path
~2.8 s
layers, none skippable
5

01 · Clients

client

Owners & staff

client

Tenants

self-service portal

02 · Edge

gateway

Edge middleware

session-cookie gate, no DB

worker

Vercel Cron

daily rent generation

03 · Next.js server

service

Routes & actions

RSC · server actions

streamed Suspense sections

service

Auth.js v5

Google, JWT sessions

04 · Domain

service

Services

Zod · authz · audit

29 domain modules

service

Org-scoped repositories

orgId + property scope

05 · Data & services

database

MongoDB

Atlas · Mongoose 8

records + private file bytes

database

Data Cache

Vercel

tagged view models

third-party

Resend

optional email

Hover a component to trace its connections, or a request-flow step to follow it through the system.

clientgatewayserviceworkerdatabasethird-partyrequest / responseasync · event · scheduleoptional · fallback

11 connections

  • Owners & staff→Edge middlewareHTTPS
  • Tenants→Edge middlewareHTTPS
  • Edge middleware→Routes & actionscookie present
  • Routes & actions→Auth.js v5claims
  • Routes & actions→Data Cacheread view models
  • Routes & actions→Servicesserver actions
  • Vercel Cron→ServicesBearer CRON_SECRET · async
  • Services→Org-scoped repositories
  • Org-scoped repositories→MongoDB
  • Services→Data Cacherevalidate tags · async
  • Services→Resendnotify · optional
›11 connections as text
  • Owners & staff→Edge middlewareHTTPS
  • Tenants→Edge middlewareHTTPS
  • Edge middleware→Routes & actionscookie present
  • Routes & actions→Auth.js v5claims
  • Routes & actions→Data Cacheread view models
  • Routes & actions→Servicesserver actions
  • Vercel Cron→ServicesBearer CRON_SECRET · async
  • Services→Org-scoped repositories
  • Org-scoped repositories→MongoDB
  • Services→Data Cacherevalidate tags · async
  • Services→Resendnotify · optional

Request flow · Creating a bill (a server action)

  1. 1Edge middleware lets the request through only if a session cookie exists; it never touches the database.
  2. 2The action resolves the actor from the session and hands the input to the bill service.
  3. 3The service Zod-parses the input, asserts the permission and checks the property is in the actor’s scope, then inserts through the org-scoped repository and records an audit entry.
  4. 4Dashboard cache tags are revalidated and a typed ActionResult returns; internal errors never cross to the browser.

Design decisions

Invariants live in unique indexes
Double-billing a month, duplicate receipts and duplicate agreement numbers are prevented by ten database indexes, not read-then-write checks.
Built for a slow cold start
A cold serverless instance pays ~2.8 s to reach Atlas, so the app shell answers from cookie claims and Data Cache and only opens a connection when it must.
Cache keys carry scope
Dashboard view models are cached per property scope, so a sub-account never reads the owner’s whole portfolio from a shared entry.
ID documents: derive, never grant
Access to a tenant’s ID is recomputed per request from an active lease, logged before bytes are served with no-store, and refused as a 404. Only the last four digits of an Aadhaar number are kept.

Trade-offs & known limits

  • Account type is per login: someone who is both staff and a tenant currently needs two email addresses.
  • File bytes are stored in MongoDB documents, which keeps authorisation in one place but bounds file size by the document limit.

Have something similar in mind?

I'm open for freelance and contract work — let's talk about what you're building.

Get in touchSee more workBack to home
←PreviousMediConnectfull stackNext→Shutterfull stack
Rohith. A

© 2026 All rights reserved.

Available for work