STEP 05 OF 06

MindLog 직접 만들고 배포하기

Claude 데스크톱 앱에 프롬프트 7개를 넣어 계획 문서부터 목업, 구현, 자동 테스트, Cloudflare 배포까지 진행합니다.

75분 실습5 / 6 단계
워크숍 진행 경로 현재 5 / 6 단계 · 83%
  1. 01개요
  2. 02Part 1
  3. 03Part 2
  4. 04Part 3
  5. 05Part 4
  6. 06부록

이 Part는 실제로 진행한 제작 과정을 그대로 따라갑니다. 코드를 한 줄도 직접 쓰지 않고, 프롬프트 7개와 터미널 한 줄로 계획 → 목업 → 구현 → 테스트 → 배포까지 갑니다.

4.0 전체 로드맵

단계작업시간
4.1준비물 확인과 작업 폴더 연결5분
4.21단계 — 아이디어를 계획 문서로 (프롬프트 1)10분
4.32단계 — 요구사항 좁히기: 백엔드·페르소나·입력 방식 (프롬프트 2)5분
4.43단계 — 근거 있는 답 설계: 가짜 인용 막기 (프롬프트 3)10분
4.54단계 — 목업으로 화면 먼저 보고 고치기 (프롬프트 4~6)10분
4.65단계 — 구현과 자동 테스트 (프롬프트 7)20분
4.76단계 — 키 만들고 Cloudflare에 배포10분
4.8마무리 — 정리, 확장 아이디어, 막히는 지점5분
완성된 구조 (화이트보드에 그려보세요):
┌──────────────────┐ HTTPS ┌────────────────────────┐ HTTPS ┌──────────────────────────┐ │ MindLog 앱 │ ───────► │ Cloudflare Worker │ ──────► │ OpenRouter │ │ (Expo · 휴대폰) │ │ (Hono · API + 웹앱) │ │ google/gemini-3.5- │ │ + 웹 브라우저 │ ◄─────── │ │ ◄────── │ flash-lite │ └──────────────────┘ └───────────┬────────────┘ └──────────────────────────┘ │ ┌───────────▼────────────┐ │ Cloudflare D1 (SQL) │ │ messages · images │ └────────────────────────┘

하나의 Worker가 API와 웹 앱을 함께 서비스합니다. 같은 서버 주소를 휴대폰 앱(Expo Go)도 그대로 씁니다. 대화·받아쓰기·사진 읽기 모두 google/gemini-3.5-flash-lite 하나로 처리합니다.

이 Part의 작업 방식 — Claude 데스크톱 앱이 기본 실행자입니다

CLAUDE 앱 문서·목업·코드 작성·테스트 실행

파란 라벨의 프롬프트를 Claude 데스크톱 앱 대화창에 붙여넣습니다. 연결된 폴더에 Claude가 직접 파일을 만들고 고치고, 테스트를 돌리고, 결과를 보여 줍니다.

내가 직접 로그인·API 키 발급·터미널 한 줄

주황 라벨이 있을 때만 내가 움직입니다. 비밀번호 입력, 계정 로그인, 배포 스크립트 실행, 승인 버튼 클릭이 여기에 해당합니다.

보안 원칙 세 가지: ① API 키를 대화창에 붙여넣지 않습니다 — Claude에게 "파일에 저장해 줘"라고 시키거나 직접 파일에 적습니다. ② Claude가 요청하는 명령·파일 접근 승인창은 읽고 나서 승인합니다. ③ 키에는 사용 한도와 만료일을 겁니다(이 워크숍은 $5 · 7일).
왜 데스크톱 앱인가요? 터미널 도구와 달리 ① 내 폴더를 연결해 두면 그 폴더에 바로 코드가 쌓이고, ② 계획서는 문서로, 화면 설계는 눌러 볼 수 있는 목업으로 나오고, ③ 브라우저 자동화로 웹 화면을 직접 눌러 보며 스스로 테스트합니다. 초보자가 "코드"가 아니라 "결과물"을 보며 판단할 수 있습니다.

4.1 준비물과 작업 폴더 연결 (5분)

준비가 끝나면 다음 두 단계로 작업 공간을 만드세요.

  1. MindLog 작업 폴더를 만듭니다.
    mkdir -p ~/projects/mobile/mindlog
  2. Claude 앱에서 프로젝트를 만들고 폴더를 연결합니다. 새 프로젝트를 만든 뒤 방금 만든 ~/projects/mobile/mindlog 폴더를 선택하세요.
📁
폴더 연결이 이 워크숍의 출발점입니다. 연결하지 않으면 Claude가 만든 결과물이 내 컴퓨터에 남지 않습니다. 빈 폴더를 하나 만들고 연결한 뒤 시작하세요.

4.2 1단계 — 아이디어를 계획 문서로 (10분)

코드부터 시키지 않습니다. 먼저 3시간 안에 끝낼 수 있는 계획을 문서로 받습니다. 이 문서가 이후 모든 작업의 기준이 됩니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 1 아이디어 → 계획 문서
모바일 앱을 만들 거예요. 내 일상을 기록하는 앱이에요.
생각나는 것들, 기억하고 싶은 것들, 일상에서 일어나는 소소한 일들을 남기는 앱이요.
기록하기 쉬워야 해서 모바일 앱으로 정했고, 글로 쓰기 힘들 때도 많으니
음성 같은 쉬운 입력 방법도 있으면 좋겠어요.

3시간 바이브 코딩 워크숍 안에 완성된 제품을 만들고 싶어요.
그래서 처음에는 기능이 많으면 안 됩니다.

3시간에 끝낼 수 있는 계획을 자세히 세워 주고, 어떤 기술을 쓸지도 정리해서
문서로 만들어 주세요.

돌아오는 것: 계획 문서 한 편. 목표와 MVP 범위(반드시 넣을 것 / 넣으면 좋은 것 / 이번엔 안 할 것), 화면 구성, 기술 스택, 데이터 모델, 3시간 타임라인, 단계별 프롬프트, 리스크와 대안까지 들어 있습니다.

여기서 꼭 확인하세요:
  • "이번엔 안 할 것"에 로그인·알림·스토어 배포가 들어가 있는가 (3시간 안에 끝내려면 빼야 합니다)
  • 화면이 3~4개로 줄어 있는가
  • 데이터 모델(테이블)이 한두 개로 단순한가

범위가 커 보이면 "○○는 이번 범위에서 빼 주세요"라고 문서를 고치게 합니다. 문서를 고치는 것이 곧 제품을 고치는 것입니다.

4.3 2단계 — 요구사항 좁히기 (5분)

계획이 나온 뒤에 "이 앱만의 것"을 정합니다. 범용 챗봇이 아니라 역할과 말투 규칙이 이 제품의 핵심입니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 2 백엔드 · 페르소나 · 대화 규칙 · 입력 방식
DB는 Cloudflare를 쓸 거예요.
간단한 기록도 하고, AI와 대화할 수 있는 기능도 넣으면 좋겠어요.

AI는 모든 질문에 답하는 범용이 아니라, 대답하는 사람의 페르소나를 유저가 고르게 해 주세요.
예를 들면 상담자, 철학자, 인문학자, 심리학자. 기본은 상담자.
각자 전문가가 이야기하듯 답하면 됩니다.

판단해서 구체적인 답이 필요 없는 경우에는, 유저의 말을 간략하게 요약하고
"그런 일이 있었군요, 다른 얘기 나눌 것이 있을까요?"처럼 되물어 주세요.

모델은 OpenRouter의 google/gemini-3.5-flash-lite를 씁니다.
유저가 글, 음성, 사진으로 대화할 수 있어야 해요.

이 한 번의 프롬프트로 계획 문서에 페르소나 표, 응답 규칙, 시스템 프롬프트 초안, 음성·사진 입력 처리 방식이 추가됩니다.

요구설계로 바뀐 모습
페르소나 4종, 기본은 상담자페르소나별 관점·근거 규칙을 가진 시스템 프롬프트 4벌
털어놓는 말에는 조언 금지모델이 먼저 listen/advise를 판단하고, listen이면 3문장 이내 요약 + 한 번만 되묻기
글·음성·사진음성은 받아쓰기 후 확인·수정, 사진은 휴대폰에서 줄여서 함께 전송

4.4 3단계 — 근거 있는 답 설계하기 (10분)

전문가처럼 답하려면 근거가 필요합니다. 그런데 LLM은 그럴듯한 가짜 인용을 만들어 냅니다 — 존재하지 않는 책, 실제로 하지 않은 말. 기록 앱에서 이것은 치명적입니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 3 전문가의 근거를 들게 하기
페르소나가 답할 때 전문가의 의견처럼 근거를 들어 주면 좋겠어요.
철학자라면 어떤 철학자의 글을 인용하고,
인문학자라면 관련된 책과 그 책에서 인용된 문구를,
심리학자라면 심리학 이론에 기초해서 답하게요.
독자에게 실제로 도움이 될 문구를 인용해 주세요.

그리고 모델이 인용을 지어내지 않게 막는 방법도 함께 설계해 주세요.
가짜 인용을 막는 3단 설계 (이 워크숍의 핵심):
  1. 검증된 근거 목록을 코드에 둡니다. quotes.ts에 철학자 문장 10개, 책 인용 10개, 심리학 이론 10개, 상담 이론 4개를 id와 함께 적어 둡니다.
  2. 모델은 문장을 쓰지 않고 id만 고릅니다. 응답을 JSON 형식으로 받되, evidence_id를 목록에 있는 id만 허용하는 enum으로 지정합니다. 목록에 없는 id는 애초에 만들어 낼 수 없습니다.
  3. 서버가 한 번 더 확인합니다. 고른 id가 실제 목록에 있고 그 페르소나의 것인지 검사하고, 아니면 근거 없이 본문만 보냅니다. 앱은 목록의 원문을 그대로 인용 카드로 보여 줍니다.

결과적으로 화면에 보이는 인용문은 100% 사람이 검수한 문장입니다. 모델이 할 수 있는 일은 "지금 상황에 어떤 문장이 맞는지 고르는 것"뿐입니다.

안전 규칙도 같이 넣습니다. 자해·자살을 암시하는 말이 감지되면 페르소나·근거 규칙과 관계없이 걱정을 전하고 한국 109, 미국 988 안내를 붙입니다. 모델이 빠뜨려도 서버가 문구를 덧붙이도록 이중으로 만듭니다.
📚
워크숍 후 숙제: 인용 목록의 번역문을 신뢰하는 한국어 판본과 대조하고, 페르소나마다 10~20개로 늘리세요. 목록의 품질이 곧 이 앱의 품질입니다.

4.5 4단계 — 목업으로 화면을 먼저 봅니다 (10분)

코드로 만들기 전에 눌러 볼 수 있는 목업을 받습니다. 이 단계에서 고치면 몇 분, 구현 후에 고치면 몇십 분이 듭니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 4 계획을 화면으로
좋아요. 이 계획을 기초로 디자인을 하죠.
전체적으로 인터페이스와 사용자 화면이 어떻게 보이는지
제가 확인하고 점검할 수 있는 목업 디자인을 만들어 주세요.

여기서 실제로 두 번 고쳤습니다. 수강생도 같은 눈으로 목업을 보세요 — 빠진 화면을 찾는 것이 목적입니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 5 첫 화면과 사용자 여정 순서
유저가 처음 보는 홈 화면은 어떻게 되나요? 홈 화면도 보여 주세요.
유저의 여정대로 화면을 순서대로 보여 주고, 인터랙티브한 목업으로 만들어 주세요.
제가 직접 흐름까지 눌러 보게요.
CLAUDE 앱에 붙여넣기 · 프롬프트 6 빠진 기능 발견
과거의 기록을 보거나, 과거에 AI와 나눈 대화를 보는 화면이 없는 것 같은데
그런 기능도 추가해 주세요.
목업에서 발견한 것고친 내용
앱을 처음 열었을 때 보이는 화면이 없음로고·한 줄 소개·기능 3개·[시작하기] 버튼의 첫 화면 추가
화면이 주제별로 흩어져 있어 흐름이 안 보임사용자 여정 순서(처음 열기 → 첫 기록 → 음성 → 확인 → 하루 화면 → …)로 번호를 매겨 재배치
지난 기록·지난 대화를 볼 방법이 없음날짜별 카드 목록 화면 추가 + 하루 화면 헤더에 들어가는 입구(시계 아이콘) 추가
목업 볼 때 체크리스트: ① 앱을 처음 여는 사람이 무엇을 보는가 ② 가장 자주 하는 행동(기록 남기기)이 몇 번의 탭인가 ③ 되돌아가는 길(뒤로·취소)이 모든 화면에 있는가 ④ 빈 화면(기록이 하나도 없을 때)은 무엇을 보여 주는가

4.6 5단계 — 구현과 자동 테스트 (20분)

이제 한 번에 시킵니다. 중요한 것은 "만들어 줘"가 아니라 "만들고, 테스트하고, 고쳐 줘"라고 말하는 것입니다.

CLAUDE 앱에 붙여넣기 · 프롬프트 7 계획대로 구현 + 테스트까지
계획대로 구현해 주세요.
필요한 Cloudflare 프로젝트를 만들고, 필요한 것들은 알아서 만들어 주세요.
가짜 AI 서버와 브라우저 자동화를 써서 철저히 테스트하고,
실패하면 고친 다음, 화면 스크린샷으로 결과를 보여 주세요.
완성된 모바일 앱을 만들어 주세요.

Claude가 연결된 폴더에 만드는 것:

폴더내용
api/Cloudflare Worker (Hono) + D1 스키마. 기록 저장, 페르소나 대화, 음성 받아쓰기, 사진 저장, 날짜별 요약 API. 검증된 인용 목록과 검사 로직 포함
mobile/Expo(React Native) 앱 — 첫 화면, 하루 화면(기록/대화 전환), 녹음 화면, 페르소나 선택, 지난 기록. iOS·Android·웹 공용
tools/가짜 AI 서버(mock), 브라우저 자동화 테스트, 앱 아이콘 생성기
scripts/deploy.sh(배포), start-app.sh(Expo Go 실행), test-live.sh(실서버 테스트)
테스트를 두 겹으로 합니다 — 키 없이, 돈 없이:
  • 가짜 AI 서버로 API 테스트 24개: 토큰 인증, 페르소나별 근거 검증, 목록에 없는 인용 제거, 위기 문구 자동 삽입, AI 장애 시 사용자 메시지 보존, 사진 저장·삭제, 받아쓰기 형식 검사, 날짜별 요약
  • 브라우저 자동화로 사용자 흐름 15단계: 첫 실행 화면 → 기록 2개 → 가짜 마이크로 녹음·받아쓰기 → 사진 첨부(자동 축소 확인) → 페르소나 전환 → 인용 카드 표시 → 지난 기록에서 어제로 이동 → 새로고침 후 상태 유지

진짜 모델 없이도 "규칙이 지켜지는지"를 전부 확인할 수 있습니다. 실제 모델 검증은 배포 후에 합니다.

자동 테스트가 실제로 잡아낸 문제들입니다. 수강생 화면에서도 비슷한 것이 나옵니다:

증상원인과 수정
지난 기록에서 날짜를 누르면 화면이 계속 쌓임새 화면을 밀어 올리고 있었음 → 아래 하루 화면으로 돌아가며 날짜만 바꾸도록 수정
웹에서 입력창이 두 줄 높이로 보이고 주황 테두리가 생김브라우저 기본 스타일 → 한 줄 높이 지정, 기본 포커스 테두리 제거
"길게 눌러 삭제"가 테스트에서 실패앱 버그가 아니라 테스트가 화면 밖 카드를 누르고 있었음 → 테스트를 수정
🧪
프롬프트 요령: "테스트해 줘"보다 "테스트를 만들고, 실행하고, 실패하면 고치고, 스크린샷으로 보여 줘"가 훨씬 강합니다. 사람은 코드가 아니라 스크린샷과 통과/실패 목록을 봅니다.

4.7 6단계 — 키 만들고 Cloudflare에 배포 (10분)

6a. OpenRouter 키 (주황 — 내가 직접)

브라우저에서 직접 사용 한도와 만료가 있는 키를 만듭니다.

openrouter.ai/settings/keys → New Key → 이름 mindlog-workshop → 만료 7일 → Credit limit Custom amount $5 → Create. 키는 이때 한 번만 보입니다.

키 값은 대화창에 붙여넣지 말고, 프로젝트 폴더의 api/.secrets.env 파일에 아래 형식으로 직접 저장합니다(이 파일은 git에 올라가지 않습니다).

OPENROUTER_API_KEY=sk-or-v1-...여기에 붙여넣기...
실수로 대화창에 붙여넣었다면 OpenRouter에서 그 키를 삭제하고 새로 만드세요. 한도 $5·만료 7일을 걸어 두는 이유가 이것입니다.

6b. 배포 한 줄 (주황 — 내가 직접)

터미널에 직접 프로젝트 폴더에서 배포 스크립트를 실행합니다.
cd ~/projects/mobile/mindlog
bash scripts/deploy.sh

스크립트가 순서대로 처리합니다: 패키지 설치 → Cloudflare 로그인(브라우저에서 "허용" 클릭) → D1 데이터베이스 mindlog-db 생성 → 테이블 생성 → 웹 앱 빌드 → Worker 배포(비밀값 포함) → 휴대폰 앱용 mobile/.env 작성 → 상태 확인.

끝나면 이런 줄이 나옵니다:

웹 앱:   https://mindlog.<내-서브도메인>.workers.dev
DEPLOY_OK https://mindlog.<내-서브도메인>.workers.dev

그 주소를 휴대폰 브라우저에서 바로 열면 앱이 동작합니다. 마이크는 HTTPS에서만 열리는데 workers.dev는 HTTPS라 그대로 됩니다.

6c. 실제 모델로 검증 (파랑 — Claude에게)

CLAUDE 앱에 붙여넣기 진짜 모델로 마지막 점검
배포된 주소로 실제 모델을 써서 테스트해 주세요.
페르소나 4명의 답이 규칙대로인지(털어놓는 말에는 조언 금지),
인용 카드가 검증된 목록에서만 나오는지,
음성 받아쓰기가 한국어로 되는지 확인하고 결과를 요약해 주세요.

6d. 휴대폰에서 네이티브 앱으로 (선택)

bash scripts/start-app.sh      # QR 코드가 뜨면 Expo Go로 스캔
bash scripts/start-app.sh --tunnel   # 같은 Wi-Fi가 아닐 때

스토어 배포는 이 워크숍 범위 밖입니다. 개념은 Part 3에서 다뤘습니다.

4.8 마무리 & 확장 아이디어 (5분)

오늘 배운 방식을 한 문장씩으로:
  • 코드보다 계획 문서가 먼저다. 문서를 고치는 것이 제품을 고치는 것이다.
  • 구현보다 목업이 먼저다. 빠진 화면은 그림에서 찾으면 몇 분, 코드에서 찾으면 몇십 분이다.
  • AI의 약점은 설계로 막는다. 인용은 검증된 목록에서 id만 고르게 하고, 서버가 다시 확인한다.
  • 테스트는 AI에게 맡기되 결과는 사람이 본다. 스크린샷과 통과/실패 목록이 판단 근거다.
  • 비밀값은 파일에, 대화창에는 절대. 한도와 만료가 있는 키를 쓴다.

숙제로 해볼 확장 아이디어

  1. 인용 목록을 페르소나마다 10~20개로 늘리고 번역문 검수하기
  2. 나만의 페르소나 추가하기 (예: 시인, 운동 코치) — personas.ts에 한 벌 더
  3. Cloudflare Cron Trigger로 일요일 밤에 "이번 주 기록 요약" 만들어 두기
  4. 기록 검색 (한 달 전 그 생각이 언제였는지)
  5. 사진을 D1 대신 R2에 저장해 용량 늘리기
  6. 로그인 붙이기 — 지금은 토큰 하나로만 보호되는 1인용 앱입니다

자주 막히는 지점

증상해결
Claude가 만든 파일이 내 컴퓨터에 없음폴더가 연결되지 않은 상태. 앱에서 폴더를 연결한 뒤 "이 폴더에 만들어 줘"라고 다시 요청
deploy.sh에서 Cloudflare 로그인이 멈춤브라우저에 뜬 승인 페이지에서 Allow를 누르지 않은 상태. 창을 찾아 승인하거나 스크립트를 다시 실행
앱에서 "서버 주소가 설정되지 않았어요"mobile/.env가 없음 → 배포 스크립트를 끝까지 실행하면 자동 생성
웹에서 마이크 버튼이 안 먹음HTTPS가 아니거나 권한 거부. workers.dev 주소로 열고 마이크 권한 허용
Expo Go에서 앱이 안 열림노트북과 휴대폰이 다른 Wi-Fi → --tunnel 옵션 사용
AI가 묻지도 않았는데 조언을 함계획 문서의 응답 규칙을 고치고 "규칙 2번을 이렇게 바꾸고 서버에도 반영해 줘"라고 요청
AI 답변이 오지 않음 (502)키 한도 초과·만료 확인. 메시지는 저장돼 있으므로 "다시 묻기"를 누르면 됩니다
💡
강사 참고: 4.2~4.5(계획·목업)는 다 같이 보면서 진행하고, 4.6(구현)은 Claude가 일하는 15~20분 동안 인용 목록 검수나 페르소나 문구 다듬기를 시키면 수강생이 기다리지 않습니다. 배포(4.7)는 반드시 시간을 남겨 두세요 — 첫 Cloudflare 로그인에서 가장 많이 막힙니다.