KCH그룹 인사총무팀 AX 파일럿 교육

KCH그룹 인사총무팀 AX 파일럿 교육

Claude Code CLI 자력 운전 + 본인 손으로 배포한 모듈 URL 1개 — 4명·4모듈·1대시보드

총 840분(14h) · 2026-05-07 (목) ~ 05-08 (금) 09:30~17:30 · 강사 김혜련(Kyra Kim)

김혜련 (Kyra Kim)

SPEAKER

김혜련 Kyra Kim · 이노핏파트너스 프로젝트 교수

『당신의 첫 AI 직원』 저자 · GPTers 스터디장 · 100X.MONSTER 운영

강사 소개 →

D1 + D2 14h 타임라인

5minCH0오프닝
85minCH1환경+MCP
60minCH2IEPR
90minCH3IPO
90minCH4첫배포
90minCH5AI Studio
150minCH6본모듈
120minCH7자동화
90minCH8통합
60minCH9클로징

공통 진행안

참가자별 셋업 메뉴

Appendix · 사전 환경 셋업

D1 시작 전(2026-05-07 09:30 이전) 본인 PC에서 1회만 실행. 워크숍 끝까지 계속 쓰입니다.

CH00 개요 D1 09:30~09:35 · 5분

오프닝 — 14h 동안 무엇을 손에 쥐는가

오늘은 자동화 툴 강의가 아닙니다. Claude Code CLI를 4명이 자력으로 운전하는 14시간입니다.

읽기 5분·업데이트: 2026-05-05
0114h의 한 줄 약속1/5

이 워크숍은 단 한 가지를 약속합니다 — 14시간이 끝났을 때 4명 모두 본인 손으로 배포한 모듈 URL 1개가 살아 있어야 합니다.

"강의를 들었다"가 아니라 "본인 손으로 만들어 배포했다"입니다. 듣기만 한 강의는 일주일이면 잊히지만, 본인이 직접 키보드를 두드려 만든 것은 30일 후에도 손에 남습니다.

IMPORTANT — 퇴실 시 손에 쥐는 것 4가지
  1. 본인 PC에서 claude 한 글자로 페어 프로그래밍 진입할 수 있는 환경
  2. Firebase App Hosting 공개 URL 1개 — 실 데이터(익명화)가 흐르고 자동화 게이트 1개가 살아 있는 상태
  3. 본인 repo의 CLAUDE.md + 슬래시커맨드 1개
  4. 30/60/90일 자력 로드맵 메모

14h는 두 가지로 나뉩니다. D1은 4명이 같은 페이스로 "기본 틀"을 한 사이클 같이 돕니다 (환경 셋업부터 첫 배포까지). D2는 본인 모듈을 자력으로 채우는 본 게임입니다.

024명·4모듈·1대시보드2/5

KCH그룹이 의뢰한 6대 산출물 중에서, 14h 안에 가장 동작 가능성이 높은 4개를 골라 4명이 분담합니다. 한 모듈씩 자유롭게 고른 게 아니라, 각자 사전설문에서 가장 강하게 원했던 영역을 매칭한 결과입니다.

참가자모듈메인 산출물자동화 게이트
이재성M2연차 자동 산출 (getLeaves(empId))Cloud Scheduler 분기 메일
김경호M3성과급/연봉 자동 산출 + KPI 수집onEvalFinalized Cloud Function
이동연M1휴양시설 5지역 + 시드 추첨Cloud Scheduler 시즌 알림
이윤재M4사내 도구 카탈로그 + 통합 인덱스일별 헬스체크 + Slack
NOTE — 이윤재 모듈의 추가 역할

다른 3명의 모듈도 결국 "사내 도구"이기 때문에, 이윤재의 M4 사내 도구 카탈로그는 자연스럽게 메인 페이지의 인덱스 역할을 겸합니다. Day 2 #8 통합 시점에 4명 URL을 이윤재 app/page.tsx에 등록하면, 그게 "통합 대시보드"가 됩니다.

"자동화 게이트"가 무엇인가요

각 모듈마다 시간이 흘러가면 자동으로 발화하는 함수 1개가 들어갑니다 (cron으로 정해진 시간에 실행되거나, 데이터가 바뀔 때 자동으로 트리거). 이 게이트가 살아 있다는 게 본 모듈이 살아 있다는 증거입니다 — 사람이 손으로 매번 호출하지 않아도 시스템이 스스로 돌아가야 진짜 자동화입니다.

03본질 — CLI 자력 운전3/5
IMPORTANT

Claude Code CLI를 4명이 자력으로 운전 → AI 페어 프로그래밍 체화. 14h 끝에 각자 본인 손으로 배포한 기능 1개 이상 작동.

"Claude Code CLI"가 무엇인가요

Claude Code는 Anthropic이 만든 CLI(터미널) 기반 AI 페어 프로그래밍 도구입니다. 본인 노트북에 깔아두고 claude 한 글자만 치면, 현재 폴더(=본인 모듈 코드 전체)를 맥락으로 들고 같이 일하는 에이전트가 켜집니다.

챗봇과 다른 점은 본인 코드를 매번 복붙해 넣지 않아도 된다는 것입니다. 챗봇은 "이 파일이랑 이 파일을 보면…"으로 매번 맥락을 다시 짜야 하지만, CLI는 폴더 전체를 이미 알고 있는 상태에서 "이거 해줘"가 가능합니다.

Stack — 14h 동안 쓰는 도구 세트

VS Code (코드 편집기) └─ Claude Code CLI (메인 — 모든 작업의 시작점) ├─ Firebase MCP (Claude가 Firestore를 직접 조작하는 다리) └─ GitHub MCP (Claude가 GitHub 이슈·커밋을 직접 조작하는 다리) Google AI Studio (D1 #5 프론트 모형용) GitHub (개인 repo 1개씩) Firebase (Firestore + Auth, 한국 리전 asia-northeast3) Firebase App Hosting (Next.js 앱을 git push 한 번에 공개 URL로 띄워주는 서비스)

Claude 앱(데스크탑/웹)은 보조 — Plan 모드 시연이나 이론 검색용으로만 가끔 쓰고, 메인 작업은 모두 CLI에서 합니다.

0414h 시간표 한 장4/5

Day 1 (목, 09:30~17:30) — 진입 + 메타스킬 + 기본 틀 한 사이클

D1은 4명이 같은 페이스로 환경부터 첫 배포까지 한 바퀴를 같이 돕니다. D1 #4 시점에 본인 URL 1개가 손에 있어야 D2가 굴러갑니다.

블록시간주제산출물
#109:35~11:00환경 셋업 + Firebase MCPclaude --version OK + Firebase 프로젝트
#211:00~12:00메타스킬 IEPR + 4단 질문M1~M4 4단 질문 워크시트
점심12:00~13:00
#313:00~14:30IPO 4섹션 작성본인 IPO 1차
#414:30~16:00첫 배포 (Firebase App Hosting)본인 URL 1개
#516:00~17:30AI Studio + KCH 컬러 강제 라인본인 모듈 시안

Day 2 (금, 09:30~17:30) — 본 모듈 작업 + 통합 + 발표

블록시간주제산출물
#609:30~12:00본 모듈 구현 1차 (Firestore + UI)본인 모듈 프론트 동작
점심12:00~13:00
#713:00~15:00실데이터 (익명화) + 자동화 게이트본인 모듈 v1
#815:00~16:30통합 인덱스통합 대시보드 1개 URL
#916:30~17:30발표 + 회고 + 30/60/90일 로드맵자력 로드맵 메모
05보안 안내 · 핵심 정리5/5

오늘 다룰 데이터는 모두 가상 더미입니다. 실 인사정보는 강의 후 마이그레이션 단계에서 들어옵니다. 단, 다음 원칙은 워크숍 14h 동안에도 그대로 강제됩니다 — 가상 데이터로 익혀둔 룰이 실 데이터에서도 그대로 작동하기 위해서입니다.

원칙무엇을 한다는 뜻인가
직원ID 토큰화"홍길동" → E001, "사번 12345" → E001. Firestore에는 토큰만 들어감
연봉 평문 저장 금지실 금액(예: 5,000만원)을 직접 저장 X. 토큰 ID로만 매핑
산출 룰은 Cloud Secret ManagerKCH 공식 인상률·기본급 같은 민감 값은 코드/.env에 절대 X
외부 API 호출 0건 (김경호 M3)산출 엔진은 사내 데이터만 사용. Claude API 호출은 워크숍 14h에서 제외
WARNING

Firestore에 데이터를 push하기 직전이 마지막 차단선입니다. Day 2 #7 시작 5분에 강사가 익명화 가드 함수(pushSafe)를 시연합니다 — 이 함수를 통과하지 않으면 push가 막히도록 강제하는 게 핵심입니다.

핵심 포인트

• 오늘 14h의 단일 목표 = CLI 자력 운전 + 본인 손으로 배포한 모듈 URL 1개

• 자동화 툴 강의가 아닌 AI 페어 프로그래밍 체화

• 4명·4모듈 → 이윤재 app/page.tsx에서 통합

• 인사정보 익명화·Secret Manager·외부 API 0건 — 3중 보안 게이트

• 본 교안과 본인 셋업 메뉴 2창 띄워서 진행

CH01 실습 D1 #1 · 09:35~11:00 · 85분

Part 1 — 환경 셋업 + Claude Code 첫 실행 + Firebase MCP

첫 90분의 단일 목표 — claude --version 응답 OK + 본인 Firebase 프로젝트 + Firebase MCP가 Firestore를 조작 가능한 상태.

읽기 14분·업데이트: 2026-05-05
01왜 이 90분이 가장 중요한가1/4

오늘 14h의 모든 후속 블록은 이 90분의 셋업 위에서 돕니다. 셋업이 완성되어야 다음이 됩니다.

  • CLI가 안 뜨면 → D1 #2 메타스킬은 듣기 강의가 됩니다 (실습 X)
  • Firebase MCP가 안 붙으면 → D1 #4의 첫 배포가 무너집니다
  • .gitignore 강제가 안 되어 있으면 → D2 #6에서 인사정보·키가 GitHub에 올라가는 사고

그래서 이 블록은 "셋업"이라는 이름이지만 실은 14h 전체의 안전 장치를 깔아두는 시간입니다. 오늘 가장 단순해 보이지만 가장 중요한 90분입니다.

IMPORTANT — 90분 안에 다음 6개 검증을 통과합니다
  1. node -v v20+ — Next.js 14가 요구하는 Node.js 버전
  2. git --version + GitHub 로그인 — 본인 repo를 clone·push할 수 있는 상태
  3. claude --version 응답 — Claude Code가 본인 PC에서 실행됨
  4. Firebase 프로젝트 생성 (한국 리전 — asia-northeast3)
  5. firebase login + firebase init — 본인 폴더에 Firestore + App Hosting 연결
  6. Firebase MCP가 Claude Code에서 동작 — Claude가 Firestore 컬렉션을 직접 조작 가능
02Part 2 · 도구 6종 진입 절차 (60분, 09:35~10:35)2/4

Step 1 — 기본 도구 6종 설치 검증 (15분)

VS Code · Git · Node.js 20+ · Claude Code · Firebase CLI · GitHub 계정. 이 6종이 본인 PC에서 정상 동작하는지 명령어로 확인합니다. 각 명령어는 "이 도구가 깔려 있는가"를 가장 가볍게 검증하는 방식입니다.

node -v # v20.x.x 이상이어야 함 (Next.js 14 요구사항) git --version # 2.40+ (대부분 시스템에 이미 있음) code --version # VS Code CLI — VS Code 메뉴 'Shell Command: Install code command'로 활성화

Claude Code 설치 (이미 설치되어 있으면 skip):

npm install -g @anthropic-ai/claude-code claude login # 브라우저가 열리면 Anthropic 계정으로 로그인 claude --version

claude login을 하는 이유 — Claude Code는 본인 Anthropic 계정의 API 사용량을 차감하는 방식으로 동작합니다. 로그인이 끝나면 본인 계정의 토큰이 본인 PC에 저장되어 매번 로그인할 필요가 없습니다.

Firebase CLI 설치:

npm install -g firebase-tools firebase login # 브라우저가 열리면 Google 계정으로 로그인

Step 2 — Firebase 프로젝트 생성 + 초기화 (20분)

이제 본인 인사총무 데이터를 담을 백엔드 프로젝트를 Firebase에 만듭니다. Firebase는 Google Cloud의 백엔드 서비스 묶음으로, 데이터베이스(Firestore) + 인증(Auth) + 배포(App Hosting) + 함수(Cloud Functions)를 한 프로젝트 안에서 같이 씁니다.

  1. Firebase 콘솔 (console.firebase.google.com) → "프로젝트 추가" → 이름 (예: kch-{본인이름영문}-pilot)
  2. 위치(리전): asia-northeast3 (서울) — 인사정보가 한국 밖으로 나가지 않도록 데이터 주권 강제
  3. Firestore 생성 — Native 모드 선택, 리전은 asia-northeast3 그대로
  4. Authentication 활성화 — Google 제공자 켜기. 도메인 lock은 코드에서 hd: 'kchglobal.co.kr'로 강제 (다른 도메인 계정 차단)
  5. App Hosting 활성화 — Next.js 프리셋 선택

본인 로컬에서 작업할 폴더를 만들고 firebase init:

mkdir kch-{이름}-{모듈} # 예: kch-mjs-leaves cd kch-{이름}-{모듈} firebase init # 선택 (스페이스로 다중 선택): # - Firestore # - Functions # - Hosting (App Hosting) # - Emulators # 프로젝트 = 위에서 생성한 프로젝트 선택

firebase init이 끝나면 본인 폴더에 firebase.json, firestore.rules, functions/, apphosting.yaml 같은 파일들이 생성됩니다. 이 파일들이 "이 폴더는 어떤 Firebase 프로젝트와 연결되어 있는가"를 기록합니다.

Step 3 — 강사 사전 push 자산을 본인 repo에 끌어오기 (15분)

본인 모듈 스타트는 빈 폴더가 아니라 강사가 미리 셋업해둔 템플릿에서 시작합니다. 4명이 같은 디자인 토큰·shadcn/ui 컴포넌트를 갖고 시작해야 D2 #8 통합 시점에 한 대시보드처럼 보이기 때문입니다.

  1. GitHub에서 템플릿 repo (kch-hr-module-template) 페이지로 이동 → "Use this template" 버튼 클릭 → 본인 repo 생성
참가자본인 repo 이름
이재성mjs-leaves
김경호kkh-performance
이동연moo-facilities
이윤재yyj-tools
  1. 본인 PC에 clone (= 본인 PC로 다운로드):
git clone https://github.com/{본인}/{repo이름}.git cd {repo이름} npm install # package.json에 적힌 의존 패키지 다운로드
  1. 템플릿에 어떤 자산이 들어 있는지 한 번 둘러봅니다. 이 자산들이 D1 #4 첫 배포의 베이스가 됩니다.
    • tailwind.config.ts — KCH 컬러 토큰 (#1962A8 / #70AEDA)이 Tailwind 변수로 미리 등록되어 있음
    • app/globals.css — Pretendard 폰트와 KCH 컬러 변수
    • components/ui/ — shadcn/ui Card·Badge·Tabs·DataTable 4종 컴포넌트
    • app/_template/page.tsx — 본인 모듈에 복붙해서 시작할 샘플 페이지
    • .mcp.json — Firebase MCP 설정 파일 (다음 §3에서 채움)
TIP

본 교안 옆에 셋업-{본인}-{모듈}.md 파일을 같이 띄워두고, §1의 사전 확정 항목을 정리해 둡니다. D1 #3 IPO 작성 때 그대로 쓰입니다.

03Part 3 · Firebase MCP 셋업 (25분, 10:35~11:00)3/4

여기가 이 90분에서 가장 중요한 단계입니다.

Firebase MCP가 무엇이고 왜 필요한가

Firebase MCP는 Claude Code가 Firestore에 직접 컬렉션·문서를 만들 수 있게 해주는 다리입니다. MCP가 없으면 Claude는 코드만 적어주고, 실제 Firestore 콘솔에 가서 컬렉션을 만들고 문서를 추가하는 건 본인이 해야 합니다 — 데이터 1건 넣는 데 클릭 5번씩.

MCP가 있으면 Claude에게 "이 컬렉션에 더미 50건 넣어줘"라고 한 줄만 시키면 됩니다. 워크숍 14h 동안 Firebase MCP는 가장 많이 쓰는 도구입니다.

Step 1 — 서비스 계정 키 발급

Claude가 본인 Firebase 프로젝트에 접근할 권한을 얻으려면 서비스 계정 키가 필요합니다. 이건 사람 계정이 아닌 "프로그램 계정"의 비밀번호 같은 것입니다.

  1. Firebase 콘솔 → 프로젝트 설정 (톱니바퀴) → 서비스 계정 탭 → "새 비공개 키 생성" 버튼
  2. 다운로드된 JSON 파일을 본인 repo 루트에 .firebase-mcp-key.json 이름으로 저장
  3. .gitignore 강제 확인 — 이 키 파일이 GitHub에 절대 올라가면 안 됩니다
# .gitignore에 다음 항목들이 있는지 확인 (대부분 템플릿에 이미 들어 있음) .firebase-mcp-key.json *adminsdk*.json serviceAccountKey.json .env .env.local .mcp.json
WARNING

이 JSON 파일은 절대 GitHub commit X. .gitignore 등록 후 git status로 추적되지 않는지 반드시 확인하세요.

만약 실수로 push되면 GitHub 캐시에 영구 남기 때문에, commit 이력에서 지워도 사실상 노출된 것으로 봐야 합니다 → 키를 즉시 재발급해야 합니다.

Step 2 — .mcp.json 설정

본인 repo 루트에 .mcp.json 파일을 만들고 다음 내용을 적습니다 (대부분 템플릿에 이미 있고, {본인-projectId} 슬롯만 본인 것으로 바꾸면 됩니다).

{ "mcpServers": { "firebase": { "command": "npx", "args": ["-y", "@gannonh/firebase-mcp"], "env": { "SERVICE_ACCOUNT_KEY_PATH": "./.firebase-mcp-key.json", "FIREBASE_STORAGE_BUCKET": "{본인-projectId}.appspot.com" } } } }

이 파일이 Claude Code에게 "이 폴더에서는 firebase라는 이름의 MCP 서버를 쓰고, 인증은 .firebase-mcp-key.json에 들어 있는 서비스 계정 키로 한다"를 알려줍니다. {본인-projectId}는 Firebase 콘솔의 프로젝트 ID(예: kch-mjs-leaves-pilot)로 교체합니다.

Step 3 — Claude Code 재시작 + MCP 인식 확인

.mcp.json이 변경되면 Claude Code를 재시작해야 새 설정이 반영됩니다.

# Claude Code 종료 후 재실행 claude

Claude Code가 켜지면 안에서 슬래시 명령으로 MCP 상태 확인:

/mcp list

결과에 firebase가 나와야 정상입니다. 안 나오면 .mcp.json의 JSON 문법 오류일 가능성이 높습니다 (콤마 빠짐, 따옴표 깨짐).

Step 4 — 첫 MCP 호출 (검증)

이제 Claude에게 첫 MCP 호출을 시켜봅니다. 다음 프롬프트를 그대로 복붙:

Firebase MCP를 사용해서 내 Firestore에 어떤 컬렉션이 있는지 확인해줘.

→ Claude가 firebase__list_collections 도구를 호출. 아직 컬렉션을 안 만들었으니 빈 결과가 돌아오면 정상입니다.

Step 5 — 첫 자율 데이터 생성 (10분)

이제 Claude가 본인 Firestore에 직접 컬렉션을 만들 수 있는지 검증합니다.

Firestore에 `_test` 컬렉션을 만들고, 문서 1개 추가해줘. { ping: "ok", createdAt: 서버 타임스탬프 } 끝나면 결과를 보고해.

→ Claude가 Firebase MCP로 직접 push → Firebase 콘솔에서 Firestore 페이지 → _test 컬렉션이 보이면 OK.

이 단계가 통과되면 Claude가 본인 Firestore의 데이터를 직접 조작할 수 있는 상태가 된 것입니다. 이게 워크숍 14h 동안 D2 #6의 컬렉션 자동 생성, D2 #7의 자동화 게이트가 가능한 이유입니다.

04Part 4 · 진도 체크리스트 + 핵심 정리4/4

다음 7개 항목이 모두 체크되면 #2 (메타스킬) 블록으로 넘어갈 준비가 된 것입니다.

  • claude --version 응답
  • ☐ Firebase 프로젝트 생성 (한국 리전)
  • ☐ 본인 GitHub repo (템플릿 기반) clone 완료
  • npm install 완료
  • .mcp.json 설정 + .gitignore.firebase-mcp-key.json 등록
  • /mcp list에 firebase 표시
  • _test 컬렉션 자동 생성 성공

먼저 끝낸 분은 본인 [셋업-{이름}-{모듈}.md] 파일을 펼쳐서 §1 ("사전 확정 항목")을 정리합니다. D1 #3 IPO 작성 시 그 항목들이 그대로 IPO 4섹션의 CONTEXT 줄로 들어갑니다.

핵심 포인트

• 첫 90분의 단일 목표 = claude --version + Firebase MCP가 Firestore 조작 가능

Firebase MCP가 핵심 — Claude가 Firestore에 직접 컬렉션·문서를 만들 수 있게 해주는 다리. 안 뜨면 D2 #6의 자동 데이터 생성이 무너짐

.gitignore 강제 = .firebase-mcp-key.json, .env, serviceAccountKey.json — 한 번 push되면 키 재발급해야 함

• 셋업이 끝났다는 건 단순히 도구가 깔린 게 아니라, Claude가 본인 인프라를 직접 조작할 수 있는 상태가 된 것

• 본인 셋업 메뉴 §1을 본 교안과 함께 두 창 띄워 진행

CH02 메타스킬 D1 #2 · 11:00~12:00 · 60분

Part 2 — 메타스킬: AI에게 "잘 시키는 법" (IEPR + 4단 질문)

AI가 결과를 못 내는 게 아닙니다. 여러분의 의도가 결정되지 않은 채 AI가 호출되고 있을 뿐입니다. 단일 목표 — "스스로 과제 정의 → AI에게 잘 시키기" 메타프레임을 4명에게 장착.

읽기 14분·업데이트: 2026-05-05
01Part 1 · 왜 알아야 하는가1/6

이 60분이 14h의 가장 깊은 곳에서 작동하는 시간입니다. 도구를 다루는 시간이 아니라, 본인이 도구에 무엇을 시킬지 결정하는 능력을 만드는 시간입니다.

4명 모두 Claude Pro 이상 유료 결제 중이고 챗봇은 이미 일상입니다. 그런데도 결과가 만족스럽지 않은 챗봇 사용자입니다. CLI를 손에 쥐어드리는 것만으로는 같은 패턴이 반복됩니다 — 더 좋은 도구를 줘도, 본인의 의도가 두루뭉술하면 결과는 두루뭉술합니다.

IMPORTANT — 이 60분이 없으면 14h가 "툴 따라하기"로 끝납니다
  • 본인이 뭘 만들고 싶은지 정의하지 못한 상태에서 Claude Code에 두루뭉술하게 시키면 → 결과가 매번 다른 톤·구조로 나옴
  • "이거 말고 저거"를 매번 다시 시키느라 14h를 다 쓰게 됨
  • 통합 시점(D2 #8)에 모듈 4개가 따로 노는 누더기가 됨

이번 블록은 "AI가 잘 일하게 하는 장치"가 아니라, "내가 의도를 결정해 AI에 못 박는 장치"입니다.

02Part 2 · 챗봇 한계 진단 워크숍 (10분, 11:00~11:10)2/6

먼저 본인 경험을 꺼냅니다. 추상적인 이론으로 가기 전에, 본인이 최근 2주 안에 챗봇에서 결과가 영 별로였던 사례 1개를 꺼내 분류해보면 다음 강의 내용이 본인 사례와 1:1로 매칭됩니다.

4명 발표

각자 2분씩 본인 사례를 발표합니다. 발표 끝나면 4건의 사례가 모이는데, 거의 항상 다음 3가지 패턴 중 하나입니다.

(A) 의도 모호(B) 맥락 부족(C) 검증 누락
"이런 거 만들어줘" 식"여기 데이터 줄게" 없이 시작결과를 검증할 기준 X
WHO·WHY 빠짐회사 룰·도메인 룰 미주입"이거 맞나?" 못 묻고 그냥 받음

이 3패턴이 나오는 이유는 단순합니다 — 사람은 동료에게 일을 시킬 때 동료가 모르는 부분을 되물어 보완할 거라고 가정합니다. 그런데 AI는 되묻지 못합니다. 안 줘진 정보는 그냥 비어 있는 채로 결과가 나옵니다.

이 3패턴이 14h 동안 어떻게 차단되는가

이 3패턴은 오늘 14h 동안 단계별로 차단됩니다. 즉 본인이 4단 질문 → IPO → CLAUDE.md → 자동 검증 게이트로 이어지는 흐름을 따라가기만 하면, 본인 챗봇 실패 사례가 14h 안에 자동으로 해결됩니다.

패턴어디서 차단되는가
(A) 의도 모호D1 #3 IPO 작성 — 본인 모듈의 WHO/WHY를 1문장으로 못 박음
(B) 맥락 부족D2 #6 CLAUDE.md — 본인 도메인 룰·금지사항을 1장 시스템 프롬프트로 영속화
(C) 검증 누락D2 #7 자동 검증 게이트 — 결과의 수치 범위·합계 일치를 자동으로 검증
NOTE

4명의 발표 사례가 이 3컬럼 안 어딘가에 들어옵니다. 이 3개가 오늘 14h 동안 우리가 해결할 문제입니다. 발표 사례가 어느 컬럼에 해당하는지 본인이 1번 분류하고 가시면, 그 분류가 14h 안에 자동으로 풀리는 걸 체감하실 수 있습니다.

03Part 3 · IEPR 3-Phase (20분, 11:10~11:30)3/6

이제 본인 사례 분류가 끝났으니, AI 협업의 본질로 들어갑니다. 핵심 질문 하나 — AI에게 일을 시킬 때 사람 조직의 분업 구조를 그대로 적용하면 왜 실패하는가.

"역할극 vs 맥락 중심"

조직에서 사람을 23개 역할로 나누면 22번의 핸드오프(작업을 다음 사람에게 넘기는 지점)가 생기고, 각 핸드오프에서 정보가 새거나 왜곡됩니다. 사람은 옆자리 동료에게 되물어 보완합니다 — "어제 회의에서 그거 어떻게 결정된 거예요?" 한마디로 누락된 맥락을 메꿉니다.

AI는 되묻지 못합니다. 그래서 같은 패턴(에이전트 23개로 쪼개기)을 적용하면 22개의 실패점이 그대로 드러납니다. 한 에이전트가 다음 에이전트에게 정보를 넘길 때, 누락된 부분은 그냥 누락된 채로 결과가 나옵니다.

IMPORTANT — AI 협업의 본질

에이전트를 사람처럼 부서로 나누지 않습니다. 하나의 의도가 끝까지 관통하도록, 의도(Intent) → 실행(Execution) → 검증(Production·Review)의 3단계 사이클을 고정 패턴으로 돌립니다. 이게 IEPR입니다.

IEPR 3-Phase 다이어그램

[Phase 1] Intent — 의도 결정화 ↓ (4단 질문 WHO/WHY/CONTEXT/VERIFY로 의도를 못 박음) [Phase 2] Execution — 코드/데이터 생성 ↓ (Claude Code + MCP가 자율 실행) [Phase 3] Production — 산출 + Review ↓ (검증 게이트가 결과를 즉시 차단/통과) [Reflection] — 무엇이 안 됐는가 → Phase 1로 회귀

이 4단계가 한 사이클입니다. Reflection이 다음 Intent의 입력이 되는 게 핵심 — 한 번에 완벽하지 않아도, 사이클을 빠르게 돌리면 매 사이클마다 의도가 더 정밀해집니다.

인간 조직 vs AI — 차이 한 장

인간 조직AI
동료에게 "그게 무슨 뜻이에요?" 되물을 수 있음못 되물음
어제 회의 맥락을 암묵적으로 공유매 호출마다 맥락 명시 필요
보고서 한 페이지를 23명이 분담해도 합쳐짐23개 에이전트로 쪼개면 22번 핸드오프 실패
의도가 모호해도 일단 진행 후 보완의도 모호하면 결과가 매번 다른 방향

이 차이가 CLAUDE.md가 왜 필요한가의 답입니다 — 매 호출마다 맥락을 다시 입력하지 않도록, 공통 맥락을 1장 시스템 프롬프트로 영속화하는 것.

KCH 4모듈을 IEPR로 매핑 (이재성 M2 예시)

추상적으로 들리는 IEPR을 실제 모듈에 적용하면 어떻게 보이는지 한 예시로 풀어보겠습니다.

Phase이재성 M2의 경우
IntentWHO=인사총무+사업부장 / WHY=법정+근속+해외특별 자동 산정 / CONTEXT=회계년도·ERP CSV 컬럼·근속표 / VERIFY=20일 산정값 검증·분기 메일 Draft 생성
ExecutiongetLeaves(empId) 함수 + Cloud Function quarterlyMail 작성 (Claude가 작성)
Production산정 결과 화면이 동작 + 메일 Draft 생성 → 사람이 검수해서 발송 결정
Reflection"어, 해외 14일 후 잔여 처리 룰이 빠져 있었네" → 다시 Intent로 돌아가 룰 추가

이 4단계가 D1 #3 IPO 작성 → D1 #4 첫 배포 → D2 #6 본 모듈 구현 → D2 #7 자동화 게이트의 흐름과 1:1 매칭됩니다. 본인이 14h 동안 IEPR 사이클을 한 번 도는 것이 이 워크숍의 골격입니다.

04Part 4 · 의도 분해 4단 질문 (15분, 11:30~11:45)4/6

이제 IEPR의 첫 단계인 Intent를 손으로 만질 수 있는 도구로 만듭니다.

4단 질문 — Intent를 못 박는 단일 도구

복잡해 보이는 의도 결정화는 사실 4가지 질문에 답하는 것으로 충분합니다.

#질문답변 형태무엇을 결정하는가
WHO 누가 쓰는가1문장 (대상 + 부속 인격)시스템 사용자 + 산출물 수신자
WHY 무엇을 결정/실행하기 위해1문장 (가치)시스템이 제공하는 단일 가치
CONTEXT 어떤 데이터/맥락이 필요한가3-5개 항목 (도메인·룰·외부)도메인 룰·외부 데이터·금지사항
VERIFY 결과가 맞는지 어떻게 안다2-3개 검증점 (수치·구조)자동 검증 게이트의 기준

이 4줄이 IPO 4섹션과 어떻게 매핑되는가

이 4줄이 다음 블록(D1 #3 IPO 작성)에서 그대로 펼쳐집니다. 1:1 매핑입니다 — 즉 4단 질문에 답하면 IPO의 절반은 이미 채워져 있는 것과 같습니다.

4단 질문IPO 4섹션
WHOI 타겟
WHYI 가치
CONTEXTP-1 IA · P-2 백엔드
VERIFYO 기능
IMPORTANT

이 4줄이 D2 #6 CLAUDE.md의 §1 Intent 섹션이 됩니다. 즉 오늘 의도를 결정화한 결과가 내일 시스템 프롬프트로 영속화됩니다 — 같은 의도를 매 세션 다시 입력하지 않아도 자동 주입됩니다. 14h가 한 줄로 이어지는 메타 흐름입니다.

PoC vs MVP — 한 줄 메시지

또 하나, 오늘 14h 동안의 산출물 수준을 정리합니다.

지금 만드는 건 PoC입니다. 살아남으면 MVP, 운영 들어가면 시스템.

  • PoC (Proof of Concept) = "이 아이디어가 동작하는가"를 빠르게 보여주는 시제품
  • MVP (Minimum Viable Product) = 실제 사용자 1명이 쓸 수 있는 최소 제품
  • 시스템 = 운영 환경에서 매일 돌아가는 안정적인 제품

오늘 14h의 산출물은 PoC입니다. 살아남으면 30/60/90일 자력 로드맵으로 MVP·시스템으로 발전합니다. PoC 단계에서 MVP/시스템 수준의 완성도를 추구하면 14h가 끝나지 않습니다 — "여기까지가 PoC, 더 이상은 후속"의 경계를 알고 가는 게 중요합니다.

05Part 5 · 4단 질문 워크시트 작성 (15분, 11:45~12:00)5/6

이제 본인 모듈로 4단 질문에 답합니다. 본인 셋업 메뉴 §1의 사전 확정 항목을 함께 펼쳐 두고, 다음 워크시트를 채웁니다.

[본인 모듈: M? — {모듈명}] WHO : ________________________________________________ WHY : ________________________________________________ CONTEXT : - _____________________________________________ - _____________________________________________ - _____________________________________________ VERIFY : - _____________________________________________ - _____________________________________________

작성 기준 — 통과해야 하는 것들

작성하면서 다음 기준을 체크합니다. 두루뭉술하게 적으면 D1 #3 IPO·D2 #6 CLAUDE.md가 두루뭉술해지고, 결과적으로 본인 코드가 두루뭉술해집니다.

  • WHO 1문장이 두루뭉술하지 않은가?
    나쁨: "직원" / 좋음: "인사총무팀 + 사업부장(메일 수신)"
  • WHY가 "무엇을 결정/실행"인가?
    나쁨: "관리하기 위해" / 좋음: "법정+근속+해외 자동 산정해 분기 메일 발송"
  • CONTEXT 3개 이상인가? 도메인 룰 빠짐 없는가? (예: 이재성 M2 — 회계년도 기준일, 근속 휴가표, 해외 14일 룰)
  • VERIFY가 검증 가능한 형태인가? 수치 또는 구조 명시되어 있는가? (예: "직원 E007 자동 산정 = 법정 15 + 근속 5 + 해외 0 = 20일")
TIP

본인 셋업 메뉴 §1의 "사전 확정 항목"이 CONTEXT의 첫 번째 줄로 들어갑니다. 이미 작성된 항목은 워크시트에 그대로 옮기시면 됩니다.

워밍업 클로징 — D2 #6 CLAUDE.md 사전 공지

마지막 1분에 다음 메타 메시지를 전달합니다.

NOTE

내일(D2 #6) CLAUDE.md 작성 시 이 4줄이 시스템 프롬프트가 됩니다. 오늘 의도를 결정화한 결과가 내일 CLAUDE.md로 영속화됩니다 — 같은 의도를 매 세션 다시 입력하지 않아도 자동 주입됩니다. 즉 지금 적은 4줄이 14h 끝까지 계속 살아 있다는 뜻입니다.

06Part 6 · 체크리스트 + 핵심 정리6/6
  • ☐ 본인 챗봇 실패 사례 1개를 (A)/(B)/(C) 패턴 중 하나로 분류
  • ☐ IEPR 3-Phase 다이어그램 머릿속 그림 (Intent → Execution → Production·Review → Reflection)
  • ☐ 인간 vs AI 차이 1줄 ("AI는 되묻지 못한다")
  • ☐ 본인 모듈 4단 질문 1줄씩 답변 (WHO·WHY·CONTEXT·VERIFY)
  • ☐ PoC vs MVP 한 줄 메시지 ("오늘은 PoC, 살아남으면 MVP")
  • ☐ 4단 질문 → IPO 4섹션 매핑 이해
핵심 포인트

• 챗봇 한계는 도구가 아니라 의도 결정화 부재가 원인 — 3패턴 (의도 모호 / 맥락 부족 / 검증 누락)

IEPR 3-Phase: Intent → Execution → Production·Review → Reflection으로 회귀. 본인 14h가 이 사이클 한 번

AI는 부서 나누듯 쓰면 실패 — 하나의 의도가 끝까지 관통하게 만들 것

4단 질문 (WHO/WHY/CONTEXT/VERIFY) = 의도 결정화 단일 도구. IPO 4섹션 → CLAUDE.md §1 Intent로 1:1 매핑돼 영속화

• PoC vs MVP — 오늘은 PoC, 30/60/90일 로드맵으로 MVP·시스템화

• 다음 블록(#3) IPO 작성에서 4단 질문 답변을 4섹션으로 펼침

CH03 실습 D1 #3 · 13:00~14:30 · 90분

Part 3 — 본인 모듈 IPO 4섹션 작성 (Plan 모드)

4단 질문 16줄을 본인 모듈의 IPO 4섹션으로 펼칩니다. 이 IPO가 D1 #5 AI Studio 프롬프트 → D2 #6 Firestore 스키마 → D2 #7 자동화 게이트의 단일 명세서가 됩니다. 산출물: 본인 IPO 1차 (4섹션 채워진 1장 md).

읽기 16분·업데이트: 2026-05-05
01Part 1 · 왜 IPO인가1/7

90분에 손에 쥐는 건 4섹션이 채워진 한 장의 md입니다. 단순해 보이지만 이 한 장이 14h 후반부 8개 블록의 단일 명세서입니다.

IPO가 없으면 어떻게 되는가

D1 #5 AI Studio → 두루뭉술한 프롬프트 → 4명 결과가 색·구조 모두 다름 D2 #6 본 모듈 구현 → Firestore 스키마 매번 다시 결정 → 시간 누수 D2 #7 자동화 게이트 → 어디에 둘지 못 정함 → 자동화 1개 못 만듦 D2 #8 통합 → 모듈 4개가 따로 노는 누더기
IMPORTANT — IPO 1장이 14h 후속 8개 블록의 단일 명세서입니다
  • D1 #5 AI Studio 시안 작성 — IPO P-1 IA 그대로 사용
  • D2 #6 Firestore 스키마 — IPO P-2 백엔드 그대로 사용
  • D2 #7 자동화 게이트 — IPO O 기능의 자동화 1개 그대로 구현
  • D2 #8 통합 인덱스 — IPO I 타겟·I 가치를 카드 메타로

IPO = Input · Process · Output

IPO는 시스템 설계의 가장 기본 골격입니다. 어떤 시스템이든 결국 "입력 → 처리 → 출력"으로 환원되기 때문에, 이 3단계로 본인 모듈을 정의하면 가장 단순하면서 빠짐 없는 명세서가 됩니다.

섹션채울 내용4단 질문 매핑 (D1 #2에서 작성한 것)
I 타겟누가 쓰는가 (대상 + 부속 인격)WHO
I 가치무엇을 결정/실행하기 위해WHY
P-1 IA페이지 구조 (홈·상세·폼·대시보드 라우트)CONTEXT의 일부 (구조)
P-2 백엔드Firestore 컬렉션 + Cloud Function 흐름CONTEXT의 일부 (데이터·룰)
O 기능동작하는 기능 + 자동화 1개VERIFY

"IA"가 무엇인가요 — Information Architecture (정보 구조). 즉 "본인 모듈이 어떤 페이지들로 구성되는가"의 라우트 목록입니다.

02Part 2 · Plan 모드 시연 (15분, 13:00~13:15)2/7

본인이 IPO 4섹션을 채우기 전에, Claude Code의 Plan 모드를 1번 시연합니다. 이 모드가 IPO 작성을 빠르게 끝내는 데 도움이 됩니다.

Plan 모드가 무엇이고 왜 필요한가

NOTE

Plan 모드는 Claude Code에게 "코드를 곧바로 쓰지 말고, 어떤 단계로 진행할지 먼저 보여줘"라고 요청하는 모드입니다. 코드를 바로 쓰면 잘못된 방향으로 이미 100줄이 나가 있고 되돌리기 비용이 큽니다 — Plan 모드는 그 비용을 미리 차단합니다.

흔히 챗봇에 "이거 만들어줘"하면 코드가 바로 쏟아져 나오는데, 그 코드가 본인 의도와 다르면 다시 시켜야 합니다. Plan 모드는 코드 전에 검증 가능한 계획서를 먼저 받아서 사람이 OK한 뒤 코드 단계로 넘어갑니다.

Plan 모드 진입

# Claude Code 안에서 Cmd+Shift+M # macOS 단축키 # 또는 슬래시 명령 /plan

진입하면 프롬프트 좌측에 [Plan] 표시가 떠서 현재 모드가 보입니다.

Plan 모드 사용 예시 — 이재성 M2 (연차)

다음 프롬프트를 그대로 복붙해보면 Plan 모드의 동작 방식이 보입니다.

[Plan 모드] 요청: 연차 자동 산출 모듈을 만들고 싶습니다. 내가 IPO 4섹션을 채울 수 있도록 다음 형태로 정리해주세요: - I 타겟 (1문장) - I 가치 (1문장) - P-1 IA (페이지 5개 이내 라우트) - P-2 백엔드 (Firestore 컬렉션 3-5개 + Cloud Function 1-2개) - O 기능 (동작하는 기능 4-6개 + 자동화 1개) 근거 정보: - 회계년도 = (확정 시 입력) - 근속 휴가표: 3·6·9·12·18·21년차=3일 / 5·10·20·25년차=5일 / 15·30년차=8일 - 해외 특별: 5개월 단위 14일 반복 - 대상: 인사총무팀 + 사업부장(메일 수신)

→ Claude가 IPO 초안을 출력. 본인이 그 형태로 받아서 손으로 다듬으면 IPO 작성이 훨씬 빠릅니다.

TIP

Plan 모드는 "AI에게 검증 가능한 계획을 먼저 받고 사람이 확정"하는 흐름입니다. 본 IPO 작성뿐 아니라 D2 #6에서 Firestore 컬렉션 스키마를 결정할 때, D2 #7에서 자동화 게이트 구조를 잡을 때도 같은 패턴으로 씁니다.

03Part 3 · 본인 IPO 1차 작성 (60분, 13:15~14:15)3/7

본인 셋업 메뉴 §2 ("IPO 4섹션 슬롯")를 펼치고, D1 #2의 4단 질문 워크시트를 함께 두고, 다음 템플릿을 채웁니다.

# {본인 모듈명} IPO ## I 타겟 (WHO) - {대상 1줄} ## I 가치 (WHY) - {결정/실행 1줄} ## P-1 IA (페이지 구조) - /{모듈경로} (홈) - /{모듈경로}/{서브1} ({설명}) - /{모듈경로}/{서브2} ({설명}) - ... ## P-2 백엔드 ### Firestore 컬렉션 - `{컬렉션1}/{docId}` — { fields ... } - `{컬렉션2}/{docId}` — { fields ... } ### Cloud Function - `{함수명}` (트리거: {schedule|onWrite|http}) — { 역할 1줄 } ## O 기능 1. {기능1} 2. {기능2} 3. ... **자동화 게이트:** {cron/onEvent} → {결과} ## VERIFY (자동 검증 게이트) - {검증1: 수치 범위} - {검증2: 구조 일치}

4명 모듈별 IPO 가이드

각 참가자 모듈의 핵심 컬렉션과 자동화 게이트는 본인 셋업 메뉴 §2에 더 상세히 적혀 있습니다. 다음 표는 한눈에 보는 요약입니다.

참가자모듈주요 컬렉션자동화 게이트자세한 슬롯
이재성M2 연차employees · leave_balances · leave_usages · org_unitsCloud Scheduler 분기 메일 (0 9 1 1,4,7,10 *)셋업-이재성 §2
김경호M3 성과관리kpi_targets · eval_5stage · salary_calc · org_unitsonEvalFinalized Cloud Function셋업-김경호 §2
이동연M1 휴양시설facilities · bookings · lottery_logs · maintenance_scheduleCloud Scheduler 시즌 알림 (0 9 * * *)셋업-이동연 §2
이윤재M4 사내 도구tools_registry · exec_logs · health_logs일별 헬스체크 (0 9 * * *) + Slack셋업-이윤재 §2

"Cloud Scheduler", "onWrite" 같은 트리거 용어

  • Cloud Scheduler — Google Cloud의 cron 서비스. "분기 첫날 09:00에 실행" 같은 시간 기반 자동 발화를 시키는 도구
  • onWrite / onUpdate — Firestore 문서가 추가·변경될 때 자동으로 실행되는 트리거. 예: "본평가가 확정되면 즉시 산출 함수 호출"
  • http — 사람이나 외부 시스템이 URL을 호출할 때 실행되는 트리거. 수동 실행용

각 모듈의 자동화 게이트는 이 3가지 중 하나로 발화합니다.

0 9 1 1,4,7,10 * 같은 cron 표기 읽는 법

cron은 5개 필드(분 시 일 월 요일)로 시간을 표현합니다.

분 시 일 월 요일 0 9 1 1,4,7,10 * → 매년 1·4·7·10월 1일 09:00 (분기 첫날) 0 9 * * * → 매일 09:00

본인이 직접 외울 필요는 없고, 본인 모듈 자동화 표에서 어떤 시간에 발화하는지만 읽을 수 있으면 됩니다.

04Part 4 · IPO 점검 (15분, 14:15~14:30)4/7

작성이 끝났으면 다음 7개 항목을 자가 점검합니다. 통과 기준이 명확하기 때문에 본인이 직접 OX를 매겨볼 수 있습니다.

항목통과 기준
I 타겟1문장 + 부속 인격 1개 이상 (예: "인사총무팀 + 사업부장")
I 가치동사 명시 (예: "자동 산정해 메일 발송") — "관리하기 위해" 같은 모호한 동사 X
P-1 IA라우트 3-7개 + URL 패턴 일관
P-2 컬렉션3개 이상 + 최소 1개에 토큰화 적용 (empId 같은 토큰 필드)
P-2 함수트리거 명시 (cron / onWrite / http)
O 기능자동화 게이트 1개 명시
VERIFY수치 또는 구조 검증점 2개 이상

이 7개가 모두 통과되면 IPO 1차가 완성된 것입니다.

05Part 5 · 메타 흐름 — IPO가 14h 후반부를 관통5/7

이 IPO 1장이 다음 8개 블록에서 어디로 가서 어떻게 쓰이는지 한 번 정리하고 갑니다. "왜 이렇게 정성스럽게 작성하는가"의 답이 여기 있습니다.

IMPORTANT

IPO 1장이 다음 8개 블록의 단일 명세서가 됩니다.

블록IPO 사용처
D1 #4I 타겟 + I 가치를 Firebase App Hosting 첫 배포의 페이지 헤더로
D1 #5P-1 IA를 AI Studio 프롬프트의 페이지 구조로
D2 #6P-2 컬렉션을 Firestore 스키마 + UI 페이지로
D2 #7O 기능 + 자동화 게이트 = Cloud Function 구현 + VERIFY 자동 검증
D2 #8I 타겟 + I 가치 = 통합 인덱스 카드의 메타정보
D2 #9I 타겟 + 자동화 게이트 = 발표 시 시연 시나리오

오늘 14h 동안 IPO를 1장 분량으로 유지합니다. 길어지면 잘 안 지켜집니다 — 길수록 본인이 다음 블록에서 다시 펼쳐 볼 가능성이 떨어지기 때문입니다.

06[부록] IPO 작성 템플릿 (전체 복사용 · KCH 인사총무 모듈 맥락)6/7

이 템플릿은 IPO 1장을 더 풍성하게 채우고 싶은 분을 위한 확장 템플릿입니다. I (Input) · P (Process) · O (Output) 3단계가 KCH 인사총무 모듈 맥락으로 변형되어 있습니다.

사용법

아래 박스 우상단의 "COPY" 버튼을 누르면 템플릿 md 전체가 클립보드에 복사됩니다. 본인 repo 루트에 IPO.md로 붙여넣고, 슬롯을 채워가면서 작성합니다.

섹션 §03의 단순 템플릿(필수 4섹션)으로도 충분합니다. 이 부록은 4단 질문 → IPO를 더 단단하게 풀어 쓰고 싶을 때 사용합니다.

# {본인 모듈명} — IPO 작성 템플릿 (KCH 인사총무 워크숍용)

**버전**: 1.0
**워크숍**: KCH그룹 인사총무팀 14h AI 워크숍
**용도**: D1 #3 (13:00~14:30) IPO 4섹션 작성

---

## 📌 템플릿 사용법

### 이 템플릿의 목적
- 본인 인사총무 모듈을 체계적으로 정의
- 4단 질문 (WHO/WHY/CONTEXT/VERIFY) → IPO 4섹션 → CLAUDE.md §1로 이어지는 흐름의 단일 명세서
- D2 #6 Firestore 스키마 / D2 #7 자동화 게이트 / D2 #8 통합 인덱스에 그대로 사용

### 작성 순서
1. **I (Input)**: 타겟 사용자 + 핵심 가치 + 도메인 룰 + 제약 조건 (30분)
2. **P-1 (Process-1)**: 페이지 구조 (IA) — Next.js 라우트 (15분)
3. **P-2 (Process-2)**: Firestore 컬렉션 + Cloud Function (15분)
4. **O (Output)**: 기능 명세 + 자동화 게이트 + 배포 계획 (15분)

### 작성 팁
- 각 섹션의 **가이드 질문**을 먼저 읽고 답하세요
- 막히면 본인 셋업 메뉴 §1·§2를 펼쳐서 그대로 옮기세요
- 1장 분량 유지 — 길어지면 D2에 안 펼치게 됩니다

---

## 🎯 모듈 정보

| 항목 | 내용 |
|------|------|
| **모듈명** (예: M2 연차) | |
| **본인 이름** | |
| **본인 repo** (예: mjs-leaves) | |
| **목표 URL** (D1 #4 시점) | |

---

# I (Input): 타겟 + 가치 + 도메인 룰

> 💡 이 섹션의 목표 — "내 모듈은 누구를 위해, 무엇을, 어떤 룰 위에서 동작하는가"를 1문장씩 못 박기

---

## 1. WHO — 타겟 사용자

### 가이드 질문
- 누가 이 모듈을 매일/매주/매월 사용하는가?
- 산출물(메일·알림·리포트)을 받는 부속 인격은 누구인가?
- KCH 사내 어느 부서·직급?

### 작성 가이드
```
[메인 사용자: 부서/직급] + [부속 인격: 결과물 수신자/결재자]
```

### 내 모듈
```
WHO:


```

---

## 2. WHY — 핵심 가치 (한 문장 동사형)

### 가이드 질문
- 이 모듈이 자동화하는 단일 가치는?
- "관리하기 위해" 같은 모호한 동사 금지 → "자동 산정해 메일 발송" 같은 동사
- 사람이 시스템 없이 하면 몇 분/시간이 걸리는 일을 몇 초로 줄이는가?

### 작성 가이드
```
[입력] → [처리: 동사형] → [출력: 사람이 받는 것]
```

### 내 모듈
```
WHY:


```

---

## 3. CONTEXT — 도메인 룰 + 외부 데이터 + 금지 사항

### 가이드 질문
- KCH 사내에 이미 정해진 룰은? (회계년도, 근속표, 한도 등)
- 외부에서 받아와야 하는 데이터는? (ERP CSV, KPI 목록 등)
- 절대 금지된 동작은? (자동 결정 금지, 평문 저장 금지 등)

### 도메인 룰 (3개 이상)
```
1.

2.

3.
```

### 외부 데이터 (있으면)
```
- 데이터 출처:
- 갱신 주기:
- 컬럼 구조:
```

### 금지 사항
- [ ] 인사정보 평문 저장 X (직원ID 토큰화 강제)
- [ ] 외부 API 호출 0건 (해당 모듈만, 김경호 M3)
- [ ] AI 자동 결정 X (산출 룰은 결정적 if-else)
- [ ] 사용자 동의 없이 협력사·외부에 데이터 공유 X
- [ ] 기타:

---

## 4. 제약 조건 (워크숍 14h 안에서 가능한 범위)

| 제약 유형 | 내용 |
|----------|------|
| **시간** | 14h (D1 9:30~17:30 + D2 9:30~17:30) |
| **인프라** | Firebase 한국 리전 (asia-northeast3) — Firestore + Auth + App Hosting + Cloud Functions |
| **프론트** | Next.js 14 + Tailwind + shadcn/ui 4종 (Card·Badge·Tabs·DataTable) |
| **디자인** | KCH 컬러 강제 (#1962A8 / #70AEDA), 다크모드 X |
| **AI 도구** | Claude Code CLI + Firebase MCP, 외부 LLM API는 워크숍 외 |
| **데이터** | 가상 더미만 (실 인사정보는 워크숍 후 마이그레이션) |

---

## ✅ Input 섹션 체크리스트

- [ ] WHO 1문장 + 부속 인격 1개 이상
- [ ] WHY 동사형 1문장
- [ ] CONTEXT 도메인 룰 3개 이상
- [ ] 금지 사항 본인 모듈 맞게 체크
- [ ] 제약 조건 확인

---

# P (Process): 설계

> 💡 이 섹션의 목표 — "어떤 페이지 + 어떤 데이터 + 어떤 자동 흐름으로 만들까"

---

## P-1 · 페이지 구조 (IA)

### 가이드 질문
- 본인 모듈에 몇 개 페이지가 필요한가? (5개 이내 권장)
- 각 페이지의 관계는? (홈 → 상세 → 폼 → 대시보드)
- 핵심 페이지는 어디인가? (D2 #6에서 가장 먼저 동작시킬 1개)

### 작성 가이드 — IA 트리
```
/m{N}-{모듈경로}        (홈)
├── /m{N}-{모듈경로}/[id]      (상세)
├── /m{N}-{모듈경로}/{서브1}   (폼/등록)
├── /m{N}-{모듈경로}/{서브2}   (대시보드/캘린더 등)
└── /m{N}-{모듈경로}/{서브3}   (필요 시)
```

### 내 모듈 IA
```


```

### 핵심 페이지 (D2 #6에서 가장 먼저 동작시킬 1개)
```
핵심 페이지: /
이유:
```

---

## P-2 · Firestore 컬렉션

### 가이드 질문
- 어떤 데이터를 저장하는가? (3개 이상 컬렉션 권장)
- 직원ID는 어떻게 토큰화하는가? (`empId(token)` 필드)
- 영구 보존이 필요한 컬렉션은? (감사 로그 등)

### 작성 가이드
```
컬렉션명/{docId} — 의미 — 핵심 필드
```

### 내 모듈 컬렉션 (3-5개)
| 컬렉션 | 의미 | 핵심 필드 |
|---|---|---|
| `{컬렉션1}/{docId}` | | |
| `{컬렉션2}/{docId}` | | |
| `{컬렉션3}/{docId}` | | |

### 영구 보존 / 토큰화 필요 컬렉션
- 영구 보존:
- 토큰화 필드:

---

## P-3 · Cloud Function (자동화 게이트)

### 가이드 질문
- 사람이 손으로 매번 호출하지 않아도 시간이 흘러가면 자동 발화하는 함수가 1개 있는가?
- 트리거는? (Cloud Scheduler cron / Firestore onWrite / http)
- 발화 후 동작은? (메일 Draft / 알림 / 산출 / 헬스체크)

### 작성 가이드
```
함수명 — 트리거 — 동작 — 검증 조건
```

### 내 모듈 자동화 게이트 (1개)
```
함수명:
트리거:        (예: Cloud Scheduler `0 9 1 1,4,7,10 *` 분기 첫날)
동작:
검증 조건:
```

---

## ✅ Process 섹션 체크리스트

- [ ] IA 트리 작성 (3-7개 라우트, URL 패턴 일관)
- [ ] 핵심 페이지 1개 명시
- [ ] Firestore 컬렉션 3개 이상
- [ ] 토큰화 적용 컬렉션 1개 이상
- [ ] Cloud Function 1개 (트리거 명시)

---

# O (Output): 기능 명세 + 배포 + 검증

> 💡 이 섹션의 목표 — "동작하는 결과물 + 검증 가능한 게이트"

---

## 1. 기능 명세 (4-6개)

### 가이드 질문
- 사용자가 핵심 페이지에서 무엇을 하면 어떤 결과를 받는가?
- 자동화 게이트는 언제·무엇을 발화시키는가?
- 단계별로 1-2-3 절차로 풀 수 있는가?

### 작성 가이드
```
기능명: [동작]
사용자 액션:  1. ... → 2. ... → 3. ...
시스템 처리:  ...
결과:         ...
```

---

### 기능 1: 핵심 동작
```
기능명:
사용자 액션:
  1.
  2.
  3.
시스템 처리:
결과:
```

### 기능 2:
```
기능명:
사용자 액션:
시스템 처리:
결과:
```

### 기능 3:
```
기능명:
```

### 기능 4 (자동화 게이트):
```
함수명:
트리거 시점:
동작:
검증 조건:
```

---

## 2. 배포 계획

| 항목 | 내용 |
|------|------|
| **호스팅** | Firebase App Hosting (한국 리전 asia-northeast3) |
| **공개 URL 형식** | `https://{본인-모듈경로}--{projectId}.{region}.hosted.app` |
| **첫 배포 시점** | D1 #4 (14:30~16:00) — IPO I 타겟·I 가치를 헤더로 띄운 단일 페이지 |
| **본 모듈 배포** | D2 #6 끝 / D2 #7 끝 / D2 #8 통합 시점 |
| **인증** | Firebase Auth Google + 사내 도메인 lock (`hd: 'kchglobal.co.kr'`) |
| **SSL** | Firebase 자동 (별도 설정 X) |

### 본인 URL 기록 (D1 #4 시점에 채움)
```
공개 URL:
```

---

## 3. VERIFY · 자동 검증 게이트 (D2 #7에서 구현)

### 가이드 질문
- 자동화 게이트가 발화한 결과가 맞는지 어떻게 사람 없이 검증하는가?
- 수치 범위 / 합계 일치 / 구조 일치 중 어떤 형태로?

### 작성 가이드
```
검증명 — 통과 조건 — 실패 시 동작
```

### 내 모듈 검증 게이트 (2-3개)
```
1. 수치 범위:
   통과 조건:
   실패 시:

2. 구조 일치:
   통과 조건:
   실패 시:

3. (선택)
```

---

## ✅ Output 섹션 체크리스트

- [ ] 기능 4-6개 명세 작성 (단계별 동작)
- [ ] 자동화 게이트 1개 = 함수명 + 트리거 + 동작 + 검증
- [ ] 배포 URL 형식 인지
- [ ] 검증 게이트 2개 이상

---

# 📊 IPO 한 장 요약

## 한 줄 요약
```
[WHO]를 위해 [도메인 룰] 위에서 [WHY]하는 [모듈명]
```

**내 모듈**:
```


```

---

## 핵심 지표

| 지표 | 목표 |
|------|------|
| **D1 #4 본인 URL** | |
| **Firestore 컬렉션 수** | 3개 이상 |
| **Cloud Function 수** | 1개 이상 (자동화 게이트) |
| **자동 검증 게이트** | 2개 이상 |
| **D2 #8 통합 인덱스 등록** | ✅ |

---

# 📅 다음 단계

## 본 IPO를 어디에 어떻게 사용하는가
- **D1 #4 (14:30~16:00)**: I 타겟 + I 가치를 Firebase App Hosting 첫 배포 페이지 헤더로
- **D1 #5 (16:00~17:30)**: P-1 IA를 AI Studio 프롬프트의 페이지 구조로
- **D2 #6 (09:30~12:00)**: P-2 컬렉션을 Firestore 스키마로 / IA를 Next.js 페이지로
- **D2 #7 (13:00~15:00)**: O 자동화 게이트 = Cloud Function 구현 / VERIFY = 자동 검증 게이트
- **D2 #8 (15:00~16:30)**: I 타겟 + I 가치 = 통합 인덱스(이윤재 M4) 카드의 메타
- **D2 #9 (16:30~17:30)**: I 타겟 + 자동화 게이트 = 발표 시연 시나리오

## 질문 리스트 (작성 중 막힌 부분)
```
1.

2.

3.
```

---

# 🎉 IPO 1차 작성 완료!

다음 단계로 넘어가세요:

1. **D1 #4 첫 배포**: 이 IPO의 I 타겟·I 가치를 페이지 헤더로 → 본인 URL 1개 손에 쥐기
2. **D1 #5 AI Studio 시안**: 이 IPO의 P-1 IA를 프롬프트로 → 시안 받기
3. **D2 #6 Firestore + UI**: 이 IPO의 P-2를 그대로 → 컬렉션 자동 생성 + UI 페이지
4. **D2 #7 자동화 게이트**: 이 IPO의 O 자동화 1개 + VERIFY 자동 검증

**IPO를 30/60/90일 자력 로드맵에서 다시 펼쳐 MVP·시스템으로 발전시킵니다.**
07Part 6 · 체크리스트 + 핵심 정리7/7
  • ☐ Plan 모드 시연 이해 (코드 전 검증 가능한 계획)
  • ☐ 본인 IPO 4섹션 1차 작성 완료
  • ☐ I 타겟 + I 가치 1문장씩
  • ☐ P-1 IA 3-7개 라우트
  • ☐ P-2 Firestore 컬렉션 3개 이상 + Cloud Function 트리거 명시
  • ☐ O 기능 4-6개 + 자동화 게이트 1개
  • ☐ VERIFY 검증점 2개 이상
핵심 포인트

IPO 1장이 14h 후반부 8개 블록의 단일 명세서

• 4단 질문 16줄 → IPO 4섹션 (WHO→I 타겟, WHY→I 가치, CONTEXT→P-1·P-2, VERIFY→O 기능)

Plan 모드 = 코드 전 검증 가능한 계획. 잘못된 방향 100줄을 미리 차단

• 본인 셋업 메뉴 §2 ("IPO 4섹션 슬롯")가 본 블록의 채움 가이드

• cron 표기·트리거 용어는 외울 필요 X — 본인 모듈에서 어떻게 발화하는지만 읽을 수 있으면 됨

• IPO는 1장 분량 유지 — 길어지면 안 지켜짐

CH04 실습 D1 #4 · 14:30~16:00 · 90분

Part 4 — 첫 배포: Firebase App Hosting으로 본인 URL 1개

14h의 추진력을 만드는 90분. 껍데기여도 좋습니다 — 본인 URL 1개가 있어야 D2 종일이 굴러갑니다. 산출물: 본인 모듈 v0 URL 4개 (이재성 / 김경호 / 이동연 / 이윤재 각 1개).

읽기 14분·업데이트: 2026-05-05
01Part 1 · 왜 첫 URL이 핵심인가1/6

이 90분에 본인 URL이 손에 없으면 D2 종일이 무너집니다 — 정확히 어떻게 무너지는지 한 번 짚고 갑니다.

URL 없이 D2를 가면 어떻게 되는가

  • D2 #6 본 모듈 구현이 로컬 개발 서버에서만 동작 → 발표할 게 없음
  • 자동 빌드 파이프라인을 못 돌려서 매 변경마다 손으로 배포 명령을 쳐야 함
  • D2 #8 통합 인덱스에 본인 URL을 넣을 수 없어서 통합 시연 불가
IMPORTANT — 첫 URL이 만드는 3가지 변화
  1. 본인 코드를 공개 환경에서 검증 — 배포 룰·환경변수 누락이 즉시 드러남 (로컬에서는 안 보이는 것들)
  2. 14h 끝에 발표할 단일 가시 자산 — 추진력의 원천
  3. 자동 빌드 파이프라인 = D2 종일의 기반. git push 한 번에 새 URL이 배포됨
NOTE

본 블록의 산출물은 "껍데기 OK"입니다. 본인 모듈명 + I 타겟 1줄 + 빈 카드 4개. 그 이상은 #5 AI Studio + #6 본 모듈 구현에서 채웁니다 — 이 블록은 "내용물"이 아니라 "배포 파이프라인"을 만드는 시간입니다.

02Part 2 · app/_template 카피 → 본인 모듈 폴더 (15분, 14:30~14:45)2/6

본인 repo에 이미 들어 있는 app/_template/page.tsx를 본인 모듈 폴더로 복사합니다. 이 템플릿은 강사가 사전 push해둔 것으로, KCH 컬러 토큰과 shadcn/ui 컴포넌트가 이미 적용된 상태입니다.

Step 1 — 템플릿 복사

# 본인 repo 안에서 (예: 이재성 mjs-leaves) cp -r src/app/_template src/app/m2-leaves # 모듈명별 매핑 # 이재성: src/app/m2-leaves # 김경호: src/app/m3-performance # 이동연: src/app/m1-facilities # 이윤재: src/app/m4-tools

cp -r는 폴더 통째로 복사하는 명령입니다 (-r은 recursive — 하위 파일까지 같이 복사).

Step 2 — IPO에서 가져온 헤더 수정

복사한 page.tsx의 헤더(상단 제목·설명)를 본인 IPO의 I 타겟·I 가치로 교체합니다. D1 #3에서 작성한 IPO가 여기 처음 사용됩니다.

// src/app/m2-leaves/page.tsx 예시 (이재성) export default function M2LeavesHome() { return ( <main className="container mx-auto p-8"> <h1 className="text-2xl font-bold text-[#1962A8]">M2 — 연차 자동화</h1> <p className="mt-2 text-gray-600"> 법정+근속+해외 자동 산정 + 분기 사업부장 메일 </p> {/* IPO P-1 IA의 페이지 4개를 빈 카드로 */} <div className="grid grid-cols-2 gap-4 mt-8"> <Card title="사업부별 집계" href="/m2-leaves/dept" /> <Card title="개인별 잔여" href="/m2-leaves/employee" /> <Card title="분기 리포트" href="/m2-leaves/quarterly" /> <Card title="ERP 업로드" href="/m2-leaves/erp-upload" /> </div> </main> ); }
TIP

빈 카드 4개로 충분합니다. 카드 클릭 → 빈 페이지여도 OK. 색·폰트는 KCH 컬러 토큰(이미 적용됨) 그대로. 내용물 채우기는 D1 #5 AI Studio + D2 #6에서 합니다.

text-[#1962A8]이 무엇인가요

Tailwind CSS 문법으로 KCH primary 컬러(#1962A8)를 텍스트 색에 직접 적용한 것입니다. Tailwind 변수로도 쓸 수 있지만, 본인이 직접 값을 보고 확인할 수 있도록 hex 코드 그대로 적었습니다.

03Part 3 · Claude Code에 위임 — Firebase App Hosting 배포 (45분, 14:45~15:30)3/6

가장 중요한 단계입니다. 배포 단계를 사람이 손으로 하나씩 하지 않고 Claude Code에 통째로 위임합니다. 이게 CLI 자력 운전의 본질 체험 1번째입니다.

Step 1 — Claude Code에 배포 요청

다음 프롬프트를 그대로 복붙. {모듈경로}{본인-projectId} 슬롯만 본인 것으로 바꿉니다.

Claude, 내 Next.js 앱을 Firebase App Hosting에 처음 배포하려고 해. 상태: - src/app/{모듈경로}/page.tsx 가 빈 카드 4개로 만들어져 있어 - firebase init 끝나 있음 - App Hosting 활성화됨 - 프로젝트 ID: {본인-projectId} 내가 해야 할 일: 1. apphosting.yaml 생성 (Next.js 14 + 한국 리전) 2. firebase.json 점검 (App Hosting 등록) 3. Github 연결 → 자동 배포 트리거 4. 첫 배포 실행 + URL 출력 순서대로 진행해줘. 막히면 멈추고 나에게 물어봐.

→ Claude가 다음을 자율 진행합니다:

  • apphosting.yaml 생성 (이 파일이 "이 앱은 Next.js이고 한국 리전에 배포한다"를 적어둠)
  • firebase.json 점검 (App Hosting 사이트 ID 등록 확인)
  • GitHub repo 연결 (Firebase가 본인 GitHub repo의 push를 감지하도록)
  • 첫 빌드 트리거 → 5-10분 빌드 → URL 출력

"막히면 멈추고 나에게 물어봐"가 핵심 — Claude가 권한·환경 변수 같은 사람의 결정이 필요한 지점에서 멈춰서 본인에게 물어봅니다. 이걸 안 적으면 Claude가 임의로 진행해서 잘못된 설정이 들어갈 수 있습니다.

Step 2 — 본인 URL 확보

배포가 끝나면 Claude가 본인 URL을 출력합니다. 이 URL을 본인 셋업 메뉴 §3 ("본인 URL 기록")에 저장합니다. 14h 동안 계속 쓰일 주소입니다.

이재성 https://m2-leaves--{projectId}.{region}.hosted.app 김경호 https://m3-performance--{projectId}.{region}.hosted.app 이동연 https://m1-facilities--{projectId}.{region}.hosted.app 이윤재 https://m4-tools--{projectId}.{region}.hosted.app

URL 클릭 → 본인 모듈 헤더 + 빈 카드 4개가 떠야 합니다. 이게 14h의 첫 가시 자산입니다.

04Part 4 · 4명 URL 디자인 정렬 (15분, 15:30~15:45)4/6

여기서 한 번 멈추고 4명 URL을 한 화면에 펼쳐 비교합니다. D2 #8 통합의 성패가 여기서 결정되기 때문입니다 — 지금 4명 디자인이 어긋나 있으면 통합 시점에 손볼 시간이 없습니다.

4명 URL 한 화면 비교 — 통일 기준

브라우저 4탭에 4명 URL을 펼치고, 다음 6개 항목이 4명 모두 동일한지 시각으로 확인합니다.

비교 항목통일 기준
Primary 컬러#1962A8 동일 (KCH 다크 블루)
Secondary 컬러#70AEDA 동일 (KCH 라이트 블루)
폰트Pretendard 단일 (한글 자모 정렬·기본 굵기 동일)
카드 border-radius8px
Shadow매우 약하게 (0 1px 2px rgba(0,0,0,0.05))
헤더 H1 사이즈28px

이 6개 중 어긋난 부분이 보이면 1줄 프롬프트로 정렬합니다.

Claude, 내 src/app/globals.css 다시 읽고 KCH 컬러 토큰을 강제로 적용해줘. Primary는 #1962A8, Secondary는 #70AEDA. shadcn/ui 컴포넌트도 다시 매핑해줘.

→ Claude가 globals.csstailwind.config.ts의 컬러 변수를 다시 정렬. git push하면 자동 빌드되어 URL이 갱신됩니다.

IMPORTANT

이 시점에 4개 URL이 색·폰트가 통일되어야 D2 #8 통합이 깔끔합니다. 따로 노는 색은 통합 시점에 손볼 시간이 없습니다 — 1시간 안에 통합 인덱스를 만들어야 하는데, 그 시간을 디자인 정렬에 쓰면 통합 자체가 무너집니다.

05Part 5 · 자동 배포 파이프라인 검증 (15분, 15:45~16:00)5/6

마지막 15분에 자동 배포 파이프라인을 한 번 더 검증합니다. 이 파이프라인이 D2 종일의 기반이기 때문에, D1에 확실히 동작하는지 확인하고 가야 합니다.

Github push → 자동 배포 검증

본인 repo의 src/app/{모듈경로}/page.tsx에서 텍스트 1줄을 의도적으로 수정합니다.

<h1 className="text-2xl font-bold text-[#1962A8]">M2 — 연차 자동화 v0.1</h1> // ↑ 수정

수정 후 git에 커밋하고 push합니다.

git add src/app/{모듈경로}/page.tsx git commit -m "chore: 첫 자동 배포 검증" git push

→ Firebase App Hosting이 자동으로 새 빌드를 트리거 → 5-10분 후 URL 갱신 확인.

feat / fix / chore 커밋 메시지 접두

git 커밋 메시지의 접두는 이 변경의 성격을 알려주는 관례입니다.

  • feat: 새 기능 추가
  • fix: 버그 수정
  • chore: 잡일·설정·실험적 변경

본인이 직접 외울 필요는 없고, 본인 슬래시커맨드(/deploy)에 적어두면 Claude가 알아서 골라 줍니다.

TIP

이 자동 배포 파이프라인이 D2 종일 작업의 기반입니다. D2에 매번 firebase deploy를 손으로 칠 필요 없이 git push로 자동 배포됩니다. 그래서 D2 #6에서 슬래시커맨드 /deploy 1개를 만들어 두면, 본인이 D2 동안 5-10번 칠 명령을 한 줄로 압축할 수 있습니다.

06Part 6 · 체크리스트 + 핵심 정리6/6
  • app/_template → 본인 모듈 폴더 카피 완료
  • ☐ 본인 모듈 헤더 (I 타겟·I 가치) 수정
  • apphosting.yaml + firebase.json 정상
  • 본인 URL 1개 확보 (껍데기 OK)
  • ☐ 4명 URL 디자인 정렬 (KCH 컬러 통일)
  • ☐ git push → 자동 배포 검증
  • ☐ 본인 URL을 셋업 메뉴 §3에 기록
핵심 포인트

• 90분 단일 목표 = 본인 URL 1개 (껍데기 OK). 내용물이 아니라 배포 파이프라인을 만드는 시간

• 첫 URL이 D2 종일의 추진력 — 발표할 단일 가시 자산

Claude Code에 배포를 위임apphosting.yaml·firebase.json·Github 연결까지 자율

• 4명 URL 펼쳐서 KCH 컬러 통일 정렬 — D2 #8 통합 성패가 여기서 결정

• 자동 배포 파이프라인 = git push → Firebase App Hosting 자동 빌드. D2 종일의 기반

CH05 실습 D1 #5 · 16:00~17:30 · 90분

Part 5 — AI Studio 프론트 모형 + KCH 컬러 강제 라인

4명이 각자 AI Studio를 자유롭게 돌리면 4모듈이 누더기가 됩니다. 사전 강제 라인 1장이 통합감을 만듭니다. 산출물: 본인 모듈 페이지 시안 5-7개.

읽기 12분·업데이트: 2026-05-05
01Part 1 · 왜 강제 라인이 필요한가1/6

D1 #4에 본인 URL은 확보됐지만, 안에 들어 있는 건 빈 카드 4개뿐입니다. 이 90분에 각 페이지의 시안(어떤 화면 구성으로 보일지의 첫 그림)을 받아옵니다.

시안을 받는 도구로 Google AI Studio를 씁니다. AI Studio는 Gemini 모델을 쓰는 무료 웹 콘솔로, 디자인 시안을 빠르게 받기에 가장 편합니다.

자유 프롬프트의 함정

같은 프롬프트라도 4명이 각자 입력하면 결과가 다음처럼 분기됩니다.

항목분기되는 양상
컬러Tailwind 기본 / Material / 임의 hex (#3B82F6 등)
폰트Pretendard / Inter / 시스템 기본
컴포넌트shadcn / Material UI / 직접 작성 div
레이아웃좌측 사이드바 / 상단 탭 / 카드만
Border-radius4px / 8px / 16px / pill

이렇게 4명 시안이 따로 놀면 D2 #8 통합 시점에 한 대시보드처럼 안 보입니다.

IMPORTANT

해법은 "통일하라"가 아니라 "강제 라인 1장을 4명이 동일 복붙"입니다. AI Studio 프롬프트 상단에 디자인 시스템 강제 라인이 들어가면 본인 IPO 내용과 무관하게 색·폰트·컴포넌트가 자동으로 묶입니다. 이 1장을 4명이 그대로 복붙하면, 출력 결과의 톤이 자연스럽게 통일됩니다.

02Part 2 · AI Studio 프롬프트 강제 라인 (10분, 16:00~16:10)2/6

다음 프롬프트 구조를 4명 모두 동일하게 씁니다. 상단 [디자인 시스템 강제] 블록 + [내 모듈 IPO] 블록 2개로 구성됩니다.

강제 라인 — 4명 동일 복붙

[디자인 시스템 강제] - 컬러: primary #1962A8 (KCH 다크 블루), secondary #70AEDA (KCH 라이트 블루), success #10B981, warning #F59E0B, danger #EF4444 - 폰트: Pretendard 한 종류만, h1=28 / h2=22 / h3=18 / body=14 / small=12 - 컴포넌트: shadcn/ui Card·Badge·Tabs·DataTable만 사용, 다른 라이브러리 금지 - 레이아웃: 좌측 사이드바 X, 상단 탭 4개(휴양시설·연차·성과관리·도구) + 메인 콘텐츠 카드 그리드 - border_radius: 8px, shadow 매우 약하게 - 다크모드 지원 X (인사총무 화이트만) - 한국어 톤: 임원 전달 수위 (반말 X), Pretendard 자모 정렬 [내 모듈 IPO] (여기에 D1 #3에서 작성한 본인 IPO 4섹션 그대로 복붙) [요청] 위 디자인 시스템 강제 라인을 따라 내 모듈의 페이지 N개 시안을 Next.js 14 (App Router) + shadcn/ui로 컴포넌트 단위로 작성해. 라우트별로 page.tsx 파일을 분리하고, 카드/배지/탭/테이블만 사용해.

왜 shadcn/ui 4종(Card·Badge·Tabs·DataTable)만 쓰는가

shadcn/ui는 React에서 가장 많이 쓰이는 UI 컴포넌트 라이브러리 중 하나입니다. 컴포넌트 종류가 수십 개가 넘는데, 우리는 그중 4종만 씁니다.

  • Card — 콘텐츠 묶는 박스. 카드 하나에 정보 한 덩어리
  • Badge — 작은 라벨. 상태(active/paused) 표시용
  • Tabs — 탭 전환. 분기·연도·카테고리 분리용
  • DataTable — 표. 직원 목록·평가 결과 같은 행 데이터용

4종으로 한정하는 이유는 두 가지입니다 — 4명 디자인이 자연스럽게 통일되고, 본인이 14h 안에 익혀야 하는 컴포넌트 수가 줄어듭니다. 본인이 후속 30일에 다른 컴포넌트(Dialog·Toast·Form 등)를 추가할 수 있지만, 워크숍 14h는 4종으로 충분합니다.

TIP

본인 IPO를 그대로 복붙하면 됩니다. 4단 질문 답변 → IPO → AI Studio 프롬프트로 흐름이 자연스럽게 이어집니다. D1 #2 → #3 → #5의 메타 흐름이 이 시점에 처음 한 사이클을 완성합니다.

03Part 3 · 4명 모듈별 시안 생성 (60분, 16:10~17:10)3/6

이제 각자 본인 모듈로 AI Studio에 호출합니다. 페이지 수와 핵심 페이지는 모듈마다 다릅니다.

본인 모듈로 AI Studio 호출 → 시안 받기

참가자모듈페이지 수핵심 페이지
이재성M2 연차5개홈·사업부별·개인별·분기 리포트·ERP 업로드
김경호M3 성과관리6개홈·KPI 입력·평가 진행·등급 결과·성과급/연봉·대시보드
이동연M1 휴양시설5개홈·지역별·신청·통합 캘린더·유지보수
이윤재M4 사내 도구5개통합 인덱스 · 카탈로그 · 등록 폼 · 대시보드 · 도구 상세

본인 셋업 메뉴 §3에 모듈별 추가 프롬프트가 적혀 있습니다 (예: 이재성 M2의 ERP 업로드 페이지는 textarea + 미리보기 카드). 그 추가 프롬프트를 [디자인 시스템 강제] 블록 다음에 추가하면 시안 품질이 올라갑니다.

AI Studio → 본인 repo로 끌어오기

AI Studio가 출력한 코드를 본인 VS Code에 직접 복붙할 수도 있지만, Claude Code에 위임하는 게 훨씬 빠릅니다. 파일 분리·import 정리를 Claude가 알아서 해주기 때문입니다.

Claude, AI Studio가 만든 다음 시안을 내 src/app/{모듈경로}/ 아래에 page.tsx 파일들로 분리해서 저장해줘. shadcn/ui 컴포넌트 import도 자동으로 맞춰줘. (시안 코드 붙여넣기)

→ Claude가 다음을 자율 진행:

  • AI Studio가 출력한 한 덩어리 코드를 라우트별 page.tsx로 분리
  • 각 파일 상단에 필요한 import 문 추가
  • shadcn/ui 컴포넌트가 누락된 경우 npx shadcn-ui add card 같은 설치 명령 안내
  • 본인 디렉토리 구조에 맞게 저장

본인은 결과를 한 번 훑어보고 OK만 하면 됩니다.

04Part 4 · AI Studio 결과 → 첫 배포 갱신 (15분, 17:10~17:25)4/6

시안이 본인 repo에 들어갔으면 git push로 배포합니다.

git push → Firebase App Hosting 자동 빌드

git add src/app/{모듈경로}/ git commit -m "feat({모듈}): AI Studio 시안 적용 v0.2" git push

→ 5-10분 빌드 → 본인 URL 갱신 → 시안이 공개 환경에서 떠야 합니다.

4명 URL 정렬 검증

D1 #4 마지막에 했던 정렬 검증을 한 번 더. 이번엔 시안이 들어온 상태에서 KCH 컬러·폰트·컴포넌트가 통일됐는지 확인합니다.

점검 항목통과 기준
4모듈 동일 폰트 (Pretendard)한글 자모 정렬·기본 굵기 동일
4모듈 동일 컬러 토큰Primary #1962A8 동일 사용
4모듈 카드 컴포넌트shadcn/ui Card 단일 사용
4모듈 탭 컴포넌트shadcn/ui Tabs 단일 사용

어긋난 부분은 1줄 프롬프트로 정렬:

Claude, 내 src/app/{모듈경로}/ 다시 읽고 KCH 컬러 토큰·Pretendard·shadcn/ui로 강제 정렬해줘.
05Part 5 · D1 마무리 (5분, 17:25~17:30)5/6

오늘 하루를 닫는 5분입니다.

D1 한 줄 회고

"오늘 가장 어려웠던 부분은 ___, 가장 추진력을 만든 부분은 ___."

이 한 줄을 본인 셋업 메뉴 §4 ("D2 진입 체크리스트") 위에 적어두시면, D2 시작 시 본인 페이스 잡기에 도움이 됩니다.

D2 사전 공지 — 본인이 준비할 것

IMPORTANT — D2 #6 시작 전 본인이 준비할 것
  • 본인 더미 데이터 — 토큰화된 형태로 (이름→E001, 사번→E001, 연봉→토큰)
  • 본인 셋업 메뉴 §4 ("D2 진입 체크리스트") 펼쳐 보기
  • 막혔던 부분 1줄 메모 → D2 #6 첫 5분에 공유
TIP

D2는 60% 자유 작업입니다. 점검 3회(10:30 / 14:00 / 16:00)가 동기화 지점. 그 사이는 본인 페이스로 진행. 2분 룰 유지 — 같은 에러 2분 → 손 들기.

06Part 6 · 체크리스트 + 핵심 정리6/6
  • ☐ AI Studio 강제 라인 + 본인 IPO 복붙 → 시안 받음
  • ☐ 본인 모듈 페이지 N개 (5-7개) 본인 repo에 저장
  • ☐ git push → Firebase App Hosting 자동 빌드 성공
  • ☐ 본인 URL이 시안 적용 상태로 갱신
  • ☐ 4명 URL 펼쳐서 KCH 컬러·폰트·컴포넌트 통일 검증
  • ☐ D1 한 줄 회고
  • ☐ D2 #6 진입 체크리스트 (셋업 메뉴 §4) 펼쳐 봄
핵심 포인트

AI Studio 강제 라인 1장이 4명 시안을 자동으로 묶는 단일 도구

• 강제 라인 = 컬러·폰트·컴포넌트·레이아웃·border-radius·다크모드 X 6요소 명시

• 4명이 동일 복붙 + 본인 IPO 추가 = 4모듈이 한 대시보드 톤

shadcn/ui 4종(Card·Badge·Tabs·DataTable)만으로 한정 — 통일감 + 학습 비용 ↓

Claude Code에 시안 정리 위임 = 자동 파일 분리·import 정리

• git push → 자동 빌드 → 본인 URL 갱신 → 4명 정렬 검증

• D1 마무리는 회고 1줄 + D2 사전 공지. 본인 셋업 메뉴 §4 펼쳐 보기

CH06 실습 D2 #6 · 09:30~12:00 · 150분

Part 6 — 본 모듈 구현 1차: Firestore + UI + CLAUDE.md 정착

Day 2 시작. CLAUDE.md 1장으로 본인 의도를 영속화한 뒤, Firestore 컬렉션을 채우고 UI를 동작시킵니다. 산출물: 본인 모듈 프론트 동작 (더미 데이터 흐름) + CLAUDE.md + 슬래시커맨드 1개.

읽기 18분·업데이트: 2026-05-05
01Part 1 · 왜 CLAUDE.md를 먼저 작성하는가1/6

D1 #2 메타스킬 마무리에 사전 공지한 내용이 있습니다:

내일 CLAUDE.md 작성 시 이 4단 질문 답변이 시스템 프롬프트가 됩니다.

이 시점이 그 이행입니다. CLAUDE.md는 본인 repo 루트에 두는 단일 문서로, Claude Code가 매 세션을 시작할 때 자동으로 가장 먼저 읽는 시스템 프롬프트 역할을 합니다. 본인이 매번 "내 프로젝트는 이런 룰이야"를 다시 입력하지 않아도 자동 주입됩니다.

CLAUDE.md 없이 D2를 가면 어떻게 되는가

IMPORTANT
  • 같은 작업을 시킬 때마다 톤·구조가 다름 — Claude가 매번 다른 방식으로 코드를 짜기 때문
  • 보안 룰(익명화·Secret Manager) 매번 다시 명시해야 함 — 까먹으면 인사정보 누수
  • 컬렉션 명명 규칙·파일 구조 매번 다시 확정 — 컬렉션 이름이 통일 안 되면 데이터 정합성 깨짐

CLAUDE.md 1장이 D2 종일의 일관성을 만듭니다.

02Part 2 · D2 시작 (15분, 09:30~09:45)2/6

본격 시작 전 15분에 어제 회고와 오늘 점검 시점을 정렬합니다.

4명 1줄 회고

"어제 못 끝낸 것 1개 + 오늘 가장 먼저 손볼 것 1개"

이 한 줄이 D2 페이스 잡기의 출발점입니다. 어제 못 끝낸 게 있다면 그 항목부터 손을 대고, 그게 없으면 CLAUDE.md 작성으로 바로 진입합니다.

D2 점검 3회 시점

D2는 60% 자유 작업입니다. 그래서 동기화 지점이 3개 정해져 있습니다 — 이 시점에 4명 모두 본인 진도를 1분씩 보고합니다.

시점무엇을 점검
10:30CLAUDE.md 작성 + 슬래시커맨드 1개 + Firestore 컬렉션 1개 진입
14:00실데이터(익명화) 흐름 + 자동화 게이트 80% 진입
16:00통합 인덱스 카드 등록 + 최종 배포 직전

이 3시점만 동기화되면, 그 사이는 본인이 본인 페이스로 진행하면 됩니다.

2분 룰 재확인

2분 룰

같은 에러 2분 → 손 들기 → 옆 분 → 강사. 14h 동안 가장 많이 시간을 잃는 함정은 "조금만 더 해보면 풀릴 것 같아서" 30분씩 끌어안고 있는 것입니다.

03Part 3 · CLAUDE.md 작성 (30분, 09:45~10:15)3/6

CLAUDE.md는 6개 섹션으로 구성됩니다. 각 섹션이 무엇을 담는지 한 번 풀어 적습니다.

CLAUDE.md 6대 섹션

본인 repo 루트에 CLAUDE.md 파일을 생성합니다.

# CLAUDE.md — {본인 모듈명} ## 1. Intent (의도 결정화 — D1 #2 4단 질문 답변) - WHO: {대상} - WHY: {결정/실행} - CONTEXT: {도메인 룰·외부 데이터} - VERIFY: {검증점} ## 2. Stack (불변) - Next.js 14 App Router + TypeScript - Firestore + Firebase Auth (한국 리전) - Firebase App Hosting 자동 배포 - shadcn/ui Card·Badge·Tabs·DataTable만 사용 - KCH 컬러: primary #1962A8, secondary #70AEDA ## 3. 보안 강제 (3중 게이트) - 직원 식별 컬럼은 Firestore push 전 토큰 치환 강제 (E001~E020) - 이름·연봉·주민번호 평문 저장 금지 - 산출 룰·API 키는 Cloud Secret Manager (코드/repo X) - .gitignore 강제: .env, .firebase-mcp-key.json, *.adminsdk*.json ## 4. 파일 구조 src/app/{모듈경로}/ src/lib/{모듈}-domain.ts ← 도메인 룰 src/lib/{모듈}-firestore.ts ← Firestore 어댑터 functions/{모듈}-automation.ts ← 자동화 게이트 ## 5. 명명 규칙 - 컬렉션: 소문자 복수 (employees, leave_balances, …) - 함수: camelCase (getLeaves, calcSalary, …) - 페이지 라우트: 모듈경로/하이픈-카밥-케이스 (m2-leaves/erp-upload) ## 6. 금지 사항 - 외부 API 호출 (김경호 M3 한정 — 워크숍 14h) - 좌측 사이드바 레이아웃 - 다크모드 - 인사정보 평문 commit - 실 연봉 금액 Firestore 저장

각 섹션이 왜 필요한가

  • §1 Intent — D1 #2 4단 질문 답변이 여기 들어옵니다. 본인 모듈의 목적이 매 세션 자동 주입되어, Claude가 항상 같은 의도 위에서 코드를 짭니다.
  • §2 Stack — Claude가 다른 stack(예: Vue, MongoDB)으로 빠지지 않도록 못 박는 섹션. "왜 굳이 적느냐"는 의문이 들 수 있는데, 적지 않으면 Claude가 "Vercel에 배포하는 게 더 쉽다" 같은 대안을 제시할 수 있습니다.
  • §3 보안 강제 — 가장 중요한 섹션. 인사정보 보호 룰을 1장에 박아두면 Claude가 코드를 짤 때 자동으로 토큰화 가드를 호출합니다.
  • §4 파일 구조 — 본인이 새 파일을 어디에 만들어야 하는지 Claude가 헷갈리지 않게 합니다.
  • §5 명명 규칙 — 컬렉션·함수·라우트 이름이 한 모듈 안에서 일관되게 가도록 강제. 통합 시점에 다른 모듈과도 자연스럽게 맞물립니다.
  • §6 금지 사항 — Claude가 실수로 하지 말아야 할 것을 못 박습니다. "외부 API 호출 0건" 같은 룰은 명시 안 하면 Claude가 편의상 외부 API를 쓰게 됩니다.

슬래시커맨드 1개 — 자주 치는 명령을 압축

CLAUDE.md 작성이 끝났으면 슬래시커맨드 1개를 만듭니다. 슬래시커맨드는 본인이 자주 치는 명령을 /이름 한 줄로 압축한 것입니다.

mkdir -p .claude/commands

.claude/commands/deploy.md 파일을 만들고:

--- description: 본인 모듈 변경사항을 git push → Firebase App Hosting 자동 배포 트리거 --- 다음 단계로 진행해줘: 1. `git status`로 변경 파일 확인 2. 직원 식별 컬럼이 평문으로 들어간 게 없는지 검증 (CLAUDE.md §3 보안 게이트) 3. `git diff --staged`로 시각 검수 4. 커밋 메시지 작성 (feat/fix/chore 접두 + 모듈명 prefix) 5. `git push origin main` 6. Firebase App Hosting 빌드 시작 안내

이제 Claude Code 안에서 /deploy만 치면 위 6단계가 자동으로 돕니다.

본인 모듈에 맞는 슬래시커맨드

참가자슬래시커맨드용도
이재성/seed-erpERP CSV 더미 1건 → Firestore 변환
김경호/run-salary평가 등급 입력 → 산출 엔진 강제 트리거 시연
이동연/run-lottery시드 추첨 시뮬레이션
이윤재/register-tool도구 카탈로그 1건 등록
TIP

슬래시커맨드 1개로 충분합니다. 본인이 D2 동안 5번 이상 칠 명령을 슬래시 1개로 압축하는 게 본질. 더 많이 만들면 본인이 외워야 하는 슬래시 종류가 늘어나서 오히려 비효율입니다.

04Part 4 · Firestore 컬렉션 + UI 1차 (90분, 10:15~11:45)4/6

이제 데이터를 채우고 화면을 동작시킵니다.

Step 1 — Firebase MCP에 컬렉션 자동 생성 위임 (20분)

본인이 Firestore 콘솔에서 컬렉션을 클릭으로 만들 필요가 없습니다. Claude에게 위임합니다.

Claude, 다음 컬렉션 N개를 Firestore에 만들어줘. 스키마는 IPO와 CLAUDE.md를 따라. 더미 데이터는 토큰화된 형태로 N건씩 (이름은 E001~E020 토큰만, 연봉·주민번호 X). (IPO P-2 백엔드 섹션 붙여넣기)

→ Claude가 Firebase MCP로 컬렉션 + 더미 데이터를 자동 push.

WARNING

더미 데이터가 토큰화되지 않은 채 들어가면 즉시 Firestore 데이터 삭제 → 토큰 치환 후 재투입. 이 시점이 익명화 룰을 손에 익히는 첫 실전입니다.

Step 2 — UI 페이지 동작 연결 (60분)

본인 모듈의 라우트 5-7개 중 가장 핵심 1개부터 데이터를 연결합니다. 처음부터 5개 다 동작시키려고 하면 시간이 모자랍니다 — 1개를 끝까지 동작시키고, 나머지는 D2 #7으로 이월합니다.

참가자핵심 페이지 1개동작해야 하는 것
이재성/m2-leaves/employee/[id]empId 1명 선택 → 법정+근속+해외 자동 산정 결과 표시
김경호/m3-performance/kpi-inputKPI 입력 폼 → 가중치 합 100% 검증 → Firestore 저장
이동연/m1-facilities/apply신청 폼 → 자격·페널티 검증 → 적격/부적격 결과
이윤재/ (통합 인덱스)4모듈 카드 4개 표시 (다른 3명 URL 카드 슬롯 준비)
Claude, 내 IPO P-1 IA의 {핵심 페이지}를 동작시켜줘. 요구: - Firestore에서 데이터 fetch (Server Component 또는 Server Action) - 화면에 핵심 정보 N개 표시 - KCH 컬러 토큰 + shadcn/ui Card·Badge로 - 빈 상태(데이터 0건) UI도 같이 CLAUDE.md를 읽고 보안 룰·명명 규칙 따라.

마지막 줄 "CLAUDE.md를 읽고…"가 핵심 — 이 한 줄로 §3 보안 룰과 §5 명명 규칙이 자동으로 반영됩니다.

Server Component / Server Action이 무엇인가요

Next.js 14의 데이터 가져오는 두 가지 방식입니다.

  • Server Component — 페이지가 서버에서 렌더링될 때 Firestore에서 데이터를 가져와 HTML과 함께 보냄. 가장 빠르고 SEO에 좋음.
  • Server Action — 사용자가 폼 제출 같은 액션을 했을 때 서버에서 실행되는 함수. 폼 입력값을 Firestore에 저장할 때 사용.

본인이 직접 둘을 구분할 필요는 없고, Claude에게 "이 페이지는 어떤 방식으로 짜는 게 적절한지"만 물어보면 알아서 골라 줍니다.

Step 3 — 10:30 점검 (10분)

10:30이 되면 1분씩 본인 진도를 보고합니다.

1분 보고 항목점검 기준
CLAUDE.md 작성 어디까지6대 섹션 빠짐 점검
Firestore 컬렉션 N개 만듦인사정보 누수 검수
핵심 페이지 동작?빈 상태 UI도 같이 점검
05Part 5 · 본 모듈 화면 다듬기 (15분, 11:45~12:00)5/6

점심 직전 15분에 화면 마감 디테일을 보강합니다.

시안 → 실제 데이터 흐름 보강

D1 #5의 시안에서 더미 카드만 있던 페이지에 실제 Firestore 데이터를 흘려 넣습니다. 이때 다음 4가지 상태를 추가합니다 — 실제 사용자가 쓸 때 데이터가 항상 있는 게 아니기 때문입니다.

다듬기 항목1줄
Loading 상태shadcn/ui Skeleton 컴포넌트 — 데이터 로딩 중 회색 박스
빈 상태"아직 데이터가 없습니다" + 추가 버튼
에러 상태"잠시 후 다시 시도해주세요" + 새로고침
합계·집계Badge로 N건·합계 표시

이 4가지를 Claude에게 한 번에 시키면 됩니다:

Claude, 내 핵심 페이지에 Loading/Empty/Error 상태를 shadcn/ui Skeleton·Card로 추가해줘.

git push → 자동 배포 갱신

git add . git commit -m "feat({모듈}): D2 1차 — 컬렉션 + 핵심 페이지 동작" git push

→ 5-10분 빌드 → 점심 시간 동안 갱신 → 점심 후 #7 시작 시 본인 URL이 데이터 흐름 상태로 떠야 함.

이제 본인 URL은 단순한 껍데기가 아니라 실제 데이터가 흐르는 모듈입니다.

06Part 6 · 체크리스트 + 핵심 정리6/6
  • CLAUDE.md 6대 섹션 작성 (Intent / Stack / 보안 / 파일구조 / 명명규칙 / 금지)
  • ☐ 슬래시커맨드 1개 (.claude/commands/*.md)
  • ☐ Firestore 컬렉션 N개 생성 + 더미 데이터 토큰화
  • ☐ 본인 핵심 페이지 1개 데이터 동작
  • ☐ Loading / Empty / Error 상태 보강
  • ☐ git push → 자동 빌드 갱신
  • ☐ 10:30 점검 통과
핵심 포인트

CLAUDE.md = 본인 repo의 단일 시스템 프롬프트. 매 세션 자동 로딩 → 의도가 매 세션 다시 입력하지 않아도 주입

• 6대 섹션 (Intent / Stack / 보안 / 파일구조 / 명명규칙 / 금지) — 빠짐 없이

• 슬래시커맨드 1개 = 본인이 D2 동안 5번 이상 칠 명령을 압축. 1개로 충분

Firebase MCP로 컬렉션 자동 생성 — 사람이 console에서 클릭 X

• 인사정보 누수 0건 — Firestore push 전 토큰 치환 강제

• 핵심 페이지 1개부터 동작 → 다른 페이지는 #7로 이월 (한 번에 5개 동작 X)

CH07 실습 D2 #7 · 13:00~15:00 · 120분

Part 7 — 본 모듈 마감: 실데이터(익명화) + 자동화 게이트 1개

점심 후 120분. 자동화 게이트 1개가 동작하면 본 모듈이 살아 있다고 말할 수 있습니다. 산출물: 본인 모듈 v1 — 실데이터(익명화) 흐름 + 자동화 게이트 1개 발화.

읽기 16분·업데이트: 2026-05-05
01Part 1 · 시작 5분 — 익명화 게이트 시연 (13:00~13:05)1/6

오늘 14h 보안의 핵심 5분입니다. 데이터를 채우기 전에 익명화 가드 함수를 만들어두는 게 순서입니다 — 가드가 없으면 그 이후 들어가는 모든 push가 위험합니다.

인사정보 익명화 룰

워크숍은 가상 더미를 쓰지만, 실 데이터로 마이그레이션된 직후 다음 룰이 그대로 적용되어야 합니다. 아래 표가 어떤 컬럼을 어떻게 처리하는지의 단일 기준입니다.

컬럼처리
이름E001, E002... 토큰 치환
사번UID 또는 토큰 치환
주민번호컬럼 자체 제거 (저장 X — 처음부터 없는 게 안전)
연락처컬럼 자체 제거
연봉토큰 ID 매핑으로만 저장 (실 금액은 Cloud Secret Manager에 별도)
부서명그대로 유지 (식별성 낮음)
평가 점수토큰 ID 기준으로만 저장

원칙: "필요해서 저장하지만 누설되면 위험한 값"은 토큰화. "꼭 저장할 필요 없는 값"(주민번호·연락처)은 컬럼 자체를 제거. 두 갈래 중 안전한 쪽으로 보내는 게 룰입니다.

Firebase MCP로 토큰 치환 함수 작성

다음 프롬프트를 그대로 복붙하면 Claude가 가드 함수와 push 가드를 한 번에 작성합니다.

Claude, src/lib/anonymize.ts 만들어줘. 다음 함수: - tokenizeEmpId(name: string): string // "홍길동" → "E001" - stripPII(record: any): any // 주민번호·연락처 컬럼 제거 - maskSalary(amount: number): string // 실 금액 → 토큰 ID 매핑 Firestore에 push 직전에 반드시 호출되도록 가드 함수도 같이 만들어: - pushSafe(collection: string, doc: any): Promise<void> → stripPII 자동 적용 후 push

pushSafe가 핵심인 이유

pushSafe(collection, doc)은 Firestore에 데이터를 push할 때 유일하게 허용되는 진입로입니다. 본인 코드에서 직접 db.collection(...).add(...)를 쓰지 않고 무조건 pushSafe를 거치게 합니다.

이 가드를 만들면, 본인이 코드를 짤 때 실수로 평문 데이터를 push하려고 해도 pushSafe가 자동으로 stripPII를 적용해 막아 줍니다. 사람의 실수를 시스템이 차단하는 구조입니다.

CLAUDE.md §3에 "모든 Firestore push는 pushSafe를 거친다"를 적어두면, 이후 Claude가 새 코드를 짤 때마다 이 룰이 자동 반영됩니다.

WARNING

이 5분이 14h 보안의 핵심입니다. 가드 함수 없이 push가 들어가면 후속 30일 실 데이터 시점에 인사정보 누수 사고가 발생할 수 있습니다.

02Part 2 · 본 모듈 페이지 마감 (60분, 13:05~14:05)2/6

이제 데이터 양을 늘리고 페이지를 마무리합니다.

Step 1 — 더미 데이터 → 실 더미(50-100건) 확장

D2 #6의 더미 데이터(N건)를 본인 모듈에 맞는 양으로 늘립니다. 50건 정도가 있어야 페이지에서 표·집계·차트를 볼 때 의미가 있습니다.

Claude, 내 모듈에 맞는 샘플 데이터 50건 더 넣어줘. 한국 인사총무 맥락 그대로. - 사번 토큰: E021~E070 - 입사일 분포: 2010~2025 - 부서: 4개 분포 (영업본부·R&D본부·인사총무팀·재무팀) - {참가자별 모듈 특화 룰} — 본인 셋업 메뉴 §5 참조 - pushSafe로 push (익명화 가드 적용)

마지막 줄 "pushSafe로 push"가 핵심. 이걸 명시 안 하면 Claude가 직접 db.collection(...).add(...)로 push할 수 있습니다.

Step 2 — 페이지 4-5개 모두 동작

D2 #6에서는 핵심 페이지 1개만 동작했습니다. 이 시간에 나머지 페이지를 동작 상태로 끌어올립니다.

참가자D2 #6 끝 상태D2 #7에서 추가
이재성개인별 잔여 1페이지사업부별 집계 + 분기 리포트 + ERP 업로드
김경호KPI 입력 폼평가 진행 + 등급 결과 + 성과급/연봉
이동연신청 폼5지역 지역별 + 통합 캘린더 + 유지보수
이윤재통합 인덱스 (4카드 슬롯)카탈로그 + 등록 폼 + 도구 상세 + 대시보드

각 페이지를 한 번에 시키지 말고 1개씩 처리합니다. "이번 페이지 끝나면 다음 페이지" 식으로 가야 Claude가 한 페이지씩 검증하면서 진행합니다.

Step 3 — 14:00 점검

14:00이 되면 1분씩 본인 진도 보고.

점검통과 기준
페이지 4-5개 동작데이터 fetch + 빈/로딩/에러 상태
익명화 가드 적용모든 Firestore push가 pushSafe 거침
디자인 토큰KCH 컬러 그대로 유지
03Part 3 · 자동화 게이트 1개 (50분, 14:05~14:55)3/6

이 50분이 D2 #7의 핵심입니다. 자동화 게이트가 없는 모듈은 사람이 매번 손으로 호출해야 하는 단순 화면입니다. 게이트가 있어야 시스템이 스스로 돌아가는 자동화가 됩니다.

자동화 게이트 = 본인 모듈이 살아 있다는 증거

각 모듈의 자동화 게이트는 모듈 특성에 맞춰 다릅니다.

참가자자동화 게이트트리거
이재성분기 사업부장 메일Cloud Scheduler 0 9 1 1,4,7,10 * (분기 첫날 09:00)
김경호성과급/연봉 자동 산출onEvalFinalized Cloud Function (본평가 확정 시)
이동연시즌 도래 알림 (에어컨·스노우 타이어)Cloud Scheduler 0 9 * * * (매일 09:00)
이윤재일별 도구 헬스체크 + SlackCloud Scheduler 0 9 * * * (매일 09:00)

세 가지 트리거 방식이 등장합니다.

  • Cloud Scheduler = 정해진 시간에 자동 발화 (cron)
  • onEvalFinalized = Firestore 문서가 변경될 때 자동 발화 (Firestore 트리거)
  • http = URL 호출로 발화 (수동·외부 시스템)

Step 1 — Cloud Function 스켈레톤 (15분)

본인 모듈에 맞는 자동화 함수를 작성합니다. 본인 셋업 메뉴 §5에 코드 슬롯이 있어서 그걸 베이스로 시작하면 됩니다.

Claude, 내 자동화 게이트 1개 만들어줘. 함수명: {본인 함수명} 트리거: {Cloud Scheduler / onWrite / http} 역할: {1줄 설명} 요구: - functions/src/{모듈}-automation.ts에 작성 - pushSafe 가드 적용 (익명화 통과) - Cloud Secret Manager에서 룰·키 가져오기 (직접 하드코딩 X) - 검증 게이트 추가 — 결과 산출 후 자동 검증 통과 여부 표시

마지막 줄 "검증 게이트 추가"가 D1 #2의 V(VERIFY)가 코드로 영속화되는 지점입니다. 자동화가 결과를 만들 때마다 그 결과가 정상 범위 안에 있는지 자동 검증하고 통과 여부를 기록합니다.

Step 2 — 로컬 시뮬레이션 (15분)

함수가 만들어졌으면 로컬 에뮬레이터에서 1회 강제 트리거로 시뮬레이션합니다. 실 cron 시간을 기다리거나 실 Firestore에 쓰지 않고도 동작 확인 가능합니다.

Claude, 위 자동화 함수를 로컬 에뮬레이터에서 강제 트리거해서 시연해줘. 순서: 1. firebase emulators:start --only functions,firestore 2. 함수 1회 강제 호출 (cron 시뮬레이션 또는 onWrite 트리거) 3. Firestore 결과 확인 4. 메일 Draft / Slack 메시지 / 산출 결과 출력

firebase emulators:start는 본인 PC에서 Firestore와 Cloud Functions의 로컬 시뮬레이터를 띄우는 명령입니다. 진짜 클라우드를 쓰지 않고도 함수 동작을 검증할 수 있습니다.

Step 3 — Cloud Functions 배포 (15분)

로컬에서 동작이 확인됐으면 실제 클라우드에 배포합니다.

cd functions npm run build firebase deploy --only functions:{본인-함수명}

배포가 끝나면 Cloud Functions 콘솔에서 본인 함수가 보이고, 거기서 "테스트" 버튼으로 강제 실행할 수 있습니다 → 본인 URL 또는 Firestore에서 결과 확인.

Step 4 — 검증 (5분)

검증 항목통과 기준
트리거 발화Cloud Functions 로그에 1회 실행 기록
결과 저장Firestore에 자동 산출 결과 기록
익명화 게이트 통과결과에 평문 인사정보 0건
검증 게이트 통과자동 검증 룰 (수치 범위 / 합계 일치) 표시
IMPORTANT

VERIFY 자동 검증 게이트가 핵심입니다. D1 #2에서 4단 질문의 V(VERIFY)가 이 시점에 자동 검증 룰로 구현됩니다 — 의도 단계에서 "이렇게 검증할 것"이라고 적은 게, 자동화 단계에서 "코드로 자동 검증"이 되었습니다. 메타 흐름이 한 사이클을 완성한 것입니다.

04Part 4 · D2 #7 마감 + git push (5분, 14:55~15:00)4/6
git add . git commit -m "feat({모듈}): 자동화 게이트 1개 동작 + 검증 게이트" git push

→ Firebase App Hosting 자동 빌드 → URL 갱신.

본인 URL에서 검증 시나리오 1회

배포가 끝나면 본인 URL에서 1회 검증 시나리오를 돌립니다. 이게 D2 #9 발표 시 시연할 시나리오의 베이스입니다.

참가자1회 검증 시나리오
이재성직원 1명 (E007) 페이지 → 자동 산정 결과 (법정 15 + 근속 5 = 20일)
김경호평가 1건 본평가 확정 → onEvalFinalized 자동 트리거 → 산출 결과 화면
이동연신청 1건 → 시드 추첨 → 당첨자 메일 Draft 확인
이윤재도구 1건 등록 → 헬스체크 강제 트리거 → Slack 메시지

이 시나리오가 동작하면 본인 모듈 v1이 완성된 것입니다.

05Part 5 · 체크리스트 + 핵심 정리5/6
  • 익명화 게이트 시연 완료 (pushSafe 가드 적용)
  • ☐ 본인 모듈 페이지 4-5개 데이터 흐름 동작
  • ☐ 자동화 함수 1개 작성 + 로컬 에뮬레이터 시뮬레이션 통과
  • ☐ Cloud Functions 배포 + 트리거 강제 실행 검증
  • ☐ 자동 검증 게이트 (수치 범위 / 합계 일치) 결과 표시
  • ☐ 본인 URL에서 1회 시나리오 검증
  • ☐ 14:00 점검 통과
핵심 포인트

자동화 게이트 1개 발화 = 본 모듈이 살아 있다는 증거. 사람이 매번 호출하지 않아도 시스템이 스스로 돌아감

• 익명화 게이트(pushSafe)는 5분 시연 + 모든 push가 통과해야 함. 가드가 없으면 사람 실수가 곧 인사정보 누수

• Cloud Function 자동화: cron / onWrite / http 1개 선택

• VERIFY 검증 게이트 = D1 #2 4단 질문의 V가 코드로 영속화. 메타 흐름이 한 사이클을 완성

• 로컬 에뮬레이터 → 클라우드 배포 → 본인 URL 시나리오 검증 — 이 3단계로 동작 확신

#7 끝 시점에 본인 URL이 v1 — 자동화 1개 발화 가능 상태여야 #8 통합 진입

CH08 실습 · 통합 D2 #8 · 15:00~16:30 · 90분

Part 8 — 통합 인덱스: 4모듈 카드 한 화면

이윤재 app/page.tsx가 단일 통합 지점. 메타 + URL 카드만으로 4모듈을 한 화면에서 진입할 수 있게 만듭니다. 산출물: 통합 인덱스 1개 URL — 4모듈 카드 4개.

읽기 14분·업데이트: 2026-05-05
01Part 1 · 통합 구조 — 메타 + URL 카드1/6

통합의 정의를 먼저 정리

미팅에서 약속한 "통합 대시보드"라는 말이 가장 헷갈리는 지점입니다. 통합에는 여러 깊이가 있는데, 워크숍 14h에서 만드는 건 가장 얇은 층의 통합입니다.

통합 깊이무엇을 의미하는가14h 가능 여부
메타 + URL 카드한 페이지에서 4모듈로 이동 가능✅ 본 워크숍
데이터 통합4모듈이 공통 데이터를 공유❌ 30일 후속
SSO 통합한 번 로그인하면 4모듈 모두 인증❌ 60일 후속
풀 통합4모듈이 1개 앱의 라우트로 합쳐짐❌ 90일 후속

오늘은 메타 + URL 카드까지가 합의된 범위입니다. 미팅 약속은 이걸로 충족되고, 더 깊은 통합은 30/60/90일 로드맵으로 분리됩니다.

통합 구조

이윤재 통합 인덱스 (app/page.tsx) ├── 카드 1: 휴양시설 (이동연 M1) — 외부 URL 새 탭 ├── 카드 2: 연차 자동화 (이재성 M2) — 외부 URL 새 탭 ├── 카드 3: 성과관리 (김경호 M3) — 외부 URL 새 탭 └── 카드 4: 사내 도구 카탈로그 (이윤재 M4 = 본인) — 내부 라우트

각 카드 클릭 → 본인 모듈 URL로 이동. 다른 3명은 외부 호스팅 URL이라 새 탭으로, 이윤재 본인 카드는 내부 라우트라 같은 사이트에서 이동합니다.

IMPORTANT

메타 + URL 카드만으로 충분합니다. iframe 임베드는 SSO·CSP(Content Security Policy) 헤더 협의가 필요해 14h 안에 끝나지 않습니다. 새 탭 외부 링크가 가장 단순하고 안전합니다.

02Part 2 · 이윤재 인덱스 페이지 활성화 (30분, 15:00~15:30)2/6

이 30분은 이윤재가 본인 app/page.tsx를 통합 인덱스로 만드는 시간입니다. 다른 3명은 본인 모듈 마지막 손질 + 본인 URL 정리.

Step 1 — 4모듈 카드 컴포넌트 작성 (이윤재)

이윤재 본인 repo의 app/page.tsx:

import { Card, Badge } from '@/components/ui'; const MODULES = [ { id: 'm1', title: '휴양시설 통합관리', owner: '이동연', description: '평창·속초·제주(2)·몽골 5지역 + 시드 추첨 + 시즌 알림', url: 'https://m1-facilities--{이동연-projectId}.{region}.hosted.app', color: '#1962A8', automation: 'Cloud Scheduler 시즌 알림', }, { id: 'm2', title: '연차 자동화', owner: '이재성', description: '법정+근속+해외특별 자동 산정 + 분기 사업부장 메일', url: 'https://m2-leaves--{이재성-projectId}.{region}.hosted.app', color: '#70AEDA', automation: '분기 메일 (Cloud Scheduler)', }, { id: 'm3', title: '성과관리 시스템', owner: '김경호', description: 'KPI 입력 + 5단계 평가 + 성과급/연봉 자동 산출', url: 'https://m3-performance--{김경호-projectId}.{region}.hosted.app', color: '#1962A8', automation: 'onEvalFinalized Cloud Function', }, { id: 'm4', title: '사내 도구 카탈로그', owner: '이윤재', description: '도구 등록·실행 상태·로그 + 일별 헬스체크', url: '/m4-tools', // 내부 라우트 color: '#70AEDA', automation: '일별 헬스체크 + Slack', }, ]; export default function IntegratedHome() { return ( <main className="container mx-auto p-8"> <header className="mb-8"> <h1 className="text-3xl font-bold text-[#1962A8]"> KCH그룹 인사총무팀 통합 대시보드 v0 </h1> <p className="mt-2 text-gray-600"> 4모듈 + 자동화 4개. 2026-05-08 워크숍 산출물. </p> </header> <div className="grid grid-cols-2 gap-6"> {MODULES.map((m) => ( <ModuleCard key={m.id} module={m} /> ))} </div> </main> ); }

위 코드의 핵심은 MODULES 배열입니다. 4개 객체가 4개 카드와 1:1 매핑됩니다. 다른 3명에게서 URL을 받으면 url 필드만 채우면 됩니다.

Step 2 — 본인 모듈 (M4) 카드는 내부 라우트로

이윤재의 M4 사내 도구 카탈로그는 동일 호스팅의 /m4-tools 라우트로 이동. 즉 같은 도메인 내부에서 페이지 이동이라 새 탭이 안 열립니다. 다른 3명은 외부 URL이라 새 탭으로 열립니다.

이 차이가 사용자 경험에 약간 어색할 수 있지만, L1 통합 깊이에서는 어쩔 수 없습니다. 풀 통합(90일 후속)이 되면 4모듈이 모두 같은 도메인 안에 들어와서 자연스럽게 됩니다.

03Part 3 · 4명이 통합 인덱스에 본인 모듈 등록 (30분, 15:30~16:00)3/6

이 30분이 4명이 마지막으로 모이는 시간입니다.

Step 1 — 3명이 본인 URL을 이윤재에게 공유 (5분)

이재성·김경호·이동연이 본인 URL을 이윤재에게 전달합니다. 채팅·공유 시트·말로 전달 — 형식은 자유입니다.

이재성: https://m2-leaves--xxx.hosted.app 김경호: https://m3-performance--xxx.hosted.app 이동연: https://m1-facilities--xxx.hosted.app

각자 본인 셋업 메뉴 §3에 기록해둔 URL을 그대로 전달하면 됩니다.

Step 2 — 이윤재가 MODULES 배열에 URL 채움 (5분)

위 page.tsx의 url 필드를 4명 실 URL로 채움 → git push → 자동 배포.

git add src/app/page.tsx git commit -m "feat: 통합 인덱스에 4모듈 URL 등록" git push

5-10분 빌드 후 통합 URL을 새로고침하면 카드 4개가 살아 움직입니다.

Step 3 — 이윤재 M4 카탈로그에도 4모듈 자동 등록 (15분)

이윤재의 M4 모듈은 본래 사내 도구 카탈로그입니다. 그래서 4모듈 자체를 사내 도구로 본인 카탈로그에 등록하면 자연스럽게 메타-셀프-인덱스 구조가 됩니다 — M4가 본인을 포함한 4모듈을 사내 도구로 등록하는 셈.

Claude, tools_registry 컬렉션에 다음 4건 추가해줘: 1. M1 휴양시설 (이동연) — type: webapp, url: ..., owner: 이동연 2. M2 연차 자동화 (이재성) — type: webapp, url: ..., owner: 이재성 3. M3 성과관리 (김경호) — type: webapp, url: ..., owner: 김경호 4. M4 사내 도구 카탈로그 (이윤재) — type: dashboard, url: /m4-tools, owner: 이윤재 pushSafe로 push.

→ 이윤재 본인 카탈로그 페이지(/m4-tools)에서도 4모듈이 카드로 표시됩니다. 즉 통합 인덱스(/)와 카탈로그 페이지(/m4-tools) 양쪽에서 4모듈을 볼 수 있습니다.

Step 4 — 16:00 점검

점검통과 기준
통합 인덱스 카드 4개 표시색·폰트·배지 통일
카드 클릭 → 본인 URL 이동4모듈 모두 이동 가능
M4 카탈로그에 4모듈 등록tools_registry 4건
자동화 게이트 4개 모두 발화 가능수동 트리거 시연 가능
04Part 4 · 테스트·재배포 (30분, 16:00~16:30)4/6

발표 직전 30분에 4명 동시 시나리오 테스트를 1번 합니다. 이게 D2 #9 발표의 리허설 역할을 합니다.

Step 1 — 4명 동시 시나리오 테스트 (15분)

다음 시나리오를 4명이 같이 화면 보면서 1번 돌립니다.

시나리오:

  1. 이윤재 통합 인덱스 URL 접속 → 카드 4개 표시 확인
  2. 카드 1번 (이동연 M1) 클릭 → 휴양시설 페이지 이동 → 신청 1건 시뮬레이션
  3. 카드 2번 (이재성 M2) 클릭 → 연차 페이지 이동 → 직원 1명 자동 산정 결과 확인
  4. 카드 3번 (김경호 M3) 클릭 → 성과관리 페이지 이동 → 평가 1건 본평가 확정 → 자동 산출
  5. 카드 4번 (이윤재 M4) 클릭 → 사내 도구 카탈로그 → 4모듈 등록 확인 + 헬스체크 트리거

이 5단계가 끊김 없이 흘러야 발표에서 동일하게 흐릅니다.

Step 2 — 발견된 이슈 즉시 수정 (10분)

테스트 중 발견된 문제는 즉시 수정합니다.

이슈 유형대응
URL 오타이윤재 page.tsx 수정 → git push
디자인 어긋남"Claude, KCH 컬러 토큰으로 다시 정렬" 1줄
자동화 트리거 X로컬 에뮬레이터로 폴백 시연

Step 3 — 최종 git push (5분)

발표 시작 전에 마지막으로 모든 push가 끝나야 빌드가 완료된 상태로 발표할 수 있습니다.

# 이윤재 통합 인덱스 repo git add . git commit -m "feat: 통합 인덱스 — 4모듈 카드 + tools_registry 등록" git push # 4명 모두 마지막 점검 push git add . git commit -m "chore: D2 마감 직전 최종 점검" git push

→ 5-10분 빌드 → 발표 시작 시점에 모든 URL 최신.

05Part 5 · 후속 데이터 통합·SSO 로드맵5/6

오늘 만든 건 메타 + URL 카드까지입니다. 더 깊은 통합은 후속 30/60/90일에 자력으로 진행합니다 — 이걸 D2 #9 발표 시 보고합니다.

NOTE — 워크숍 14h 외, 후속 자력
  • 30일 — 데이터 통합 (Firestore 단일 프로젝트로 4모듈 데이터 합치기)
  • 60일 — SSO 통합 (Firebase Auth 단일 도메인 + 4모듈 라우팅)
  • 90일 — 풀 통합 (4모듈을 1개 Next.js 앱의 라우트로 합치기)
06Part 6 · 체크리스트 + 핵심 정리6/6
  • ☐ 이윤재 app/page.tsx 통합 인덱스 활성화
  • ☐ 4모듈 카드 컴포넌트 작성 + KCH 컬러 통일
  • ☐ 3명이 본인 URL을 이윤재에게 공유
  • ☐ 이윤재 MODULES 배열에 4명 URL 채움
  • ☐ M4 tools_registry에 4모듈 자동 등록
  • ☐ 4명 동시 시나리오 테스트 통과
  • ☐ 최종 git push + 빌드 갱신
핵심 포인트

통합 인덱스 = 메타 + URL 카드. 데이터 통합·SSO는 30/60/90일 로드맵

• 이윤재 app/page.tsx가 단일 통합 지점 — M4의 tools_registry가 메타-셀프-인덱스

• 4모듈 카드 + 새 탭 이동 = SSO 협의 불필요

• 4명 동시 시나리오 테스트 1회 = 발표 리허설 역할

• 90분 끝 시점에 통합 인덱스 1개 URL이 4모듈로 이동 가능

CH09 클로징 D2 #9 · 16:30~17:30 · 60분

Part 9 — 발표 + 회고 + 30/60/90일 자력 로드맵

14h 끝 60분. 4명이 각자 3분 시연 + 30/60/90일 자력 로드맵을 들고 퇴실합니다. 산출물: 발표 메모 4종 + 자력 로드맵 4종.

읽기 14분·업데이트: 2026-05-05
01Part 1 · 14h 회고 — 무엇이 손에 남았는가1/8

먼저 14h 동안 본인이 어디에서 어디로 왔는지 1번 짚고 갑니다. 단순한 도구 학습이 아니라 본인의 능력 자체가 달라진 시간임을 확인하는 단계입니다.

출발점 vs 도착점

시점4명 상태
D1 09:30Claude Pro 챗봇 일상 사용자. CLI 미경험
D1 17:30claude --version OK + 본인 URL 1개 (껍데기) + IPO 1장
D2 17:30본인 모듈 v1 (실데이터 익명화 + 자동화 1개) + 통합 인덱스 + CLAUDE.md + 슬래시커맨드 1개

이틀 전과 지금이 완전히 다릅니다. 챗봇 사용자에서 CLI 페어 프로그래머로 직책 자체가 바뀐 것입니다.

IMPORTANT — 14h 후 손에 쥐는 자산 4종
  1. CLI 자력 운전 — 본인 PC claude 한 글자로 페어 프로그래밍 진입
  2. 본인 모듈 v1 — Firebase App Hosting 공개 URL (실데이터·익명화·자동화)
  3. CLAUDE.md + 슬래시커맨드 1개 — 본인 의도가 영속화된 단일 시스템 프롬프트
  4. 통합 대시보드 v0 — 4모듈 카드 인덱스

이 4종을 손에 쥐고 퇴실하는 게 14h의 단일 결과입니다.

02Part 2 · 4명 발표 (30분, 16:30~17:00)2/8

발표는 1명당 7분입니다 (3분 시연 + 2분 30/60/90일 + 2분 Q&A). 7분 안에 본인 모듈이 어떻게 작동하는지를 시연하는 게 핵심.

시연 3분 — 본인 URL에서 1회 시나리오

각자 본인 URL에 접속해서 다음 시나리오를 1번 돌립니다. D2 #8에서 이미 한 번 리허설한 시나리오라서 익숙한 흐름입니다.

참가자시연 시나리오
이재성1) 직원 1명 (E007) 페이지 → 자동 산정 결과 (법정+근속+해외) 2) ERP CSV 1건 붙여넣기 → 사업부별 분류 3) 분기 메일 Cloud Scheduler 강제 트리거 → Gmail Draft 4) 통합 인덱스에서 M2 카드 클릭
김경호1) KPI 입력 폼 → PM 1명 케이스 → 가중치 검증 통과 2) 자기평가 → 본평가 확정 → onEvalFinalized 자동 트리거 3) 산출 결과 화면 + 자동 검증 게이트 (rangeOk·sumOk·rankBranchOk) 4) 30/60/90일 확장 로드맵 — ②④⑤⑥
이동연1) 평창 페이지 → 신청 1건 → 자격 자동 검증 2) 시드 추첨 실행 → 결과 + 시드 표시 (감사 가능) 3) 통합 캘린더 → 5지역 색상 분기 4) 시즌 도래 알림 D-7 시뮬레이션 → 메일 발송
이윤재1) SSO 로그인 (사내 도메인) → 도메인 lock 검증 2) 도구 1건 신규 등록 → 카탈로그 표시 3) 일별 헬스체크 강제 트리거 → 대시보드 로그 4) 통합 발표 진행 — 4모듈 카드 인덱스 시연
TIP

이윤재가 통합 발표 흐름의 중심입니다. 4명이 각자 시연 후 이윤재가 통합 인덱스 카드 4개를 한 번에 보여주는 것으로 클로징합니다 — 4모듈이 1대시보드로 묶이는 그림이 마지막에 떠야 합니다.

30/60/90일 로드맵 2분

본인 셋업 메뉴 §6 ("후속 30일 자력 로드맵")에서 작성한 내용을 발표합니다. 이게 워크숍 후 본인이 실제로 진행할 다음 단계의 약속입니다.

Q&A 2분

동료 + 강사가 질문합니다. 발표보다 Q&A에서 더 깊은 학습이 일어나는 경우가 많습니다.

03Part 3 · 14h를 관통하는 4가지 핵심 원리3/8

발표가 끝났으면 14h를 관통한 4가지 원리를 정리합니다. 이 4가지를 손에 쥐고 가시면, 본인이 후속 30일에 새 자동화를 만들 때 같은 원리를 적용할 수 있습니다.

원리 1 — CLI 자력 운전이 본질이다

어디서 체험했나

  • D1 #1: claude --version + Firebase MCP 셋업
  • D1 #4: Claude Code에 배포 위임 (apphosting.yaml 자동 생성)
  • D2 #6: Firebase MCP로 컬렉션 + 더미 데이터 자동 push
  • D2 #7: 자동화 함수 + 로컬 에뮬레이터 시뮬레이션

내일부터 적용법 — 본인 PC에서 새 프로젝트 시작할 때마다 가장 먼저 claude 진입. 반복 작업을 손으로 안 하고 CC에게 맡기는 습관이 1주일 안에 굳어지면 14h의 본질이 체화됩니다. 이게 안 되면 다시 챗봇 사용자로 돌아갑니다.

원리 2 — 의도 결정화가 결과 품질을 만든다

어디서 체험했나

  • D1 #2: IEPR 3-Phase + 4단 질문
  • D1 #3: IPO 4섹션 = 4단 질문 1:1 매핑
  • D2 #6: CLAUDE.md = 4단 질문 답변의 영속화
  • D2 #7: VERIFY = 자동 검증 게이트

내일부터 적용법 — 새 작업 시작 시 코드 치기 전에 "WHO·WHY·CONTEXT·VERIFY 4줄"을 먼저 적기. 이게 안 적히면 도메인이 충분히 정의 안 된 것 — 이때 코드 치면 무조건 헛걸음입니다. 4줄 적는 데 5분, 헛걸음하면 30분 손해.

원리 3 — 첫 URL이 추진력을 만든다

어디서 체험했나

  • D1 #4: Firebase App Hosting 첫 배포 → 본인 URL 1개
  • D2 #6~#7: 자동 빌드 파이프라인이 매 push마다 갱신
  • D2 #8: 4명 URL 카드 인덱스

내일부터 적용법 — PoC 단계에서도 공개 환경 배포 우선. 로컬에서 100% 다듬고 배포하지 말고, 60% 동작 단계에서 배포 → 자동 빌드 파이프라인 위에서 다듬기. 공개 URL이 강제하는 룰(환경변수·HTTPS·CORS 등)이 품질을 끌어올립니다.

원리 4 — 통합 인덱스 = 메타 + URL 카드

어디서 체험했나 — D2 #8: 통합 인덱스 = 메타 + URL 카드만, 데이터 통합·SSO는 후속.

내일부터 적용법 — 큰 통합 약속이 들어오면 첫 단계는 항상 메타 + URL 카드. 풀 통합은 30/60/90일 로드맵으로 분리 보고. 처음부터 풀 통합으로 가면 끝나지 않습니다.

04Part 4 · 30/60/90일 자력 로드맵 (4명 1줄씩)4/8

각자 본인 셋업 메뉴 §6에 적은 로드맵을 한 표로 정리합니다.

30일 — 강의 직후 첫 마일스톤

참가자30일 자력 항목
이재성ERP 직접 연동 (현재는 CSV import) — parseErp.tserpApiClient.ts 교체
김경호⑥ AI 평가 의견 초안 생성기 (제외했던 기능) — Claude API + 마스킹 + 워터마크
이동연카카오 알림톡 사업자 등록 + 템플릿 심사 통과 후 적용
이윤재AGENTS.md 멀티에이전트 패턴 풀 구현 (개발·리뷰·디자인·운영 4개 에이전트)

60일 — 운영 안정화

참가자60일 자력 항목
이재성채용 평가 자동화 (M2 코드 80% 재사용) + 복지포인트·생일 쿠폰
김경호② 통지서 PDF + 메일 / ④ 중간점검 스케줄러
이동연5지역 → 6지역 확장 + 유지보수 자동화 강화
이윤재GitHub Webhook 실시간 + Slack 알림 정교화

90일 — 시스템 격상

참가자90일 자력 항목
이재성Apps Script 기존 자산 통합 → Cloud Functions 마이그레이션
김경호⑤ 전사 성과 현황 대시보드 + 53개 직무역량 매핑
이동연이윤재 SaaS와 데이터 통합 (4~8주 별도 프로젝트)
이윤재데이터 통합 (Firestore 단일 프로젝트) + SSO + 풀 통합
TIP

30일 항목 1개만 자력으로 끝내도 14h가 100% 회수됩니다. 90일까지 다 안 해도 됩니다 — 첫 30일 1개가 가장 중요합니다. 30일에 0개를 끝내면 14h가 0% 회수됩니다.

05Part 5 · 5일 내 실행 과제 (강의 직후)5/8

본인 모듈 자동화를 설계만 하고 끝나면 학습 효과가 급감합니다. 5일 이내에 실데이터 1건으로 1회 추가 실행하세요. 그래야 14h의 메모리가 사라지기 전에 한 번 더 손에 익습니다.

과제

  • 이번 주 금요일까지, 본인 모듈을 실 인사총무 데이터 1건으로 1회 더 실행 (가능한 부분만 익명화 적용)
  • 실행 결과를 동료 1명에게 공유 (사내 강사화 발판)
  • 막힌 점 1개를 본인 repo CLAUDE.md "시행착오 일지" 섹션에 기록

CLAUDE.md에 시행착오 일지 섹션을 추가하면, Claude가 같은 실수를 반복하지 않도록 자동으로 학습합니다.

06Part 6 · TF 협업의 다음 단계 — 사내 강사화6/8

"혼자 쓰는 건 자산, 팀이 공유하는 건 시스템"

오늘 4명이 만든 것이 인사총무팀 다른 분에게 전파되면 워크숍이 진짜 살아납니다. 본인이 손에 쥔 4종 자산은 본인 자산이지만, 그게 다른 분에게도 복제되면 시스템이 됩니다.

단계행동
1주일 이내본인 모듈 URL을 인사총무팀 다른 분 1명에게 공유 + 기능 1개 시연
2주일 이내본인 CLAUDE.md를 다른 분에게 공유 + Claude Code 첫 진입 코칭
1개월 이내4명 중 2명 이상이 본인 모듈을 다른 팀에 이식

본인이 사내 강사가 된다는 부담이 들 수 있지만, 본인이 만든 모듈을 직접 시연하는 게 가장 강력한 강의입니다 — 이론을 다시 가르칠 필요 없이, "이거 봐, 이렇게 동작해" 한 번이면 됩니다.

07Part 7 · Digital Labor First7/8

CEO 지시 "AI 먼저, 사람은 뒤에"의 실천 모델을 14h 동안 손으로 익히신 셈입니다. 정리하면 다음과 같습니다.

단계누가무엇을
1. 의도 결정화사람 (4단 질문)WHO·WHY·CONTEXT·VERIFY
2. 코드 생성 + 자동화AI (Claude Code + MCP)Firestore 컬렉션·UI·Cloud Function
3. 검증·결재·전파사람자동 검증 통과 후 결재, 동료 전파
IMPORTANT

AI 산출물은 완벽하지 않습니다. 익명화 누락·검증 게이트 우회 가능성·도메인 룰 미반영이 있을 수 있습니다. 하지만 빈 화면에서 시작하는 것보다 훨씬 빠릅니다. 여러분의 판단이 거기 얹어져야 KCH 인사총무팀의 진짜 시스템이 됩니다.

이게 Digital Labor First의 단일 메시지 — AI는 빠르고, 사람은 정확합니다. 둘을 합치면 빠르고 정확한 시스템이 됩니다.

08Part 8 · 마지막 메시지 (5분, 17:25~17:30) + 핵심 정리8/8

오늘 14h 동안 여러분은 도구를 배운 게 아닙니다. 사고 프레임을 업그레이드한 겁니다.

  • 본인 모듈 v1이 아니라, 인사총무팀 전반을 자동화하는 시작점
  • 자동화 1개가 아니라, 하나의 IEPR 메타프레임으로 N개를 파생할 수 있는 능력
  • 4명 TF가 아니라, 각자가 사내 강사화의 씨앗을 가진 창작자

내일부터 30일 로드맵 1개만 시작해도, 다음 분기 KCH 인사총무팀의 업무 풍경은 완전히 달라져 있을 겁니다.

14시간 함께 해주셔서 감사합니다.

핵심 포인트

• 14h 후 손에 쥐는 자산 4종 — CLI 자력 운전 / 모듈 v1 / CLAUDE.md / 통합 대시보드

4가지 핵심 원리 — CLI 자력 / 의도 결정화 / 첫 URL 추진력 / 통합 인덱스 메타+URL

30/60/90일 자력 로드맵 — 30일 1개만 끝내도 14h가 100% 회수

• 5일 내 실데이터 1건 1회 실행 + 동료 1명 공유 (사내 강사화 발판)

• Digital Labor First — 의도는 사람, 실행은 AI, 검증·결재·전파는 다시 사람

• 본인이 사내 강사가 되는 가장 강력한 방법 = 본인이 만든 모듈을 직접 시연

M2 셋업 메뉴 — 이재성 개인 repo: mjs-leaves

셋업 메뉴 — 이재성 (M2 연차 자동화)

본 셋업 메뉴는 이재성 님 본인 진도와 맞물려 본 교안과 두 창 띄워서 진행합니다. 법정+근속+해외 자동 산정 + 분기 사업부장 메일. 핵심 함수 getLeaves(empId): LeaveBalance. 자동화 게이트 0 9 1 1,4,7,10 *.

읽기 13분
§0모듈 개요 — 이 모듈이 무엇을 하는가1/7

이재성 님의 M2 모듈은 인사총무팀의 연차 산정과 분기 보고를 자동화합니다. 지금까지는 매년 직원별로 법정 연차·근속 휴가·해외 특별 휴가를 손으로 계산하고, 분기마다 사업부장에게 메일로 보고하던 작업이 다음과 같이 바뀝니다.

  • 직원 1명 페이지를 열면 → 법정+근속+해외 산정 결과가 자동으로 계산되어 표시
  • ERP에서 export한 CSV를 붙여넣으면 → 사업부별 집계가 자동 분류
  • 매 분기 첫날 09:00 → 사업부장 4명에게 메일 Draft가 자동 생성 (사람이 검수 후 발송)

이 자동화의 단일 함수가 getLeaves(empId)입니다. 직원 ID 하나만 받으면 그 직원의 모든 휴가 잔여를 한 번에 돌려줍니다.

§1사전 확정 4건 (D1 #1~#3 사이 결정)2/7

본인 모듈을 만들기 전에 다음 4가지를 결정해야 합니다. 이 결정이 빠지면 코드의 기본 분기가 안 잡혀서 D2 #6 본 모듈 구현 단계에서 매번 다시 결정해야 합니다.

#항목왜 필요한가결정 시점본인 답변
1회계년도 기준일 (1/1 vs 4/1 vs 입사월)법정 연차는 회계년도 기준으로 부여·소멸됨 — 1/1 기준이면 매년 1/1에 새 연차 부여, 4/1 기준이면 매년 4/1에 부여, 입사월 기준이면 직원별로 다름D1 #3 IPO 작성 시__________
2ERP 추출 컬럼 구조 (CSV export 샘플 1건)지금 ERP에서 어떤 컬럼이 어떤 순서로 나오는지 모르면, 파싱 함수가 추측에 의존해 동작D1 시작 전 가져옴__________
3해외 14일 사용 후 잔여 처리 (이월 vs 소멸 vs 환산)해외 특별 휴가는 5개월 단위 14일이 부여되는데, 14일을 다 못 쓰고 5개월이 끝났을 때 어떻게 처리하는지가 룰에 따라 다름D1 #3 IPO 작성 시__________
4분기 메일 수신자/시점/포맷 (본인+팀장+CFO?, 분기 1일?, HTML 표 포맷?)누구에게 어떤 형식으로 보내는지에 따라 메일 템플릿이 달라짐D1 #3 IPO 작성 시__________
IMPORTANT

#2가 가장 중요합니다. ERP CSV 샘플 1건이 없으면 D2 #6의 "ERP 붙여넣기 → 사업부 분류" 페이지가 더미만으로 동작합니다. 본인이 출근 전 사내 ERP에서 1건 export해서 가져와주세요. 인사정보 평문이면 토큰 치환 후 가져오기.

§2IPO 4섹션 슬롯 (D1 #3 작성)3/7

D1 #3에서 본인 IPO를 작성할 때 다음 슬롯을 그대로 본인 IPO 파일에 복붙하면 됩니다.

# M2 연차 자동화 IPO ## I 타겟 (WHO) - 인사총무팀(이재성) + 사업부장(메일 수신) ## I 가치 (WHY) - 법정+근속+해외 자동 산정 + 분기 사업부장 메일 자동 발송 ## P-1 IA - /m2-leaves (홈 — 사업부 4개 카드) - /m2-leaves/dept/[id] (사업부별 집계) - /m2-leaves/employee/[id] (개인별 잔여) - /m2-leaves/quarterly (분기 리포트) - /m2-leaves/erp-upload (ERP CSV 붙여넣기) ## P-2 백엔드 ### Firestore 컬렉션 - employees/{empId} — { empId(token), joinDate, isOverseas, deptId, salaryToken } - leave_balances/{id} — { empId, fiscalYear, legal, seniority, special, overseas, total } - leave_usages/{id} — { empId, usedDate, category, days, reason } - org_units/{orgId} — { deptId, deptName, headEmail } ### Cloud Function - quarterlyMail (트리거: Cloud Scheduler `0 9 1 1,4,7,10 *`) — 분기 첫날 09:00 KST 사업부장 메일 Draft ## O 기능 1. ERP CSV 붙여넣기 → 사업부 분류 2. 직원 1명 자동 산정 (`getLeaves(empId)` → 법정+근속+해외) 3. 사업부별 집계 페이지 (총 휴가일수·사용일수·잔여) 4. 개인별 잔여 페이지 (카테고리별 표시) **자동화 게이트:** Cloud Scheduler 분기 메일 → Gmail Draft 생성 (자동 send X — 사람 검수) ## VERIFY - 직원 E007 (입사 2018-03-15) 자동 산정 = 법정 15 + 근속 5 + 해외 0 = 20일 - 분기 메일 Draft 4개 (사업부 4개) 생성 + Gmail 받은편지함 확인 - 익명화 게이트 통과 (이름·연락처 평문 0건)

컬렉션 이름의 의미

  • employees — 직원 마스터. 사번 토큰·입사일·해외근무여부·소속 부서
  • leave_balances — 휴가 잔여. 연도별 1행씩 (법정·근속·특별·해외 분리)
  • leave_usages — 휴가 사용 트랜잭션. 사용 1건당 1행 (사용일·카테고리·일수)
  • org_units — 조직 마스터. 사업부장 이메일 (분기 메일 수신자)

employeesleave_balances를 분리한 이유 — 직원 정보는 자주 바뀌지 않지만 휴가 잔여는 매년 새로 부여되기 때문에 연도별로 행을 분리하는 게 깔끔합니다.

§3D1 #5 AI Studio 프롬프트 슬롯 + URL 기록4/7

D1 #5에서 AI Studio에 시안을 받을 때, 본인 IPO 위에 [디자인 시스템 강제 라인] 복붙 후 다음 추가 라인을 붙입니다.

[M2 연차 모듈 특화] - 페이지 5개 시안 (홈·사업부별·개인별·분기·ERP 업로드) - 카드 컴포넌트로 사업부 4개 표시 (영업·R&D·인사총무·재무 더미) - 개인별 잔여는 DataTable로 카테고리별 분리 표시 - ERP 업로드 페이지는 textarea + 미리보기 카드 - 분기 리포트는 Tabs (Q1/Q2/Q3/Q4) + DataTable - 색상은 KCH 컬러 (primary #1962A8) — 다른 모듈과 통일

이 라인이 시안 품질을 올려줍니다. 단순히 "5개 페이지 만들어줘"보다 "어떤 컴포넌트로 어떤 정보를 보여줘"라고 구체화하는 게 결과 차이를 만듭니다.

본인 URL 기록

D1 #4 첫 배포가 끝났을 때 본인 URL을 여기 기록합니다.

본인 URL: ________________________________________________

이 URL은 14h 끝까지 살아 있는 본인 자산의 단일 주소입니다. D2 #8 통합 시점에 이윤재에게 이 URL을 전달합니다.

§4D2 진입 체크리스트5/7

D2 #6 시작 전에 다음 항목을 점검합니다. 미완성이 1개라도 있으면 D2 #6 시작 후 첫 30분에 보강합니다.

  • ☐ ERP CSV 샘플 1건 가져옴 (없으면 강사가 더미 50행 시드)
  • ☐ CLAUDE.md 6대 섹션 작성 + §1의 회계년도 기준일 + 해외 잔여 룰 명시
  • ☐ 슬래시커맨드 /seed-erp 1개 — ERP CSV 더미 1건 → Firestore 변환
  • ☐ Firestore 컬렉션 4개 더미 데이터 (employees 30건, leave_balances 30건, leave_usages 100건, org_units 4건)
  • ☐ 핵심 페이지 1개 (/m2-leaves/employee/[id]) 동작
§5자동화 게이트 슬롯 — 분기 메일 (D2 #7)6/7

D2 #7에서 자동화 함수를 만들 때 다음 코드를 베이스로 시작합니다. Claude에게 "이 베이스 코드를 내 환경에 맞게 채워줘"라고 시키면 됩니다.

// functions/src/quarterlyMail.ts import { onSchedule } from 'firebase-functions/v2/scheduler'; import { google } from 'googleapis'; export const quarterlyMail = onSchedule( { schedule: '0 9 1 1,4,7,10 *', timeZone: 'Asia/Seoul' }, async () => { const orgs = await getOrgUnits(); for (const org of orgs) { const summary = await aggregateLeavesByOrg(org.orgId); const html = renderEmailHtml(summary); const gmail = google.gmail({ version: 'v1', auth: serviceAccountAuth }); await gmail.users.drafts.create({ userId: 'me', requestBody: { message: { raw: createRawMessage(org.headEmail, '[분기] 연차 사용 현황', html) }, }, }); // Draft만 생성 — 사람 검토 후 발송 (자동 send X) } } );

왜 Draft만 생성하는가

자동 발송(send)이 아니라 Draft 생성으로 한 이유 — 사람이 마지막에 1번 검수하는 단계를 강제하기 위해서입니다. 분기 메일에 잘못된 데이터가 들어가서 사업부장에게 발송되면 사고입니다. Draft로 두면 본인이 Gmail 받은편지함의 임시보관함을 열어 1번 확인하고 발송 결정합니다.

검증 게이트 — 자동화가 정상인지 확인하는 기준

  • 4개 사업부 모두 Draft 생성됨
  • 각 Draft에 사업부별 데이터 포함 (다른 사업부 데이터 누수 0건)
  • 직원 식별 컬럼 평문 0건 (token만)

이 3개가 통과되면 분기 메일 자동화가 정상 동작하는 것입니다.

§6후속 30/60/90일 자력 로드맵7/7

D2 #9 발표 시 이 로드맵을 발표합니다. 14h 끝나고 다음 단계로 무엇을 진행할지의 약속입니다.

30일 — 강의 직후

  • ERP CSV → ERP API 직접 연동 (parseErp.tserpApiClient.ts 교체)
    • 지금은 사람이 ERP에서 export해서 붙여넣어야 하는데, API가 생기면 본인 모듈이 자동으로 ERP를 호출
  • 분기 메일 자동 send (Draft → Send) — 권한 + 발송 로그 추가
    • Draft 검수 단계를 통과한 메일은 자동 발송으로 격상

60일 — 운영 안정화

  • 채용 평가 자동화 (M2 코드 80% 재사용 — Form → Firestore → 분류 → Gmail → PDF)
    • M2의 패턴(폼 → DB → 분류 → 메일)이 채용 평가에도 그대로 적용됨
  • 복지포인트·생일 쿠폰 (Cloud Scheduler 동일 패턴)
  • 연차수당 자동 계산 (미사용일수 × 일평균임금)

90일 — 시스템 격상

  • Apps Script 기존 자산 → Cloud Functions 마이그레이션
    • 기존 GAS로 만든 자동화들을 점진적으로 Cloud Functions로 옮김
  • 이윤재 SaaS와 데이터 통합 (이재성 모듈을 M4 카탈로그에 풀 등록)
TIP

30일 항목 1개만 끝내도 14h가 100% 회수됩니다. ERP API 연동 1건만 살리면 본인 시간이 매주 1-2시간씩 절약됩니다.

M3 셋업 메뉴 — 김경호 개인 repo: kkh-performance

셋업 메뉴 — 김경호 (M3 성과관리 시스템)

본 셋업 메뉴는 김경호 님 본인 진도와 맞물려 본 교안과 두 창 띄워서 진행합니다. KPI 수집 (③) + 성과급/연봉 자동 산출 엔진 (①). 메인 산출물 ①+③ 통합. 자동화 게이트 onEvalFinalized Cloud Function (본평가 확정 시 자동 산출). 외부 API 호출 0건.

읽기 16분
§0모듈 개요 — 이 모듈이 무엇을 하는가1/9

김경호 님의 M3 모듈은 KCH그룹 6대 산출물 중 ①+③을 통합한 단일 시스템입니다. 직원의 KPI 입력에서부터 5단계 평가, 그리고 성과급·연봉의 자동 산출까지 한 화면 안에서 흘러갑니다.

지금까지는:

  • KPI 목표 → 엑셀로 수집 → 본인이 손으로 취합
  • 평가 결과 → 별도 양식 → 본인이 손으로 산출
  • 성과급·연봉 → 매번 룰 적용해서 손으로 계산

워크숍 후에는:

  • KPI 입력 폼 → Firestore 자동 저장 + 가중치 합 100% 자동 검증
  • 본평가 확정 즉시 → onEvalFinalized Cloud Function이 자동 발화 → 성과급·연봉 자동 산출
  • 산출 결과 → 자동 검증 게이트 3종(rangeOk·sumOk·rankBranchOk) 통과 여부 표시

이 모듈의 핵심은 onEvalFinalized — 본평가가 확정되는 순간 자동으로 산출 엔진이 돌아갑니다. 사람이 산출 트리거를 누를 필요가 없습니다.

§1사전 확정 3건 (D1 시작 전 가져오기)2/9

본인 모듈은 KCH 공식 산출 룰이 핵심 입력입니다. 이 룰이 없으면 산출 엔진이 더미 룰로 동작합니다.

#항목왜 필요한가결정 시점본인 답변
1KCH 공식 산출 룰 (등급별 인상률 + 성과급 산정 룰 + 직급별 분기)산출 엔진의 단일 입력. 이 룰이 없으면 결과 자체가 의미 없음D1 시작 전 본인이 가져옴__________
2본부장/PM/AM 직급별 가중치 비율평가 가중치가 직급마다 다름. xlsx 자료에 일부 있음D1 #3 IPO 작성 시__________
3기본급 데이터 출처 (Cloud Secret Manager 시드? 사내 ERP 호출?)산출 결과는 기본급에 인상률을 곱하는 방식 — 기본급 출처가 없으면 산출 불가D1 #3 IPO 작성 시 (워크숍은 더미 토큰)__________
WARNING — #1이 가장 중요합니다

본인이 D1 시작 전에 다음 3종을 가져와주세요.

  • 등급별 인상률 표 (EX/VG/GD/NI/UN 각 인상률 %) — 5등급마다 인상률이 다름
  • 성과급 산정 룰 (기본급 × 인상률 × 본부 기여도?) — 곱셈 구조의 변수가 무엇인지
  • 직급별 분기 규칙 (본부장 vs PM vs AM 다른 룰?) — 직급마다 인상률 곱셈이 다른지

EX/VG/GD/NI/UN이 무엇인가요

KCH 5단계 평가 등급의 약자입니다.

  • EX (Excellent) — 90점+
  • VG (Very Good) — 80점대
  • GD (Good) — 70점대
  • NI (Need Improvement) — 60점대
  • UN (Unsatisfactory) — 60점 미만

각 등급마다 인상률이 다르고, 직급별로도 다릅니다. 이 매트릭스가 산출 엔진의 핵심 입력값입니다.

§2IPO 4섹션 슬롯 (D1 #3 작성)3/9
# M3 성과관리 시스템 IPO ## I 타겟 (WHO) - 인사총무팀(김경호) + 사업부장(평가자) + 임직원(피평가자) ## I 가치 (WHY) - KPI 입력 → 집계 → KCH 5단계 평가 → 성과급·연봉 자동 산출까지 한 화면 ## P-1 IA - /m3-performance (홈 — 진행률 + 산출 현황) - /m3-performance/kpi-input (KPI 입력 폼) - /m3-performance/eval (평가 진행) - /m3-performance/result (등급 산출) - /m3-performance/salary (성과급·연봉 산출 — ① 메인) - /m3-performance/dashboard (확장) ## P-2 백엔드 ### Firestore 컬렉션 - kpi_targets/{empId_year} — { empId(token), year, rank, items[], weightSum, status } - eval_5stage/{empId_year} — { selfScore, mainScore, grade, contribution, finalizedAt } - salary_calc/{empId_year} — { grade, rank, baseSalaryToken, inflationRate, bonusAmount, newSalaryAmount, selfVerified, verifyDetails } - org_units/{orgId} — 이재성과 공유 ### Cloud Function - onEvalFinalized (트리거: Firestore onUpdate `eval_5stage`) — 본평가 확정 시 ① 산출 엔진 자동 실행 ## O 기능 1. KPI 입력 폼 + 가중치 합 100% 검증 (③) 2. 자기평가 → 본평가 잠금 해제 3. 본평가 확정 → 5등급 자동 환산 4. 등급 → 성과급·연봉 자동 산출 (①) 5. 자동 검증 게이트 3종 — rangeOk·sumOk·rankBranchOk **자동화 게이트:** `onEvalFinalized` 본평가 확정 즉시 산출 엔진 트리거 ## VERIFY - 가중치 합 100% 미만이면 입력 불가 - 산출 결과 인상률 0~15% 범위 (rangeOk) - 산출 합계 = baseSalary + bonus (sumOk, 1원 미만 오차) - 직급별 분기 (director/pm/am) 적용 (rankBranchOk) - 익명화: empId·baseSalary 토큰만, 평문 0건

자동 검증 게이트 3종이 무엇인가

산출 엔진이 결과를 만들 때마다 다음 3가지를 자동 체크합니다.

  • rangeOk — 인상률이 정상 범위 안인가? (0~15%) — 룰 적용이 잘못되면 음수나 100% 같은 비정상 값이 나올 수 있어서 차단
  • sumOk — 합계가 일치하는가? (newSalary == baseSalary + bonus, 1원 미만 오차 허용) — 부동소수점 계산 오류 차단
  • rankBranchOk — 직급 분기가 적용됐는가? — 직급 코드가 director·pm·am 중 하나여야 함

3개 모두 통과되면 selfVerified: true. 하나라도 실패하면 selfVerified: false로 저장되고 사람 결재가 필요합니다.

§3D1 #5 AI Studio 프롬프트 슬롯 + URL 기록4/9
[M3 성과관리 모듈 특화] - 페이지 6개 시안 (홈·KPI 입력·평가·등급 결과·성과급/연봉·대시보드) - KPI 입력 폼: 전략과제(SI) + Objective + KR + 가중치(%) — 행 추가/삭제 가능 - 가중치 합계 표시 + 100% 미만 시 빨간 배지 - 평가 진행: Tabs (자기평가 / 본평가) + 점수 입력 슬라이더 - 등급 결과: 5등급(EX/VG/GD/NI/UN) 배지로 표시 - 성과급/연봉: 토큰 ID 기준 표 + 자동 검증 결과 배지 (rangeOk/sumOk/rankBranchOk) - 색상은 KCH 컬러 (primary #1962A8) — 임원 보고용 톤

KPI 입력 폼은 OKR 구조(SI·Objective·KR + 가중치)를 따릅니다. 본인이 KCH 내부에서 쓰는 OKR 양식이 따로 있으면 그 양식 그대로 적용 가능.

본인 URL 기록

본인 URL: ________________________________________________
§4D2 진입 체크리스트5/9
  • KCH 공식 산출 룰 Cloud Secret Manager에 등록 — SALARY_INFLATION_TABLE 같은 키 이름으로
  • ☐ CLAUDE.md 6대 섹션 작성 + 보안 룰 (외부 API 호출 0건 / 연봉 평문 X / 산출 룰 코드 X)
  • ☐ 슬래시커맨드 /run-salary 1개 — 평가 등급 입력 → 산출 엔진 강제 트리거
  • ☐ Firestore 컬렉션 3개 더미 (kpi_targets 30건, eval_5stage 30건, salary_calc 빈 상태)
  • ☐ 직급별 가중치 시드: 본부장 1명 / PM 2명 / AM 2명
  • ☐ 핵심 페이지 1개 (/m3-performance/kpi-input) 동작 + 가중치 검증
§5자동화 게이트 슬롯 — onEvalFinalized (D2 #7)6/9

이 함수가 김경호 모듈의 핵심입니다. 본평가가 확정되는 순간 자동으로 산출 엔진이 발화합니다.

// functions/src/salaryCalc.ts import { onDocumentUpdated } from 'firebase-functions/v2/firestore'; import { defineSecret } from 'firebase-functions/params'; const inflationTable = defineSecret('SALARY_INFLATION_TABLE'); export const onEvalFinalized = onDocumentUpdated( { document: 'eval_5stage/{evalId}', secrets: [inflationTable] }, async (event) => { const after = event.data?.after.data(); const before = event.data?.before.data(); // 본평가 확정 시점에만 트리거 if (!after?.finalizedAt || before?.finalizedAt) return; const { empId, year, grade, rank } = after; // 룰 적용 — 직급별 분기 const rules = JSON.parse(inflationTable.value()); const rate = getInflationRate(grade, rank, rules); const baseSalary = await getBaseSalaryFromVault(empId); const bonus = calculateBonus(baseSalary, rate, after.contribution); const newSalary = baseSalary + bonus; // 자동 검증 게이트 3종 const verify = { rangeOk: rate >= 0 && rate <= 0.15, sumOk: Math.abs(newSalary - (baseSalary + bonus)) < 1, rankBranchOk: ['director', 'pm', 'am'].includes(rank), }; await pushSafe('salary_calc', { empId, // token year, grade, rank, baseSalaryToken: hashSalary(baseSalary), // 토큰만 inflationRate: rate, bonusAmount: bonus, newSalaryAmount: newSalary, selfVerified: verify.rangeOk && verify.sumOk && verify.rankBranchOk, verifyDetails: verify, computedAt: FieldValue.serverTimestamp(), }); } );

코드의 핵심 포인트

  • if (!after?.finalizedAt || before?.finalizedAt) return; — 본평가 확정 시점에만 발화. 이 가드가 없으면 평가 문서가 변경될 때마다 트리거되어 무한 반복.
  • defineSecret('SALARY_INFLATION_TABLE') — KCH 공식 인상률 표를 Cloud Secret Manager에서 가져옴. 코드에 절대 박지 않음.
  • pushSafe('salary_calc', ...) — 직접 db.collection.add(...) 안 쓰고 익명화 가드를 거침.
  • baseSalaryToken: hashSalary(baseSalary) — 실 금액을 직접 저장하지 않고 토큰으로만.

검증 게이트

  • PM 1명 (E007) 본평가 확정 → 즉시 salary_calc/E007_2026 문서 생성
  • selfVerified: true (rangeOk·sumOk·rankBranchOk 모두 통과)
  • 평문 연봉 금액 0건 (baseSalaryToken만)
§6후속 30/60/90일 자력 로드맵7/9

KCH 6대 산출물 중 워크숍에서는 ①+③만 다뤘고, 나머지 ②④⑤⑥은 후속 자력 로드맵으로 분리됩니다. 이 로드맵을 D2 #9 발표 시 자력 발표하는 게 김경호 발표의 차별 포인트입니다.

30일 — 강의 직후

  • ⑥ AI 평가 의견 초안 생성기 (제외했던 기능)
    • 마스킹 함수 + Claude API 호출 + 워터마크 강제 [초안 — 사람 검토 필요]
    • M3 코드 + 보안 패턴 그대로 활용
    • 워크숍에서 보안상 제외했던 기능을 마스킹·워터마크 룰을 갖춘 상태로 복귀

60일 — 운영 안정화

  • ② 연봉결정 통지서 PDF + 메일 (React-PDF 라이브러리 사용)
  • ④ 중간점검 스케줄러 + 알림 (Cloud Scheduler — 평가 중간 점검 시점 자동 알림)
  • 53개 직무역량 매핑 (xlsx 자료를 Firestore 컬렉션으로 마이그레이션)

90일 — 시스템 격상

  • ⑤ 전사 성과 현황 대시보드 (Recharts 차트 라이브러리)
    • 등급 분포·본부 평균·인상률 분포 차트
  • 이윤재 SaaS와 통합 (M3을 M4 카탈로그에 풀 등록)
§7보안 체크포인트8/9

본인 모듈은 4명 중 가장 민감한 데이터를 다룹니다. 다음 7개를 워크숍 14h 동안 그대로 강제합니다.

  • 연봉·이름·사번 외부 API 호출 0건 (워크숍 14h)
  • ☐ 산출 룰 = Cloud Secret Manager (.env X, 코드 하드코딩 X)
  • ☐ 기본급 = 토큰 매핑 (Firestore에 직접 금액 저장 X)
  • ☐ AI 자동 결정 X — 등급·성과급·연봉 모두 결정적 룰 (노무 분쟁 방지)
  • ☐ Firestore 저장 시 직원ID 토큰화 (pushSafe)
  • ☐ 자동 검증 게이트 — 산출 결과 인상률 범위·합계·직급 분기 자동 검증, 실패 시 selfVerified: false → 사람 결재
  • ☐ PDF·메일 발송은 확장 로드맵 ② (워크숍 14h 외)
"AI 자동 결정 X"가 왜 중요한가

평가 등급·성과급 결정에 AI가 직접 개입하면 노무 분쟁의 소지가 됩니다. "AI가 결정한 게 맞느냐"는 의문이 들었을 때, 결정 과정을 100% 룰로 설명할 수 있어야 합니다. 그래서 본인 모듈의 모든 결정은 결정적 룰(if-else 트리)로만 진행하고, AI는 의견 초안 생성(⑥, 30일 후속) 같은 보조 역할에만 한정합니다.

§8발표 차별 포인트9/9
김경호 발표

메인 ①+③ 시연 후 ②④⑤⑥를 30/60/90일 확장 로드맵으로 자력 발표 — 단순히 "한 모듈 만들었다"가 아니라 "KCH 6대 산출물 풀 이식 동선이 보이는 강사화 자산"으로 발표.

이 차별 포인트가 본인 발표를 다른 3명과 구분 짓습니다. 다른 분들은 본인 모듈 1개의 시연이 발표의 전부지만, 김경호 님은 6대 산출물의 첫 2개(①+③)를 끝냈고 나머지 4개의 동선이 보인다는 메시지가 핵심.

M1 셋업 메뉴 — 이동연 개인 repo: moo-facilities

셋업 메뉴 — 이동연 (M1 휴양시설 통합관리)

본 셋업 메뉴는 이동연 님 본인 진도와 맞물려 본 교안과 두 창 띄워서 진행합니다. 5지역(평창·속초·제주(2)·몽골). 핵심 함수 runLottery(applicants, capacity, seed) (시드 기반 결정적 추첨). 자동화 게이트 Cloud Scheduler 시즌 도래 알림 (0 9 * * * — 매일 09:00).

읽기 14분
§0모듈 개요 — 이 모듈이 무엇을 하는가1/8

이동연 님의 M1 모듈은 흩어진 5지역 휴양시설 운영을 한 페이지로 통합합니다. 지금까지는 5지역(평창·속초·제주 유승·제주 중흥·몽골)이 각각 다른 엑셀 시트·다른 업체 메일로 분리 운영됐지만, 워크숍 후에는 다음과 같이 동작합니다.

  • 5지역 카드를 한 화면에서 보고, 지역별로 한도·페널티 룰이 다 다르게 적용
  • 신청자가 폼을 제출하면 → 자격·페널티 자동 검증 → 적격/부적격 즉시 표시
  • 추첨이 필요한 경우 → 시드 기반 결정적 추첨 (감사 가능 — 같은 시드면 같은 결과)
  • 매일 09:00 → 시즌 도래 유지보수 알림 자동 발송 (에어컨 필터·스노우 타이어 같은 시기성 작업)

핵심 함수 runLottery재현 가능한 추첨입니다. 일반적인 랜덤 추첨은 매번 다른 결과지만, 시드 기반은 같은 시드를 입력하면 항상 같은 결과 → 추첨 분쟁 시 검증 가능합니다.

§1사전 확정 항목2/8

본인은 사전설문 9p PRD에 5지역 룰을 다 정리해 오셨습니다. 그래서 §1의 1번 항목은 ✅ 가져옴 상태로 시작합니다.

#항목왜 필요한가결정 시점본인 답변
15지역 한도/페널티 표 (평창·속초·제주2·몽골)신청 검증 룰의 단일 입력사전설문에 정리됨 → Firestore 시드 데이터로 입력✅ 가져옴
2임직원 더미 30명추첨·신청 시뮬레이션용 더미 데이터D1 #1 셋업 시 강사가 시드__________
3청소·차량업체 이메일 (동의 받은 경우만)협력사 자동 공유 자동화의 수신자D2 #7 자동화 게이트 작성 시__________
4카카오 알림톡 — 가이드 문서만 (사업자 심사 1~2주 → 워크숍 외)사업자 등록 후 진행되는 후속 단계D2 #9 발표 시 후속 30/60/90일 로드맵✅ 결정됨

5지역 한도 룰

각 지역마다 한도가 다릅니다. 이 룰이 신청 검증 함수의 분기 조건이 됩니다.

지역주말 한도평일 한도비고
평창2무제한평일 한도 없음
속초22표준
제주 유승 + 제주 중흥합산 2합산 2두 시설을 합산해서 한도 적용
몽골 썸머캠프1인 2회 / 총 2박(5~10월만)시즌제

제주 한도가 "합산 2"인 이유 — 제주에 시설이 2개(유승·중흥) 있지만, 직원 입장에서는 같은 지역으로 인식되기 때문에 한도를 합산 적용.

페널티 룰

신청 후 취소 시점에 따라 페널티가 다릅니다.

시점페널티
7일 전제한 없음
1~6일 전2개월 정지
당일·노쇼6개월 정지
6개월 내 2건1년 금지 (강한 페널티)
제천 14일 전필수 — 14일 전 미취소 시 페널티 가중

카카오 알림톡이 왜 워크숍 외인가

카카오 알림톡은 사업자 등록 → 발신 프로파일 등록 → 템플릿 심사 1~2주가 필요합니다. 14h 안에 처리할 수 없어서 워크숍 외로 분리. 워크숍에서는 이메일 알림만 구현하고, 알림톡은 후속 30일 로드맵으로 갑니다.

§2IPO 4섹션 슬롯 (D1 #3 작성)3/8
# M1 휴양시설 통합관리 IPO ## I 타겟 (WHO) - 인사총무팀(이동연) + 5지역 숙소 담당 + 차량 담당 ## I 가치 (WHY) - 5지역 엑셀 시트 → 단일 페이지. 데이터 누락 0 + 시즌 알림 자동화 ## P-1 IA - /m1-facilities (홈 — 5지역 카드) - /m1-facilities/[id] (지역별 상세) - /m1-facilities/apply (신청 폼) - /m1-facilities/calendar (통합 캘린더 — react-big-calendar) - /m1-facilities/maintenance (유지보수 일정) ## P-2 백엔드 ### Firestore 컬렉션 - facilities/{facilityId} — { name, region, weekendQuota, weekdayQuota, jejuShared, cancelDeadlineDays, partners } - bookings/{bookingId} — { empId(token), facilityId, checkIn, checkOut, status, partnerConsent } - lottery_logs/{lotteryId} — { facilityId, dateRange, seed, applicants, eligible[], winners[], excluded[] } - maintenance_schedule/{itemId} — { facilityId, task, dueDate, alertOffsetDays, status } ### Cloud Function - seasonalMaintenanceAlert (트리거: Cloud Scheduler `0 9 * * *`) — 유지보수 D-7 알림 메일 ## O 기능 1. 5지역 카드 + 지역별 상세 페이지 2. 신청 폼 → 자격 자동 검증 (페널티 룰 적용) 3. 시드 추첨 (`runLottery` — 재현 가능 + 감사 로그 영구 보존) 4. 통합 캘린더 (5색 분기 표시) 5. 협력사 자동 공유 (동의 체크 시에만) **자동화 게이트:** 시즌 도래 알림 (Cloud Scheduler) → 메일 자동 발송 ## VERIFY - 평창 신청 → 자격 검증 적격/부적격 판정 - 시드 추첨 동일 시드 → 동일 결과 (감사 가능) - 6개월 내 2건 취소자 → 자동 1년 금지 - 시즌 도래 알림 D-7 시뮬레이션 → 메일 1건 발송 - 익명화: empId 토큰만, 이름·연락처 평문 0건

lottery_logs가 영구 보존인 이유

추첨 로그(lottery_logs)는 감사 가능성 때문에 영구 보존입니다. 추첨에 대한 분쟁이 생겼을 때 "당시 시드는 무엇이었고, 누가 신청자였고, 누가 당첨됐고, 누가 한도 초과로 제외됐는지"를 모두 추적 가능해야 합니다. 그래서 한 번 기록되면 삭제되지 않습니다.

§3D1 #5 AI Studio 프롬프트 슬롯 + URL 기록4/8
[M1 휴양시설 모듈 특화] - 페이지 5개 시안 (홈·지역별·신청·통합 캘린더·유지보수) - 홈: 5지역 카드 (평창·속초·제주2·몽골) — 각 카드에 한도 표시 - 신청 폼: 체크인·체크아웃·동의 체크 (협력사 정보 공유) - 통합 캘린더: react-big-calendar (지역별 5색 분기) - 평창: #1962A8 (KCH primary) - 속초: #70AEDA (KCH secondary) - 제주 유승: #10B981 - 제주 중흥: #059669 - 몽골: #F59E0B - 유지보수: 카드 + 배지 (D-7, D-14 알림) - 색상은 KCH 컬러 통일 (primary #1962A8)

react-big-calendar가 무엇인가

react-big-calendar는 React에서 가장 많이 쓰이는 캘린더 컴포넌트입니다. 월/주/일 뷰를 지원하고 이벤트를 색상으로 구분 표시 가능. 본인 모듈의 통합 캘린더는 5지역 예약을 한 화면에서 색으로 구분해 보여주는 페이지입니다.

본인 URL 기록

본인 URL: ________________________________________________
§4D2 진입 체크리스트5/8
  • ☐ 5지역 시설 마스터 시드 (5건 — facilities 컬렉션)
  • ☐ 임직원 더미 30명 (employees 컬렉션 — 이재성과 공유)
  • ☐ CLAUDE.md 6대 섹션 작성 + 시드 결정성 룰 + 동의 체크 룰 강제
  • ☐ 슬래시커맨드 /run-lottery 1개 — 시드 추첨 시뮬레이션
  • ☐ Firestore 컬렉션 4개 (facilities 5건, bookings 50건, lottery_logs 빈 상태, maintenance_schedule 10건)
  • ☐ 핵심 페이지 1개 (/m1-facilities/apply) 동작 + 페널티 검증
§5자동화 게이트 슬롯 — 시즌 알림 + runLottery (D2 #7)6/8

시즌 도래 알림 함수

매일 09:00에 발화하는 cron 함수입니다. 유지보수 일정(maintenance_schedule)을 훑어서 D-7 시점에 도달한 항목이 있으면 알림 메일을 자동 발송합니다.

// functions/src/seasonAlert.ts import { onSchedule } from 'firebase-functions/v2/scheduler'; export const seasonalMaintenanceAlert = onSchedule( { schedule: '0 9 * * *', timeZone: 'Asia/Seoul' }, async () => { const today = new Date(); const items = await db.collection('maintenance_schedule').get(); for (const doc of items.docs) { const item = doc.data() as MaintenanceItem; const daysUntil = daysBetween(today, new Date(item.dueDate)); if (daysUntil === item.alertOffsetDays && item.status === 'pending') { await sendAlert(item); // Gmail API } } } );

시드 추첨 핵심 함수 — runLottery

runLottery가 본인 모듈의 핵심 함수입니다. 같은 시드 → 같은 결과를 보장하는 결정적 추첨입니다.

// lib/lottery.ts import seedrandom from 'seedrandom'; export function runLottery(applicants: string[], capacity: number, seed: string): string[] { const rng = seedrandom(seed); const shuffled = [...applicants].sort(() => rng() - 0.5); const winners = shuffled.slice(0, capacity); // 영구 감사 로그 pushSafe('lottery_logs', { seed, applicants: applicants.length, winners, excluded: applicants.filter(a => !winners.includes(a)), runAt: FieldValue.serverTimestamp(), }); return winners; }

seedrandom이 무엇인가

seedrandom은 시드를 받아서 결정적인 난수를 생성하는 라이브러리입니다. JavaScript의 기본 Math.random()은 매번 다른 값이지만, seedrandom('abc123')은 항상 같은 순서의 값을 출력합니다. 이게 추첨 분쟁 시 재현성을 보장하는 핵심.

검증 게이트

  • 동일 시드 → 동일 추첨 결과 (재현성 검증) — 같은 시드를 두 번 돌렸을 때 결과가 같아야 함
  • D-7 시뮬레이션 → 알림 메일 1건 발송
  • 페널티 룰 적용 (6개월 내 2건 → 1년 금지)
  • 익명화: empId 토큰만
§6후속 30/60/90일 자력 로드맵7/8

30일 — 강의 직후

  • 카카오 알림톡 사업자 등록 + 템플릿 심사 통과 (1~2주)
  • 5지역 → 6지역 확장 (facilities 컬렉션 시드 추가)

60일 — 운영 안정화

  • 몽골 시즌제 (5~10월) 신청 시점 시즌 체크 로직
    • 11월에 몽골 신청하려고 하면 자동 차단
  • 유지보수 자동화 강화 (시기별 — 에어컨·외창·침구·스노우타이어)
  • 카카오 알림톡 운영 (사업자 심사 통과 후)

90일 — 시스템 격상

  • 이윤재 SaaS와 데이터 통합
  • 만족도 조사 자동화 (체크아웃 D+1 자동 발송)
§7자동화의 경계8/8

본인 모듈에서 자동화하면 안 되는 부분이 있습니다. 자동화의 경계를 명시하는 게 발표 시에도 중요합니다.

  • 자동 추첨 (시드·로그로 감사 가능) — 결정적 룰이라 자동화 OK
  • 취소 사유 인정/불인정 자동 판정 — 시스템은 분류·통계만, 인정/불인정은 사람이 결정
  • ⚠️ 협력사 정보 공유 — 사용자 동의 체크 시에만 (개인정보 보호)
  • ⚠️ 카카오 알림톡 — 사업자 심사 필요 (1~2주), 워크숍 14h 외
IMPORTANT — 취소 사유 자동 판정 금지 룰이 가장 중요

취소 사유는 "갑자기 출장이 잡혀서", "가족 일이 생겨서" 같은 다양한 맥락이 있는데, 이걸 AI가 자동으로 인정/불인정 판정하면 직원 사이에 형평성 분쟁이 생깁니다. 시스템은 분류·통계까지만 하고, 인정/불인정 판단은 인사총무팀 사람이 합니다. 발표 시 이 boundary를 1줄 명시하세요 — 자동화의 한계를 명확히 알고 있다는 게 강사화 자산의 차별점입니다.

M4 셋업 메뉴 — 이윤재 개인 repo: yyj-tools (통합 인덱스 포함)

셋업 메뉴 — 이윤재 (M4 사내 도구 카탈로그 + 통합 인덱스)

본 셋업 메뉴는 이윤재 님 본인 진도와 맞물려 본 교안과 두 창 띄워서 진행합니다. 사내 도구 카탈로그(도구 등록·실행 상태·로그) + 4모듈 통합 인덱스 골격. 자동화 게이트 Cloud Scheduler 일별 헬스체크 (0 9 * * *) + Slack/Gmail 알림.

읽기 18분
통합 골격 역할

다른 3개 모듈도 결국 사내 도구이므로 M4가 자연스럽게 메인 페이지의 인덱스 역할을 합니다. D2 #8 통합 시점에 M1·M2·M3을 M4 레지스트리에 등록.

§0모듈 개요 — 이 모듈이 무엇을 하는가1/10

이윤재 님의 M4 모듈은 사내에 흩어진 도구들을 한 카탈로그로 등록·관리하는 시스템입니다. 동시에 본 워크숍의 통합 인덱스 역할을 겸합니다 — 다른 3명의 모듈도 결국 "사내 도구"이기 때문에 M4 카탈로그에 등록되면 자연스럽게 통합이 이뤄집니다.

본인 모듈은 두 층의 산출물을 동시에 만듭니다.

  1. 카탈로그 페이지 (/m4-tools) — 사내 도구 등록·실행 상태·로그
  2. 통합 인덱스 페이지 (/) — 4모듈 카드를 한 화면에서 보는 메인 진입점

본인 학습 포커스인 AGENTS.md / 멀티에이전트 오케스트레이션을 같이 다루면서, 프론트 디자인 완성도와 프로젝트 세팅 워크플로우를 같이 익힙니다.

자동화 게이트 — 일별 헬스체크

매일 09:00에 cron이 발화 → 등록된 사내 도구들의 URL을 한 번씩 ping → 응답 없는 도구는 Slack 알림. 즉 사내 도구의 죽음을 자동으로 감지하는 시스템입니다.

§1사전 확정 항목2/10

본인 학습 포커스는 코드 작성보다 프로젝트 세팅·결과물 퀄리티 워크플로우입니다. 그래서 사전 확정 항목 중 1번이 가장 중요합니다.

#항목왜 필요한가결정 시점본인 답변
1AGENTS.md / CLAUDE.md 멀티에이전트 책임 분리 초안본인 학습 포커스의 단일 산출물. 4명 중 본인만 다루는 자산D1 #3 IPO 작성 시__________
2Firebase Auth + 사내 도메인 lock (hd: 'kchglobal.co.kr')사내 직원만 접근 가능하게 강제D1 #4 첫 배포 시__________
3Slack Webhook URL (없으면 콘솔 로그 폴백)헬스체크 알림 수신 채널D2 #7 자동화 게이트 작성 시__________
TIP

본인 학습 포커스는 프론트엔드 완성도 + 디자인 시스템 + AGENTS.md/CLAUDE.md + 멀티 에이전트 오케스트레이션입니다. 코드 작성 자체보다 프로젝트 세팅·결과물 퀄리티 워크플로우.

AGENTS.md가 무엇이고 CLAUDE.md와 어떻게 다른가

  • CLAUDE.md — Claude Code가 본인 repo의 모든 작업에 적용하는 단일 시스템 프롬프트
  • AGENTS.md — 멀티에이전트 협업 패턴을 정의하는 문서. "어떤 작업이 들어오면 어떤 에이전트가 어떤 순서로 처리하는가"의 룰

두 파일은 같이 동작합니다. CLAUDE.md가 모든 작업의 기본 룰이라면, AGENTS.md는 복잡한 작업을 여러 에이전트로 분담시킬 때의 흐름표입니다. 본인 학습 포커스 §5에서 자세히 다룹니다.

§2IPO 4섹션 슬롯 (D1 #3 작성)3/10
# M4 사내 도구 카탈로그 + 통합 인덱스 IPO ## I 타겟 (WHO) - 인사총무팀(이윤재) + (확장) 그룹 전체 ## I 가치 (WHY) - 팀원 도구 흩어짐 0. 누가 뭘 운영 중인지 즉시 파악 + 4모듈 통합 인덱스 골격 ## P-1 IA - / (통합 인덱스 — 4모듈 카드) - /m4-tools (도구 카탈로그) - /m4-tools/register (도구 등록 폼) - /m4-tools/dashboard (실행 로그 + KPI) - /m4-tools/[id] (도구 상세 + GitHub 패널) ## P-2 백엔드 ### Firestore 컬렉션 - tools_registry/{toolId} — { name, owner, type, trigger, deps, githubRepo, lifecycle, links, description } - tools_registry/{toolId}/exec_logs/{logId} — { status, duration, trigger, payload, timestamp } - health_logs/{logId} — { toolId, endpoint, status, responseMs, checkedAt } ### Cloud Function - dailyHealthCheck (트리거: Cloud Scheduler `0 9 * * *`) — 일별 도구 헬스체크 + Slack 알림 ## O 기능 1. 통합 인덱스 (4모듈 카드 + URL 임베드) 2. 도구 등록 폼 (메타정보 + GitHub repo URL) 3. 카탈로그 페이지 (라이프사이클 필터: active/paused/beta/deprecated) 4. 도구 상세 (GitHub 커밋·이슈·릴리스 패널) 5. SSO 로그인 (사내 도메인 lock) **자동화 게이트:** 일별 헬스체크 + 죽은 도구 Slack 알림 ## VERIFY - SSO 로그인 → `@kchglobal.co.kr`만 통과 (다른 도메인 차단) - 도구 1건 등록 → 카탈로그 표시 + tools_registry 1건 추가 - 헬스체크 강제 트리거 → 4모듈 전체 health_logs 4건 생성 - 도구 1건 다운 → Slack 메시지 1건 (또는 콘솔 로그) - 익명화: 도구 owner는 GWS 이메일만 (개인 정보 X)

tools_registry/{toolId}/exec_logs/{logId} 구조가 왜 nested인가

tools_registry/{toolId}/exec_logs/...는 도구별로 실행 로그가 따로 쌓이는 구조입니다 (Firestore의 subcollection 패턴). 이렇게 분리한 이유 — 도구 1건 상세 페이지를 열었을 때 그 도구의 실행 로그만 빠르게 가져오기 위해서입니다. 모든 로그를 한 컬렉션에 다 쌓으면 필터링 쿼리가 느려집니다.

§3D1 #5 AI Studio 프롬프트 슬롯 + URL 기록4/10
[M4 사내 도구 + 통합 인덱스 모듈 특화] - 페이지 5개 시안 (통합 인덱스·카탈로그·등록 폼·대시보드·도구 상세) - 통합 인덱스 (/) — 가장 중요 - 4개 카드 (M1 휴양시설 / M2 연차 / M3 성과관리 / M4 사내 도구) - 각 카드에 모듈명·owner·자동화 1줄 + 외부 링크 아이콘 - 헤더: "KCH그룹 인사총무팀 통합 대시보드 v0" - 카탈로그: 도구 카드 + 라이프사이클 배지 (active=초록 / paused=노랑 / deprecated=회색) - 등록 폼: 도구명·owner·type·GitHub repo URL·tags - 대시보드: 실행 로그 시계열 차트 + 헬스체크 KPI - 도구 상세: 메타 + GitHub 패널 (커밋 5개 / 이슈 3개 / 릴리스 1개) - 색상은 KCH 컬러 통일 (primary #1962A8) - 반응형 (모바일/데스크탑 둘 다 깔끔하게)

본인 URL 기록

본인 URL: ________________________________________________

본인 URL은 통합 인덱스의 URL이기도 합니다. D2 #9 발표 시 마지막에 보여줄 URL.

§4D2 진입 체크리스트5/10
  • AGENTS.md 작성 — 4개 에이전트 책임 분리 (개발·디자인·리뷰·운영)
  • ☐ CLAUDE.md 6대 섹션 (Intent / Stack / 보안 / 파일구조 / 명명규칙 / 금지)
  • ☐ 슬래시커맨드 /register-tool 1개 — 도구 1건 등록
  • ☐ Firebase Auth + 도메인 lock (hd: 'kchglobal.co.kr')
  • ☐ Firestore 컬렉션 3개 더미 (tools_registry 5건, exec_logs 빈 상태, health_logs 빈 상태)
  • ☐ 핵심 페이지 1개 (/) — 통합 인덱스 4카드 슬롯 준비
§5AGENTS.md 작성 슬롯 (D1 #3 또는 D2 #6)6/10

본인 학습 포커스의 단일 산출물입니다. 다른 3명에게는 없는 자산입니다.

# AGENTS.md — KCH 인사총무 통합 대시보드 ## 에이전트 책임 분리 ### 개발 에이전트 (Claude Code CLI 메인) - 코드 작성·리팩토링 - Firebase MCP로 DB 조작 - Next.js 페이지·컴포넌트 구현 ### 디자인 에이전트 (Claude UI) - shadcn/ui 컴포넌트 디자인 - 디자인 토큰 적용 (KCH 컬러 #1962A8 / #70AEDA) - 반응형 레이아웃 ### 리뷰 에이전트 (Claude Code 서브에이전트) - PR 리뷰 - 보안 룰 검사 (.env commit 체크 / 인사정보 마스킹 검증) - 컨벤션 체크 ### 운영 에이전트 - 헬스체크 - 알림 (Slack/Gmail) - 라이프사이클 관리 ## 위임 트리거 - "도구 1개 추가" → design → dev → review → ops 순차 - "에러 발생" → review → dev (수정) - "배포" → ops (헬스체크 → 알림)

4개 에이전트가 어떻게 협업하는가

위 AGENTS.md의 핵심은 "위임 트리거" 섹션입니다. 사용자가 어떤 작업을 시켰을 때, 어떤 에이전트가 어떤 순서로 처리하는지 흐름이 정의되어 있습니다.

예: "도구 1개 추가" 작업

  1. design 에이전트 — 도구 카드 mockup 생성 (KCH 컬러 적용)
  2. dev 에이전트tools_registry 컬렉션에 메타 추가 (Firebase MCP)
  3. review 에이전트 — 보안 룰 검사 (.env commit 체크 / 마스킹 검증)
  4. ops 에이전트 — 헬스체크 추가 (cron 스케줄)

이런 식으로 4개 에이전트가 순차 협업하면, 한 작업의 디자인·구현·리뷰·운영이 빠짐 없이 처리됩니다. 워크숍 14h에서는 이 패턴을 시연 수준까지 만들고, 풀 구현은 30일 후속입니다.

§6자동화 게이트 슬롯 — 일별 헬스체크 + 도메인 lock (D2 #7)7/10

일별 헬스체크

// functions/src/healthCheck.ts import { onSchedule } from 'firebase-functions/v2/scheduler'; export const dailyHealthCheck = onSchedule( { schedule: '0 9 * * *', timeZone: 'Asia/Seoul' }, async () => { const tools = await db.collection('tools_registry') .where('lifecycle', '==', 'active').get(); for (const doc of tools.docs) { const tool = doc.data() as Tool; const result = await checkTool(tool); // HTTP ping or webhook await pushSafe('health_logs', { toolId: tool.toolId, status: result.status, responseMs: result.ms, checkedAt: FieldValue.serverTimestamp(), }); if (result.status === 'down') { await sendSlackAlert(`🔴 도구 다운: ${tool.name} (owner: ${tool.owner})`); } } } );

핵심은 where('lifecycle', '==', 'active') — 라이프사이클이 active인 도구만 헬스체크합니다. pauseddeprecated 상태인 도구는 죽어 있어도 알림을 안 보냅니다 (운영자 의도이므로).

Firebase Auth + 도메인 lock

본인 모듈은 사내 직원만 접근 가능해야 합니다. 그래서 SSO 로그인 시 도메인을 강제로 체크합니다.

// lib/auth.ts import { signInWithPopup, GoogleAuthProvider, signOut } from 'firebase/auth'; import { auth } from './firebase'; export async function signIn(): Promise<User> { const provider = new GoogleAuthProvider(); provider.setCustomParameters({ hd: 'kchglobal.co.kr' }); // 도메인 hint const { user } = await signInWithPopup(auth, provider); if (!user.email?.endsWith('@kchglobal.co.kr')) { await signOut(auth); throw new Error('사내 계정만 사용 가능'); } return user; } // middleware.ts — 모든 보호 라우트 export function middleware(req: NextRequest) { const session = req.cookies.get('session'); if (!session) return NextResponse.redirect('/login'); return NextResponse.next(); }

hd 파라미터와 클라이언트·서버 양쪽 검증

hd: 'kchglobal.co.kr'은 Google 로그인 화면에서 KCH 도메인 계정만 우선 표시되게 하는 hint입니다. 단, 이건 hint일 뿐 강제는 아니라서 사용자가 의도적으로 다른 계정으로 로그인할 수 있습니다. 그래서 클라이언트 측에서 한 번, 서버 측 미들웨어에서 한 번 더 검증합니다 — 양쪽 검증이 두 번 막아주는 안전 장치.

검증 게이트

  • SSO 로그인 → 사내 도메인만 통과 (@gmail.com 차단)
  • 헬스체크 강제 트리거 → 4모듈 전체 health_logs 기록
  • 도구 1건 다운 시뮬레이션 → Slack 메시지 1건
§7D2 #8 통합 인덱스 활성화 (본인 책임)8/10

D2 #8에서 본인 app/page.tsx에 4모듈 카드 4개를 등록합니다. 자세한 실행 절차는 Part 8 통합 인덱스 §2 참조.

MODULES 배열 작성

const MODULES = [ { id: 'm1', title: '휴양시설 통합관리', owner: '이동연', url: '...' }, { id: 'm2', title: '연차 자동화', owner: '이재성', url: '...' }, { id: 'm3', title: '성과관리 시스템', owner: '김경호', url: '...' }, { id: 'm4', title: '사내 도구 카탈로그', owner: '이윤재', url: '/m4-tools' }, ];

다른 3명이 본인 URL을 전달해주면 url 필드에 채워 넣습니다.

tools_registry에도 4모듈 자동 등록

다른 3명 URL을 본인 M4 카탈로그에도 자동으로 등록 → 메타-셀프-인덱스 구조.

"메타-셀프-인덱스"가 무엇인가

  • 본인 모듈(M4) = 사내 도구를 등록하는 카탈로그
  • 4모듈 자체도 사내 도구 → 본인 카탈로그에 등록 가능
  • 즉 본인 모듈이 본인을 포함한 4모듈을 사내 도구로 등록하는 구조

이런 자기 참조 구조를 메타(자기 자신을 가리킴) + 셀프 인덱스(자신을 자신의 인덱스에 포함)라고 부릅니다. 이게 자연스럽게 되는 이유는 M4가 "사내 도구"라는 추상화 위에 만들어졌기 때문 — 다른 3모듈도 결국 "사내 도구"의 한 종류입니다.

§8후속 30/60/90일 자력 로드맵9/10

30일 — 강의 직후

  • AGENTS.md 멀티에이전트 풀 구현 (개발·리뷰·디자인·운영 4개 에이전트 자동 호출)
    • 워크숍에서는 패턴 시연·룰 작성까지 → 30일에 실제 자동 협업 구현
  • 도구 실 등록 — 사내 팀에게 등록 가이드 메일 + admin 승인

60일 — 운영 안정화

  • 알림 채널 정교화 (Slack 웹훅 + 임계치 — 실패율 > 10% / 응답 > 30s)
    • 단순 down 알림이 아니라 KPI 기반 임계치
  • GitHub Webhook 실시간 (push·issue·release → Firestore 즉시 업데이트)

90일 — 시스템 격상

  • 데이터 통합 (Firestore 단일 프로젝트로 4모듈 통합)
  • 풀 통합 (4모듈을 1개 Next.js 앱의 라우트로)
    • L1 Façade 졸업 → 진짜 통합
  • KPI 통합 대시보드 (4모듈 자동화 발화 횟수·성공률·실패율)
§9·§10보안 체크포인트 + 통합 발표 진행자 역할10/10

§9 보안 체크포인트

  • ☐ Firebase Auth 도메인 lock 강제 (클라이언트 + 서버 미들웨어 양쪽)
  • RBAC — 도구 소유자 또는 admin만 등록·수정 (Role-Based Access Control)
  • .gitignore 강제 (.env, *.json credentials, .mcp.json)
  • ☐ GitHub PAT(Personal Access Token)는 Cloud Secret Manager
  • ☐ Slack Webhook URL도 Secret Manager
  • ☐ 통합 인덱스 카드는 새 탭 외부 링크 (iframe 임베드 X — CSP 협의 불필요)

RBAC가 무엇인가

Role-Based Access Control. 사용자 역할에 따라 접근 권한이 다른 시스템입니다. 본인 모듈에서는:

  • 도구 소유자 (owner) — 본인이 등록한 도구의 메타·라이프사이클 수정 가능
  • admin — 모든 도구 수정 가능
  • 일반 직원 — 보기만 가능, 수정 불가

이 구조가 있어야 도구 카탈로그가 신뢰할 수 있는 자산이 됩니다. 누구나 다른 사람 도구를 수정할 수 있으면 카오스가 됩니다.

§10 통합 발표 진행자 역할

D2 #9 통합 발표 진행자

이윤재가 D2 #9 통합 발표 흐름의 진행자입니다. 4명이 각자 시연 후 본인이 통합 인덱스 카드 4개를 한 화면에 보여주는 것으로 워크숍 14h가 클로징됩니다.

본인 발표는 다른 3명과 다릅니다. 다른 분은 본인 모듈 시연이 발표의 전부지만, 본인은:

  1. 본인 모듈 시연 (3분)
  2. 통합 인덱스 시연 (1분, 발표의 클로징) — 4명 모듈을 한 화면에서 본인이 묶어서 보여줌

이 마지막 1분이 워크숍 전체의 클로징 그림입니다. 4명이 각자 만든 모듈이 본인 통합 인덱스 한 페이지에서 묶여 보이는 순간 — 이게 미팅에서 약속한 "통합 대시보드"의 시각적 증거가 됩니다.

A1 Appendix 1 D1 시작 전 본인 PC 1회 셋업

Appendix 1 — 기본 프로그램 설치 · SSH 설정 · GitHub 연결

본 부록은 D1 시작 전(2026-05-07 09:30 이전)에 본인 PC에서 한 번만 실행하면 끝나는 환경 셋업 명령어를 모아둔 단일 문서입니다. 본 교안 사전준비-체크리스트.md와 함께 봐주세요. 체크리스트는 "무엇을"이고, 본 부록은 "어떤 명령으로"입니다. 운영체제별로 §1만 다릅니다. §2(SSH)와 §3(GitHub 연결)은 macOS·Windows·Linux 모두 동일합니다.

읽기 18분
📦 배포-repo.zip 다운로드
D1 시작 전, 본인 PC에 압축 해제 후 §1~§3을 진행하세요.
⬇ 다운로드
030초 흐름1/6
배포-repo.zip 다운로드 ↓ 본인 PC에 압축 해제 (한글 폴더명 OK) ↓ [§1] 필요한 프로그램 6종 설치 ── 한 번만 ↓ [§2] SSH 키 생성 + GitHub 등록 ── 한 번만 ↓ [§3] 본인 GitHub에 private repo 1개 만들고 zip 내용 push ↓ D1 시작 시점에 `npm install` 실행만 하면 OK

배포 zip 다운로드 링크는 D-1 시점 강사가 별도 안내합니다. 보통 Google Drive 또는 사내 공유 링크로 전달됩니다.

§1필요한 프로그램 설치2/6

설치 항목은 6개입니다. 모두 무료, 워크숍 끝난 후에도 계속 씁니다.

#프로그램용도버전
1Git코드 버전관리 + GitHub push2.30+
2Node.jsNext.js 14 빌드·실행20 LTS (필수)
3GitHub CLI (gh)repo 생성·인증 자동화2.0+
4Claude Code워크숍 14h 메인 IDE최신
5Firebase CLIFirebase 배포·init13+
6VS Code보조 에디터최신

1.1 macOS

먼저 Homebrew (macOS용 패키지 매니저) 확인. 없으면 한 줄로 설치:

# Homebrew 설치 여부 확인 which brew # 없으면 설치 (10분 소요) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # 설치 후 PATH 등록 (Apple Silicon 기준) echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)"

이제 6개 프로그램을 한 번에 설치:

# 1~3: Git, Node.js 20, GitHub CLI brew install git node@20 gh # Node 20을 기본으로 (이미 설치된 다른 버전이 있다면) brew link --overwrite node@20 # 4: Claude Code (npm 글로벌) npm install -g @anthropic-ai/claude-code # 5: Firebase CLI npm install -g firebase-tools # 6: VS Code brew install --cask visual-studio-code # VS Code 터미널 명령(`code .`) 활성화 # VS Code 실행 → Cmd+Shift+P → "Shell Command: Install 'code' command in PATH" 클릭

검증 (모두 버전 번호가 나와야 OK):

git --version # git version 2.x node --version # v20.x npm --version # 10.x gh --version # gh version 2.x claude --version # 0.x 또는 1.x firebase --version # 13.x code --version # 1.x

1.2 Windows 10/11

PowerShell을 관리자 권한으로 열고 (시작 메뉴 → "Windows PowerShell" 우클릭 → 관리자로 실행) Winget (Windows 기본 패키지 매니저)으로 설치합니다.

# 1. Git for Windows winget install --id Git.Git -e # 2. Node.js 20 LTS winget install --id OpenJS.NodeJS.LTS -e --version 20.18.0 # 3. GitHub CLI winget install --id GitHub.cli -e # 6. VS Code winget install --id Microsoft.VisualStudioCode -e

PowerShell 창을 한 번 닫고 새로 엽니다 (PATH 갱신을 위해). 그다음 npm 글로벌 패키지 2종:

# 4. Claude Code npm install -g @anthropic-ai/claude-code # 5. Firebase CLI npm install -g firebase-tools

검증 (PowerShell):

git --version node --version npm --version gh --version claude --version firebase --version code --version
TIP — Winget이 없는 구버전 Windows라면

각 프로그램 공식 사이트에서 .msi/.exe로 설치

WARNING

Node.js 18 이하는 Next.js 14에서 경고가 발생합니다. 반드시 20 LTS 사용.

1.3 Linux (참고)

Ubuntu/Debian 기준. macOS·Windows 4명 대상이라 수강생은 보지 않아도 OK.

sudo apt update sudo apt install -y git curl # Node.js 20 LTS (NodeSource) curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - sudo apt install -y nodejs # GitHub CLI curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list sudo apt update && sudo apt install -y gh # Claude Code, Firebase CLI npm install -g @anthropic-ai/claude-code firebase-tools # VS Code sudo snap install code --classic
§2SSH 키 생성 + GitHub 등록3/6

GitHub에 코드를 push하려면 SSH 키 1쌍 (private + public)이 필요합니다. 한 번 만들어 등록해두면 영구적으로 쓰입니다.

2.1 SSH 키 생성 — macOS / Windows / Linux 공통

# 본인 GitHub 이메일로 키 생성 (Ed25519 알고리즘) ssh-keygen -t ed25519 -C "your-email@example.com" # 질문 3개에 모두 Enter (기본 위치, 빈 비밀번호) # - Enter file in which to save the key: [Enter] # - Enter passphrase: [Enter] # - Enter same passphrase again: [Enter]
NOTE

Windows에서는 Git Bash 또는 PowerShell 어느 쪽에서 실행해도 OK. 같은 명령어가 동작합니다.

생성된 키는 다음 위치에 저장됩니다:

OS위치
macOS / Linux~/.ssh/id_ed25519 (private) + ~/.ssh/id_ed25519.pub (public)
WindowsC:\Users\{본인}\.ssh\id_ed25519 + id_ed25519.pub

2.2 SSH 에이전트에 키 등록

macOS:

# ssh-agent 시작 eval "$(ssh-agent -s)" # macOS Keychain 연동 (재부팅해도 유지됨) ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Windows (PowerShell 관리자):

# OpenSSH 인증 에이전트 서비스 시작 (자동 시작 설정) Get-Service ssh-agent | Set-Service -StartupType Automatic Start-Service ssh-agent # 키 등록 ssh-add $env:USERPROFILE\.ssh\id_ed25519

Linux:

eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519

2.3 Public 키를 GitHub에 등록

(A) 클립보드 복사

# macOS pbcopy < ~/.ssh/id_ed25519.pub # Windows (PowerShell) Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub | Set-Clipboard # Linux (xclip 필요) xclip -selection clipboard < ~/.ssh/id_ed25519.pub

(B) GitHub 웹으로 이동 → 등록

  1. https://github.com/settings/ssh/new 접속
  2. Title: 본인이 알아볼 이름 (예: kch-laptop-mjs-2026)
  3. Key type: Authentication Key
  4. Key: 위에서 복사한 값 붙여넣기 (ssh-ed25519 AAAA...로 시작)
  5. Add SSH key 클릭

2.4 GitHub CLI 로그인 (선택이지만 강력 권장)

gh CLI 로그인까지 해두면 워크숍 중 repo 생성·issue 생성을 명령 한 줄로 합니다.

gh auth login # 질문 3개: # - What account? → GitHub.com # - protocol? → SSH # - authenticate? → Login with a web browser # 표시된 8자리 코드 메모 → 엔터 → 브라우저 열림 → 코드 입력 → Authorize

2.5 검증

# SSH 인증 검증 (GitHub에 ping) ssh -T git@github.com # 첫 접속이면 fingerprint 확인 질문 → yes 입력 # 정상 결과: # Hi {본인-username}! You've successfully authenticated, but GitHub does not provide shell access. # gh CLI 로그인 검증 gh auth status # 정상: ✓ Logged in to github.com account {본인}

위 두 검증이 모두 통과하면 GitHub 연결 준비 끝입니다.

2.6 Git 사용자 정보 등록 (한 번만)

Git이 commit을 만들 때 "누가 만들었는지"를 기록할 이름·이메일을 한 번 등록합니다. GitHub에 등록한 이메일과 같은 값을 쓰세요 (그래야 GitHub commit 페이지에 본인 프로필 아이콘이 표시됩니다).

git config --global user.name "본인이름영문" git config --global user.email "your-github-email@example.com" # 등록 확인 git config --global user.name git config --global user.email
§3GitHub 연결 — 배포 zip을 본인 repo로 옮기기4/6

3.1 흐름 요약

배포-repo.zip 다운로드 → 압축 해제 (배포-repo/ 폴더 생성) → 본인 모듈 폴더만 골라 작업 (예: 이재성=mjs-leaves) → 공통 템플릿(kch-hr-module-template)을 베이스로 본인 모듈 README 합치기 → 본인 GitHub에 빈 private repo 1개 생성 → git init → commit → push

3.2 압축 해제

OS방법
macOSFinder에서 배포-repo.zip 더블클릭 → 자동 압축 해제
Windows파일 우클릭 → "압축 풀기" → 본인이 알기 쉬운 폴더 선택 (예: C:\workshop\)

압축 해제 결과:

배포-repo/ ├── README.md ├── kch-hr-module-template/ ← ★ 본인 베이스 (전체 파일) ├── mjs-leaves/ ← 이재성 README만 ├── kkh-performance/ ← 김경호 README만 ├── moo-facilities/ ← 이동연 README만 └── yyj-tools/ ← 이윤재 README만

3.3 본인 모듈 폴더 만들기 (4명이 각자 본인에 맞춰 1번만)

참가자별 본인 repo 이름:

참가자본인 repo 이름
이재성mjs-leaves
김경호kkh-performance
이동연moo-facilities
이윤재yyj-tools

예시: 이재성 (mjs-leaves) 기준

압축 해제한 배포-repo/ 안에서 작업합니다.

# 1. 압축 푼 폴더로 이동 cd 배포-repo # 2. 공통 템플릿을 본인 repo 이름으로 복사 (베이스) cp -r kch-hr-module-template mjs-leaves-mine # Windows (PowerShell) # Copy-Item -Recurse kch-hr-module-template mjs-leaves-mine # 3. 본인 README로 교체 cp mjs-leaves/README.md mjs-leaves-mine/README.md # Windows (PowerShell) # Copy-Item mjs-leaves/README.md mjs-leaves-mine/README.md -Force # 4. 본인 폴더로 이동 cd mjs-leaves-mine
TIP

폴더 이름에 -mine을 붙인 이유는 압축 해제된 원본 폴더(mjs-leaves/)와 충돌을 피하기 위해서입니다. 본인 repo로 push할 때 GitHub 이름은 mjs-leaves(본인 깔끔한 이름)로 만들면 됩니다.

3.4 본인 GitHub에 빈 private repo 생성 + 첫 push

방법 A — gh CLI 한 줄 (권장):

# 본인 폴더 안에서 실행 (예: mjs-leaves-mine/) git init -b main git add . git commit -m "init: 본인이름 모듈 워크숍 시작" # GitHub에 빈 repo 생성 + 자동 remote 연결 + push 한 번에 gh repo create mjs-leaves --private --source=. --push

https://github.com/{본인}/mjs-leaves 접속하면 코드가 올라가 있어야 합니다.

방법 B — 웹으로 repo 만들고 수동 연결:

  1. https://github.com/new 접속
  2. Repository name: mjs-leaves (본인 모듈 이름)
  3. Private 선택
  4. README · .gitignore · license는 모두 체크 해제 (이미 우리 폴더에 있음)
  5. Create repository 클릭

그다음 본인 폴더에서:

git init -b main git add . git commit -m "init: 본인이름 모듈 워크숍 시작" git remote add origin git@github.com:{본인}/mjs-leaves.git git push -u origin main

3.5 검증

# 로컬 git 상태 git status # nothing to commit, working tree clean # remote 연결 확인 git remote -v # origin git@github.com:{본인}/mjs-leaves.git (fetch) # origin git@github.com:{본인}/mjs-leaves.git (push) # 브라우저로 본인 repo URL 접속 → 파일 28개 보이면 성공

3.6 다음 단계 — D1 시작 전 마지막 한 줄

# 의존 패키지 설치 (5분 소요, 인터넷 필요) npm install

워크숍 D1 09:30에 본 교안 Part 1 — 환경 셋업 + Firebase MCP의 Step 2부터 진행합니다 (Firebase 프로젝트 생성·MCP 키 발급).

§4자주 막히는 곳 — 트러블슈팅5/6
증상원인해결
git pushPermission denied (publickey)SSH 키 미등록§2.3 다시 — public 키를 GitHub에 등록했는지 확인
ssh -T git@github.comConnection refused사내 망에서 22번 포트 차단HTTPS+PAT로 우회 (별도 안내) 또는 IT팀에 SSH 화이트리스트 신청
npm installEACCES (macOS/Linux)npm 글로벌 폴더 권한sudo npm install -g {패키지} (1회만 OK) 또는 nvm 사용 권장
gh auth login 후에도 push 실패git remote URL이 https로 되어 있음git remote set-url origin git@github.com:{본인}/{repo}.git
Windows에서 한글 폴더명 깨짐PowerShell 인코딩PowerShell에서 chcp 65001 실행 후 다시 시도 (UTF-8 모드)
node: command not found (Windows)PATH 미반영PowerShell 창을 닫고 새로 열기. 그래도 안 되면 재부팅
claude --version 안 됨npm 글로벌 PATH 누락npm config get prefix 결과를 PATH에 추가
§5빠른 점검 체크리스트 (D1 09:30 시작 전)6/6
  • git --version 결과 표시
  • node --version → v20.x
  • gh --version 결과 표시
  • claude --version 결과 표시
  • firebase --version 결과 표시
  • ssh -T git@github.com → "Hi {본인}! You've successfully authenticated"
  • gh auth status → "✓ Logged in"
  • ☐ 본인 GitHub repo URL 접속 → 파일 28개 + README.md 본인 모듈 내용 표시
  • ☐ 본인 PC 본인 폴더에서 npm install 통과

위 9개가 모두 OK이면 D1 #1 90분이 정상 동작할 환경입니다.

A2 Appendix 2 Firebase MCP 셋업 가이드

Appendix 2 — Firebase MCP 셋업 가이드

대상: 강사 사전 학습 + 워크숍 D1 #1 환경 셋업 시 학생용 · 소요 시간: 강사 1회 셋업 ~15분, 학생당 ~10분 · 목적: Claude Code CLI에서 Firestore를 직접 조작 — DB 스키마·컬렉션·데이터를 CC 자율 사이클로 관리.

2026-05 개정

서비스 계정 키(JSON) 방식 폐기. Google 공식 firebase-tools mcp + firebase login OAuth 인증으로 전환. 키 파일 자체가 없어 유출 위험 0, 회사 GWS 조직 정책에 막히지 않음.

읽기 14분
0Firebase MCP이란?1/8

MCP = Model Context Protocol — Anthropic이 만든 표준. Claude Code가 외부 시스템(DB·API·툴)에 접근할 때 쓰는 프로토콜.

Firebase MCP = Firestore·Firebase Auth·Firebase Storage 조작용 MCP 서버. Google이 공식 제공하며 firebase-tools (Firebase CLI) 자체에 내장됨. Claude Code가 직접 Firestore에 컬렉션 만들고·문서 추가하고·룰 배포할 수 있음.

Without Firebase MCP (수동)

사람: Firebase Console에서 컬렉션 생성 사람: 더미 데이터 한 줄씩 입력 사람: Firestore 룰 콘솔에서 작성·배포 사람: 코드는 Cursor/CC에서, DB는 콘솔에서 — 컨텍스트 분리

컨텍스트 스위칭 ↑, CC가 DB 상태를 모름

With Firebase MCP (CC 자율)

CC: "employees 컬렉션에 더미 데이터 20건 넣어" CC: → Firebase MCP 호출 → Firestore에 직접 push CC: "현재 이 컬렉션 구조 보여줘" → 즉시 응답 사람: 결과 확인만

CC가 코드·DB·룰을 한 컨텍스트에서 관리

인증 방식 (왜 키 파일 안 쓰나)

Firebase MCP는 firebase-tools CLI와 같은 인증을 공유한다. 즉 firebase login으로 로그인한 OAuth 토큰을 그대로 사용.

항목서비스 계정 키 (구)OAuth 로그인 (현)
파일 형태JSON 평문OS 키체인에 토큰
만료없음 (영구)자동 만료 + 갱신
회수콘솔에서 수동 삭제firebase logout 한 줄
GitHub commit 사고즉시 영구 권한 노출토큰 회수 가능
회사 GWS 조직 정책 차단차단됨 (default)영향 없음

OAuth가 모든 면에서 우수. 키 방식은 더 이상 권장 X.

1사전 준비2/8
  • ☐ Firebase 프로젝트 생성 완료 (한국 리전)
  • Firebase CLI 설치 (npm install -g firebase-tools) → firebase --version 확인
  • Firebase CLI 로그인 완료 (firebase login) — 브라우저에서 본인 GWS 계정으로 인증
  • ☐ Claude Code 설치·로그인 완료 (claude --version)
  • ☐ Node.js 20+ 설치 (node -v)

회사 GWS 계정으로 진행 가능. 이 방식은 조직 정책 iam.disableServiceAccountKeyCreation에 영향받지 않음.

2셋업 순서 (5단계, 약 15분)3/8

Step 1 — Firebase 프로젝트 정보 확인 (2분)

firebase login # 로그인 안 했으면 먼저 firebase projects:list # 본인 프로젝트 ID 메모 (예: kch-dashboard) firebase use kch-dashboard # 활성 프로젝트 지정

Step 2 — Firestore 데이터베이스 활성화 (3분)

  1. Firebase Console → Firestore DatabaseCreate database
  2. Production mode 선택 (Test mode는 보안 룰 X)
  3. 한국 리전 (asia-northeast3 서울) 선택
  4. 생성 완료

Step 3 — Firebase MCP 등록 (2분)

두 경로 중 하나 선택. 경로 A 권장 (학생용 단순).

경로 A — /plugin 명령으로 자동 설치 (권장)

Claude Code 안에서 한 줄:

> /plugin install firebase@claude-plugins-official > /reload-plugins
  • claude-plugins-official 마켓플레이스는 Claude Code에 기본 등록되어 있어 별도 marketplace add 불필요
  • 플러그인 내부에 위 .mcp.json이 이미 들어있어 자동 설정됨
  • /reload-pluginsClaude Code 재시작 없이 즉시 활성화
  • 설치 위치: ~/.claude/plugins/cache/claude-plugins-official/firebase/

만약 /plugin 명령이 안 보이면: Claude Code 버전이 낮은 것. npm install -g @anthropic-ai/claude-code@latest 또는 brew upgrade claude-code로 업데이트 후 터미널 재시작.

경로 B — 프로젝트 로컬 .mcp.json 직접 작성

프로젝트 루트에 .mcp.json 파일 생성:

{ "mcpServers": { "firebase": { "command": "npx", "args": ["-y", "firebase-tools@latest", "mcp"] } } }

언제 이 경로: 프로젝트별로 MCP 구성을 git에 commit해서 팀원과 공유할 때. 개인 작업·학생 워크숍은 경로 A가 단순.

공통: 추가 환경변수·키 경로 불필요. firebase-tools가 Step 1의 OAuth 토큰을 자동으로 사용. firebase use로 지정한 프로젝트가 기본 타깃.

Step 4 — MCP 인식 확인 (2분)

경로 A를 골랐다면: /reload-plugins만 실행 → 재시작 불필요. 바로 다음 명령:

> /mcp list # firebase MCP가 보이면 OK

경로 B를 골랐다면: .mcp.json을 새로 만든 디렉토리에서 Claude Code를 처음 켜는 거라 재시작 필요:

# 현재 CC 세션 종료 후 프로젝트 디렉토리에서 새로 시작 cd <프로젝트 루트> claude > /mcp list # firebase MCP가 보이면 OK

Step 5 — 동작 확인 (3분)

> Firestore에 test_collection 만들고 더미 문서 1개 넣어줘

CC가 Firebase MCP를 호출해서 컬렉션·문서를 만들면 셋업 성공.

Firebase Console에서 직접 확인:

  • Firestore Database → test_collection 보임 → ✅

Step 6 — Firestore Security Rules 초기 배포 (3분)

프로젝트 루트에 firestore.rules:

rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 인증된 사용자만 읽기·쓰기 (워크숍 14h 동안 단순화) match /{document=**} { allow read, write: if request.auth != null; } } }
firebase deploy --only firestore:rules
WARNING

프로덕션에서는 위 룰은 절대 X. 컬렉션별 세분 룰 작성 필요. 워크숍 14h 데모 한정.

3CC와 함께 쓰는 패턴4/8

3.1 CLAUDE.md에 룰 강제 (프로젝트 루트)

# CLAUDE.md — Firebase 작업 룰 이 프로젝트는 Firestore + Firebase Auth + Firebase App Hosting 사용. Firebase MCP는 firebase-tools CLI 내장 버전(`firebase-tools mcp`)을 사용한다. ## DB 작업 시 - 컬렉션 생성·수정은 Firebase MCP 사용 (수동 콘솔 X) - 더미 데이터 삽입 후 즉시 사용자에게 결과 보고 - Firestore 룰 변경 시 반드시 `firebase deploy --only firestore:rules` 후 검증 ## 인증 - 절대 서비스 계정 키 JSON을 만들거나 사용하지 말 것 - 인증은 firebase-tools CLI의 OAuth 토큰을 통해서만 (사용자가 firebase login으로 로그인됨) - GOOGLE_APPLICATION_CREDENTIALS 환경변수 등장하면 안 됨 ## 보안 - 직원 식별 정보(이름·사번·연봉)는 토큰 치환 후 저장 - API 키는 .env.local에서 읽음, GitHub commit 금지

3.2 자율 사이클 예시 (이재성 연차 모듈)

사용자: 직원 마스터 컬렉션 만들고 더미 20명 넣어줘. 사번·입사일·해외여부·사업부·연봉. CC: [1] Firebase MCP로 employees 컬렉션 생성 [2] 한국 인사 맥락의 더미 데이터 20개 생성 (이름은 토큰 E001~E020) [3] Firestore에 push (Firebase MCP) [4] 검증: firebase MCP로 컬렉션 read → 20개 문서 확인 [5] 보고: "employees 컬렉션 생성 + 20개 더미 push 완료. 입사 1년 미만 3명 / 5년차 4명 / 15년 1명 / 30년 1명 (룰 테스트용 다양성) 포함."
4자주 만나는 에러 + 해결법5/8
에러원인해결
MCP server firebase failed to startNode 20 미만, 또는 firebase-tools 미설치node -v 확인, npm install -g firebase-tools
Error: Failed to authenticate, have you run firebase login?OAuth 토큰 없음firebase login 실행 후 CC 재시작
No active projectfirebase use 안 함firebase use <projectId> 실행
Firestore PERMISSION_DENIEDSecurity Rules 차단Step 6 룰 확인 (request.auth != null)
Project not foundprojectId 오타firebase projects:list로 정확한 ID 확인
MCP tool not foundCC 재시작/리로드 안 함경로 A: /reload-plugins. 경로 B: Claude Code 종료 후 재시작
Firebase MCP가 /mcp list에 안 보임 (경로 B).mcp.json 위치 또는 JSON 문법 오류프로젝트 루트에 있는지, JSON 파싱 유효한지 확인
/plugin 명령 인식 안 됨 (경로 A)Claude Code 버전 낮음npm install -g @anthropic-ai/claude-code@latest 또는 brew upgrade claude-code 후 터미널 재시작
Plugin not found in any marketplace (경로 A)마켓플레이스 캐시 outdated/plugin marketplace update claude-plugins-official 후 재시도
5보안 체크리스트6/8

이 가이드의 OAuth 방식은 키 파일 자체가 없어 유출 위험이 거의 없음. 그래도 다음은 강제:

  • .mcp.json만 commit, 어떤 secrets도 들어가지 않게 유지
  • .gitignore에 다음 포함:
    .env .env.local
  • 서비스 계정 키 JSON을 만들지 말 것 — 만들었다면 즉시 Firebase Console에서 회수 + 로컬 파일 삭제
  • ☐ 개인 디바이스에 firebase login → 디바이스 분실 시 즉시 firebase logout 또는 GWS 관리자 페이지에서 OAuth 토큰 회수
  • ☐ Firestore 룰: 워크숍 14h는 인증 기반 단순 룰, 프로덕션 전 컬렉션별 세분 룰 작성 필요
  • ☐ 인사정보 익명화 게이트 강제 후 Firestore push

운영 단계 권고 (워크숍 종료 후)

  • 로컬 개발: firebase login 그대로 유지
  • 서버 배포 (Cloud Run, App Hosting 등): Workload Identity Federation 사용. 서비스 계정 키 영구 폐기
  • CI/CD: firebase login:ci로 발급되는 토큰 사용 + GitHub Secrets에 저장 (만료 가능, 회수 가능)
6자주 쓰는 명령어 모음7/8
# Firebase CLI firebase login # OAuth 로그인 (1회) firebase logout # 로그아웃 + 토큰 회수 firebase projects:list # 프로젝트 목록 firebase use # 활성 프로젝트 지정 firebase deploy # 전체 배포 firebase deploy --only firestore:rules # 룰만 배포 firebase deploy --only hosting # Hosting만 배포 firebase emulators:start # 로컬 에뮬레이터 # Claude Code MCP > /mcp list # MCP 서버 목록 > /mcp logs firebase # MCP 로그 (디버그용) # Claude Code Plugins (경로 A) > /plugin install firebase@claude-plugins-official # Firebase 플러그인 설치 > /plugin marketplace update claude-plugins-official # 마켓플레이스 캐시 새로고침 > /reload-plugins # 재시작 없이 플러그인 적용 > /plugin # 플러그인 매니저 UI 열기 # Firestore 데이터 검증 firebase firestore:export gs:// # 백업
7참고8/8

SPEAKER

강사 소개

KCH그룹 인사총무팀 AX 파일럿 교육의 진행 강사입니다.

김혜련 (Kyra Kim)

김혜련 Kyra Kim

이노핏파트너스 프로젝트 교수

AI Automation Make.com Claude Code Vibe-coding

저서

『당신의 첫 AI 직원』

서울경제경영출판사 · 2026

커뮤니티

GPTers 스터디장 (16~19기)

100X.MONSTER 운영

강의 이력

  • · LG AX Camp for Leaders (임원교육)
  • · LG U+ 리더 AI 업무자동화 심화 교육
  • · 멀티캠퍼스 — n8n AI 자동화 실전
  • · 세계일보 Vibe-coding 교육 코칭
  • · SKT Design Camp 코칭
  • · SKT Dify 교육 코칭 외 다수