설계를 진짜 서비스로 — '구독 다이어트' 3주차 구현 정리
목차
구독 다이어트 — 3주차 구현 정리
목표: 설계를 실제로 동작하는 서비스로. 멀티 에이전트 오케스트레이션 + Token maxxing 활용. 결과: 회원가입·DB·영속까지 갖춘 웹앱을 공개 URL로 배포 → subscription-diet.vercel.app
1. 스택 (확정)
- Next.js 16 (App Router, TypeScript) + Tailwind CSS v4 — 웹앱
- Prisma 6 + PostgreSQL(로컬은 SQLite → 배포는 Vercel/Neon Postgres)
- 인증 직접 구현 — bcryptjs(비밀번호 해시) + jose(JWT, httpOnly 쿠키)
- 배포: Vercel → 공개 URL (폰 브라우저·PWA·웹뷰 테스트)
- 아키텍처 = 웹뷰형 마이데이터 플러그인 (2주차 설계와 동일 결)
왜 웹앱? 하나면 URL 접속 · PWA · 웹뷰 임베드 · (Capacitor) .apk 를 다 커버한다.
2. 진행 요약 (단계별)
- 계획 — 계획서·WBS 간트로 작업을 T-01~T-19로 분해
- 기반 굳히기 — 공유 “계약”(타입·샘플거래·탐지로직·상태스토어·공용컴포넌트·디자인토큰)을 먼저 확정
- 화면 병렬 구현 — 에이전트 4명이 화면 7개를 동시에 제작
- 백엔드 승격 — “껍데기 아니냐” 지적 → 회원·DB·영속을 진짜로 (3장)
- 팀 검증 — 서로 다른 렌즈의 에이전트 4명 투입 (4장)
- 배포 — Vercel + Postgres, 방화벽 우회 (5장)
- 다듬기 + 기능 4종 추가 — 온보딩·설정·로고 정비 + 목표/직접추가/캘린더/인사이트 (6장)
멀티 에이전트의 핵심: “얼마나 똑똑한 에이전트냐”보다 “공유 계약을 얼마나 명확히 주느냐.” 기반(인터페이스)을 먼저 굳히지 않고 병렬로 던지면 서로 다른 가정으로 통합 때 깨진다.
3. “껍데기 → 진짜 서비스” — 백엔드 승격
초기엔 코드에 박제된 12개 구독 + localStorage였다. “동작”은 하지만 계정도, 데이터 유입 통로도 없는 반쪽. 그래서 승격했다.
- 실연동은 불가(마이데이터 사업자 자격·기능적합성/보안 인증·기관 계약) → 연동이라는 “행위”만 모의하고, 그 뒤의 회원·DB·영속·계정별 데이터·탐지는 전부 진짜로 구현
- 구조:
proxy.ts(라우트 게이트) ·lib/auth.ts+app/actions/*(인증·연동·구독) ·lib/detect.ts(탐지) ·lib/queries.ts+lib/store.tsx(스냅샷·상태) - 탐지 로직이 심장 — 거래를 가맹점별로 묶고 → 월 단위 반복 + 금액 안정성 → 구독 판정, 근거·신뢰도 동반. 데이터는 결정적(deterministic) 으로 만들어 하이드레이션 불일치 방지
최신 프레임워크의 함정 둘
- Prisma 7이 datasource 설정을 갈아엎어(driver adapter 요구) → 검증된 Prisma 6으로 다운
- Next 16이 미들웨어 규약을
middleware→proxy.ts(함수명 proxy) 로 변경
배운 것: 최신을 쓰면 “되는 코드”가 아니라 “이 버전에서 되는 코드”를 확인해야 한다.
4. 에이전트 팀 검증 (만든 손 ≠ 검증한 손)
리뷰어 3명은 읽기 전용, QA만 테스트 작성·실행:
| 에이전트 | 렌즈 |
|---|---|
| 코드 리뷰어 | 로직 결함·에러 처리·프레임워크 관례 |
| 보안 리뷰어 | 인증·세션·권한·시크릿 |
| 디자이너 | 빈/에러 상태·일관성·모바일 |
| QA | 실제 브라우저 E2E |
- 핵심 버그(QA 발견): 로그아웃→재로그인 시 해지 구독이 되살아나 보임. DB는 멀쩡, 범인은 브라우저 Router Cache.
revalidatePath로는 클라 캐시가 안 비워져 → 로그인을 하드 내비게이션(window.location.assign)으로 바꿔 캐시 폐기 - 그 외: 연동 이중 적재 레이스 → 원자적 claim / 해지 실패 무음 삼킴 → 롤백+재동기화 / 폴백 시크릿 → 프로덕션 fail-closed
- 교훈: 말보다 증거. QA 서술이 “미수정”이라 해도 실제 테스트를 다시 돌려 확인
- 최종: 브라우저 E2E 14/14 통과 + 빌드 클린
5. 배포 — 방화벽이라는 벽
- 서버리스는 파일 시스템에 못 쓴다 → SQLite → Postgres(Prisma는
provider한 줄만 교체) - 함정: 개발망이 아웃바운드 DB 포트(5432)를 차단 → 로컬
prisma db push실패(P1001) - 우회: 테이블 생성을 로컬이 아니라 Vercel 빌드 단계에서 실행 — 클라우드 빌드망은 DB에 닿는다
- 라이브 검증: 배포 URL에 대고 가입→(모의)연동→홈 탐지까지 브라우저 프로브 통과
로컬 검증 ≠ 프로덕션 검증. 안 되면 “실행 위치”를 의심하라.
6. 다듬기 + 추가 기능 4종
다듬기: 온보딩을 실제 마이데이터풍 4단계(자산 미연결 → 간편인증 → 문자 PIN → 카드·계좌 선택)로, 생년월일·휴대폰 실검증, 브랜드 로고(딥그린 타일+하향 트렌드 심볼), 설정/마이페이지(계정 수정·연결 끊기·탈퇴·로그아웃).
기능 4종(데이터 계층 먼저 고정 → 화면 병렬):
- 🎯 구독 다이어트 목표 — 월 목표 대비 지출 게이지
- ✏️ 구독 직접 추가 — 자동 탐지 안 되는 구독 수동 CRUD (읽기 전용 탈피)
- 📅 결제 캘린더 — 달력에 결제일·금액
- 💡 스마트 인사이트 + 실데이터 알림 — 하드코딩 알림 → 실제 탐지 결과 기반 제안
처음 7화면이 16화면(12 라우트) 규모로 성장했다.
7. 최종 산출물 (제출용 최종본)
| 구분 | 파일 | 내용 |
|---|---|---|
| 발표자료(통합) | 구독다이어트_최종발표_설계구현.pptx | 37장 = 설계(26)+구현(11) 병합. 대표 제출본 |
| 기능명세서 | 구독다이어트_기능명세서_v2.docx | FR-01~24 + 16화면 갤러리 + ERD (실제 앱 기준) |
| 데이터 모델 | 구독다이어트_ERD.dbml | 실제 스키마 4테이블 (dbdiagram용) |
| 동작 앱 | subscription-diet.vercel.app | 라이브 배포 |
| 블로그 | 설계 정리 · 구현 정리 (이 시리즈) | 2·3주차 기록 |
- 발표 분권 원본:
구독 다이어트_완성본.pptx(26장, 2주차 설계) ·구독다이어트_발표자료_v2.pptx(11장, 3주차 구현) - 부속: 라이브 16화면 캡처 + ERD 렌더 · 3주차 계획서/WBS · 앱 소스
8. 회고
- 기반(계약)을 먼저. 병렬 개발은 공유 인터페이스가 굳어 있을 때만 안전하다.
- “껍데기”를 스스로 의심하라. 화면이 눌러지는 것과 서비스가 도는 건 다르다.
- 할 수 없는 건 솔직하게. 실연동은 제도의 벽 — 모의로 두고 나머지를 진짜로.
- 검증은 남에게, 그리고 증거로. 만든 사람이 자기 걸 통과시키면 안 된다.
- 로컬과 프로덕션은 다른 세계. 방화벽·파일시스템처럼 배포에서만 드러나는 벽이 있다.
- 동작 → 검증 → 다듬기 순서. 예쁘게부터 만들면 헛수고가 되기 쉽다.