About
I build the whole vertical slice
I build product end to end — Flutter apps, NestJS APIs, and the Postgres schemas underneath them.
I'm a full-stack developer who tends to end up owning the whole vertical slice — the mobile client, the API it talks to, the database schema behind it, and the admin console someone needs to actually run the thing.
Most of my recent work has been Nestora: a society management platform where five different roles — resident, security guard, society admin, maintenance staff and a platform super admin — each get their own shell in one Flutter app, backed by a NestJS API across fifteen domain modules and a twenty-two model PostgreSQL schema. Before it came DealPlate, a location-first restaurant deals marketplace on the same stack. Both are the kind of project where the interesting problems aren't in any one layer but in the seams between them.
I like the parts of the job that don't demo well: getting the data model right the first time, keeping migrations incremental instead of rewriting the schema, and making auth boundaries something you can reason about rather than hope about.
Mission
Build software where the hard parts are handled properly — the data model, the auth boundary, the case that only shows up in production — and document the reasoning so the next person doesn't have to reverse-engineer it.
Vision
To keep working across the full depth of a product rather than a single layer of it, and to get good enough at the seams between layers that the architecture stops being the thing that limits what gets built.
Journey
How I got here
The points where the way I build something actually changed, and what caused the change.
July 2026
Nestora — five roles, one app
Built a society management platform where resident, security guard, society admin, maintenance staff and a platform super admin each get their own shell behind a single sign-in. The billing taught me the most: generating recurring rent and maintenance lazily on read, deduplicated against what exists, made the job idempotent — but only because deletion is soft, since a hard-deleted bill looks identical to a missing one to the generator.
FlutterNestJSPostgreSQLIdempotencyJune 2026
DealPlate — schema first
Started the marketplace with the database rather than the endpoints. The initial Prisma migration landed on 13 June, followed within a week by a marketplace restructuring, featured promotions, menus and campaigns, flyer PDFs, geo-aware notifications, reviews and plans — each as its own incremental migration rather than a schema rewrite.
PostgreSQLPrismaSchema designJune 2026
A NestJS API that grew to 23 modules
Built the backend as one module per domain — restaurants, promotions, coupons, loyalty, referrals, catering, staff, subscriptions, campaigns, devices, reviews, admin. A Firebase auth guard and a parameter decorator made identity a structural concern instead of something every controller re-derived.
NestJSTypeScriptFirebaseJune 2026
One Flutter codebase, two products
Shipped the app carrying both the diner and owner experiences behind a role gate at the root — around thirty screens across two shells, plus device-level work: GPS proximity, maps, QR scanning for coupon redemption, and FCM push registration.
FlutterDartGeolocationJune 2026
An operations console, deliberately separate
Built the admin surface as its own Next.js App Router application rather than another tab in the owner app — different auth posture, different risk, different device. Non-destructive moderation via a suspension flag, with privileged actions written to an audit log.
Next.jsApp RouterReactJune 2026
Using a model for extraction, not generation
Added flyer scanning so an owner could photograph existing paper marketing instead of filling in a form. The interesting constraint was making the output trustworthy: a fixed JSON schema with an enum kept in sync with the app's categories, and an explicit failure when no API key is configured, so one unconfigured feature never breaks promotion creation.
Claude APIVisionStructured output2026
Two answers to the same auth question
Built i-Bank as a counterweight to DealPlate's federated identity — self-issued JWTs through a Passport strategy and a guard, with unit tests concentrated on the auth service and controller. Building both clarified the actual trade-off: control over token lifetime versus not owning credential storage.
NestJSJWTPassport2026
Shipping something with no backend at all
AudioScript went the other way: a Flutter transcription client calling Groq's Whisper endpoint directly on the user's own API key. Removing the server removed the trust question with it — a reminder that architecture decisions are often product decisions wearing a technical hat.
FlutterGroqLocal-first
What's next
Where to go from here
The detail lives on the project pages — architecture, data models, and the parts that broke.