Skip to content
<Hyun/>
All projects

Kansas Korean

Live · Community meetup

Find your people. Make a plan.

Choose an interest, join a meetup and carry your itemized share into a prefilled Venmo payment.

Interactive explanation · not the live service

Loading interactive explanation…

Watch the original recordingsMobile · Recording notes included

Use the left and right arrow keys to switch slides.

Mobile

Recorded from a local build with fictional members; AMC showtimes and translations were stubbed.

Joining a weekly pickleball meetup, matching an AMC showtime, checking a bowling settle-up, and switching the app from Korean to Spanish.

1 / 6
Explore the architectureSystem diagrams, design decisions and detailed flows

System overview

  1. PWA in browserUI + service worker
    Step 1, pages + /api
    VERCELNext.js appApp Router + API routes
    Drizzle
    STORAGENeon Postgresmeetups, rules, alerts
  2. VERCELVercel Crondaily, 13:00 UTC
    GET /api/cron
    Next.js app
    Step 2, VAPID push
    Web Push servicesbrowser push endpoints
    alert + badge
    PWA in browser

Other connections

  • Next.js apptoUpstash Redisshowtime cache
  • Next.js apptoVercel Blobupload tokens
  • Next.js apptoKakao / GoogleOAuth
  • Next.js apptoAMC + TMDBshowtimes
  • Next.js apptoClaude Haikutranslate
One Next.js app on Vercel serves both regional domains. It stores meetups and alerts in Postgres, caches AMC showtimes in Redis, keeps photos in Blob and sends Web Push to installed PWAs. The purple path: (1) a host posts a meetup, or the daily cron opens a recurring one, and it is saved with its alerts; (2) subscribers get a Web Push with an unread badge.
View the diagram as text

Parts

  • PWA in browser (UI + service worker): Client / UI
  • Vercel Cron (daily, 13:00 UTC): Background job
  • Next.js app (App Router + API routes): Owned service
  • Web Push services (browser push endpoints): External service
  • Neon Postgres (meetups, rules, alerts): Data store / broker
  • Upstash Redis (AMC showtimes, picks): Data store / broker
  • Vercel Blob (meetup photos): Data store / broker
  • Kakao / Google (OAuth sign-in): External service
  • AMC + TMDB (showtimes, film metadata): External service
  • Claude Haiku (on-demand translation): External service

Connections

  • Step 1: PWA in browser → Next.js app: pages + /api
  • Next.js app → Neon Postgres: Drizzle
  • Vercel Cron → Next.js app: GET /api/cron
  • Step 2: Next.js app → Web Push services: VAPID push
  • Web Push services → PWA in browser: alert + badge
  • Next.js app → Upstash Redis: showtime cache
  • Next.js app → Vercel Blob: upload tokens
  • Next.js app → Kakao / Google: OAuth
  • Next.js app → AMC + TMDB: showtimes
  • Next.js app → Claude Haiku: translate

How a weekly meetup reaches members

  1. Host posts a weekly meetup

    The host ticks 'repeat weekly' and the browser posts to /api/posts. The server checks the HMAC-signed session cookie and picks the region from the request's hostname.

  2. Rule and first occurrence saved

    A recurring rule is stored with the chosen weekday, and the first occurrence is created right away. The meetup, the host's participation and one inbox row per subscriber of that category and region are written in a single transaction.

  3. Subscribers get a push

    Alert text is rendered in each recipient's language, then sent as VAPID-signed Web Push to every device they subscribed, with that person's unread count. The service worker shows the notification and sets the app-icon badge.

  4. Daily cron opens next week

    Vercel Cron calls the reminders route once a day with a bearer secret. For each region, the server creates any occurrence due in the next 7 days that does not exist yet, keyed by rule and date; deleted occurrences count as existing, so a skipped week is not re-created.

  5. Day-of reminder

    In the same run, participants of today's meetups, in each region's own time zone, get a reminder. Meetups already reminded are skipped, so re-running the cron sends no duplicates.

The project & my contribution

Problem
Hobby meetups like movie nights, pickleball and climbing needed one place to plan, sign up and split costs.
Solution
A meetup app where members post and join meetups, comment, share photos, leave reviews and split costs, with recurring schedules and push alerts. One codebase serves both cities.
Result
Live in both cities since July 2026, with weekly recurring meetups.
  • 73 members
  • 70 meetups
  • 507 RSVPs

Live site: Korean interface by default; English and Spanish are available.

The source code is private. I'm happy to walk through it on request.

How it's built

  • Next.js 15 on Vercel with Neon Postgres (Drizzle), Upstash Redis and Vercel Blob
  • Kakao and Google sign-in; in-app inbox and Web Push to an installable PWA
  • Korean, English and Spanish UI, with on-demand Claude Haiku translation of posts

Highlights

  • A daily cron creates recurring meetups idempotently, so a canceled week stays canceled
  • Meetups and their notifications are written in one transaction, localized per recipient
  • Cost splitting in integer cents and prefilled Venmo links; payment confirmation stays in Venmo