Four years of picking up whatever the problem needed and refusing to hand it off halfway. Apps, APIs, pipelines, 3D interfaces, LLM systems at work, and two Android apps built at night because I apparently can't sit still.
Because every other one wants my bank login and a subscription to tell me I spend too much on coffee.
Tap an arrow, it slides off the board — if nothing's in its way. A puzzle game I built because the one I played had more ads than levels.
Own a Graph RAG platform end to end — Neo4j traversal, hybrid retrieval, the whole ingestion pipeline. Also shipped an outbound-call agent solo under a GCP-only mandate.
Owned deploys on EC2 with GitLab pipelines (~40% faster), tuned Nginx and load balancing for 99.9% uptime, reworked the database for 30% faster queries at 2× the concurrency.
3D robot simulation for Orangewood Labs, OAuth + Stripe payment flows, a Kinesis→Redshift Lambda pipeline at 100k+ concurrent users, and a configurable analytics dashboard.
Two MEAN-stack SPAs, 15+ responsive screens plus the APIs behind them, a from-scratch 3D environment with joystick controls, and real-time collaboration over Socket.io.
Schema, API, UI, deploy, the 2am alert. Fewer handoffs, fewer places for the truth to go missing.
Tests, pipelines, uptime. Save the novelty for the part users can actually see.
Three.js, RAG, now Android — each one started as a thing I hadn't done, on a deadline.
Four years, four companies, one habit: taking the piece nobody else wanted to own. Notes below, roughly in reverse.
Two Android apps built after work hours, mostly to find out what I didn't know. Both still in progress, both installed on my own phone — the only QA that counts.
One rule: tap an arrow and it slides off the board — but only if nothing blocks its path. Clear all of them and you win. I built it because the version I was playing had more ad breaks than puzzles.
I was hooked on a little arrow puzzle game until it started showing me an ad between every single level. Two seconds of thinking, thirty seconds of a man shouting about mobile legends. I closed it and thought: this is a solvable board and a few rules. I can just build this.
So it's not a physics engine or a 60fps showpiece — it's an algorithm. Grid, arrow directions, path checks, solvability. The fun is entirely in the rules, which suits me fine.
Every arrow has a length and a direction, and it only slides out if its whole path to the edge is empty. Sounds like one if-statement. It was a week of edge cases involving arrows that overlap the path of the one you just tapped.
L-shaped arrows turn a corner, so "path" becomes two segments and the corner cell belongs to both. My first version let them slide straight through walls, which players enjoyed more than they should have.
Scatter arrows on a grid and you mostly get deadlocks. So I wrote a solver first and only ship a board if it can be cleared — and I rank difficulty by how many moves the solver is forced into, not by arrow count. Six arrows can be nastier than twenty.
Later levels don't fit on screen, so there's zoom, pan and a FIT button — and once you can zoom out, a thin arrow becomes a 9px tap target. Hit areas are now much fatter than the arrows you actually see, plus three hearts so a fat-finger tap costs you something but not the level.
It happily certifies boards that are solvable and joyless. My friends' review was "it's nice," which is worth nothing, so I started watching them play in silence instead — that's how I learned people always try the bent arrows first and expect them to turn the other way.
No art, no engine, no shaders. A solver and a good board generator carry the entire game.
"I can build this without the ads" got further than any of my tidier project ideas ever have.
Every expense app I tried wanted my bank login, a subscription, and my attention. I wanted a text field and a number. So: offline-first, no account, entry in under three seconds.
I tracked my spending for exactly eleven days before every app I tried got in the way — onboarding flows, categories I didn't ask for, a paywall on the graph. The friction wasn't the money, it was the app.
Also, I'd never shipped anything mobile. Building the thing I'd personally use every day seemed like the fastest way to find out whether I'd stick with it. I did.
No server to be the source of truth. Local storage, migrations, and the app being killed mid-write are now my problem. Humbling.
Added budgets, tags, recurring bills, currency conversion. Deleted three of the four. The good version is the small one.
Rendering the monthly breakdown took a weekend. Looking at the monthly breakdown took considerably longer.
Optional encrypted export, a home-screen widget, and a settings screen with exactly four switches.
Accounts, bank sync, an AI assistant that tells me to cook at home.
An LLM retrieval platform where the answers have to be right. Neo4j graph traversal on top of hybrid vector + keyword search, over documents that were never designed to be parsed by anyone.
Plain vector search is great at "roughly about this" and terrible at clinical terminology, where two near-identical strings mean different things and one wrong retrieval is worse than no answer. Meanwhile the source material is PDFs: tables, footnotes, headers that lie.
Docling parses the PDFs into something with hierarchy; chunking follows the document, not a character count. Most of the quality lives here, which nobody wants to hear.
Entities and relationships in Neo4j, so retrieval can walk from a term to the things actually connected to it instead of hoping the embedding noticed.
Vector for semantics, keyword for exact terminology, graph for context. LangChain orchestrates; the LLM gets the last word and very little room to invent one.
Architecture calls, code reviews, and explaining chunking strategy for the fortieth time. The system stays coherent because someone is annoying about it.
Used on real clinical queries, not a benchmark. Two internal awards came out of this work.
Build the evaluation harness first. We built it second and spent a month arguing from vibes.
A virtual agent that dials people, verifies their data, and hangs up without anyone filing a complaint. Designed and delivered end to end under a hard constraint: GCP only, no exceptions, no favourite tools.
"Build it on GCP" is a sentence with consequences. Dialogflow CX for the conversation, Vertex AI Agent Builder (ADK) for the agent logic, Cloud Run for everything that needed to be code, Twilio for the actual telephone. No escaping to a familiar stack when something got awkward.
"Yeah, no, that's the old one" is a complete sentence to a human and a crisis for a state machine. Most of the design work was the messy middle.
On a phone call, a second of silence sounds broken. Every round trip had to be budgeted like it was expensive, because it was.
When the agent doesn't understand twice, it stops guessing and hands off. An agent that bluffs on the phone is a support ticket with a voice.
A Three.js interface inside an Angular app that renders a robot arm and simulates its movements — so a sales engineer could demo the hardware without shipping the hardware.
Robot arms are heavy, expensive, and reluctant to fit in a suitcase. A browser twin meant onboarding a client could start on a call instead of a delivery date. I had not written a line of Three.js before this project, which felt relevant at the time and doesn't now.
There was nothing to ask. I read the Three.js docs, half a robotics PDF, and about four hundred forum threads from 2016, then wrote the joint chain myself. Took weeks. Would take a weekend now — but I'd know less.
Base, shoulder, elbow, three wrists — each one moves everything above it. Chain the transforms wrong and the arm folds through its own base, which reads less like a demo and more like a warning.
Change detection wants to run; the renderer wants to be left alone. Keeping the scene outside Angular's zone was the fix and also the lesson.
A simulation that moves almost like the real arm is worse than none — clients notice, and then they stop trusting the rest of the demo.
Same role, same twelve months: OAuth + JWT auth, Stripe payments and invoicing, a Kinesis→Redshift Lambda pipeline, and a configurable analytics dashboard. Generalist training wheels came off here.
I started in 2022 writing screens for an internship and somehow ended up owning a graph database in a medical domain. In between: 3D robot simulations, payment flows, deploy pipelines, a Lambda that hauls video events into a warehouse, and an analytics dashboard people could reconfigure themselves.
None of that was planned. Each one was "we need someone to figure this out" and nobody else raised a hand fast enough. That's more or less my whole career strategy, and I'm at peace with it.
These days: applied LLM work at Deloitte USI during the week, Android at night, because apparently rest is for people with fewer half-finished repos.
Building the two Android apps, breaking them, rebuilding them. Occasionally reading a paper and pretending I'll implement it. Based in Gurugram; from Lucknow, which I will bring up unprompted.
I check my inbox far more often than is healthy. There is a non-zero chance I reply before you've closed the tab.
The moment you close this tab without emailing me, a webhook fires. It hits a Lambda. The Lambda provisions one (1) small curse in your name. Cold start, so you get a few seconds' head start.
Nothing dramatic. Every recruiter you message from then on opens it, reads it all the way through, thinks huh, genuinely strong profile — and leaves you on seen. No reply. No rejection. Just the two blue ticks and a long, quiet life.