Knowledge Base · Beta

Voyagent — the whole story

One quiz each, one plan for everyone. This is the single source of truth for what Voyagent is, why it exists, how it's built, and how a teammate picks it up and carries it from beta to a real launch — without reading a line of code first.

Last updated for the Beta milestone. Live app: voyagent.netlify.app · Metrics: Voyagent Pulse

1 · What it is

Voyagent is a group-trip planner that turns a chaotic group chat into one fair plan. Every traveller answers a 60-second quiz (budget, vibe, home city, hard "no"s). The app reconciles everyone's answers into destination suggestions, the group votes, and Voyagent writes a day-by-day itinerary that respects every budget and dealbreaker — then you can re-tune any day or simply ask to shift things around. A public share page turns any trip into something you can post to friends.

The tagline says it best: Everyone’s voice, one trip.

2 · Why we built it

Group travel dies in the planning. Five friends, five budgets, five ideas of "fun", one endless thread where nobody wants to be the organiser. Existing tools assume one planner doing all the work; they don't reconcile people. We built Voyagent around a single belief:

The hard part of a group trip isn't finding places — it's making a decision everyone feels good about. So the product's job is fairness and momentum, not a bigger list of hotels.

Every design choice flows from that: the quiz is 60 seconds so nobody drops off; budgets anchor to the lowest so nobody gets priced out; dealbreakers are hard overrides so the shy person's "no" still wins; the plan appears the moment the group votes so the energy never stalls.

3 · Who it's for

4 · How it works

  1. Create — a name, rough dates, and a destination-or-vibe (or hit "let Voyagent decide" for the surprise roulette).
  2. Invite — share a link; friends join with just a name, no sign-up.
  3. Quiz — each person: daily budget (log slider), vibes, home city, optional age band, hard dealbreakers (the preset "no"s adapt to the trip — a beach trip offers "No water sports", a trek offers "No steep treks"). ~60 seconds.
  4. Suggest — the app proposes three destinations, each with a why naming the people it fits.
  5. Vote — everyone taps their pick; the tally is live.
  6. Plan — a day-by-day itinerary, each item tagged with who it's "for", with map/booking links.
  7. Adapt — re-tune a day, and it's weather-aware: live rain forecasts trigger a banner, and a rainy re-tune swaps exposed plans for covered or indoor alternatives. Or just ask: "move dinner to 9pm" and it happens for the whole group.
  8. Share — a public page for WhatsApp/Instagram that never exposes the private trip.
Design principle — consensus, not a dictator. A single person can push the group forward, but the app warns by name when someone hasn't finished their quiz or voted, and everyone's answers keep shaping the plan. Fairness is a feature, not an afterthought.

5 · Architecture & stack

Deliberately boring and cheap to run — the right call for a weekend build that might become real.

LayerChoiceWhy
FrontendPreact + htm via CDN, one file, no build stepZero toolchain; edit-and-refresh; installs as a PWA
APIOne shared api-core.js → Express locally, Netlify Function in prodSame code both places; no drift
DatabaseSupabase (Postgres) with a SQLite dev fallbackManaged, realtime, generous free tier
AIOpenAI gpt-4o by default; Claude supportedStructured JSON outputs; seeded fallback if the key is missing
HostingNetlify (app) · Vercel (this Pulse + KB)Git-push deploys, free TLS, edge CDN
RealtimeSupabase broadcast pings + 2.5s pollingInstant roster/vote updates without exposing data

North-star of the architecture: the browser holds no secrets. The app talks to a thin server that owns the database key; the database itself denies all direct access.

6 · Where everything lives

ThingLocation
App (live)voyagent.netlify.app
App sourceGitHub AbhilashKairali/voyagent
Pulse + this KBthis Vercel site · GitHub AbhilashKairali/voyagent-pulse
DatabaseSupabase project rmlwmjzzkeilxxcsxsdy
Frontend UIpublic/index.html (one file — screens, quiz, itinerary, chat)
Server + routesapi-core.js · adapters server.js, netlify/functions/api.mjs
The decision engineai.js (all prompts, schemas, fallbacks)
Data layersdb-supabase.js (prod) · db.js (local) — identical interfaces
Metrics aggregatorstats.js → served at /api/stats (aggregates only)
Schemasupabase/schema.sql
Status docsLAUNCH_CHECKLIST.md, FEEDBACK_STATUS.md, README.md

7 · The decision engine

All intelligence lives in ai.js. Four jobs, each a system prompt + a strict JSON schema + a seeded fallback so the app never blanks:

The rules every prompt enforces

Battle-tested. The prompts were attacked with prompt-injection payloads, gibberish, and illegal requests, then scored by an independent judge panel: injection resisted, junk gets a clarifying question, unsafe asks produce a clean lawful plan. See §9.

8 · Pulse & metrics

The Pulse dashboard follows Pirate Metrics (AARRR) — Dave McClure's five-stage growth funnel that investors expect to see:

StageIn Voyagent
AcquisitionTrips started, travellers joined, per-day trend
ActivationQuiz completion %, reached-a-vote, reached-a-plan %
Retentionneeds accounts — on the roadmap (see §11)
ReferralAverage group size = built-in virality (every trip is an invite)
Revenuefree in beta; AI-cost per trip is the unit-economics proxy

North Star metric: shared plans delivered — the moment a group gets one agreed plan is the value Voyagent exists to create. Everything else is a step toward it.

The dashboard reads a public, cached, aggregate-only feed (/api/stats): counts and category breakdowns, never a name, trip title, or IP. It refreshes every 60 seconds, and a month + year filter (past and future months) lets you track progress month-wise.

9 · Security & privacy

10 · Do's & don'ts

Do

Deploy through git. App → GitHub → netlify deploy --prod. Pulse → GitHub → Vercel. Every change ships the same way.
Keep secrets in host env vars. .env is git-ignored; keys live in Netlify/Vercel dashboards only.
Run migrations before deploying code that needs them. New column → supabase/schema.sql + apply to the live project first.
Add a seeded fallback for every AI feature. The app must never blank if the API is down or capped.
Bump the AI limits for demo day via LIMIT_* env vars, then restore them.

Don't

Never ship the service-role key to the browser or into the Pulse site. The dashboard reads only the public aggregate feed.
Don't expose raw rows in analytics. Aggregate server-side; suppress tiny buckets.
Don't trust user text as instructions. Everything from a brief/quiz/chat is data — keep the guard rails on every prompt.
Don't use short instance-property names in the frontend (e.g. _sb) — they collide with Preact internals. Use distinctive names.
Don't paste API keys into chat or commits. Rotate the current OpenAI key before any public launch (it was shared once).

11 · Beta → launch

What turns this from a great demo into a real product, in rough priority order:

  1. Accounts (Google sign-in). Unlocks true retention metrics, trip history, and per-user privacy. The single biggest unlock.
  2. Real booking links & prices (affiliate hotels/flights) — the first revenue path.
  3. Expense splitting post-trip — a sticky reason to come back.
  4. Push notifications — "3 of 5 have voted" nudges lift activation.
  5. Vote deadlines & reminders — momentum for slow groups.
  6. Multilingual — the quiz and plan in the group's language.
  7. Observability — error tracking (Sentry) and a private ops view alongside the public Pulse.
  8. Harden multi-user concurrency for large groups; formal load testing.
Why this order: accounts unlock the metrics investors ask for (retention/cohorts) and are the prerequisite for revenue and privacy. Booking links are the clearest path to money. Everything else compounds engagement once those two exist.

12 · Run it yourself

No keys needed for a local look — the app serves seeded demo content and uses a local SQLite file.

git clone https://github.com/AbhilashKairali/voyagent
cd voyagent
npm install
node server.js        # → http://localhost:4600

To use real AI + the shared database, add a .env (git-ignored) with OPENAI_API_KEY, SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY. The Pulse dashboard is fully static — deploy the voyagent-pulse repo to Vercel; it needs no env vars because it reads the app's public /api/stats feed.

13 · Glossary


Voyagent is a beta project. This KB is the living source of truth — update it when the product changes. Questions? Start with the code map in §6, then ai.js for behaviour and api-core.js for routes.