AI Driven Development대기업 프로세스를 AI 팀으로

5. 데이터 모델링과 DB 구축

이 단계에서 하는 것: 앞에서 정한 Supabase/Postgres를 사용해 데이터 모델을 docs/ERD.md에 설계한다. 이어서 마이그레이션으로 테이블·행 수준 보안(RLS)·기본 데이터를 실제 DB에 적용하고, 회원가입·로그인(Auth)을 설정한다. 다음 단계로 넘길 것: 접속해 사용할 수 있는 DB와 인증 설정, .env.local의 접속 정보, RLS로 사용자별 접근을 제한한 테이블. 다음 단계에서는 이 데이터 모델을 바탕으로 API 명세서를 작성한다.

사용할 기술(Supabase·Postgres·Auth·RLS)은 앞의 아키텍처 설계에서 정했다. 이번 단계에서는 데이터 모델을 설계하고 실제 DB를 구축한다. DBA는 정해진 기술을 기준으로 작업한다.

이번 단계에서는 사람과 AI가 맡을 작업을 구분한다. 사람은 자신의 계정으로 Supabase 대시보드에 로그인해 프로젝트를 만들고 접속 정보를 준비한다. Claude Code에는 데이터 설계와 마이그레이션 작성·적용을 맡긴다.

[사람]이 하는 일 (대시보드·인증): Supabase 프로젝트 만들기 · 접속 키와 연결 문자열 복사 · 회원가입/로그인 설정 · (끝나고) DB 비밀번호 재설정. [Claude]가 하는 일 (모델링·구축·적용): ERD 설계 · 테이블·RLS·시드 마이그레이션 작성 · .env.local의 연결 문자열로 실제 DB에 적용. (앱에서 DB를 부르는 코드는 백엔드 몫이라 여기서 만들지 않는다.)

각 단계의 [사람] 표시는 대시보드에서 직접 할 일을, [Claude] 표시는 프롬프트로 요청할 일을 뜻한다.

사람은 계정과 접속 정보를, Claude는 DB 설계와 적용을 맡는다 [사람] — 대시보드·인증 · Supabase 프로젝트 만들기 · 접속 키·연결 문자열 복사 · 회원가입/로그인(Auth) 켜기 · 작업이 끝나면 DB 비밀번호 변경 브라우저 로그인은 사람만 할 수 있다 [Claude] — 설계·코드·적용 · ERD 설계 (docs/ERD.md) · 테이블·RLS·시드 SQL 작성 · 연결 문자열로 DB에 직접 적용 · 마이그레이션 적용·정책 확인 연결 문자열 결과 — RLS로 사용자별 격리 각자 자신의 거래만 볼 수 있다 · 다른 사용자의 데이터 요청은 거부

준비 확인


따라하기

단계 1 — [사람] Supabase 프로젝트 만들기 (대시보드)

  1. supabase.com에 로그인하고 New project를 누른다.
  2. Organization을 고른다(없으면 하나 만든다).
  3. Project name에 moneynote 를 적는다.
  4. Database Password를 정하고 안전한 곳에 보관한다. 뒤 단계에서 연결 문자열을 만들 때 필요하다.
  5. Region은 가까운 곳을 고른다 — 한국이면 Northeast Asia (Seoul)(ap-northeast-2).
  6. Create new project를 누르고 1~2분 기다린다.

이렇게 나오면 성공: 프로젝트 대시보드 화면이 열린다.

단계 2 — [사람] 접속 정보를 .env.local에 모으기 (대시보드)

Supabase 연결에 필요한 값은 세 가지다. 대시보드에서 확인해 .env.local 파일에 입력한다. 이후 Claude가 이 파일의 값을 사용한다.

① Project Settings → API 에서 URL과 키를 가져온다. 대시보드 좌측 맨 아래 ⚙ Project Settings → API(또는 API Keys).

무엇을 (Project Settings → API) 설명 .env.local 변수명
Project URL https://<프로젝트ref>.supabase.co NEXT_PUBLIC_SUPABASE_URL
anon public 키 최근 대시보드는 publishable 이라고도 부른다(같은 값) NEXT_PUBLIC_SUPABASE_ANON_KEY

② 상단 초록색 Connect 버튼 → Session pooler 탭에서 연결 문자열을 가져온다. 이런 모양이다.

postgresql://postgres.<프로젝트ref>:[YOUR-PASSWORD]@aws-0-<지역>.pooler.supabase.com:5432/postgres

[YOUR-PASSWORD] 자리에 단계 1에서 정한 DB 비밀번호를 넣어 문자열을 완성한다.

왜 Direct가 아니라 Session pooler인가. 같은 창의 Direct connection(db.<ref>.supabase.co)은 IPv6 전용이라, IPv6가 안 되는 환경에서는 접속이 안 된다. Session pooler는 IPv4에서도 되니 이걸 쓴다.

③ 프로젝트 폴더의 .env.local(없으면 새로 만든다)에 아래처럼 넣고, 오른쪽 값만 자기 것으로 바꾼다.

NEXT_PUBLIC_SUPABASE_URL=https://<프로젝트ref>.supabase.coNEXT_PUBLIC_SUPABASE_ANON_KEY=<anon(publishable) 키>SUPABASE_DB_URL=postgresql://postgres.<프로젝트ref>:<비밀번호>@aws-0-<지역>.pooler.supabase.com:5432/postgres

[service_role 키를 사용하지 않는 이유] Supabase 대시보드에는 service_role(secret) 키도 있다. 이 키는 RLS 정책을 우회하므로 이번 실습에서는 사용하지 않는다. 서버는 로그인한 사용자의 토큰으로 Supabase에 접근해 RLS가 적용되도록 한다. 그러면 서버 코드에서 사용자 조건을 빠뜨리더라도 DB가 다른 사용자의 데이터 접근을 막을 수 있다.

이렇게 나오면 성공: .env.local에 세 줄(URL·anon 키·연결 문자열)이 정확한 이름으로 들어간다.

[확인] 견본 파일(.env.example)도 만든다. .env.local은 저장소에 올리지 않으므로 필요한 환경변수 이름을 안내할 파일이 있어야 한다. docs/가이드/깃커밋컨벤션.pdf의 규칙에 따라 환경변수를 추가할 때마다 .env.example도 갱신한다. 실제 값은 넣지 않고 이름만 기록한다.

.env.local에 있는 변수 이름 중 .env.example에 빠진 것을 더해줘. 값은 비우고 이름만. 이미 있으면 그대로 둬.

단계 3 — [Claude] DBA 역할로 ERD 설계

'DBA' 서브에이전트 만들어줘. 데이터 설계와 DB·인증 구축만 담당한다 — docs/아키텍처.md·docs/PRD.md·docs/화면기획서.md를 기준으로 ERD(논리 데이터 모델)를 설계하고, 테이블·RLS·시드 마이그레이션을 만들고 실제 DB에 적용한다. 기술 스택은 앞에서 아키텍트가 정한 것을 따르고, 그 위에 스키마를 구축한다. 라이브러리는 최신 공식 문서를 확인해서 쓰고, 필요한 의존성은 알아서 추가한다. 마이그레이션은 되돌릴 수 있게 만들고, 데이터를 지우는 파괴적 작업은 먼저 확인받는다. API·화면 코드는 만들지 않는다.

서브에이전트를 만든 뒤에는 Claude Code를 한 번 다시 띄운다(/exit 뒤 claude). 새 서브에이전트는 다음 세션부터 보인다.

DBA 서브에이전트로, docs/아키텍처.md·docs/화면기획서.md·docs/PRD.md를 근거로 ERD를 docs/ERD.md로 만들어줘.테이블·컬럼·제약·접근 제어는 네가 설계하고 이유를 ERD에 적어. 질문은 PRD를 바꿔야 하는 것만 남겨.

테이블과 컬럼을 DBA에게 맡기는 이유: 무엇을 저장해야 하는지는 PRD와 화면기획서에, 접근 규칙(자기 데이터만, 클라이언트는 DB에 직접 접근하지 않는다)은 PRD와 CLAUDE.md에, 이름 규칙은 코딩컨벤션에 있다. DBA는 그걸 읽고 테이블·컬럼·제약·RLS를 정한다. 사람이 컬럼 이름까지 불러 주면 DB 설계를 사람이 하고 AI는 받아 적는 꼴이다. 이름이 사람마다 달라도 괜찮다 — 다음 단계의 API 명세가 "필드 이름은 ERD의 컬럼 이름 그대로"라고 ERD를 가리키므로, 각자의 프로젝트 안에서는 끝까지 같은 이름이 쓰인다. 이렇게 나오면 성공: docs/ERD.md에 테이블 목록(사용자 프로필·카테고리·거래·결제 정도가 나온다)과 컬럼·제약, 거래·결제가 사용자에 매여 있다는 관계, 사용자별 접근 제한(RLS), 기본 카테고리 시드가 정리된다. 테이블마다 왜 그렇게 나눴는지 이유가 붙어 있다. 문서를 열어 PRD의 기능마다 저장할 자리가 있는지 본다 — 프리미엄 여부, 결제 기록, 메모가 빠졌으면 그 이름을 짚어 다시 요청한다. 질문은 비어 있거나 PRD를 고쳐야 하는 것만 남는다.

단계 4 — [Claude] 마이그레이션 만들고 실제 DB에 적용

docs/ERD.md와 가이드 문서를 지정해 마이그레이션 작성과 적용을 요청한다. SQL을 파일로 남기면 어떤 변경을 적용했는지 확인할 수 있고, 실제 DB에 적용해야 설계가 동작하는지 검증할 수 있다.

Claude가 .env.local의 연결 문자열을 읽고 SQL을 실행하도록 요청한다. 연결 문자열에는 비밀번호가 들어 있으므로 프롬프트에 복사하지 않는다. 단계 2에서 설정한 SUPABASE_DB_URL을 사용한다.

[도구 설치] Claude가 DB에 접속해 SQL을 적용하려면 psql(PostgreSQL 클라이언트)이나 Supabase CLI가 필요하다. 도구가 없다면 설치 후 적용하도록 요청한다. Supabase CLI는 Mac에서 brew install supabase/tap/supabase로 설치하거나 프로젝트에 npm i -D supabase로 추가할 수 있다.

DBA 서브에이전트로, docs/ERD.md대로 마이그레이션 파일을 만들고 Supabase DB에 적용해줘. 연결은 .env.local을 확인해줘. 적용 후 결과를 나한테 보여줘.

이렇게 나오면 성공: Claude가 "테이블 n개·정책 적용·시드 적용 완료"처럼 보고한다. ERD의 테이블 수와 같은지 센다.

[사람 검증] 적용 결과를 대시보드에서 직접 확인한다. AI의 완료 보고와 실제 DB 상태가 일치하는지 살펴본다. 1. Supabase 대시보드 좌측 Table Editor 를 누른다 → profiles·categories·transactions·payments 테이블이 보인다. categories를 누르면 시드 카테고리(카페/식비·교통·급여 등)가 행으로 들어 있다. 2. 좌측 Database → Policies를 누른다 → transactions에 조회·등록·수정·삭제 정책 4개가 활성화되어 있는지 확인한다. 빠진 정책이 있으면 해당 동작에서 접근 제한을 다시 점검한다. 3. (나중에 화면에서 두 계정으로 로그인하면, 서로의 거래가 안 보이는지 화면으로도 다시 확인한다.)

막히면(연결 오류): ENOTFOUND나 접속 실패가 나면 Direct가 아니라 Session pooler 문자열인지, 비밀번호가 맞는지 확인한다. 비밀번호가 기억 안 나면 Project Settings → Database → Reset database password로 새로 정하고 그 값으로 다시 만든다.

단계 5 — [사람] 회원가입/로그인 켜기 (대시보드)

  1. 좌측 Authentication → Sign In / Providers(또는 Providers) 로 간다.
  2. Email 을 켠다.
  3. 실습 편의를 위해 "Confirm email"(이메일 확인)을 끈다. → Save. 그래야 확인 메일 없이 가입 즉시 로그인된다.

이렇게 나오면 성공: 이메일 회원가입/로그인이 켜졌고, 확인 메일 단계 없이 가입하면 바로 로그인된다.

단계 6 — [Claude] 실습용 테스트 계정 만들기 (한 번만)

이후 API·화면·배포 단계에서 반복해서 사용할 테스트 계정을 만든다. 실습에서는 아래 이메일과 비밀번호를 사용한다.

표준 테스트 계정 — 이 값을 그대로 쓴다. - 이메일: demo@moneynote.dev - 비밀번호: moneynote1234

테스트 계정을 하나 만들어줘: 이메일 demo@moneynote.dev, 비밀번호 moneynote1234.그리고 이 계정으로 예시 거래 3건(이번 달 월급 수입 300만, 스타벅스 지출 4500, 지하철 지출 1400)을 넣어줘.이후 실습에서 이 계정으로 나도 로그인해서 확인할 거야.

이렇게 나오면 성공: demo@moneynote.dev 계정과 예시 거래 3건이 만들어진다. 이후 사람이 이 계정으로 로그인해 거래가 표시되는지 확인한다. 실습이 끝날 때까지 계정과 데이터를 유지한다.


이 단계 마무리

TechLead · macro@prag-ai.com