가능한 날짜를 투표로 모아서 모임 일정을 잡는 서비스. 회원가입 없이, 링크 하나로 끝.
🔗 서비스 바로가기
여러 명이 모일 날짜를 맞추려고 단톡방에서 "이날 되세요?"를 반복하는 번거로움을 줄이기 위해 만들었습니다.
- 주최자가 날짜 범위와 최소 인원을 정해 방을 만든다
- 링크를 공유한다 (회원가입 불필요)
- 참여자가 가능한 날짜를 골라 투표한다
- 최소 인원 조건을 만족하는 날짜가 나오면 서버가 자동으로 확정한다
투표 / 확정
- 회원가입 없이 닉네임만으로 투표, 같은 브라우저에서만 본인 투표 수정 가능 (
vote_token기반) - 최소 인원 조건 충족 시 자동 확정 (
try_confirm_room— DB 락으로 동시 요청 안전하게 처리) - 최다 득표 날짜가 동점이면 서버가 자동으로 재투표 상태로 전환, 동점 후보만 다시 투표받음
- 닉네임이 중복돼도 차단하지 않고 "이름(2)"로 자동 구분
- 확정일이 지나면 같은 결과 화면에서 "지난 모임"으로 표시 (축하 애니메이션은 생략)
주최자
- 방 생성 시 발급된
host_key로만 가능한 강제 확정 / 방 삭제 - 마감된 방에서 "이 설정으로 새 방 만들기" — 이름·최소 인원을 그대로 복사해 새 방 생성
그 외
- Supabase Realtime으로 투표 현황 실시간 갱신
- 링크 복사 / 카카오톡 공유 / Web Share API
- 다크모드 (라이트 기본, 토글 시
localStorage에 저장) - 키보드 전용 사용자를 위한 시간 선택 휠(방향키 지원) + 전역 focus 표시
prefers-reduced-motion대응 — 모션 줄임 설정 시 확정 애니메이션 정지- 마감된 방까지 진행됐지만 확정되지 않은 경우 결과 요약 + "새 방 만들기" 안내
| 영역 | 사용 기술 |
|---|---|
| 프레임워크 | Next.js 16 (App Router), React 19, TypeScript |
| DB / 인증 | Supabase (PostgreSQL, Row Level Security, Realtime) |
| 스타일 | Tailwind v4 + 커스텀 CSS 변수 / nj-* 클래스 (app/globals.css) |
| Rate Limit | Upstash Redis (미설정 시 인메모리로 자동 폴백) |
| 테스트 | Playwright E2E |
| 배포 | Netlify (@netlify/plugin-nextjs) |
| 패키지 매니저 | pnpm |
- 인증 없는 익명 투표 —
supabase.auth를 쓰지 않고 anon key + RLS로만 접근을 제어합니다. 투표 수정 권한은 서버가 발급한vote_token(UUID, 별도 테이블에 보관, anon SELECT 불가)으로 검증합니다. - 주최자 권한 —
host_key도 같은 방식으로 별도 테이블에 보관해 일반 SELECT로는 절대 노출되지 않습니다. - 동시성 — 자동 확정 로직(
try_confirm_room)은 PostgresFOR UPDATE락으로 동시 투표 요청에도 단 한 번만 확정되도록 보장합니다. - 서버가 모든 판단을 내림 — 재투표 여부, 동점 후보, 확정 여부를 전부 서버 RPC가 계산해서
rooms테이블에 기록합니다. 클라이언트는 그 결과를 그대로 읽기만 합니다.
더 자세한 설계 의도와 트레이드오프는 CLAUDE.md에 정리돼 있습니다.
- 확정 후 알림 — 이메일 또는 Web Push (카카오 알림톡은 사업자 등록·전화번호 수집이 필요해 현재 설계와 맞지 않아 보류)
- 장소 조율 — 날짜뿐 아니라 모임 장소도 함께 제안/투표