Lazy Developer9 min

SaaS 하나를 7일 만에 만들었다

2026년 4월 · 귀찮은개발자 EP.04

2026년 4월 · 귀찮은개발자 EP.04

EP.02에서 Apsity를 만들면서 앱 12개의 피드백이 쏟아지기 시작했다. 이메일로, 리뷰로, DM으로. 처음엔 스프레드시트에 정리했다. 근데 “다크모드 넣어주세요”하고 “밤에 눈 아파요”는 같은 요청인데, 다른 사람이 다른 말로 쓴다. 비슷한 요청을 묶고, 우선순위를 매기고, 처리됐으면 알려주는 거. 전부 수동이었다. 스프레드시트는 쌓이기만 하고 정리가 안 됐다.

Canny라는 서비스가 있다. 딱 이 용도다. 피드백 수집, 투표, 로드맵. 근데 가격을 보니 월 $79부터 시작한다. 비슷한 서비스들도 사정은 비슷하다. Nolt가 $29, UserVoice는 훨씬 비싸다. 인디 개발자한테는 과하다. Apsity를 만들 때도 그랬다. 기존 도구가 비싸거나 안 맞으면 직접 만든다. 이번에도 그렇게 하기로 했다.

피드백 수집부터 AI 자동 분류, 공개 로드맵, 체인지로그, 투표, 이메일 알림까지 전부 들어간 SaaS를 만들기로 했다. 이름은 FeedMission으로 정했다. 이 글은 그 시작 과정의 기록이다.

FeedMission 랜딩 페이지 — AI 피드백 관리 SaaS
완성된 FeedMission 랜딩 페이지 / GoCodeLab
빠르게 보기

– Canny 월 $79 → 인디 개발자한테 과하다 → 직접 만들기로 결정
– Apsity 때 익힌 Next.js + Supabase 조합 위에 AI 클러스터링을 추가 설계
– Claude한테 요구사항을 정리해서 던짐 → 52분 만에 MVP 10,742줄 나옴
– DB 모델 9개, API 12개, 대시보드 8페이지, 위젯, AI 파이프라인이 한 커밋에
– MVP 이후가 진짜 — 구조 변경, 성능, 보안에 더 많은 시간이 들었다

뭘 만들 건지 정리했다

무작정 Claude한테 “피드백 도구 만들어줘”라고 하지 않았다. Apsity 경험이 있으니까 알고 있다. 요구사항이 구체적이어야 결과도 구체적으로 나온다. EP.01에서 만든 CLAUDE.md 자동화도 같은 원리였다. 먼저 내가 원하는 게 뭔지를 정리해야 한다.

Canny, Nolt, Fider를 직접 가입해서 써봤다. 공통적으로 있는 기능은 피드백 보드, 투표, 로드맵, 체인지로그. 여기까지는 기본이다. 근데 내가 원하는 건 하나가 더 있었다. 피드백이 쌓이면 비슷한 것끼리 자동으로 묶어주는 기능. 수동으로 하면 피드백 50개 넘으면 사실상 불가능하다. Canny에도 이런 기능은 없었다.

정리하면 이렇다.

// 내가 정리한 FeedMission 요구사항

기본: 피드백 수집 위젯 + 공개 보드 + 투표
관리: 로드맵 칸반 + 체인지로그 + 이메일 알림
AI: 비슷한 피드백 자동 분류 (임베딩 + 클러스터링)
AI: 감정 분석 + 인사이트 자동 생성
수익: FREE / STARTER $9 / PRO $19 플랜
플랫폼: Script + React + iOS + Android + iframe + GTM

AI 클러스터링이 핵심 차별점이었다. 기존 도구들은 피드백을 수집하고 보여주는 데까지만 한다. “비슷한 것끼리 묶어주는 것”은 직접 만들어야 했다. 피드백 텍스트를 숫자 배열(임베딩)로 바꾸고, 비슷한 숫자 패턴을 가진 것끼리 자동으로 묶는 방식이다. 이 부분은 다음 편에서 자세히 다룬다.

Claude한테 요구사항을 던졌다

Apsity를 만들 때와 같은 방식이다. Claude 창을 열고, 정리한 요구사항을 그대로 넣었다. 아키텍처 제안을 먼저 받고, 괜찮으면 구현을 시작한다.

스택은 Apsity 때 익힌 조합을 베이스로 잡았다. Next.js + Supabase + Vercel. 여기에 추가로 필요한 것들이 있었다.

// Apsity에서 가져온 스택
Next.js — 이미 익숙한 프레임워크
Supabase — 로그인 + DB 한 곳에서. 서울 리전
Vercel — 배포 + Cron. EP.02에서 타임아웃 해결법도 알고 있다

// 새로 추가한 것들
Prisma — DB 모델 관리. 스키마 정의하면 타입이 자동으로 나옴
pgvector — PostgreSQL에서 벡터 검색. AI 클러스터링 핵심
Voyage AI — 텍스트를 1024개 숫자로 변환 (임베딩)
LemonSqueezy — 결제. Stripe보다 세금 처리가 간단
Resend — 이메일 발송. EP.03에서 써봤던 것

Apsity 경험이 컸다. Next.js에서 Server Component와 Client Component를 언제 나눠야 하는지, Supabase Auth의 미들웨어를 어떻게 잡는지, Vercel Cron의 타임아웃을 after()로 우회하는 법까지. EP.02에서 직접 부딪히면서 배운 것들을 여기서 바로 쓸 수 있었다.

새로 배워야 할 건 pgvector(벡터 검색)와 LemonSqueezy(결제 연동)였다. 이 두 가지는 Claude한테 물어보면서 같이 진행했다.

52분 만에 MVP가 나왔다

3월 26일 오전 9시 41분. create-next-app으로 프로젝트를 시작했다. Claude한테 정리한 요구사항을 넣고 구현을 시작했다. DB 모델 정의, API 라우트 작성, 대시보드 페이지, 공개 보드, 위젯 스크립트, AI 파이프라인.

10시 33분. 커밋을 올렸다.

234006b feat: FeedMission MVP 전체 구현
73 files changed, 10742 insertions(+)

52분. 73개 파일. 10,742줄. Apsity MVP 때보다 빨랐다. 바이브코딩이 빠른 건 사실인데, 이유는 “Claude가 코드를 써줘서”가 아니라 “내가 뭘 만들지 구체적으로 알고 있어서”다. 요구사항이 명확하면 Claude의 결과물도 정확해진다. 반대로 “피드백 도구 만들어줘” 같은 막연한 요청을 던지면, 내가 원하지 않는 구조가 나와서 오히려 시간이 더 든다.

EP.02에서도 똑같았다. “iOS 앱 여러 개 운영하는 개발자가 수익을 한 화면에서 보고 싶다”는 두 줄이었지만, 그 두 줄을 쓰기 전에 내가 뭘 원하는지 정리하는 시간이 있었다. 바이브코딩의 진짜 속도는 코드 생성이 아니라 판단 속도에서 나온다.

MVP에 뭐가 들어있었나

52분 만에 나온 코드를 열어보면 이런 구조다.

// DB 모델 9개 (Prisma)
User, Project, Feedback, Cluster, RoadmapItem,
Changelog, Vote, NotificationLog, Subscription

// API 라우트 12개
/api/feedback — 피드백 CRUD + 위젯 CORS
/api/clusters — AI 클러스터 조회/편집
/api/roadmap — 로드맵 칸반 CRUD
/api/changelog — 체인지로그 + 발행 시 자동 이메일
/api/dashboard — 통계 집계 (8개 쿼리 병렬)
/api/insights — AI 인사이트 카드 생성


// 대시보드 8페이지
Overview, Feedback, Clusters, Roadmap,
Changelog, Notifications, Widget, Settings

// AI 파이프라인 3파일
clustering.ts — 피드백 → 임베딩 → 클러스터 배정
embeddings.ts — Voyage AI 벡터 생성 + Claude 감정 분석
summaries.ts — Claude로 클러스터 제목/요약 + 인사이트 생성

Feedback 모델에 embedding vector(1024) 컬럼이 있다. 피드백 텍스트를 Voyage AI로 1024개 숫자로 변환해서 저장한다. pgvector가 이 숫자들의 유사도를 검색해준다. “다크모드 넣어주세요”와 “밤에 눈 아파요”가 비슷한 숫자 패턴을 가지게 되고, 자동으로 같은 그룹에 묶인다. 이게 핵심 기능이다.

피드백이 들어오면 사용자한테는 바로 “접수됐습니다”를 돌려준다. 임베딩 생성과 클러스터링은 EP.02에서 써봤던 after() 패턴으로 백그라운드에서 처리한다. 편의점 비유 그대로다. 계산은 바로 끝나고, 뒤에서 영수증이 나온다.

FeedMission 대시보드 — 피드백 통계, AI 클러스터, 로드맵 진행률, 인사이트 카드
FeedMission 대시보드 Overview / GoCodeLab

“돌아가는 코드”와 “제품” 사이

빌드는 됐다. 타입 에러도 없었다. 근데 직접 써보는 순간 고칠 것들이 쏟아졌다.

첫 번째. 사이드바가 화면을 너무 많이 먹었다. 탑 내비게이션으로 바꾸는 데 4분 걸렸다. 두 번째. URL에 UUID가 박혀 있어서 /dashboard/clx7abc123def/feedback 같은 주소가 나왔다. slug 기반으로 리팩토링하기로 했다. 폴더 이름만 바꾸면 될 줄 알았는데, 13개 파일에서 params.projectId를 참조하고 있었다. 하나하나 찾아서 고치는 데 30분. 세 번째. 프로덕션에 배포했더니 느렸다. Vercel Function이 미국에서 돌고 있었고, Supabase DB는 서울에 있었다. 매 쿼리마다 태평양을 횡단하고 있었다.

이런 것들은 AI가 만든 코드에서 잡아주지 않는다. “동작하는 코드”와 “쓸 수 있는 제품” 사이에는 이런 판단들이 쌓여 있다. Apsity를 만들 때도 같은 패턴이었다. MVP는 빠르게 나오고, 진짜 시간은 그 다음에 든다.

바이브코딩의 현실
AI가 만든 코드를 그대로 쓰면 안 되는 이유가 여기에 있다. 리전 설정, 미들웨어 최적화, 보안 취약점, CLS 같은 것들은 코드를 직접 실행하고 써봐야 보인다. Claude가 초안을 빠르게 만들어주면, 나는 “이거 왜 느리지?”, “이 URL 구조가 맞나?”, “이 데이터가 노출되면 안 되는 거 아닌가?”를 판단하는 데 시간을 쓸 수 있다.

이후 며칠간 일어난 일들

Day 1 자정까지 성능 관련 커밋만 5개가 쌓였다. Vercel 리전을 서울(icn1)로 바꾸고, 미들웨어에서 공개 경로의 불필요한 인증 호출을 스킵하고, Prisma 싱글톤 캐싱을 넣고, 스켈레톤 높이를 맞춰서 화면 점프를 없앴다.

5일간 코드를 안 만지고 직접 써봤다. Canny, Nolt도 다시 가입해서 비교했다. 부족한 것들을 적었다.

Day 6에 복귀해서 38파일을 한 번에 개선했다. 보안 패치 7개, DB 인덱스 6개, 대시보드 병렬 쿼리 최적화. 위젯 SDK를 5종으로 늘렸고, iOS SwiftUI와 Android Kotlin 네이티브 위젯을 만들었다. LemonSqueezy 결제를 연동하고 가격을 원화에서 달러로 피벗했다. 중간에 node_modules 686K줄을 실수로 커밋해서 28초 만에 삭제 커밋을 올리기도 했다.

Day 7에 랜딩 페이지를 리뉴얼하고, AI 클러스터링 우선순위 공식을 개선했다.

FeedMission 7일간 51개 커밋 타임라인
7일간 51개 커밋 타임라인 / GoCodeLab
51
총 커밋
37
Claude Co-Authored (72.5%)
3일
활성 코딩일 (7일 중)
52분
MVP 생성 시간

이 각각의 과정 — AI 클러스터링이 어떻게 동작하는지, 보안 취약점을 어떻게 잡았는지, 결제와 플랜 시스템을 어떻게 만들었는지 — 은 뒤의 에피소드에서 하나씩 다룬다.

72.5%가 AI, 나머지는 판단

51개 커밋 중 37개에 Claude Co-Authored-By 태그가 붙어 있다. 72.5%. 이 숫자가 “Claude가 72.5%를 만들었다”는 뜻은 아니다. 내가 요구사항을 정리하고, Claude가 코드를 생성하고, 내가 리뷰하고, 수정하고, 커밋한다. 이 과정에서 커밋에 Co-Authored 태그가 붙는 거다.

EP.02에서도 같은 패턴이었다. Claude한테 요구사항을 던지면 스택 제안이 오고, 맞는 말이면 그대로 쓰고, 아니면 방향을 바꾼다. 판단은 항상 내 몫이다. “이 구조가 맞나?”, “이 보안 처리가 충분한가?”, “이 가격이 맞나?” 같은 질문들. 코드 생성은 빨라졌지만 판단의 양은 줄지 않았다. 오히려 빨리 만들어지니까 더 많은 판단을 해야 했다.

바이브코딩이 “AI한테 다 맡기는 것”이 아닌 이유가 여기에 있다. 빠르게 만들고, 빠르게 써보고, 빠르게 판단하는 것. 속도가 올라가는 건 코드 생성이 아니라 피드백 루프 전체다.

다음 편에서

FeedMission의 핵심 차별점은 AI 클러스터링이다. “다크모드 넣어주세요”와 “밤에 눈 아파요”가 어떻게 같은 그룹에 묶이는지. 피드백 텍스트를 1024개 숫자로 바꾸고, 코사인 유사도로 비교하고, 자동으로 이름까지 붙이는 파이프라인. clustering.ts 188줄에 전부 들어있다. EP.05에서는 그 얘기를 한다.

자주 묻는 질문

52분 MVP가 실제로 쓸 수 있는 수준인가요?
“동작하는 코드”는 52분에 나왔다. 하지만 제품 수준으로 올리는 데 나머지 6일이 들었다. 구조 변경, 성능 최적화, 보안 패치, 결제 연동 등. MVP는 출발점이지 완성이 아니다.
Canny 대신 직접 만드는 게 나은가요?
팀 규모와 예산에 따라 다르다. Canny는 잘 만들어진 도구다. 근데 월 $79이 부담되고, AI 자동 분류 같은 커스텀 기능이 필요하면 직접 만드는 게 맞을 수 있다. Next.js + Supabase 경험이 있으면 기본 기능은 빠르게 나온다.
AI 클러스터링은 어떻게 동작하나요?
피드백 텍스트를 1024개 숫자(임베딩)로 변환한다. 비슷한 의미의 문장은 비슷한 숫자 패턴이 나온다. 이걸 비교해서 유사도 0.85 이상이면 같은 그룹으로 묶는다. EP.05에서 상세히 다룬다.
바이브코딩으로 만든 코드 품질은 괜찮나요?
MVP 단계에서는 동작하지만 그대로 쓰면 안 된다. FeedMission에서도 보안 취약점 7개, 성능 이슈 4개를 따로 잡았다. AI가 초안을 만들어주면, 사람이 리뷰하고 판단하는 과정이 반드시 필요하다.
Next.js + Supabase 경험 없이도 따라할 수 있나요?
가능하다. Claude한테 “Next.js에서 Supabase 인증 어떻게 하는 거야?”부터 물어보면 된다. EP.02에서 처음 이 조합을 쓴 과정이 나와 있다.

관련 글