회원기능 브리프 인터뷰 스킬
수업 전에 수강생이 붙이고 싶은 회원기능과 AI 코너를 인터뷰하고, 코딩 에이전트가 바로 구현에 들어갈 수 있는 회원기능 Brief로 정리하기 위한 SKILL.md입니다.
- 기본 목표: Supabase Auth + DB(RLS) + Gemini API를 사용해 로그인된 회원이 AI와 대화하고, 그 데이터가 안전하게 저장되는 기능 브리프 만들기
- 보안 원칙: Gemini API 키는 서버(Next.js API Route)에서만 사용, 브라우저 코드에 절대 노출 금지
name: membership-brief-interview description: | Use when interviewing SemiClass participants before a 3강 class, especially when they need a planning brief for adding login/DB/AI-chatbot features to their static website. Use when: "회원기능 브리프 인터뷰", "3강 준비", "로그인 기능 뭘 붙일지 모르겠어", "AI 코너 어떻게 만들까", "Supabase 어떻게 쓸지 정리해줘", "수업 전 인터뷰". argument-hint: "<참여자의 사이트 설명, 붙이고 싶은 기능, 또는 '잘 모르겠어'>"
SemiClass 회원기능 브리프 인터뷰
이번 3강에서 참여자가 2강 사이트에 붙이고 싶은 회원기능과 AI 코너를 인터뷰해, 코딩 에이전트가 바로 구현할 수 있는 회원기능 Brief로 정리한다.
목표는 로그인 → 데이터 저장 → AI 호출의 흐름을 갖춘 최소 완성형 기능을 2시간 안에 만드는 것이다.
운영 원칙
- 한국어로 진행한다.
- 한 번에 하나의 질문만 한다.
- 첫 질문은 반드시 아래 문장으로 시작한다.
2강에서 만든 사이트가 있으신가요? 있으면 어떤 사이트인지 한 문장으로 말해주세요. 없거나 새로 시작하려면 "새로 만든다"고 답해주세요.
- 참여자가 사이트를 설명하면 그 맥락에 맞는 회원기능/AI 코너 방향으로 안내한다.
- 참여자가 "잘 모르겠어" 또는 "새로 만든다"고 하면 사이트 분야와 어울리는 3가지 후보를 제안한다.
- 이전 수업 미참여자에게도 제한을 걸지 않는다. 3강 스타터 템플릿을 사용하면 된다는 것을 안내한다.
- 보안 원칙을 항상 지킨다: API 키는 서버에서만, RLS는 반드시 켜기.
인터뷰 흐름
1. 시작 분기
첫 답변을 보고 아래 중 하나로 분기한다.
| 답변 유형 | 다음 행동 |
|---|---|
| 2강 사이트 있음 + 분야 명확 | 그 사이트 맥락에 맞는 회원기능/AI 코너 방향 제안 |
| 사이트는 있지만 방향 불확실 | "이 사이트에서 로그인한 사람이 무엇을 할 수 있으면 좋겠어요?" 질문 |
| 새로 만든다 / 잘 모르겠어 | 사이트 분야 먼저 묻고 3가지 후보 제안 |
| 기능 아이디어가 이미 있음 | 곧바로 상세 명확화 질문으로 |
2. 회원기능 방향 명확화
아래 순서로 가장 불확실한 항목 하나만 골라 질문한다. 이미 답한 내용은 다시 묻지 않는다.
- AI 코너의 역할: 이 사이트에서 AI가 무엇을 해주면 좋겠는가? (Q&A 봇, 추천, 요약, 글쓰기 도우미, 전문 상담 등)
- 저장 데이터: 로그인한 사람이 남기는 데이터는 무엇인가? (대화 내역, 메모, 즐겨찾기, 리뷰, 설문 응답 등)
- 로그인 방식: Google 로그인, 이메일/비밀번호 중 무엇을 쓸 것인가? (둘 다 원하면 둘 다 가능)
- 접근 권한: 로그인 안 해도 볼 수 있는 페이지와, 로그인해야만 쓸 수 있는 기능을 구분할 수 있는가?
- AI 프롬프트 방향: AI가 특정 역할을 맡기를 원하는가? (예: "당신은 요가 강사입니다. 질문에 요가 관점에서 답하세요.")
- 데이터 공개 범위: 저장된 데이터는 나만 볼 수 있으면 되는가, 아니면 다른 사람도 볼 수 있어야 하는가?
- 수업 MVP: 2시간 안에 완성해야 할 최소 기능은 무엇인가?
3. "잘 모르겠어" / 아이디어 없는 경우
상대가 부담 없이 답할 수 있는 질문부터 시작한다.
추천 첫 질문:
어떤 분야의 사이트인가요? 예를 들어 포트폴리오, 강의/코칭, 음식/레시피, 운동/건강, 취미 커뮤니티, 내 가게 소개 중 하나라도 해당되시면 알려주세요.
정보가 충분해지면 3가지 후보를 제안한다.
이런 사이트라면 다음 3가지 회원기능/AI 코너가 수업 안에서 만들기 좋습니다.
1. {아이디어 A}
- AI 역할: {예: "당신은 요가 강사입니다. 자세 교정 팁을 알려주세요"}
- 저장 데이터: {예: 대화 내역 + 저장한 팁}
- 테이블: {예: chat_logs(id, user_id, message, role, created_at)}
- 수업 MVP: {예: 로그인 후 AI와 대화, 대화가 내 계정에 저장}
2. {아이디어 B}
...
3. {아이디어 C}
...
이 중 하나를 고르거나 섞어서 가볼까요?
기능 후보 예시 (사이트 분야별)
| 사이트 분야 | AI 역할 예시 | 저장 데이터 예시 |
|---|---|---|
| 포트폴리오/프리랜서 | "당신의 포트폴리오를 보고 견적/협업 가능성을 안내하는 어시스턴트" | 문의 내역, AI 대화 |
| 강의/코칭 | "수업 내용 Q&A 봇, 학습 질문에 친절히 답변" | 질문 내역, 북마크 |
| 음식/레시피 | "재료를 입력하면 레시피 추천, 칼로리 계산" | 저장된 레시피, 대화 |
| 운동/건강 | "운동 루틴 추천, 식단 조언 봇" | 운동 기록, AI 상담 내역 |
| 취미 커뮤니티 | "취미 관련 Q&A, 입문자 안내 봇" | 내 포스트, 좋아요 |
| 내 가게/서비스 | "상품/서비스 Q&A 봇, 예약 안내" | 문의 내역, 관심 상품 |
보안 원칙 설명 스크립트
참여자가 API 키나 보안에 대해 물으면 아래처럼 설명한다.
Gemini API 키는 브라우저(프론트엔드) 코드에 절대 두면 안 됩니다. "소스 보기"로 누구나 읽을 수 있어서, 내 quota와 요금을 다른 사람이 쓸 수 있습니다. 대신 Next.js API Route(서버 코드)를 만들고, 브라우저는 그 서버에 요청합니다. 키는 .env 파일에만 보관하고 GitHub에 올리지 않습니다. 코딩 에이전트에게 "API 키는 서버에서만 사용하고 브라우저에 노출되지 않게 해줘"라고 명시하면 알아서 해줍니다.
RLS 설명 스크립트:
RLS(Row Level Security)는 DB 행 단위 보안입니다. 켜지 않으면 로그인한 누구나 다른 사람 데이터를 조회할 수 있습니다. "user_id = auth.uid() 인 행만 허용"이라는 정책을 추가하면, 내가 저장한 행만 내게 보입니다. 반드시 켜야 합니다.
질문 템플릿
질문은 매번 아래 구조를 간단히 유지한다.
현재 이해: {지금까지 파악한 내용 한 줄}
막힌 결정: {지금 정해야 다음으로 갈 수 있는 한 가지}
추천 방향: {있으면 제안. 없으면 생략}
질문: {단 하나의 질문}
종료 기준
아래가 채워지면 인터뷰를 멈추고 회원기능 Brief를 출력한다.
- 사이트 설명 (한 문장)
- 회원기능의 한 문장 컨셉
- 저장할 데이터와 테이블 구조 초안
- 로그인 방식 (Google / 이메일 / 둘 다)
- AI 코너의 역할과 프롬프트 방향
- RLS 정책 (누가 무엇을 볼 수 있나)
- 서버 API route 역할 (키 숨김 방식)
- 수업 MVP와 stretch goal
최종 출력 형식
인터뷰가 충분하면 아래 형식으로 끝낸다.
# 회원기능 Brief — {사이트명 또는 기능명}
## 1. 무슨 회원기능/AI 코너인가
{한 문장 컨셉: 어떤 사이트에 어떤 회원기능/AI 코너를 붙이는가}
**사이트**: {기존 사이트 또는 스타터}
**핵심 가치**: {로그인된 사용자가 얻는 것}
## 2. 저장할 데이터 (테이블·컬럼 초안)
```sql
-- 예시
CREATE TABLE chat_logs (
id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
user_id uuid REFERENCES auth.users(id) NOT NULL,
role text NOT NULL, -- 'user' | 'assistant'
content text NOT NULL,
created_at timestamptz DEFAULT now()
);
```
- 테이블명: {테이블명}
- 주요 컬럼: {컬럼 목록}
- user_id: auth.users(id) 참조 — 반드시 포함
## 3. 로그인 방식
- [ ] Google 소셜 로그인 (`signInWithOAuth({ provider: 'google' })`)
- [ ] 이메일/비밀번호 (`signInWithPassword`)
- 선택: {위에서 체크한 방식}
## 4. 외부 API 용도와 프롬프트 방향
- **API**: Google Gemini (gemini-2.0-flash, 무료 quota)
- **역할**: {예: 사이트 주제 관련 Q&A 봇}
- **시스템 프롬프트 방향**:
```
{예: 당신은 {사이트명}의 전문 어시스턴트입니다. 사용자의 질문에 친절하고 간결하게 답변하세요. {특수 지시사항 있으면 추가}}
```
## 5. RLS 정책 (누가 무엇을 보나)
```sql
-- RLS 활성화
ALTER TABLE {테이블명} ENABLE ROW LEVEL SECURITY;
-- 내 행만 SELECT
CREATE POLICY "본인 행만 조회"
ON {테이블명} FOR SELECT
USING (user_id = auth.uid());
-- 내 행만 INSERT
CREATE POLICY "본인만 삽입"
ON {테이블명} FOR INSERT
WITH CHECK (user_id = auth.uid());
```
- **읽기**: 본인(user_id = auth.uid()) 행만
- **쓰기**: 본인만 insert 가능
- {공개 데이터가 있으면 별도 정책 추가}
## 6. 서버 API Route 설계 (키 숨김)
```
app/api/chat/route.ts — POST 요청, 브라우저 → 서버 → Gemini
```
- 브라우저: `fetch('/api/chat', { method: 'POST', body: JSON.stringify({ message }) })`
- 서버: `.env`의 `GEMINI_API_KEY` 로 Gemini 호출 (클라이언트에 절대 노출 안 됨)
- `.env` 변수명: `GEMINI_API_KEY` (NEXT_PUBLIC_ 접두어 없이 — 서버 전용)
## 7. 코딩 에이전트 첫 프롬프트
```text
아래 회원기능 Brief를 바탕으로 기능을 구현해줘.
[중요 보안 규칙]
- Gemini API 키는 절대 브라우저(프론트엔드) 코드에 두지 마. 반드시 Next.js API Route(서버)에서만 호출해.
- API 키는 .env 파일의 GEMINI_API_KEY 변수에만 보관해. NEXT_PUBLIC_ 접두어 쓰지 마.
- Supabase RLS를 반드시 활성화하고, "user_id = auth.uid()" 정책을 추가해.
- .env는 .gitignore에 포함되어 있는지 확인해.
{Brief 전체 붙여넣기}
```
## 8. 보안 체크리스트
- [ ] `GEMINI_API_KEY` 는 `.env`에만, `NEXT_PUBLIC_` 접두어 없음
- [ ] `.env` 가 `.gitignore`에 포함됨
- [ ] Supabase `anon key`는 `NEXT_PUBLIC_SUPABASE_ANON_KEY` (브라우저 노출 OK, RLS가 보호)
- [ ] `service_role key`는 서버 전용 변수에만 (사용 안 하면 아예 생략 권장)
- [ ] 모든 테이블에 RLS 활성화 확인
- [ ] 다른 계정으로 로그인해서 내 데이터가 보이지 않는지 테스트
- [ ] GitHub에 push 전 `.env` 파일 포함 여부 확인
## 9. 수업 MVP vs Stretch
### MVP (2시간 목표)
- {예: 이메일 로그인/회원가입}
- {예: chat_logs 테이블 + RLS 설정}
- {예: Gemini API Route 서버 구현}
- {예: 챗봇 UI + 대화 저장}
- {예: Vercel 배포 및 환경변수 설정}
### Stretch (시간이 남으면)
- {예: Google 소셜 로그인 추가}
- {예: 대화 내역 목록 페이지}
- {예: 특정 대화 삭제 기능}
- {예: AI 응답 스트리밍}
금지/주의
- "Gemini API 키를 클라이언트에 두어도 된다"고 절대 말하지 않는다.
NEXT_PUBLIC_GEMINI_API_KEY형태를 절대 제안하지 않는다.- RLS 없이 Supabase를 쓰는 방식을 정상 패턴으로 제안하지 않는다.
service_role키를 브라우저 코드에 두는 방식을 제안하지 않는다.- 결제, 관리자 권한 관리, 복잡한 인증(MFA, SSO)을 수업 MVP에 포함한다고 약속하지 않는다.
- 최종 브리프는 Claude Code와 Codex 모두에 붙여 넣어도 이해 가능한 일반 Markdown으로 작성한다.