비개발자가 하루에 사이드 프로젝트 3종 라이브 배포까지
Claude Code Max 하나로 랜딩페이지·AI 챗봇·n8n 자동화 자료까지 — Supabase + Vercel만 쓰는 미니멀 스택.
1. 왜 이걸 만드나
한국 외주 시장(크몽·숨고)에서 가장 수요 큰 게 AI 챗봇 외주(9개월 1.2만 건). 그 다음이 자동화·랜딩페이지. 영업하려면 "이런 거 만들 수 있어요" 보여줄 데모가 있어야 함. 3종을 하루에 묶어서 라이브 URL로 만들기로 결정.
운영 원칙: 인프라 스택은 Vercel + Supabase 두 가지로만 한정. AWS, Firebase, Clerk, Auth0 등 다른 거 안 씀. 외부 의존 늘릴수록 디버깅 비용 늘어남. 최소 스택으로 묶어두고 Claude Code가 그 안에서 자유롭게 일하게 함.
2. Supabase MCP — 한 번 등록해두면 자동화 끝장
Claude Code에 Supabase MCP 서버를 프로젝트 스코프로 등록:
claude mcp add --scope project --transport http supabase \
"https://mcp.supabase.com/mcp?project_ref=<project_ref>"
이거 하면 Claude가 직접 list_projects, apply_migration, execute_sql, get_publishable_keys 같은 툴을 써서 DB 만지고 마이그레이션 적용함. 비개발자가 SQL 직접 안 쳐도 됨.
MCP로 자동화 가능한 키 vs 수동
| 키 | MCP 자동? |
|---|---|
| Project URL | ✅ 자동 |
| Publishable / anon key | ✅ 자동 |
| Service role / secret key | ❌ 보안상 미노출 — 수동 복사 |
참고로 Supabase가 2025년에 키 시스템을 개편했음. 옛날 service_role JWT는 이제 sb_secret_* 형식으로 바뀌고, 대시보드 "Secret keys" 탭에 들어있음. 환경변수 이름은 SUPABASE_SERVICE_ROLE_KEY 그대로 두고 값만 새 형식으로 넣으면 됨.
3. 마이그레이션 + RLS + 보안 advisor
3개 마이그레이션 파일을 한 번에 적용:
0001_init_subscribers.sql— 이메일 수집 (랜딩페이지)0002_init_conversations.sql— 챗봇 대화 로그0003_init_subscriptions.sql— profiles + usage_events (결제 동기화 대비)
모든 테이블 RLS(Row-Level Security) 활성화. 그 다음 Supabase advisor 돌리면 자동으로 보안 이슈 잡아줌:
// advisor가 잡은 거
- function_search_path_mutable on public.set_updated_at
- handle_new_user is callable via REST as anon role
// hardening 마이그레이션 한 번 더 적용
create or replace function public.set_updated_at()
returns trigger language plpgsql
set search_path = public, pg_temp
as $$ ... $$;
revoke execute on function public.handle_new_user()
from anon, authenticated, public;
4. 모델 교체 여정 — 오늘의 하이라이트
03 챗봇은 처음 Claude Sonnet 4.6으로 만들었음. 외주 데모인데 매번 토큰 비용 = 영업 ROI 안 좋음. → 무료 모델로 교체.
1차: Gemini 2.5 Flash
Google AI Studio 무료 키 (일 1500회 — 데모 충분). SDK 교체하고 role 매핑 처리:
// Anthropic role "assistant" → Gemini role "model"
const contents = messages.map((m) => ({
role: m.role === "assistant" ? "model" : "user",
parts: [{ text: m.content }],
}));
로컬 테스트 OK. Vercel 배포 후 첫 호출 OK. 두 번째 호출... 503 UNAVAILABLE. 반복.
진단 — 어디가 문제냐
| 호출 위치 | 결과 |
|---|---|
| 로컬 → Google 직접 (curl) | ✅ 100% 성공 (3/3) |
| 로컬 → Google streaming + system instruction | ✅ 성공 |
| Vercel 서버 → Google | ❌ 100% 503 (3/3) |
코드/모델/system prompt 문제 아님. 추정: Vercel egress IP 풀이 Google 무료 티어에서 다른 수천 사용자와 quota 공유 → throttle. 더 가벼운 gemini-2.5-flash-lite로 바꿔봐도 동일.
2차: Groq Llama 3.3 70B
완전 무료 + 신용카드 등록 불필요 + 분 30회 / 일 1000회 (데모용 차고 넘침). OpenAI 호환 API라 SDK 단순:
const apiStream = await groq.chat.completions.create({
model: "llama-3.3-70b-versatile",
messages: [
{ role: "system", content: SYSTEM_PROMPT },
...messages,
],
temperature: 0.5,
max_tokens: 500,
stream: true,
});
배포 후 3회 연속 호출 → 3/3 모두 성공. 한국어 답변 품질도 FAQ 챗봇 용도면 충분. 안정화 완료.
교훈: Vercel + Google 무료 LLM 조합은 데모 용도로도 비현실적. Groq가 사이드 프로젝트 무료 데모에 훨씬 적합.
5. Vercel 배포 함정 3가지
① 첫 배포 자동 prod
git 미연결 프로젝트의 첫 vercel deploy는 자동으로 prod 타겟으로 감. 의도와 달리 라이브가 됨. 두 번째 배포부터는 같은 명령이 preview로 떨어지고 prod 가려면 --prod 명시 필요. 일관성 없음.
② Preview env CLI 버그
git 미연결 프로젝트에 preview 환경변수 추가가 사실상 안 됨:
$ vercel env add NEXT_PUBLIC_SUPABASE_URL preview --value "..." --yes
{
"status": "action_required",
"reason": "git_branch_required",
"message": "Add to which Git branch? Pass branch as third argument..."
}
"all preview branches"로 추가하라는 제안 명령을 실행해도 같은 에러. 우회법: --build-env로 빌드 시점에 직접 주입:
vercel deploy \
--build-env "NEXT_PUBLIC_SUPABASE_URL=$URL" \
--build-env "NEXT_PUBLIC_SUPABASE_ANON_KEY=$KEY"
③ 셸 env가 .env.local을 덮어씀
Next.js는 이미 셸에 set된 변수는 .env.local로 덮어쓰지 않음. 옛날에 .zshrc에 export한 만료된 키가 있으면 새 키 입력해도 무시됨. dev 서버에서 503 / 인증 실패가 나올 때 의심해볼 곳:
$ env | grep -iE "(GOOGLE|GEMINI|GROQ|ANTHROPIC)_API_KEY"
GOOGLE_API_KEY=AIzaSy...<- 만료된 옛 값
$ grep "API_KEY" ~/.zshrc
6. CLAUDE.md 가드레일 — AI 폭주 방지
프로젝트 루트에 CLAUDE.md 두고 운영 정책 박아둠. 핵심 룰 3개:
- API 호출 실패 → 자동 우회/fallback/mock 금지. 원본 에러 그대로 사용자에게 보고하고 즉시 작업 중단.
- 외부 패키지/서비스 도입 → 사용자에게 먼저 묻기.
- 프로덕션 배포 → 사용자 명시 승인 후에만.
오늘 실수로 vercel deploy 한 번이 prod로 자동 배포됨. Claude가 즉시 "정책 위반에 가까운 상황입니다"라고 보고. 사용자가 "포트폴리오 더미는 prod 직행 OK"라는 예외 룰을 추가하고 진행. 가드레일이 실제로 작동.
7. 정리 — 하루 산출물
- Supabase 4 테이블 (subscribers, conversations, profiles, usage_events) + RLS + 보안 hardening
- Vercel 프로덕션 배포 2건 (랜딩, 챗봇) + e2e 검증
- 외주 견적 시안 자료 1건 (n8n 워크플로우 묶음)
- LLM provider 2번 교체 (Anthropic → Gemini → Groq)
- CLAUDE.md 정책 1건 갱신 (포트폴리오 더미 예외 룰)
비개발자/주니어가 Claude Code Max 활용해 하루에 이만큼. 외주 시작 가능 상태. 다음 단계는 영업.