처음에는 가볍게 시작한 사이드 프로젝트였다.
“친구네 가게에 예약 페이지 하나 만들어 주면 괜찮지 않을까?”
이 정도 생각이었다.
동네 미용실, 네일샵, 작은 식당 같은 곳을 보면 아직도 예약을 인스타 DM이나 카카오톡으로 받는 경우가 많다.
사장님 입장에서는 손님이 문의할 때마다 시간을 확인해야 하고, 손님 입장에서는 매번 이름, 날짜, 시간, 인원, 문의사항을 반복해서 보내야 한다.
물론 예약 솔루션은 이미 많이 있다.
그런데 작은 가게 사장님 기준으로 보면 문제가 있다.
너무 어렵거나, 너무 비싸거나, 디자인이 너무 복잡하다.
그래서 이번에는 최대한 단순한 기준을 하나 잡았다.
사장님이 가입한 뒤 5분 안에 자기 가게 예약 페이지를 가질 수 있어야 한다.
이 기준으로 클로드 코드와 함께 예약관리시스템 MVP를 만들어봤다.
결과적으로 단순한 예약 페이지가 아니라 멀티테넌트 구조를 가진 B2B SaaS 형태의 예약관리시스템이 만들어졌다.
작업 시간은 3일도 걸리지 않았다.
1. 만든 것
1) 전체 구조
이번에 만든 것은 작은 가게 사장님을 위한 예약관리시스템이다.
내부 코드명은 모과이 예약이고, 프로젝트명은 moguwai-booking 으로 잡았다.
구조는 B2B SaaS 형태다.
즉 하나의 서비스 안에서 여러 가게가 가입하고, 각 가게마다 고유한 예약 페이지를 가지는 방식이다.
타깃 사용자는 크게 두 종류다.
① 작은 가게 사장님
② 예약하려는 손님
사장님은 가입 후 자기 가게 예약 페이지를 만들고, 손님은 그 링크로 들어와 예약한다.
복잡한 관리자 교육이나 별도 설치 없이, 웹에서 바로 사용할 수 있는 구조로 잡았다.
2) 핵심 흐름
전체 흐름은 아래처럼 구성했다.
① 사장님 가입
② 4단계 온보딩 진행
③ 가게 이름 기반의 슬러그 주소 발급
④ 손님은 해당 링크로 접속
⑤ 회원가입 없이 4단계 예약 진행
⑥ 사장님은 대시보드에서 예약 확인 및 취소
⑦ 예약 고객은 고객 명부에 자동 적재
⑧ 방문 횟수가 많은 고객은 VIP로 자동 표시
⑨ 가게 페이지의 AI 챗봇이 기본 문의에 응답
예를 들어 손님이 “오늘 6시 가능해요?” 같은 질문을 하면, 챗봇이 가게 정보와 운영시간을 바탕으로 답변하는 구조다.
처음 의도는 단순한 예약 페이지였지만, 만들다 보니 실제 운영 가능한 SaaS MVP에 가까운 형태가 되었다.
2. 왜 예약관리시스템을 만들었나
1) 작은 가게의 예약 문제
작은 가게에서는 예약 관리가 생각보다 번거롭다.
특히 1인 매장이나 소규모 매장은 전화를 받을 사람이 따로 없다.
시술 중이거나 손님 응대 중이면 예약 문의에 바로 답하기 어렵다.
손님도 마찬가지다.
예약 가능한 날짜와 시간을 확인하려고 매번 메시지를 보내야 한다.
사장님이 늦게 답하면 손님은 다른 곳으로 가버릴 수도 있다.
2) 이번 프로젝트의 기준
그래서 내가 생각한 핵심은 거창한 기능이 아니었다.
작은 가게가 자기 가게 전용 예약 링크 하나를 가질 수 있으면 된다.
그리고 손님은 그 링크에서 몇 단계만 거치면 예약을 끝낼 수 있으면 된다.
이번 프로젝트의 목표는 아래와 같았다.
① 사장님이 어렵지 않게 가입할 수 있어야 한다
② 별도 개발 지식 없이 가게 페이지가 생성되어야 한다
③ 손님은 회원가입 없이 예약할 수 있어야 한다
④ 사장님은 대시보드에서 예약과 고객을 볼 수 있어야 한다
⑤ 나중에 실제 SaaS처럼 확장할 수 있는 구조여야 한다
이 조건을 만족하는 MVP를 빠르게 만드는 것이 이번 프로젝트의 목적이었다.
3. 사용한 기술 스택
1) 전체 기술 구성
이번 프로젝트에서는 의존성을 최대한 줄이는 방향으로 갔다.
기능을 많이 붙이기보다, 적은 구성으로 끝까지 동작하는 구조를 우선했다.
사용한 주요 스택은 아래와 같다.
- 프레임워크: Next.js 16.2.4
- UI: React 19, Tailwind CSS v4
- 백엔드: Supabase Auth, Postgres, RLS, RPC
- AI: Gemini API
- 검증: zod
- 배포: Vercel
- 폰트: Pretendard, Instrument Serif
2) 백엔드 서버를 따로 두지 않은 이유
이 프로젝트에서 따로 백엔드 서버를 띄우지는 않았다.
Next.js Server Actions와 Supabase 조합으로 회원가입, 로그인, 데이터 저장, 권한 처리, 통계성 조회까지 처리했다.
작은 SaaS MVP를 만들 때 이 조합은 상당히 생산성이 좋다.
예전 방식으로 생각하면 백엔드 API 서버를 따로 만들고, DB 연결하고, 인증 붙이고, 권한 처리하고, 배포 환경까지 따로 잡아야 한다.
그런데 Supabase를 쓰면 Auth, Postgres, RLS, Storage, RPC 같은 기본 구성이 이미 준비되어 있다.
여기에 Next.js Server Actions를 붙이면 작은 서비스 하나는 꽤 빠르게 만들 수 있다.
이번 프로젝트도 이 장점이 컸다.
4. 클로드 코드와 작업할 때 가장 중요했던 것
1) 그냥 시작하면 원하는 결과가 잘 안 나온다
이번 프로젝트는 처음부터 끝까지 클로드 코드와 함께 만들었다.
그런데 클로드 코드를 그냥 켜고 “예약관리시스템 만들어줘”라고 하면 원하는 결과가 나오기 어렵다.
특히 최신 Next.js 프로젝트에서는 더 그렇다.
이유는 크게 두 가지였다.
첫 번째는 클로드가 알고 있는 Next.js와 실제 내가 쓰는 Next.js 16의 차이가 있었다.
예를 들어 middleware.ts 관련 변경, params와 searchParams 처리 방식, useActionState와 redirect 동작 같은 부분에서 헷갈리는 지점이 있었다.
두 번째는 디자인 방향이었다.
AI에게 SaaS 대시보드를 만들라고 하면 검은 배경에 흰 글자, 보라색 네온, 카드형 다크 패널 같은 디자인을 자주 제안한다.
그런데 이번 서비스의 대상은 개발자가 아니라 작은 가게 사장님과 일반 손님이다.
너무 개발자스러운 다크 테마는 맞지 않았다.
2) CLAUDE.md와 AGENTS.md를 먼저 작성했다
그래서 프로젝트 루트에 CLAUDE.md와 AGENTS.md를 두고 규칙을 먼저 정리했다.
CLAUDE.md에는 이런 내용을 넣었다.
- 모든 애플리케이션 테이블은 mbk_ prefix를 사용한다.
- 사용자 격리는 mbk_users 테이블을 경유한다.
- auth.users를 직접 FK로 남발하지 않는다.
- RLS owner 정책은 is_mbk_user() AND owner_id = auth.uid() 기준으로 작성한다.
- 다크 테마는 사용하지 않는다.
- 검은 배경 + 흰 글자 패널 디자인을 금지한다.
- 사용자 메시지, 주석, 문서는 한국어를 우선한다.
- Gemini 모델은 폴백 체인을 고려한다.
AGENTS.md에는 이런 식으로 적었다.
This is NOT the Next.js you know.
APIs and conventions may differ from your training data.
Read current project dependencies and docs before writing code.
이 두 파일이 있고 없고의 차이가 컸다.
클로드 코드가 프로젝트의 규칙을 계속 참고하면서 코드를 만들기 때문에, 초반에 협업 규칙을 잘 박아두면 이후 작업 품질이 훨씬 안정된다.
이번에 느낀 것은 이것이다.
AI 협업 프로젝트의 절반은 프롬프트가 아니라 프로젝트 규칙 문서다.
5. 진행 흐름
1) 처음 예상보다 빨랐다
처음에는 넉넉하게 6일 정도 잡았다.
그런데 실제로는 3일도 걸리지 않았다.
물론 이것은 아무 준비 없이 3일 만에 만들었다는 의미는 아니다.
이전에 Next.js, Supabase, Vercel, Claude Code를 계속 써보면서 시행착오를 줄여둔 것이 컸다.
실제 진행 흐름은 대략 아래와 같았다.
2) Day 1 — 인증, 온보딩, 대시보드 골격
1일차에는 인증과 온보딩, 대시보드 뼈대를 만들었다.
진행한 작업은 아래와 같다.
① Supabase 프로젝트 생성
② mbk_users, mbk_businesses, mbk_staff 기본 테이블 생성
③ 이메일과 비밀번호 기반 가입, 로그인 구현
④ Server Actions와 zod 기반 입력값 검증
⑤ 4단계 온보딩 구현
⑥ 가게 슬러그 자동 생성
⑦ 슬러그 충돌 시 최대 5회 재시도 처리
⑧ 대시보드 레이아웃과 사이드바 구성
⑨ 주요 빈 페이지 생성
온보딩은 아래 흐름으로 잡았다.
① 업종 선택
② 가게 정보 입력
③ 운영시간 설정
④ 담당자 설정
온보딩이 끝나면 가게 이름을 기반으로 슬러그가 만들어진다.
예를 들어 가게 이름이 “모과이헤어”라면 /moguwai-hair 같은 형태의 주소를 가지는 방식이다.
3) Day 2 — 예약 흐름, RLS, 동시성 처리
2일차에는 실제 예약 흐름과 멀티테넌시 격리를 구현했다.
추가한 주요 테이블은 아래와 같다.
- mbk_reservations
- mbk_blocked_dates
- mbk_customers
그리고 /가게이름 형태의 공개 예약 페이지를 만들었다.
손님은 여기서 회원가입 없이 4단계를 거쳐 예약할 수 있다.
예약 생성은 단순 INSERT로 처리하지 않았다.
동일 시간대 중복 예약을 막아야 했기 때문에 create_reservation 이라는 PL/pgSQL RPC를 만들었다.
이 RPC 안에서 충돌 검사를 하고, 문제가 없을 때만 예약을 INSERT하도록 했다.
즉 예약 가능 여부 확인과 저장을 하나의 트랜잭션 흐름으로 묶은 것이다.
또한 고객 방문 횟수를 기준으로 3회 이상이면 VIP로 표시되도록 했다.
4) Day 3 — AI 챗봇, 방문자 로그, 디자인 정리
3일차에는 AI 챗봇, 방문자 로그, 디자인 다듬기를 진행했다.
/api/chat 라우트를 만들고 Gemini API를 직접 호출했다.
가게 정보, 운영시간, 예약 안내 문구 등을 시스템 프롬프트에 합성해서 넣었다.
완전한 RAG 시스템은 아니지만, 가게 페이지에 필요한 컨텍스트를 넣어주는 간이 RAG 형태로 구성했다.
그리고 /visitor-log 비공개 운영 페이지를 따로 만들었다.
접속 로그는 proxy.ts 쪽에서 fire-and-forget 방식으로 기록하도록 했다.
마지막으로 디자인 토큰을 정리했다.
사용한 토큰은 대략 아래와 같다.
- --paper
- --surface
- --ink
- --accent
전체 화면의 톤은 페이퍼 느낌으로 맞췄다.
처음에 AI가 만든 일부 다크 패널은 모두 제거하고, 반투명 인디고 계열의 밝은 그라디언트로 바꿨다.
6. 가장 까다로웠던 부분
1) Next.js 16 관련 차이
이번 프로젝트에서 가장 까다로웠던 부분은 크게 세 가지였다.
첫 번째는 Next.js 16 관련 차이였다.
내가 알던 Next.js와 실제 프로젝트에서 쓰는 Next.js 16 사이에 차이가 있었다.
특히 헷갈렸던 부분은 아래와 같다.
① middleware.ts 관련 구조 변경
② params, searchParams의 Promise 처리
③ useActionState 안에서 redirect()가 기대한 대로 화면 이동을 일으키지 않는 문제
가장 오래 잡아먹은 것은 세 번째였다.
회원가입이나 로그인 후에 redirect('/dashboard')를 호출했는데 화면이 이동하지 않았다.
처음에는 Supabase 응답이 늦은 줄 알았다.
그런데 원인은 서버 액션에서 redirect를 호출하는 패턴이 useActionState 흐름 안에서 기대한 방식으로 동작하지 않는 것이었다.
결국 패턴을 바꿨다.
서버 액션에서는 직접 redirect하지 않고, redirectTo 값을 반환하게 했다.
그리고 클라이언트에서 그 값을 받아 router.push를 실행하는 방식으로 통일했다.
서버 액션에서는 아래처럼 이동할 경로만 반환한다.
return {
success: true,
redirectTo: '/dashboard',
}
이렇게 바꾸니 회원가입, 로그인, 온보딩 완료 후 이동 흐름이 안정됐다.
7. 멀티테넌시 격리
1) 왜 mbk_users가 필요했나
두 번째로 중요했던 부분은 멀티테넌시 격리였다.
Supabase 인스턴스를 다른 사이드 프로젝트와 같이 사용할 가능성이 있었기 때문에, 이 앱의 사용자와 데이터를 확실히 분리해야 했다.
단순히 auth.users를 직접 기준으로 삼으면 다른 앱 사용자와 섞일 가능성이 있다.
그래서 mbk_users라는 앱 전용 멤버십 테이블을 만들었다.
구조는 대략 아래와 같다.
create table mbk_users (
id uuid primary key references auth.users(id),
email text not null,
created_at timestamptz default now()
);
2) RLS 정책에서 앱 사용자 여부를 확인했다
RLS 정책에서는 auth.uid()만 보지 않고, 이 사용자가 mbk_users에 존재하는지도 같이 확인했다.
이를 위해 is_mbk_user() 함수를 만들었다.
create function is_mbk_user() returns boolean
language sql security definer as $$
select exists(select 1 from mbk_users where id = auth.uid())
$$;
owner 정책은 이런 식으로 잡았다.
create policy "owner only" on mbk_businesses
using (is_mbk_user() and owner_id = auth.uid());
즉 사용자가 Supabase Auth에는 존재하더라도, mbk_users에 등록되어 있지 않으면 이 앱의 사용자로 인정하지 않는 구조다.
회원가입 직후에는 mbk_users에 INSERT한다.
로그인 직후에는 mbk_users 멤버십을 확인한다.
만약 이 앱의 사용자가 아니면 즉시 signOut 처리한다.
이렇게 하니 같은 Supabase 인스턴스를 공유해도 이 프로젝트의 데이터는 깔끔하게 분리된다.
8. 챗봇이 같은 오류만 반복하던 문제
1) 처음에는 모든 질문에 같은 답만 나왔다
세 번째는 AI 챗봇 문제였다.
처음 챗봇을 붙였을 때는 어떤 질문을 해도 같은 답변만 나왔다.
“죄송합니다. AI 응대에 일시적인 오류가 발생했습니다. 전화로 문의해 주세요.”
이 문구만 계속 반복됐다.
처음에는 프롬프트 문제라고 생각했다.
그런데 로그를 따라가 보니 문제가 두 개 겹쳐 있었다.
2) SDK 문제와 role 순서 문제가 겹쳤다
첫 번째는 @google/generative-ai SDK 관련 문제였다.
SDK가 deprecated 상태라 호출 흐름이 깔끔하지 않았다.
그래서 SDK를 걷어내고 REST API를 직접 호출하는 방식으로 바꿨다.
그런데 이번에는 400 에러가 났다.
에러 메시지를 보니 contents의 첫 메시지는 role: user 여야 한다는 내용이었다.
문제는 채팅 UI였다.
처음 화면에 보여주는 환영 메시지를 role: model로 넣어두고 있었다.
그러다 보니 실제 사용자의 첫 질문은 두 번째 메시지가 되어버렸다.
Gemini API 입장에서는 첫 메시지가 model이므로 잘못된 요청이 된 것이다.
3) 해결 방법
해결은 단순했다.
API로 보내기 전에 앞쪽의 model 메시지를 잘라냈다.
const trimmed = [...messages]
while (trimmed.length > 0 && trimmed[0].role !== 'user') {
trimmed.shift()
}
이렇게 처리하니 챗봇이 정상적으로 응답하기 시작했다.
문제 자체는 단순했지만, 겉으로 보기에는 “챗봇이 그냥 실패한다” 정도로만 보였기 때문에 원인을 찾는 데 시간이 걸렸다.
9. 클로드 코드가 잘했던 부분
1) 문서화
이번 프로젝트에서 클로드 코드가 특히 잘했던 부분은 문서화였다.
명시적으로 요청하니 핵심 파일 상단에 한국어 주석 블록을 일관되게 붙여줬다.
예를 들어 아래 내용을 파일 상단에 정리해줬다.
① 이 파일이 어떤 역할을 하는지
② 주요 흐름은 무엇인지
③ 수정할 때 주의할 점은 무엇인지
④ 관련 테이블이나 API는 무엇인지
또한 docs/handover 폴더에 인수인계 문서도 꽤 자세히 만들어줬다.
나중에 이 프로젝트를 다시 열어보거나, 다른 사람이 이어받는다고 해도 구조를 이해하기 쉬운 형태가 되었다.
2) 디자인 토큰 일관성
디자인 토큰을 일관되게 적용하는 것도 좋았다.
초반에 --paper, --surface, --ink 같은 변수를 정해두니, 이후 새로 만든 컴포넌트도 비슷한 톤으로 만들어졌다.
AI가 매번 제각각 디자인을 만드는 것이 아니라, 기존 토큰을 참고해서 같은 분위기를 유지했다.
이런 점은 생각보다 중요하다.
MVP라고 해도 화면마다 톤이 다르면 급하게 만든 티가 많이 난다.
반대로 디자인 토큰이 잡혀 있으면 짧은 시간에 만든 프로젝트라도 어느 정도 일관성이 생긴다.
3) 디버깅 과정
디버깅 과정에서도 도움이 됐다.
“왜 이게 안 되지?”라고 던지면 가능한 원인을 몇 가지로 나누고, 하나씩 좁혀가는 식으로 접근했다.
챗봇 오류도 결국 이런 식으로 같이 추적해서 해결했다.
물론 AI가 항상 정답을 바로 맞히는 것은 아니다.
하지만 로그, 에러 메시지, 현재 코드 흐름을 같이 보여주면서 좁혀가면 꽤 쓸 만한 페어 프로그래밍 파트너가 된다.
10. 클로드 코드의 한계
1) 테스트 코드는 명시적으로 시켜야 한다
물론 한계도 있었다.
가장 큰 한계는 자동 테스트였다.
명시적으로 시키지 않으면 테스트 코드를 거의 만들지 않는다.
이번 프로젝트도 결과적으로 단위 테스트 0개로 끝났다.
MVP 속도만 보면 괜찮지만, 실제 운영 서비스로 가져가려면 테스트는 반드시 보강해야 한다.
2) 최신 버전은 계속 기준을 잡아줘야 한다
또 하나는 최신 버전 대응이다.
Next.js 16처럼 학습 데이터와 실제 버전 차이가 있는 경우에는 AGENTS.md나 CLAUDE.md로 계속 방향을 잡아줘야 한다.
그렇지 않으면 예전 방식의 코드를 제안할 때가 있다.
특히 프레임워크 버전이 빠르게 바뀌는 영역에서는 AI에게 “네가 알고 있는 방식이 최신이 아닐 수 있다”는 점을 계속 알려주는 것이 좋다.
3) 가끔 너무 친절하다
마지막으로 AI는 가끔 너무 친절하다.
시키지 않은 fallback, null check, try-catch를 계속 붙이려고 한다.
물론 방어 코드는 필요하다.
하지만 MVP 단계에서 너무 많은 방어 코드가 들어가면 흐름이 복잡해진다.
그래서 CLAUDE.md에 아래 같은 규칙을 넣는 것이 좋다.
- 불필요한 방어 코드 금지
- 핵심 흐름 우선
- 과도한 추상화 금지
- 요청하지 않은 기능 추가 금지
이런 기준을 정해두면 결과물이 훨씬 단순하고 관리하기 쉬워진다.
11. MVP 자체 평가
1) 면접관이나 의뢰자가 본다면
만들고 끝내는 것보다, 남이 봤을 때 어떻게 보일지도 점검해봤다.
면접관이나 외주 의뢰자가 본다고 가정하면 아래처럼 볼 수 있을 것 같다.
2) 잘 된 부분
핵심 흐름 완성도는 괜찮다.
가입, 온보딩, 가게 페이지 생성, 손님 예약, 사장님 대시보드까지 이어진다.
디자인과 UX도 나쁘지 않다.
다크 패널을 제거하고, 작은 가게 서비스에 어울리는 밝은 톤으로 정리했다.
멀티테넌시 격리도 어느 정도 신경 썼다.
mbk_users와 is_mbk_user()를 기준으로 앱 사용자와 데이터를 분리했다.
보안도 MVP 기준에서는 기본은 했다.
RLS, zod, RPC를 사용했고 service_role 사용 지점도 최소화했다.
3) 부족한 부분
운영 안정성은 아직 부족하다.
Sentry 같은 에러 추적 도구는 붙이지 않았다.
로그 모니터링도 아직 약하다.
자동 테스트도 부족하다.
테스트 코드가 없다.
실제 운영 전에는 가장 먼저 보강해야 할 부분이다.
챗봇 비용 방어도 아직 부족하다.
/api/chat에 rate limit이 아직 없다.
AI API는 공개 페이지에 붙는 순간 비용 사고 위험이 생긴다.
따라서 실제 운영으로 가져가려면 rate limit은 반드시 필요하다.
4) 한 줄 평가
지금 상태를 한 줄로 정리하면 이렇다.
포트폴리오용 SaaS MVP로는 충분히 보여줄 만하지만, 실제 운영 서비스로 가려면 테스트, 모니터링, rate limit은 보강해야 한다.
12. 다음에 가장 먼저 보강할 것
1) /api/chat rate limit
다음에 한 가지만 보강한다면 /api/chat에 rate limit을 붙일 것이다.
AI 챗봇은 편리하지만, 공개 페이지에 붙는 순간 비용 위험이 생긴다.
누군가 반복 호출하거나 봇이 들어오면 Gemini API 비용이 예상보다 빠르게 늘 수 있다.
그래서 Upstash Redis 같은 것을 사용해서 IP 기준 또는 가게 기준으로 일정 시간 안의 호출 횟수를 제한하는 것이 좋다.
2) MVP 단계에서 필요한 제한 기준
예를 들면 아래 정도만 해도 MVP 단계에서는 꽤 도움이 된다.
① 같은 IP에서 1분에 10회 이상 호출 제한
② 같은 가게 페이지에서 1분에 30회 이상 호출 제한
③ 비정상 요청은 429 응답
④ 관리자 페이지에서 최근 호출 수 확인
이 정도만 붙여도 AI 챗봇의 비용 사고 가능성을 크게 줄일 수 있다.
13. 이 프로젝트로 얻은 것
1) 단순히 예약관리시스템 하나를 만든 것이 아니다
이번 프로젝트에서 얻은 것은 단순히 예약관리시스템 하나가 아니다.
AI와 협업해서 풀스택 SaaS MVP를 빠르게 만드는 흐름을 다시 확인했다.
특히 아래 세 가지가 중요했다.
① 프로젝트 규칙을 먼저 정한다
② 데이터 구조와 권한 구조를 초반에 잡는다
③ 디자인 방향을 AI에게 명확히 알려준다
이 세 가지가 없으면 AI는 빠르게 코드를 만들 수는 있어도, 프로젝트 전체의 일관성은 흔들릴 수 있다.
반대로 규칙을 잘 잡아두면 속도와 일관성을 동시에 가져갈 수 있다.
이번 프로젝트는 그걸 확인한 사례였다.
2) AI 협업에서 중요한 것은 속도보다 기준이다
AI 도구를 쓰면 속도는 빨라진다.
하지만 기준이 없으면 빠르게 엉킬 수도 있다.
예를 들어 테이블 이름 규칙이 없으면 어떤 테이블은 reservations, 어떤 테이블은 booking_reservations, 어떤 테이블은 mbk_reservations처럼 제각각 생길 수 있다.
디자인 기준이 없으면 어떤 페이지는 다크 테마, 어떤 페이지는 화이트 테마, 어떤 페이지는 그라디언트 범벅이 될 수도 있다.
즉 AI 협업에서 중요한 것은 “빨리 만들어줘”가 아니라 “이 기준 안에서 만들어줘”다.
이번 프로젝트에서는 CLAUDE.md와 AGENTS.md가 그 기준 역할을 했다.
14. 이후 시리즈로 정리하고 싶은 내용
1) Next.js 16에서 헷갈렸던 부분
이번 글에서는 전체 후기를 중심으로 정리했다.
하지만 실제로는 따로 풀어볼 만한 내용이 몇 가지 있다.
첫 번째는 Next.js 16에서 헷갈렸던 부분이다.
proxy.ts, async params, useActionState와 redirect 문제는 따로 정리해볼 만하다.
특히 기존 Next.js 경험이 있는 사람일수록 오히려 헷갈릴 수 있는 부분이 있었다.
2) Supabase 공유 인스턴스에서 앱별 사용자 격리하기
두 번째는 Supabase 공유 인스턴스에서 앱별 사용자 격리하기다.
mbk_users 패턴과 RLS 헬퍼 함수를 조금 더 깊게 정리해볼 수 있다.
여러 사이드 프로젝트를 하나의 Supabase 인스턴스에서 운영하려는 사람에게는 꽤 유용한 내용이 될 수 있다.
3) Gemini 챗봇 오류 디버깅
세 번째는 Gemini 챗봇이 같은 오류만 반복하던 이유다.
contents role 문제, model 메시지 제거, REST API 직접 호출 흐름을 따로 정리해볼 수 있다.
겉으로는 단순한 챗봇 오류처럼 보였지만, 실제로는 SDK 문제와 메시지 role 순서 문제가 겹쳐 있었다.
4) 클로드 코드 협업 문서 작성법
네 번째는 클로드 코드와 협업할 때 CLAUDE.md를 어떻게 작성할지다.
AI가 프로젝트 규칙을 지키게 만드는 문서 작성법도 따로 글로 정리할 만하다.
이 부분은 앞으로 AI 기반 개발을 계속할수록 더 중요해질 것 같다.
15. 마무리
1) 3일도 안 걸린 이유
이번 예약관리시스템은 3일도 걸리지 않았다.
하지만 정확히 말하면, 3일도 안 걸리게 만들 수 있도록 준비해둔 것이 컸다.
Next.js와 Supabase 조합을 미리 써봤고, Vercel 배포 흐름도 익숙해져 있었고, 클로드 코드에게 어떤 식으로 지시해야 하는지도 어느 정도 감이 있었다.
그리고 프로젝트 시작 전에 규칙을 정해두었다.
① 다크 테마 금지
② 페이퍼 톤의 밝은 디자인
③ mbk_ prefix 기반 테이블 구성
④ mbk_users를 통한 사용자 격리
⑤ CLAUDE.md와 AGENTS.md를 통한 AI 협업 규칙 고정
이런 기준이 있었기 때문에 작업 속도가 빨라졌다.
2) 최종 정리
AI 도구를 쓰면 무조건 빠른 것이 아니다.
기준이 명확할 때 빠르다.
이번 프로젝트는 그걸 다시 확인한 작업이었다.
작은 가게 예약 페이지 하나에서 시작했지만, 결과적으로는 멀티테넌트 SaaS MVP 한 벌이 만들어졌다.
다음 사이드 프로젝트도 이 방식으로 진행해볼 생각이다.
'개발지식창고 > AI Dev Workflow' 카테고리의 다른 글
| Claude Code로 빨라진 개발, 그만큼 더 조심해야 할 것들 (0) | 2026.05.02 |
|---|---|
| 예약관리시스템 챗봇에 Upstash Redis Rate Limit 붙이기 — 비용 폭탄 막는 5분 작업 (1) | 2026.05.02 |
| Claude Code 잘 쓰는 사람과 못 쓰는 사람의 차이 (0) | 2026.04.19 |
| Claude Code 토큰 제한에 끊겼을 때 내가 정리한 이어서 작업하는 방법 (0) | 2026.04.19 |
| Claude Code로 쇼핑몰과 당근마켓형 중고거래 플랫폼을 만들어보니 느낀 점 (0) | 2026.04.19 |



