← all work

LINKUPGO · FULL-STACK AI · SOLO BUILD

LinkUpGo

AI-driven social planning that turns "I don't care, you pick" into a locked calendar invite.

role
Product designer & engineer (solo)
timeframe
2025-Present · field-tested in NYC
stack
AI orchestration · Full-stack · Field-tested
Visit the live app ↗

Outcomes

8.5s p99: tap → 5 ranked venues live trace
4 parallel LLM judges score every plan
6 field-tested feedback cycles shipped
01

Research

Budgets, vibes, location, and energy get negotiated through endless messages until the group defaults to indecision. The field-testing insight: convergence beats discovery — the real competitor is Maps plus three group chats.

six friction→fix cycles · nyc field testing · logged in the repo

01 · No-results crash

Suggestion engine crashing on empty results

→ graceful empty state that routes back to filters

02 · Stale membership

New members didn't appear live; refresh threw 'session not found'

→ real-time join broadcast + session re-fetch

03 · Blind proximity

Distance filtering ignored how people travel

→ per-user mode (car / walk / transit) feeds travel-time thresholds

04 · Wrong hierarchy

Plan cards led with the member's name, not the plan

→ plan title primary, people secondary

05 · Dead-end details

'Details' opened the venue website

→ routes straight to Google Maps

06 · Unused dependency

Ticketmaster integration didn't earn its keep

→ removed — venues only, simpler pipeline

friends are the harshest usability lab
02

Design

Five steps, each one tap: Onboarding → New Plan → Voting → Lock → Calendar. The AI Planner does the work between taps, and a post-outing rating feeds the next plan.

Five steps, each one tap: Onboarding → New Plan → Voting → Lock → Calendar. Click through the real flow below — every screen is the shipped product's design, down to the black-on-lime contrast and the post-lock vote lockout.

390 × 844

Hey, Kunal

New York

Ready to LinkUpGo?

Start a new planning session with your groups.

Active plans

Team Lunch locked · May 28

New Plan

Title
Friday Night
Where?
Budget
Energy
Vibe LevelVibey
ChillVibeyGoing outFull send
Who's in?
YouRushiSam

Building your shortlist

Generating the brief, grounding candidates in Google Places, then 4 judges scoring in parallel.

Friday Night

Voting

Lock this plan?

Voting closes for everyone once locked.

Rate this event

Your feedback helps improve recommendations.

Tap to rate
What stood out? (optional)
Would you recommend this place?
Additional notes (optional)
Share your experience...
fig 2.1 — linkupgo v2, interactive walkthrough
03

Architecture

A 3-phase orchestrator: ① generate a Zod-validated plan brief, ② hydrate candidates through Perplexity and Google Places (geo via Mapbox + H3), ③ score with a weighted panel of four parallel LLM judges, then diversify with an MMR post-pass (λ = 0.7, hard quota backstop). React 19 + Vite 7 · Express + Drizzle · Postgres (Neon) · TanStack Query.

client tap POST /api/suggest 3-phase orchestrator① generate brief② hydrate candidates③ score + diversify 5× writes<50ms each 5 ✦ brief: LLM → Zod-validated JSON · hydrate: Perplexity + Google Places (Mapbox + H3) score: 4-judge panel → MMR diversity post-pass (λ = 0.7, hard quota backstop) Postgres (Neon) · Drizzle · Express · React 19 + Vite 7 · TanStack Query
fig 3.1 — request path — one tap to five ranked venues, p99 ~8.5s (live trace)
judgeweightmodel
Vibe match0.40Claude Haiku 4.5
Neighborhood0.25Gemini 2.5 Flash
Hidden gem0.20Claude Haiku 4.5
Budget0.15Gemini 2.5 Flash-Lite

judges run in Promise.all — p99 is the slowest judge, not the sum

fig 3.2 — panel of llm judges — weighted, parallel, abstention-aware; no judge sees another's output

why this design — the rejected alternatives

single-LLM picks venues end-to-end

→ decomposed, testable phases

one judge, one bias

→ weighted panel of four

"5 cocktail bars in a row"

→ MMR diversity + hard quotas

hallucinated addresses

→ everything grounded in Google Places

Observability: a devLog channel, an eval harness (golden set + replay + judge calibration), shadow-compare running v1 and v2 side-by-side on the same input, and friend reports from the field.

04

Shipped

A working full-stack app (public repo), field-tested with friends in NYC across six logged friction→fix cycles.

  • What exists — a working full-stack app in a public repo: auth, squads, real-time updates, and the full plan→lock→calendar loop.
  • The practice — a friend takes the app to a real bar → friction gets logged → smallest viable spec → ship with an eval → validate on the next outing.
  • Next experiments — vote-grounded preference learning, reservation booking, native iOS + push. Ordered by leverage, framed as experiments, not promises.