01 The Challenge
Society Payments Arrive Split Across UPI, Bank Transfers And Cheques. Committees Reconciled Them By Hand, Weekends Lost To Spreadsheets.
Case Study · 02 / AI Society Management
An AI-Native Operating System For Housing Societies: Billing, Payments, Complaints, Notices And The Gate In One App, With AI That Reconciles Bank Statements Against Every Flat.
Product Design & Full-Stack Engineering ·

01 · By The Numbers
Counted Straight From The Codebase And Git History. No Vanity Metrics, No Projections.
46
Assistant Tools
Allowlisted, Tool-Calling
8
User Roles
Committee · Residents · Staff
50
SQL Migrations
PostgreSQL 16 + RLS
77
Test Files
Vitest + Property Tests
02 · Overview
Society Payments Arrive Split Across UPI, Bank Transfers And Cheques. Committees Reconciled Them By Hand, Weekends Lost To Spreadsheets.
We Paired An AI Extractor With A Deterministic Matcher: The Model Reads Statements, Code Decides Matches, And An Officer Confirms Before Anything Is Written.
One Installable App For Dues, Payments, Complaints, Notices And The Gate, With An Assistant That Answers Only From The Society’s Own Records.
03 · What We Built
Committees, Residents And Gate Staff Share One System. Each Role Sees Exactly The Pages It Should.
Upload A Bank Statement; AI Extracts Every Row And A Deterministic Matcher Tags It Matched, Unmatched Or Ambiguous Against Each Flat.
46 Allowlisted Tools Answer From Society Records; Any Change Comes Back As A Proposal To Confirm Or Decline.
Recurring Maintenance Plans, One-Off Charges, Fines, Late Fees, Credits And Payment Proofs.
A Gate Console With QR Passes, Photo Capture, Pre-Registration And Live Arrival Alerts To Residents.
Session → Tenant → RBAC Middleware Plus Postgres Row-Level Security And A Trigger-Backed Audit Log.
04 · Architecture
Every Request Passes Session → Tenant → RBAC And Runs In A Transaction Scoped To One Society, With Postgres RLS As The Second Wall.
8 Roles · 50 Migrations · Cloudflare Workers
05 · Stack
A Lean, Typed Stack With SQL You Can Read, Chosen So Tenant Isolation Is Enforced By The Database, Not Just The App.
export function classify( txn: CanonicalTransaction, residents: ResidentIdentifiers[],): MatchOutcome { const desc = normalize(txn.description); const descAlnum = alnum(txn.description); // Deterministic ordering: residents by id, each resident's flats by flatId. const ordered = [...residents] .sort((a, b) => (a.residentId < b.residentId ? -1 : a.residentId > b.residentId ? 1 : 0)) .map((r) => ({ ...r, flats: [...r.flats].sort((a, b) => (a.flatId < b.flatId ? -1 : a.flatId > b.flatId ? 1 : 0)), })); // Build (resident, flat) candidate pairs from MATCHING identifiers. const pairs: MatchCandidate[] = [];$ wrangler deploy→ nandy-app published to Cloudflare Workers06 · PageSpeed
Google PageSpeed Insights Scores For nandyai.com: Speed, Accessibility And SEO Engineered In From Day One.
Tell Us What You’re Building. We’ll Reply Within One Business Day With A Scoped Plan.