Inspiration

Moving to a new city is sold as a fresh start — but most people underestimate how hard it is to turn that into a social life. You might meet people at work or flatmates, yet still have no answer to a simple question: what am I doing this Saturday, and who am I doing it with?

The problem we kept coming back to:

  • Dating apps optimise for romance, not friendship — and the stakes feel wrong for "I just want people to hang out with."
  • Networking events feel transactional; you collect LinkedIn connections, not plans.
  • Meetup groups are often too big or too anonymous — showing up alone to twenty strangers is its own kind of daunting.
  • Group chats and forums rarely convert into IRL plans; someone has to propose a time, place, and vibe, and that person is usually the most extroverted person in the room.

What newcomers actually need is not more profiles to browse. They need a default plan: one activity, a small group that is already matched to them, a time and place decided, and a gentle nudge to show up. Less "find your people in the infinite scroll" — more "your party is ready; here's this week's quest."

We built Side Quest for that gap — starting in Auckland, where thousands of people arrive every year and many are new at the same time, but nobody has a low-stakes path to a standing weekly routine with friendly strangers.

The name reflects the product philosophy: friendship can start as a side quest — optional, low commitment, fun — and become your main storyline if you keep showing up each week.


What it does

Side Quest is a weekly ritual, not a social network. Each week you get matched into a party of six for one curated activity — coffee and a walk, a cooking class, a market morning — with enough structure that showing up feels doable.

End-to-end flow:

  1. Sign up with email (Clerk) — no guest bypass; real accounts only
  2. Onboarding + vibe quiz — your answers become a semantic profile
  3. Finding → Find my party — pgvector matching forms your group in Aurora
  4. Group reveal — see who's in your party, why you fit, and this week's venue
  5. Confirm your seatpayments are disabled for the hackathon demo, so seat confirm is instant and you can unlock the full flow without Stripe
  6. Party chat — concierge welcome + icebreakers; say hi before you meet
  7. Home — this week's quest card, party avatars, live chat preview
  8. Explore — join optional open quests (client-side layer for the demo)
  9. Survey (post-event) — feedback improves your embedding for next week's match

Who it's for: People new to a city — students, migrants, remote workers, anyone rebuilding their social circle — who want one reliable Saturday plan with compatible strangers, not another app to maintain.

What success looks like: You show up, have a good time, exchange numbers offline, and come back next week — not that you spend hours in our app.


How we built it

Frontend — v0 → Cursor → Vercel

We used v0 to generate the initial functional UI — landing page, app shell, weekly quest cards, and core page structure — as a working starting point on the Vercel stack. We then refined and wired everything in Cursor: connected real Clerk auth, Aurora-backed API routes, matching flow, chat polling, explore tiles, and hackathon polish (home layout, group reveal, payment bypass for judges).

The result is a Next.js 16 App Router app deployed on Vercel: mobile-first shell (home, finding, group reveal, chat, explore, quests, profile), Clerk middleware on all routes except landing, sign-in/up, health check, and Stripe webhook.

AWS database — Aurora PostgreSQL

We use Amazon Aurora PostgreSQL Serverless v2, accessed via the RDS Data APInot Aurora DSQL.

We chose Aurora PostgreSQL deliberately:

  • pgvector is a first-class extension — our matching engine runs cosine similarity in SQL (<=> on profiles.embedding)
  • Relational model fits the weekly ritual: users, events, groups, memberships, messages, and surveys are naturally relational with foreign keys and unique constraints
  • RDS Data API lets Vercel serverless functions talk to Aurora over HTTP — no connection pool, no long-lived TCP from edge functions
  • Serverless v2 scales with usage and fits a weekly batch-matching product without ops overhead

Aurora DSQL is a different product (distributed SQL, different access patterns). Side Quest needs Postgres + pgvector + a mature ORM path — Aurora PostgreSQL was the right fit.

Deliberate data model

The schema mirrors the product journey — not a generic "users table plus extras":

Table Role in the product
users Clerk identity, city, newcomer flag, subscription_status (seat gating)
profiles Vibe quiz answers + embedding vector(1024) — the matching signal
preferences Likes/dislikes updated from surveys — feeds re-embedding
venues Curated Auckland activities (name, type, address, capacity)
events One open "week" at a time — links to venue, starts_at, status
groups A matched party for an event; stores concierge reveal payload
group_members Who is in which party + match score; unique per group/user
messages Party chat (user + agent); polled from Aurora every 3s
surveys Post-event vibe score + open text; one per user per group
agent_traces Audit log of concierge actions (venue pick, reveal, chat host)
rate_limits Per-user API counters — works across serverless instances

How the layers connect:

quiz save → Bedrock Titan → profiles.embedding (pgvector)
                ↓
POST /api/match → kNN in Aurora → groups + group_members
                ↓
POST /api/agent/reveal → venue on events + rationale on groups
                ↓
confirm seat → users.subscription_status = active
                ↓
POST /api/agent/host → messages (concierge welcome)
                ↓
POST /api/survey → preferences + re-embed → better next match

Matching guardrails live in application logic and the schema: one group per user per open event, unique (group_id, user_id) on memberships, unique survey per user per group.

ORM: Drizzle with aws-data-api/pg. Embeddings written with explicit ::vector casts; HNSW index on profiles.embedding for production kNN performance.

Embeddings — Amazon Bedrock Titan

Quiz answers → amazon.titan-embed-text-v2:0 → 1024-dim vector in Aurora. Post-event surveys update preferences and trigger re-embedding so the next week's match reflects how the last quest actually went.

Concierge (V1)

Template-based group reveal + rule-based venue selection. /api/agent/host posts welcome + icebreakers into party chat once per group. All actions logged in agent_traces.

Payments (disabled for judges)

Production path: Stripe Checkout → webhook → subscription_status = active in Aurora.

For the hackathon demo, payments are turned off (NEXT_PUBLIC_PAYMENTS_DISABLED=1). Judges click Confirm my seat and the app calls /api/me/confirm-seat to unlock group reveal and party chat instantly — so you can experience the full flow without a test card.

Ops scripts

seed / seed:local, check:aws, inspect:db, demo:match, chat:reseed — verify Aurora connectivity, pgvector, and the golden path before demoing.


Challenges we ran into

Choosing Aurora PostgreSQL over DSQL

We needed pgvector and a relational weekly-ritual schema, not a greenfield distributed SQL model. Aurora PostgreSQL + Data API was the stack the hackathon rewards and our matching pipeline requires.

RDS Data API + pgvector

Serverless functions cannot hold Postgres connection pools. The Data API solved deployment, but vector literals and RDS response parsing needed dedicated helpers — embedding writes use explicit ::vector casts; row parsing handles Data API field shapes.

Bedrock rate limits

Titan embedding RPM on new accounts in ap-southeast-2 throttled seeding and quiz saves. We added deterministic fallback for dev/demo and documented Service Quotas for production.

Matching needs a crowd

Real pgvector kNN requires embedded profiles. Seeding ~40 synthetic Auckland users was essential; guardrails (one group per user per event, exclude assigned users) had to be correct before the golden path worked.

v0 gave us speed; Cursor gave us integration

v0 produced usable UI quickly, but the product only became real when we wired Clerk, Aurora APIs, matching, and chat in Cursor — full-stack thinking, not a static mockup.

Judges need the full path

We disabled the payment wall so confirm seat → reveal → chat is one continuous demo, not a dead end at Stripe.


Accomplishments that we're proud of

  • Aurora PostgreSQL as the centre of gravity — not Aurora DSQL, not a sidecar DB: matching, chat, subscriptions, surveys, rate limits, and agent traces in one deliberate Postgres schema with pgvector
  • Real semantic matching — Bedrock Titan + cosine kNN in SQL, not hard-coded groups
  • v0 + Cursor full-stack velocity — generated UI on Vercel's stack, refined into a working product with real AWS backend
  • Judge-ready demo — email sign-in only, instant seat confirm, full weekly loop in minutes
  • Concierge that reduces awkwardness — reveal, icebreakers, chat welcome without over-building live LLM chat for V1
  • Honest scope — weekly ritual first; not a pretend social network

What we learned

The problem is coordination, not discovery. People do not lack ways to meet strangers — they lack a default plan with matched people and a time/place already chosen. Side Quest optimises for showing up, not scrolling.

How we solve it: a weekly ritual, not a one-off. Meeting someone compatible once is luck. Showing up to the same kind of activity, with the same small group rhythm, week after week — that is how you create your own luck. Travellers and people who have moved city to city know this already: the friendships that stick rarely come from a single great night out. They come from running into the same people again, having one more conversation, and slowly becoming part of each other's routine. Side Quest is built around that insight — one quest per week, same party energy, low enough stakes to come back even if week one felt awkward.

Consistency lowers the social bar. A app that only helps you meet strangers once treats every Saturday like starting from zero. A weekly ritual means the second and third hangout are easier than the first — you are not re-introducing yourself to the universe every weekend; you are continuing a thread. That is the product bet: friendship needs repeat exposure, and we structure the product so repeat exposure is the default, not something you have to organise yourself.

Icebreakers exist so someone else says the awkward thing first. Everyone knows the generic openers — where are you from, what do you do, how long have you been here — and how stiff they can feel when you are already nervous about meeting strangers. Our concierge posts tailored prompts in party chat before the event so the first message is not on the shyest person in the room, and the conversation can start somewhere specific instead of somewhere weird. Small design choice, big difference in how safe it feels to say hi.

Aurora PostgreSQL + Vercel is a credible production pair when you design for Data API: stateless routes, polling chat, embedding writes as explicit SQL, rate limits in the same database.

The data model tells the story. Events → groups → members → messages → surveys is the weekly ritual in tables. Judges should see that the architecture and the UX describe the same product.

v0 accelerates UI; integration is still the hackathon. The winning move was generating functional screens fast, then using Cursor to connect every screen to Aurora-backed APIs.

Remove friction for evaluators. Disabling payments for the demo was a product decision — judges should feel the reveal and chat, not our Stripe integration.


What's next for Side Quest

Near term (V1.1)

  • Live AI concierge in party chat — contextual nudges (Claude via Vercel AI SDK), building on agent_traces
  • Aurora-backed open quests — move Explore from client storage into events / messages
  • Re-enable Stripe in production; keep instant confirm only for staging demos if needed
  • Past party roster on Quests

If users stick (V2)

  • "Hang again" after survey — concierge nudges mutual interest into the same open quest
  • Opt-in contact share after events
  • More cities with local venue seed data
  • Monthly community events — once a month, host a bigger gathering (20–30+ people) so regulars from different weekly parties cross paths. The weekly side quest stays intimate; the monthly event is where familiar faces from across the city start to feel like a scene

What we are not building

Infinite swipe feeds, friend graphs, or 1:1 DMs. Side Quest exists to get six compatible strangers to one activity, once a week — with an optional monthly moment to widen the circle. Success is offline friendship, not time-in-app.

Built With

  • amazon-aurora-postgresql-serverless-v2
  • amazon-bedrock
  • amazon-rds-data-api
  • aws-sdk
  • clerk
  • cursor
  • drizzle-orm
  • motion
  • next.js
  • pgvector
  • react
  • stripe
  • typescript
  • v0
  • vercel
  • vitest
  • zod
Share this project:

Updates