Phase 1.0 BUILD 시작 + API 4개 인증
매일 코드 + LogOnTable + MCP + Agent Teams의 28일 여정 시작
📑 이 챕터에서 다룰 내용
- 권2 서문 — 권1에서 권2로
- 0-1. Phase 1.0 4주 구조 — 28일 한 페이지
- 0-2. 매일 양식 — BUILD.md 5분 entry
- 0-3. MCP 활용 — 매일 시간 절감
- 0-4. Agent Teams 적용 시점 — Day 5+
- 0-5. E4 LogOnTable 매일 — 4 요소 표준화
- 0-6. E2 매일 페이스 점검 — 누적 시간 자동 추적
- 1-1. Day 1 — 공공데이터 API 4개 인증
- 1-2. Day 2 — API 호출 테스트 + 응답 sample 저장
- 1-3. Day 3 — LLM 분류 prompts.ts + 첫 5건 자동 분류
- 1-4. Day 1~3 누적 — 첫 LogOnTable 6 트레이스
- 📌 챕터 정리
권1 (Phase 0)이 21시간으로 완성됐습니다. 5파일+ 체계가 가동되고, 5확장 5개가 등장했고, READY: YES를 받았습니다.
이제 코드 작업이 시작됩니다 — 권2 Phase 1.0 BUILD. 권1과 다른 톤이 시작됩니다.
| 권 | 본질 | 문서 패턴 |
|---|---|---|
| 권1 (Phase 0) | "무엇·언제·READY" (메타·계획) | SPEC·PLAN·REVIEW 만드는 자리 |
| 권2 (Phase 1.0) | "매일 코드 + LogOnTable" (실행) | BUILD.md 매일 갱신·코드 트레이스 |
| 권3 (Phase 1.1 + 출시) | "통계·알림·심사·커뮤니티" (마무리) | BUILD 마지막 + 외부 노출 |
권2는 28일 (Phase 1.0). G1 (Day 7) + G2 (Day 28) 두 게이트.
권1 제7장 끝에서 git tag v0.1-phase0-completed가 박혔습니다. 이제 매일 펼치는 챕터들이 시작됩니다. 이 첫 챕터는 권2 28일 동안 어떻게 일할 것인가의 가이드입니다. 매일 무엇을 펼치고, 무엇을 적고, 어떻게 게이트를 통과하는지 안내합니다.
- 사전 지식: 권1 (Phase 0) 완성 / git tag v0.1-phase0-completed
- 이 장의 목적: Phase 1.0 28일의 매일 양식 + G1·G2 게이트 흐름 + MCP·Agent Teams·E4·E2 운영 매뉴얼
- 완료 후 결과물: Phase 1.0 첫째 날 시작 준비 완료
┌──────────────────────────────────────────────────────────────┐ │ 1주차 (Day 1~7) — G1: API 4개 + 시딩 20개 │ │ Day 1: API 4개 인증 신청 (개발계정 30분 자동승인) │ │ Day 2: API 호출 테스트 + 응답 sample 저장 │ │ Day 3: LLM 분류 prompts.ts + Haiku 첫 5건 분류 │ │ Day 4: 시딩 데이터 20개 검수 (수동) + confidence 분포 확인 │ │ Day 5: G-1 LLM JSON fallback + raw_response 보존 │ │ Day 6: G1 통과 조건 점검 + 문서화 │ │ Day 7: G1 통과 의식 (git tag + 휴식 의무) │ ├──────────────────────────────────────────────────────────────┤ │ 2주차 (Day 8~14) — Supabase 프로젝트 + 핵심 SQL │ │ Day 8: Supabase 프로젝트 + 4 테이블 SQL + IP rate limit Redis│ │ Day 9: trigger 3개 (jupjups 집계 / IP rate / is_active) │ │ Day 10: 복합 인덱스 (P1) + benefits seed 20개 INSERT │ │ Day 11: pg_cron 매일 03:00 정상 (4 API 호출) │ │ Day 12: 어드민 검수 큐 페이지 (Day 5 LLM JSON fallback 결과)│ │ Day 13: 운영자 검수 SLA 7일 알림 (cron 매일 09:00) │ │ Day 14: 운영자 페이스 점검 ★ (E2 누적 시간 & 회고) │ ├──────────────────────────────────────────────────────────────┤ │ 3주차 (Day 15~21) — 카카오 인증 + 닉네임 + FCM │ │ Day 15: 카카오 로그인 + access·refresh 토큰 자동 갱신 │ │ Day 16: 닉네임 자동 부여 (형용사 풀 20개+ + fallback) │ │ Day 17: FCM 토큰 발급·만료 처리 │ │ Day 18: User profile 자발적 필터 (소상공인 / 개인) │ │ Day 19: 어드민 페이지 (검수 + 신고 처리 SLA 24h) │ │ Day 20: 신고 처리 자동 알림 │ │ Day 21: 토요일 작업 X (E2 의식) │ ├──────────────────────────────────────────────────────────────┤ │ 4주차 (Day 22~28) — G2: DB·인증·pg_cron 완성 │ │ Day 22~23: 통합 테스트 (4 테이블 + 트리거 + 카카오 + pg_cron)│ │ Day 24: 통계 조작 시도 시뮬 (UNIQUE + IP rate limit 검증) │ │ Day 25: G2 통과 조건 검증 (★ 페이스 점검 포함) │ │ Day 26: G-3 is_active 트리거 SQL 검증 │ │ Day 27: G2 통과 점검 (모든 항목 PASS) │ │ Day 28: G2 통과 의식 (git tag + 1일 휴식) │ └──────────────────────────────────────────────────────────────┘
24일 작업 + 4일 의식·휴식·점검 = 28일.
권1에서 사용한 양식이 그대로 이어집니다. BUILD.md에 매일 5분 양식 + LogOnTable 트레이스를 작성합니다.
## Phase 1.0 Day N (날짜) [계획] - [PLAN.md Day N 작업 항목 그대로] [실행] - [실제 산출물 — 코드 줄 수·파일·기능] [LogOnTable 트레이스] > 결정: [핵심 결정 한 줄] > 근거: [왜 그 결정인가] > 대안 비교: [다른 옵션과 트레이드오프] > 부작용: [부산물·미래 부담] [이슈] - [발생/해결, 없으면 "없음"] [누적 시간] [Phase 0 21h] + [Phase 1.0 누적] = [총합] [E2 페이스 점검] - 누적 시간 60h 트리거 거리: [Xh 여유] - 토요일 작업 X 준수 - 주간 회고: 일요일 30분
매일 4시간 일하면 그 중 5분만 BUILD.md 갱신합니다. 그러나 그 5분이 6개월 후 동업자가 펼치는 답 + R4 1인 번아웃 트리거 자동 감지 + 권3 회고 자료가 됩니다.
5분 × 28일 = 약 2.3시간. 2시간으로 28일 운영 매뉴얼이 박힙니다.
1탄 v2 새 14장에서 본 MCP가 권2부터 작동합니다.
줍줍 권2의 MCP 조합 (3개 필수)
[필수 3개] - Supabase MCP: DB 자연어 조작 (Day 8 이후 매일) - GitHub MCP: commit + PR 자동 (매일) - Playwright MCP: E2E 테스트 (Day 14·21·28 게이트) [선택 1개 — 출시 전 도입] - Slack MCP: 운영 알림 (Day 19~)
MCP 시간 절감 측정
| 작업 | MCP 없이 | MCP 있을 때 | 절감 |
|---|---|---|---|
| DB 조회 | 3분 (Supabase 대시보드) | 10초 (자연어) | -90% |
| commit | 2분 (수동) | 5초 (자연어) | -95% |
| E2E 테스트 | 5분 (Playwright 직접) | 30초 (자연어) | -90% |
| 매일 약 | 30~50분 | MCP 활용 | -80% |
권2 끝 (Day 28)까지 누적 약 24시간 절감. R4 1인 번아웃 핵심 완화책입니다.
권2의 Agent Teams 적용은 Day 5+부터. 처음 4일 (Day 1~4)은 순차 작업을 권장합니다. 이유: BUILD 첫 흐름 이해가 우선이기 때문입니다.
CLAUDE.md §6 File Structure 분배 기준
src/ app/(tabs)/business/ ← 에이전트 A (소상공인) app/(tabs)/individual/ ← 에이전트 B (개인 복지) components/ ← 공통 (직접 수정) lib/ ← 공통 (직접 수정) api/ ← 에이전트 C (Day 8 이후 가능) tests/ ← 통합 단계
Agent Teams 적용 vs 순차 결정 트리
질문 1: 작업 A의 결과를 작업 B가 기다려야 하는가? YES → 순차 (독립성 X) NO → 다음 질문 질문 2: A·B가 서로 다른 폴더를 수정하는가? YES → Agent Teams 가능 NO → 순차 (충돌 위험) 질문 3: 각 작업이 30분+ 걸리는가? YES → Agent Teams 효율 NO → 순차 (위임 비용 > 절감)
3 질문 모두 YES일 때만 Agent Teams. 한 번이라도 NO면 순차입니다.
권2부터 LogOnTable이 매일 등장합니다. 권1의 제0~7장에 흩어진 7 트레이스가 매일 1~3 트레이스로 증가합니다.
4 요소 작성 표준화
| 요소 | 길이 | 내용 |
|---|---|---|
| 결정 | 1줄 | 핵심 결정 짧게 |
| 근거 | 1~2줄 | 왜 그 결정인가 (SPEC §·PLAN·CLAUDE §·표준 도구 매핑·1탄 v2 챕터 등 인용) |
| 대안 비교 | 1~3줄 | 다른 옵션과 트레이드오프 |
| 부작용 | 1줄 | 부산물·미래 부담 |
6개월 후 비개발자 동업자가 BUILD.md를 펼치면 약 100~200개 트레이스 (권2+권3 합계)가 있습니다. 동업자가 "왜 jupjups 테이블에 UNIQUE 제약?" 질문하면 Day 8 트레이스에 답이 있습니다.
매일 5분이 "인수인계 매뉴얼"의 본질입니다.
권1 제6장에서 박힌 R4 (1인 번아웃) 트리거 4가지가 매일 점검됩니다.
[BUILD.md 매일 entry 끝에] [E2 페이스 점검] - 누적 시간: [Phase 0 21h] + [Phase 1.0 누적 Xh] = [Total] - 60h/4주 트리거 거리: [Yh 여유] - 토요일 작업 X: [Day 21·28 점검] - 주간 회고 (일요일 30분): [Day 7·14·21·28 작성 의무] [트리거 발생 시] [ ] 누적 60h+/4주 [ ] 회고 부재 2주+ [ ] 토요일 4주 연속 [ ] "피곤하다" BUILD.md 회고 등장
위 4 트리거 중 하나라도 발생 시 → 즉시 1일 휴식 + 다음 주 목표 25% 축소.
게이트 통과 의식 의무
G1 (Day 7) 통과 후: - git tag v0.1-G1-passed - 1일 휴식 (Day 8 휴식 또는 Day 7 일요일 휴식) - 1주차 회고 (BUILD.md 1KB+) G2 (Day 28) 통과 후: - git tag v0.1-G2-passed - 1일 휴식 (Day 29) - 4주 회고 (BUILD.md 2KB+, 큰 회고)
📌 제0장 정리
- 권2 = 매일 코드 + LogOnTable + MCP + Agent Teams + E4·E2 운영. 28일 (G1·G2 두 게이트)
- 4주 구조: 1주차 (G1 D7) API + 시딩 / 2주차 Supabase + SQL / 3주차 카카오 + FCM / 4주차 (G2 D28) 통합 테스트
- 매일 5분 양식: 계획 + 실행 + LogOnTable + 이슈 + 누적 + 페이스
- MCP 조합: Supabase + GitHub + Playwright (필수 3개) + Slack (Day 19~ 선택)
- Agent Teams: Day 5+ 시작. CLAUDE.md §6 폴더 구조가 분배 기준
- E4 매일: 4 요소 트레이스 (결정·근거·대안·부작용). 권2 누적 40~50개 예상
- E2 매일 점검: 4 트리거 자동 + 2번 게이트 휴식 + 4번 주간 회고
이 장이 줍줍의 첫 실제 코드 작업 자리입니다. Day 1~3은 외부 의존성 (공공데이터 API 4개)부터 시작합니다 — 가장 위험한 부분을 먼저 처리합니다.
- 사전 지식: 권1 + 권2 제0장 / Claude Code 실행 + 5파일 모두 / data.go.kr 가입 의도
- 이 장의 목적: Day 1 (API 4개 인증) + Day 2 (호출 테스트) + Day 3 (LLM 분류 prototype)
- 완료 후 결과물: API 4개 인증키 (.env.local) + 응답 sample 4개 + LLM 분류 prompts.ts + 첫 5건 자동 분류
작업 시작
cd jupjup git status # 깨끗한 상태 확인 cat REVIEW.md | tail -3 # READY: YES 확인 claude /model claude-sonnet-4-6 # BUILD는 Sonnet (1탄 v2 새 28장) /effort medium /context # 5파일 + MCP 활성 확인
4 API 인증 신청 — data.go.kr 통합 진행
"4 API 인증 신청 가이드를 단계별로 줘. data.go.kr·기업마당·중소벤처24· 복지로 (중앙·지자체) 4개. 각각의 가입·활용신청·키 받는 시간을 명시. CLAUDE.md §3 Critical Constraints 준수 — 키는 .env.local에만, GitHub 노출 X."
Claude (Sonnet) 응답 — 단계별 가이드
data.go.kr → 회원가입 (개인·일반). 휴대폰 본인인증 또는 카카오 인증.
마이페이지 → 활용신청 → API 검색. 4개 신청: 기업마당 BizinfoApi / 중소벤처24 / 복지로 중앙부처 / 복지로 지자체
4개 모두 자동승인. 운영계정은 1~2일 소요 (배포 직전 신청).
키 받은 후 즉시 .env.local에 저장. .gitignore가 .env.local 차단하는지 확인합니다.
PUBLIC_DATA_BIZINFO_KEY=... PUBLIC_DATA_SMTECH_KEY=... PUBLIC_DATA_WELFARE_CENTRAL_KEY=... PUBLIC_DATA_WELFARE_LOCAL_KEY=...
ANTHROPIC_API_KEY 등도 같은 곳에 저장합니다. .env가 아니라 .env.local이 표준입니다 (Next.js / Expo 모두 동일).
.gitignore에 .env*, .env.local, .env.local.* 4개 패턴 확인 필수입니다.
Day 1 첫 LogOnTable
[LogOnTable 트레이스 ① — 첫 트레이스]
- 결정: data.go.kr 통합 게이트웨이 사용 (4 API 모두)
- 근거: 별도 가입 4번 X, 한 번의 회원가입으로 4 API 인증 가능
- 대안: 각 부처 사이트 직접 가입 — 인증 4번 + 키 관리 4번 = 부담
- 부작용: data.go.kr 장애 시 4 API 모두 영향. R7 리스크에 추가 트리거
[LogOnTable 트레이스 ② — .env.local 보안]
- 결정: 4 API 키를 .env.local에 저장 (커밋 X)
- 근거: CLAUDE.md §3 Critical Constraints 절대 준수
- 부작용: 운영계정 발급 시 새 키 4개 추가 (Day 60~ EAS Secrets 분리)
누적: Phase 0 21h + Phase 1.0 Day 1 1.5h = 22.5h
git add .gitignore # .env.local 추가됐는지 확인 (수정 없으면 스킵) git commit --allow-empty -m "Phase 1.0 Day 1: 4 API 개발계정 인증 + .env.local"
"4 공공데이터 API 호출 테스트 스크립트 작성 + 응답 sample 4개 저장. 요구사항: 1. lib/api/test-fetch.ts (4 API 각각 fetch 함수) 2. tests/api-samples/ 폴더에 응답 raw JSON 4개 저장 3. CLAUDE.md §3 — process.env 키 사용 4. 에러 처리 (try/catch + Sentry 호환 구조 — 실제 Sentry는 Day 56) 5. JSON.parse 실패 시 raw text 보존"
Claude가 작성한 lib/api/test-fetch.ts (약 80줄)
// lib/api/test-fetch.ts
// 4 공공데이터 API 호출 테스트
interface ApiSample {
source: string;
url: string;
count: number;
raw_response: any;
parse_success: boolean;
error?: string;
}
const API_KEYS = {
bizinfo: process.env.PUBLIC_DATA_BIZINFO_KEY!,
smtech: process.env.PUBLIC_DATA_SMTECH_KEY!,
welfare_central: process.env.PUBLIC_DATA_WELFARE_CENTRAL_KEY!,
welfare_local: process.env.PUBLIC_DATA_WELFARE_LOCAL_KEY!,
};
export async function testFetchAll(): Promise<ApiSample[]> {
const results: ApiSample[] = [];
for (const [source, url] of Object.entries(ENDPOINTS)) {
try {
const fullUrl = `${url}?serviceKey=${encodeURIComponent(key)}&numOfRows=5&type=json`;
const resp = await fetch(fullUrl, {
method: 'GET',
headers: { 'Accept': 'application/json' },
});
const text = await resp.text();
let raw_response: any;
let parse_success = true;
try {
raw_response = JSON.parse(text);
} catch {
raw_response = text; // raw text 보존 (G-1 fallback 패턴)
parse_success = false;
}
results.push({ source, url, count, raw_response, parse_success });
} catch (err: any) {
results.push({
source, url, count: 0,
raw_response: null,
parse_success: false,
error: err.message,
});
}
}
return results;
}
실행 결과 (실제 호출)
- ✓ bizinfo: 5 items, parse_success
- ✓ smtech: 5 items, parse_success
- ✓ welfare_central: 5 items, parse_success
- ⚠️ welfare_local: 5 items, parse_success — but XML 형식 (JSON 아님)
G-1 (LLM JSON fallback)이 즉시 의미 있어집니다. welfare_local API가 XML 응답하는 경우 발견 — Gemini가 선견적으로 잡은 영역입니다.
[LogOnTable 트레이스 ① — Gemini의 선견 입증]
- 결정: welfare_local API XML fallback — Day 3 LLM 분류 prompts.ts에 "raw text 처리 분기" 추가
- 근거: 권1 제2장 Gemini G-1 (LLM JSON fallback)의 "실제 발생". SPEC v4 §3-2의 fallback 명세가 사용 직전에 입증됨
- 부작용: prompts.ts에 if-else 분기 추가 (XML → text → LLM 분류)
누적: 22.5h + Day 2 (2h) = 24.5h
Claude가 작성한 lib/parser/prompts.ts (약 90줄)
export const SYSTEM_PROMPT_BUSINESS = `
당신은 정부 지원사업 공고를 분석하는 전문가입니다.
아래 공고 원문을 읽고, 반드시 JSON 형식으로만 응답하세요.
JSON 외의 설명, 마크다운, 백틱은 절대 포함하지 마세요.
추정하지 마세요. 정보가 없으면 null로 표시하세요.
[출력 스키마 — 소상공인 타겟]
{
"name": "사업명",
"support_type": "GRANT | LOAN | CONSULTING | SPACE",
"target_business_type": "식당/카페 | 도소매 | 제조업 | ...",
"target_stage": "창업준비 | 1년미만 | 3년미만 | ...",
"deadline": "YYYY-MM-DD 또는 null",
"confidence": 0.0
}
`;
Claude가 작성한 lib/parser/classify.ts (약 70줄)
export async function classifyContent(
raw_content: string,
tab: 'business' | 'individual',
): Promise<ClassifyResult> {
const resp = await client.messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 1024,
system,
messages: [{ role: 'user', content: raw_content }],
});
// E5 [7] — JSON parse 실패 시 fallback
try {
const parsed = JSON.parse(text);
const confidence = parsed.confidence ?? 0;
// confidence 0.7 미만 → admin 큐 직행
if (confidence < 0.7) {
return { ...parsed, confidence, status: 'admin_queue', raw_response: text };
}
return { ...parsed, confidence, status: 'auto_active', raw_response: null };
} catch {
return { confidence: 0, status: 'admin_queue_parse_failed', raw_response: text };
}
}
첫 분류 실행 결과
- "수원시 카페 청년 지원금" → confidence 0.85, auto_active ✓
- "전국 소상공인 컨설팅 지원" → confidence 0.79, auto_active ✓
- "서울시 중장년 창업 자금" → confidence 0.72, auto_active ✓
- "광역지자체 음식점업 시설 개선 보조" → confidence 0.65, admin_queue
- "일반 사업자 정책자금 안내" → confidence 0.45, admin_queue
3건 auto_active + 2건 admin 큐. SPEC v4 §3-2의 "confidence 0.7 미만 → admin 큐"가 작동 입증됐습니다.
[LogOnTable 트레이스 ① — 환각 방지 명세]
- 결정: 두 시스템 프롬프트에 "추정 X, 누락 null" 명시 + JSON 외 X
- 근거: SPEC v4 §3-2 (E5 [7]) 코드 적용. 첫 5건 분류에서 입력에 없는 필드는 null로 처리됨
- 부작용: confidence < 0.7인 2건 admin 큐 — Day 12 어드민 페이지 작업과 직결
[LogOnTable 트레이스 ② — Haiku 4.5 비용]
- 결정: Haiku 4.5 사용 (분류 단순 작업)
- 근거: 1탄 v2 새 28장 비교 우위 표 — 단순 분류는 Haiku 자리. Sonnet 비용의 1/4. 월 1,500건 약 $1.5
- 부작용: 복잡한 한국어 공고 시 confidence 낮아질 수 있음 → admin 큐로 자연 처리
누적: 24.5h + Day 3 (3h) = 27.5h
권1 (Phase 0) 7 트레이스 + 권2 Day 1~3 6 트레이스 = 13 트레이스
매 트레이스가 "왜 그 결정인가" + "근거" + "대안" + "부작용" 4 요소로 구성됩니다.
권2 28일 끝 시점 누적 약 50개 트레이스 예상. 6개월 후 동업자가 펼치는 답입니다.
📌 권2 제1장 정리
- 핵심: Day 1~3 = API 4개 인증 + 호출 테스트 + LLM 분류 prototype. 첫 5건 분류 (3 auto + 2 admin) 성공
- Day 1 — API 4개 인증: data.go.kr 통합 게이트웨이, 30분 안에 개발계정 4개, .env.local 보안
- Day 2 — 호출 테스트: lib/api/test-fetch.ts (80줄), 4 API sample, welfare_local XML 응답 발견 → G-1 입증
- Day 3 — LLM 분류: prompts.ts (90줄, E5 [4]), classify.ts (70줄, E5 [7]), 첫 5건: 3 auto + 2 admin
- 누적 시간: 27.5h (Phase 0 21h + Day 1~3 6.5h)
- R4 트리거 거리: 60h - 27.5h = 32.5h 여유 (1주차 안전)
4 API 인증 + 호출 테스트 + LLM 분류가 6.5시간 안에 완성됐습니다. SPEC v4의 메타 명세가 코드에서 입증되기 시작했습니다 — Gemini의 G-1 (XML fallback)이 Day 2에 즉시 의미 있어졌고, E5 [4] [7]이 Day 3에 작동했습니다.
LogOnTable 트레이스 6개가 BUILD.md에 박혔습니다. 6개월 후 동업자가 "왜 data.go.kr 통합 게이트웨이?" 또는 "왜 Haiku?" 펼치면 본문에 답이 있습니다.