Projects

Kyareureuk Party (꺄르륵 파티)

"오늘이 지나면 우리 사이, 달라질 거야." A mobile-first platform that turned Yeonrim Bar's fully manual matchmaking-night workflow into something the staff can run themselves.

TimelineDec 2025 – Feb 2026
ClientYeonrim Bar (연림)
RoleSole full-stack engineer
StackNext.js 16 · TypeScript · Firebase · Kakao OAuth

Overview

A mobile-first web platform handling the full lifecycle of a small recurring private event — invitation-only access, gender-balanced registration, payment, admin approval, and real-time roster updates — built for one specific Seoul bar and used roughly twice a week.

Yeonrim is a small bar in Seoul that hosts private matchmaking parties — guests pay to attend an evening designed around meeting other people, with a gender-balanced roster and an admin-curated guest list. The bar was running this entirely manually: invitations through KakaoTalk groups, payment tracking in a notebook, gender balance enforced by counting messages, questionnaire responses collected on paper. Kyareureuk Party replaced all of that. It handles invitation-only access (single shared bar password), Kakao OAuth onboarding, a structured questionnaire, gender-quota tracking with real-time Firestore listeners, manual bank-transfer payment with admin verification, and an admin dashboard for the bar to approve or reject registrants. Live at yeonrim.space, running ~2 events per week, averaging ~10 successful registrations per session.

Stack

frontend
Next.js 16 (App Router) React 19 TypeScript Tailwind CSS 4 Radix UI
backend & data
Firebase Authentication Firestore (real-time listeners) Next.js API routes Firestore security rules
auth & payments
Kakao OAuth manual bank transfer + admin verify (TossPayments attempted, rolled back)
deployment
Vercel yeonrim.space (live)

The Problem

Yeonrim was running its events entirely manually — KakaoTalk groups, paper questionnaires, gender balance enforced by counting messages. It didn't scale, and it made the staff the bottleneck.

The bar's matchmaking events have a few hard constraints that make manual coordination brittle. Gender quotas need to be enforced in real time, because the event's premise depends on roughly balanced attendance. Payment needs to be confirmed before the spot is held, but bank-transfer reconciliation by hand is slow. The admin has to approve registrants individually (the events depend on trust), but that approval step needs context — who is this person, what did they say in the questionnaire — that was sitting in different chat threads. Before this platform, the bar staff was effectively a single-threaded human queue handling all of it.

Hand-drawn ideation sketches for Kyareureuk Party
Fig 1 · Ideation sketches — user flows, system architecture, and feature requirements mapped out before any code was written.
💡
How might we
replace a fully manual event-coordination workflow with a small, mobile-first platform that the bar can actually run themselves — including real-time gender balance, payment verification, admin approval, and onboarding — without overshooting into something more complex than the bar needs?

Architecture

One admin, ~10 guests per event, mobile-only. The architecture follows the scale, not the convention.

Decision Why this scale, not the convention
Firebase over custom backendOne admin + ~20 guests/week. The complexity of a Postgres + custom auth stack would have been overhead. Firestore's real-time listeners handle the live-roster requirement out of the box.
Manual bank transfer over TossPaymentsInitially attempted Toss (Korea's standard processor); the integration complexity outweighed the benefit for the bar's volume. The pivot to manual + admin verification shipped sooner and fit the use case better.
Mobile-first from sketch 0Every guest is on their phone — there's no "desktop user" segment. Designing layouts mobile-first meant no responsive retrofit. Tailwind + Radix made this fast.
Radix UI primitives over custom design systemAccessibility on forms, dialogs, and status indicators ships free. Building those from scratch for one platform is not where the engineering time pays off.
Route protection via session stateGuests can't skip required steps (questionnaire → quota check → payment → approval) by editing URLs — checked server-side, not just client-side.

Pipeline

Five-stage workflow with state in Firestore. The admin's approval action propagates to the guest's device immediately via real-time listeners.

Guest journey: Admin journey: shared bar password admin dashboard (live) │ │ ▼ │ Kakao OAuth login │ │ │ ▼ │ questionnaire (matching context) │ │ │ ▼ │ gender-quota check │ │ │ Firestore ▼ │ real-time bank transfer (manual, with reference) │ listener │ │ ▼ ▼ status: waiting ──────────► approve / reject │ │ ▼ (status updates instantly via Firestore) │ status: confirmed ◄──────────────────────────────────┘

Repo structure

kyareureuk-party/ ├── src/ │ ├── app/ # Next.js App Router pages │ │ ├── admin/ # admin dashboard + approval management │ │ ├── api/auth/ # Kakao OAuth endpoints │ │ ├── auth/ # authentication flow │ │ ├── bank-transfer/ # payment processing │ │ ├── dashboard/ # user dashboard │ │ ├── questionnaire/ # matching questionnaire │ │ ├── status/ # real-time participant status │ │ ├── waiting/ # approval waiting page │ │ └── page.tsx # home + password gate │ ├── components/ # UI primitives (Radix-based) │ ├── lib/ │ │ ├── firebase.ts │ │ ├── firestore.ts # DB ops + approval workflow │ │ └── utils.ts │ └── types/ # TypeScript type definitions ├── firestore.rules └── ideation.jpeg # the original sketches

Findings

A live platform handling real registrations for a real business — not a portfolio piece pretending to be a product.

The strongest signal isn't a technical metric; it's that the platform has been in continuous use since launch, running events the bar's staff would otherwise coordinate manually. The platform handles end-to-end flow for ~10 registrants per event across roughly two events per week, with Kakao OAuth, real-time admin approval, and bank-transfer verification all working together. The bar admin uses the dashboard live during the event window; guests use the mobile flow on their phones.

~10 / session
successful registrations per event
2× / week
event frequency the platform supports
Live
production at yeonrim.space

Limitations

  • Bound to one venue. The platform is intentionally scoped to Yeonrim. Generalizing would mean templating the questionnaire, quota rules, and admin flows — non-trivial work the bar didn't need.
  • Manual payment verification. The admin still has to confirm each bank transfer. Scales fine at 2 events/week × 10 guests; would need automation if volume grew.
  • No returning-guest profile. Guests fill the questionnaire each event. A profile system would reduce friction for repeat attendees, but isn't currently in the platform.
  • Single admin assumption. The dashboard is built for one decision-maker. Multi-admin coordination (handoff, conflict resolution) isn't modeled.

Lessons Learned

The right architecture for a 10-user system is not a smaller version of the right architecture for a 10,000-user system. Picking simpler tools wasn't a compromise — it was the correct fit.

What worked. Committing to mobile-first from the very first sketch. Every guest is on their phone — there's no "desktop user" segment to consider — and designing the layouts mobile-first meant I never had to retrofit responsiveness later.

What didn't. The initial TossPayments integration. I assumed the bar would want a real payment processor; the bar actually wanted less infrastructure to manage, not more. The integration was building toward a complexity level the use case didn't justify. I rolled it back and built the manual bank-transfer workflow with admin verification, which fit the scale better and shipped sooner. The pivot itself was the lesson — knowing when to drop a "more sophisticated" solution that fits the use case worse.

What I'd do differently. Validate the workflow with the bar admin in a paper prototype or low-fidelity Figma before writing the auth code. Several iterations on the admin dashboard happened only because I'd built features the admin didn't actually use the way I'd expected. Walking through the user flow with them before any code would have caught those misalignments earlier.

← Prev: Quanta Next: Pocha Ordering Platform →