← My work

Full-stack web product · Social sports

Relay

From the first invite to the final score, Relay keeps a pickleball session together. Find a court, bring the crew, run rotations, and share a Story—with an AI Agent to answer game questions and prepare plans for review.

Contribution
Designed and built independently
Current state
Live web product · Source available
Built with
Next.js · TypeScript · Tailwind · Supabase · Resend · PostgreSQL · Drizzle ORM · Vercel AI SDK · OpenRouter · Tiptap · Zod · Vitest · Playwright

AI Agent

A conversation grounded in the game, with a separate boundary for creation.

Explore the game

Ask about upcoming games, rosters, invitations, groups, open games, Philippine courts, or Relay guides. Answers use permission-checked tools and link back to relevant records.

Build a plan in conversation

When enabled, prepare a hosted game or draft, replay a completed game, create a group, or set up device-local Quick Play. Agent reuses supplied details and asks one missing question at a time.

Review, then create

A server-owned proposal makes the schedule, audience, and creation effects explicit. Confirmation rechecks permissions; retries recover the saved result. Creation availability depends on current Agent settings.

Product showcase

Inside Relay

Selected product surfaces and public demonstrations. Demo images use illustrative records; captions identify those examples.

Relay public Agent demo answering a question about the next game, roster, waitlist, and court booking with sample data
01Agent · public demo with sample dataFull resolution ↗
Relay public Story showcase presenting five visual themes for invitations, photo memories, and results
02Story themes · public showcaseFull resolution ↗
Relay public pickleball invitation with session details, roster capacity, and guest RSVP controls
03Plan and RSVPFull resolution ↗
Relay play setup showing Paddle Stack, Mix It Up, Court Climb, and Team Round Robin formats
04Play formatFull resolution ↗
Relay active courts view with live scoring and the paddle queue
05Live courtsFull resolution ↗
Relay courtside scoring view with large team scores and touch controls
06Courtside scoringFull resolution ↗

Problem and response

The problem

Recreational pickleball groups coordinate the plan, roster, venue cost, court order, and scores across group chats, spreadsheets, and whoever happens to remember what comes next.

The approach

Start with a court, a hosted game, or device-local Quick Play. A shared game link connects guest RSVPs, the roster, costs, rotations, scores, chat, and Stories. Agent adds a conversational entry point: explore authorized game details, answer one missing question at a time, and review a proposal before creating anything.

Product journey · 7 connected features

One session, from first plan to shared memory.

Relay replaces the scattered chat, spreadsheet, scorekeeper, and payment follow-up with one continuous product flow.

01 · Plan

Plan it before the chat gets noisy.

Philippines court discovery, date and time, courts, capacity, booking details, and readiness.

Create a game

Set the plan. Share the link.

02 · Invite

One link answers every question.

Guest RSVP, host approval, capacity, and an automatic waitlist. Guests do not need an account.

Saturday, August 22

Saturday Night Pickle

Central Pickle · 7:00–10:00 PM

Players
8 of 10 going
Estimated
₱300 / player
Join this gameYour name
GoingMaybeCan’t go

03 · Organize

Keep the crew, not the admin.

Roster controls, recurring groups, calendar, global search, and Play Again.

Game readinessAlmost ready75%

Roster · 8 going · 1 waitlisted Add player

  • VanHostGoing
  • AJRegularGoing
  • MikaCasualGoing

04 · Play

Run every court from one phone.

Device-local Quick Play or hosted games, five play formats, multi-court scoring, and standings.

Court 1Balanced Mix● Live
Van + AJ8VSMika + Bea6
−   +−   +

05 · Repay

Split what the host already covered.

GCash, Maya, bank or cash, proof review, exclusions, and adjusted shares.

Court repayment
₱2,4007 paying players · ₱300 each2 confirmed
  • VanPaid upfront₱2,400
  • AJConfirmed₱300
  • MikaProof sent₱300

06 · Stay in sync

The conversation stays with the game.

Realtime chat, photos, reactions, system updates, and useful notifications.

Saturday Night Pickle8 players in sync
AJ joined the game

Parking is open beside Court 2.

Perfect. I’ll bring the extra balls.

Court 1 match started
Message the group Send

07 · Remember

Turn the night into a story.

Five Story themes for invitations, photo memories, and results. Share or download a 1080 × 1920 image.

Session recapChoose your storyResults
My game3–1Van

#2 · +12

Winning teamVan + AJ3

wins together

Standings

1 Van 3–1

2 AJ 2–2

3 Mika

01 / 07

Architecture

Next.js Server Components load the initial session state. Server actions and queries enforce authorization and product rules. Agent uses Vercel AI SDK and OpenRouter to stream answers through permission-checked tools, with explicit approval before creation.

  1. Feature-based modules

    Session, roster, payment, match, queue, group, and notification code is organized with its schemas, actions, queries, and interface components.

  2. Authorization on every write

    Mutations validate the signed-in user, session role, lifecycle state, and Zod input before changing data.

  3. Typed relational model

    Drizzle and PostgreSQL model sessions, players, courts, matches, queues, expenses, chat, and memories with explicit constraints.

  4. Tool-calling Agent with scoped data

    An authenticated API validates requests and usage limits, then uses Vercel AI SDK, @ai-sdk/react, and OpenRouter for chat and streaming. Zod-validated tools read authorized games, groups, courts, and Help Center articles. Models receive selected fields, never a database connection or arbitrary SQL access.

  5. Review before creation

    When creation is enabled, Agent gathers missing details into owner-scoped proposals. Server-generated review cards require explicit approval; confirmation rechecks permissions and calls shared business commands. Stored results let retries recover an existing creation without duplicates. Provider credentials are encrypted server-side with AES-256-GCM.

  6. Small client boundaries

    Public RSVP, progressive forms, court controls, scoring, and realtime reconciliation run on the client. The rest of the page remains server-rendered.

Key product and engineering decisions

These decisions affect what users can do, where product rules live, and how the system handles failure or change.

Make the session the product boundary

The session owns the plan, roster, expenses, courts, queue, matches, chat, and recap. Users can move through one game without learning separate management areas.

Let the shared link carry the plan

Invitees can check the time, venue, capacity, estimated cost, and booking status, then RSVP by name without creating an account.

Design for courtside use

Large score controls, deterministic rotations, visible queue state, and focused live views prioritize fast one-handed decisions beside the court.

What you can inspect

The live product and public repository provide concrete evidence of the implemented features, architecture, tests, and documentation.