Full-stack engineer, backend-leaning — marketplace API integrations, data pipelines, and LLM-backed features in production. I build the measurement as well as the feature: a system that returns a plausible wrong answer fails the same way whether that answer came from a SQL query or a language model, and most of what I ship is the apparatus that catches it.
TypeScript · Node.js · PostgreSQL · React · retrieval & evaluation · Amazon SP-API
🌍 Remote from India (UTC+5:30) — 5.5h of daily overlap with Tokyo and with Central Europe, on one ordinary working day. Full-time, available now. Arithmetic at the bottom.
📧 vipinc.sao@gmail.com · LinkedIn · Portfolio
Merged into projects I don't maintain
- kestra (27.9k★) — PR #12605, merged Nov 2025. Picked up filed issue #12583: the Gantt view rendered "Invalid date" for executions that never started. Added defensive date parsing.
- trufos — PR #416, merged Jun 2025. HTTP header
autocomplete for an Electron REST client. +495/−74 across 8 files, over several rounds with the
maintainer: a
useMemopass for re-render cost, then a rework to shadcn's combobox.
I finished my degree in 2023 and spent the next two and a half years teaching myself and building, including a two-month research internship in late 2024 and both merged PRs above. Since December 2025 I've been full-time on an internal multi-channel e-commerce operations platform — marketplace API integrations, catalog pipelines, an email/SMS notification service, a fifteen-tab analytics frontend, and Claude and Gemini in production for classification and extraction, source-fenced to stored data so the feature reports a gap rather than inventing a figure.
Sole author of five production subsystems; 97% of that frontend and 86% of its backend; 180 merged
PRs and 149 SQL migrations; second of thirteen contributors. About two fix: commits per feat:.
Product lines and internal system names omitted; the mechanisms are mine to describe.
A dashboard that was confidently wrong for months. A paginated query looped over ranged offsets
with no ORDER BY. Postgres guarantees no stable row order across separate queries, so successive
pages overlapped: the loop returned the expected row count, and after de-duplication it was 11.4%
short. The period-over-period trend read −8.2% when the truth was −14.9% — the bug imitated a
business story. Identical across five runs, which is exactly why nobody caught it: a stable wrong
query plan looks like data, not like a defect. Fixed, then written up as a standing rule and an
audit method for every other ranged pagination loop in the codebase.
A vendor plan that died on day two of every month. 5,000 requests, burned in about 48 hours by an uncapped five-minute refresh job, then dead for four weeks. I built a Postgres-backed atomic budget governor, routed all seven consumers through it, and sized per-consumer daily caps to ~99% of plan against a 32-day cycle. The interesting part was the allocation: serving every consumer daily is arithmetically impossible inside that budget, so it rotates rather than covers. One job turned out to have no per-item cursor — it re-fetched the same first N items every run and had never reached most of the set, which is starvation wearing the costume of throughput.
Saying no, with numbers. Could we mirror listing content across every sales channel automatically? I measured rather than estimated and returned a documented no: write access on 1 of 5 channels (I probed each surface live; one API introspected to zero mutations under every grantable scope), 33% of targets with complete source content, and 10% image compliance against a ≥2000px hero requirement where the median source asset's longest side was 720px — a photography budget, not an engineering task.
Also: a fail-closed gate on the single writer every live-listing write path converges on, after one unguarded write collapsed a product range's images from nine to two · listing-quality checks whose reporting treated never ran identically to found nothing, putting true coverage at 19.3% of what the dashboard claimed · a timezone double-offset that made every "day" run 07:00→07:00, rewritten timezone-independent and covered by 44 tests across four zones including the 23- and 25-hour DST days · a metric I shipped and flagged untrustworthy rather than silently correcting.
Smart Ingredient Analyzer — hybrid retrieval over an 839-chunk Open Food Facts corpus, evaluation wired into CI. BM25, dense embeddings and reciprocal rank fusion written by hand; no vector database, because at this corpus size a brute-force scan is ~322k multiply-adds against a model call measured in hundreds of milliseconds — and the code says the argument expires in the low hundreds of thousands of chunks rather than pretending it generalises.
The eval set is the part I'd want to be asked about: 58 hand-written questions, 40 with a known-correct passage and 18 that test refusal rather than recall.
npm run evalgates CI against a recall@5 floor. Hybrid hits 95% — in about six seconds, no API key needed.- Hybrid does not beat BM25 alone here, and the ablation table is in the repo rather than deleted from it. Not one query that lexical misses at k=5 and dense finds. Dense stays at reduced weight with the three questions where it earns its place printed by name.
- The abstention thresholds are deliberately not F1-optimal. Tightening cosine from 0.42 to 0.49
buys F1 0.88 over 0.84 — and starts refusing
carrageenan, a real additive the corpus describes. The shipped rule holds 100% abstention precision at 72% recall.
Every verdict must cite a passage that was actually retrieved; a citation that doesn't resolve is
rejected and the model asked again. Allergen flags and the health score are computed in code, never
asked of the model. Node/Express · Transformers.js · Tesseract.js · React · Groq
Auth Service — RS256 access tokens with pinned
algorithms; refresh-token rotation with reuse detection, where replaying a rotated token revokes the
whole family, row-locked so concurrent refreshes can't fork it. 101 tests against a real PostgreSQL,
0 advisories. I also found an authentication bypass in my own code here: a missing await on
bcrypt.compare let an un-awaited Promise pass the check, so any password was accepted.
TypeScript · Express · PostgreSQL · TypeORM · Jest
AI Interview Platform — voice mock
interviews scored per answer against explicit criteria, on the browser-native Web Speech API; 76.8 kB
of route JS became 13.5 kB when the paid voice SDK came out. Scores are written server-side as
issued, so a candidate can't supply their own. Next.js · Supabase · shadcn/ui
Social Share — every platform's crop from one
upload, processed locally with sharp. Owner-scoped storage, path-traversal validation, upload
sniffing by binary signature. 195 tests in five seconds, no accounts or database needed.
Next.js · TypeScript · Prisma · sharp · Clerk
| Languages | TypeScript · JavaScript · SQL · Python |
| Backend | Node.js · Express · PostgreSQL · TypeORM · Prisma · Supabase · REST APIs |
| Frontend | React · Next.js · Tailwind · shadcn/ui |
| AI / retrieval | BM25 · dense embeddings · RRF · labelled eval sets · abstention & citation enforcement · Claude · Gemini · Groq · Transformers.js |
| Integrations | Amazon SP-API · Twilio · Shopify · Cloudinary · scheduled jobs · Playwright |
| Infra | Docker · GitHub Actions · OpenTelemetry · DigitalOcean · Vercel |
My standard day is 09:00–18:00 IST — an ordinary Indian working day, not a shifted one. Tokyo is only +3:30 from here, so against a 09:00–18:00 Tokyo office and a 09:00–17:00 European one, that day buys 5.5h with Japan and 5.5h with Central Europe (4.5h once CET moves to winter time), 6.5h with Singapore and 4.5h with the UK. An hour earlier makes Japan 6.5h; an hour later makes Europe 6.5h.
Japan is where I'm trying to get to — I'd relocate for the right team, and until then Tokyo hours cost me nothing from here. Europe and the UK are the live remote track. US roles only work where the company is genuinely async-first: from India I reach US Eastern for about half an hour a day and the rest of the US not at all, and I won't pretend otherwise.
📧 vipinc.sao@gmail.com — I reply within 24 hours.



