프로젝트를 만들고, 사람을 초대해서, 할 일을 같이 본다.
5주 α MVP. 솔로 사이드. 디자인 핸드오프는 untitled/project/handoff/Stride MVP Handoff.html (Claude Design 익스포트).
- Framework — Next.js 16 (App Router, Server Actions) · TypeScript
- UI — Tailwind v4 + Pretendard + JetBrains Mono · lucide-react · next-themes
- DB / Auth — Supabase Postgres + Prisma
- Server state — @tanstack/react-query (5초 폴링)
- Forms — react-hook-form + zod
- DnD — @dnd-kit (W3 칸반)
- Mail — Resend + react-email (W4 초대)
- OG fetch — cheerio (W5 백링크)
# 1. 의존성
pnpm install
# 2. 환경변수 — Supabase + Resend 키 입력
cp .env.example .env.local
# 3. 개발 서버
pnpm dev # → http://localhost:3000W1 D2부터는
DATABASE_URL설정 후pnpm prisma migrate dev --name init으로 스키마 적용.
app/ # 라우트 + RSC
globals.css # ← 디자인 토큰 (DESIGN.md 그대로)
layout.tsx # Pretendard + ThemeProvider
page.tsx # 임시 랜딩 (W1 D1)
actions/ # server actions (도메인별)
lib/
db.ts # Prisma singleton
supabase/{server,client}.ts
result.ts # ActionResult<T> 타입
components/
theme-provider.tsx # next-themes wrapper
theme-toggle.tsx
ui/ # 프리미티브 (W1 D3-)
shell/ # Sidebar, Topbar
tasks/ docs/ projects/
emails/ # react-email 템플릿 (W4)
prisma/
schema.prisma # ← SCHEMA.md 그대로 (11 테이블)
globals.css에서 :root + .dark CSS 변수 + @theme inline로 매핑.
| Tailwind 클래스 | CSS 변수 | 기본값(warm) |
|---|---|---|
bg-bg |
--bg |
#faf9f7 |
bg-panel / bg-panel-2 |
--panel / --panel-2 |
#fff / #f5f4f1 |
text-text / text-text-2 / text-muted |
--text / --text-2 / --muted |
|
bg-accent / bg-accent-soft |
--accent |
#c2410c (rust) |
bg-good / bg-warn / bg-danger / bg-info / bg-purple |
||
border-border / border-border-strong |
||
font-sans / font-mono |
Pretendard Variable / JetBrains Mono |
다크모드는 <html class="dark"> 클래스 토글 (next-themes).
| 주차 | 결과 |
|---|---|
| W1 ✓ | 가입 → 로그인 → 비번 재설정 → 프로필 → 다크모드 |
| W2 ✓ | 프로젝트 CRUD · 상세 layout · 할 일 리스트 + 인라인 편집 |
| W3 ✓ | 칸반(dnd-kit) · 라벨 · 마감일 · 5초 폴링(router.refresh) |
| W4 ✓ | 초대(Resend) · 수락 흐름 · 역할 변경/제거 · RLS 검증 |
| W5 ✓ | 문서 + 백링크(cheerio OG fetch) · 모바일 풀스크린 모달 · 파일럿 준비 |
상세는 untitled/project/handoff/ROADMAP.md.
/login/signup/forgot/reset— Supabase Auth 위임/home— 인사말 + 프로젝트 카드 그리드 + 빈 상태 CTA/projects/new— 색·아이콘·코드 입력 (워크스페이스 내 unique)/projects/[id]/tasks— 리스트(상태 그룹핑·접기) ↔ 칸반(dnd-kit) 토글, 5초 폴링/projects/[id]/docs/[docId]— 본문 없는 링크 컬렉션, URL 붙여넣으면 OG fetch/projects/[id]/team— 멤버 / 초대 모달 / 보류 초대 / 역할 dropdown/invite/[token]— 만료·비로그인·이메일 mismatch·정상 4분기/profile— 이름·아바타·비밀번호 변경
- Supabase Dashboard: Authentication → "Confirm email" 끄기 권장 (dev)
.env.local에DATABASE_URL/NEXT_PUBLIC_SUPABASE_URL/NEXT_PUBLIC_SUPABASE_ANON_KEY채우기pnpm prisma migrate deploy— auth_and_rls 마이그레이션이 트리거 + RLS 정책 적용- (선택) Resend 키 — 없어도 초대 흐름 동작, URL 복사로 수동 전달 가능
pnpm dev→ 본인 계정 → 첫 프로젝트 → 팀원 초대 → 파일럿 시작 🥂
- RLS는 W1부터 켜기 (미루면 W4에 모든 쿼리 재검토)
- Mutation = Server Action, 폴링 = Route Handler
- 권한은
requireProjectMember()한 함수 → RLS는 2차 방어 - Workspace 처음부터 두기 (나중에 가장 아픈 모델)
- 타임존 UTC 저장, 표시할 때만 KST
- Result 패턴
{ok, data}|{ok, error}(throw 금지) - OG fetch 실패해도 진행 (5s timeout, 1MB, redirect 3)
refetchIntervalInBackground: false- 상태 매니저 도입 미루기