이 단계에서 하는 것: Supabase에 데이터베이스(프로젝트)를 만들고, 접속 정보를 앱에 넣고, ERD대로 테이블·시드를 만들고, 회원가입/로그인(Auth)과 행 수준 보안(RLS)을 켠다. 마지막에 두 계정으로 서로의 데이터가 안 보이는지 실제로 확인한다. 다음 단계로 넘길 것: 실제로 동작하는 DB와 로그인,
.env.local에 든 접속 키, 그리고 RLS로 사용자별 격리가 걸린 테이블.
여기서부터 이 과정의 핵심이 드러난다 — 사람이 할 일과 AI가 할 일이 뚜렷이 나뉜다. Claude Code는 브라우저(대시보드)를 대신 눌러 줄 수 없고, 로그인·프로젝트 생성·키 발급 같은 인증은 사람만 할 수 있다. 그래서 이 장은 이렇게 갈린다.
[사람]이 하는 일 (대시보드·인증): Supabase 프로젝트 만들기 · 접속 키와 연결 문자열 복사 · 회원가입/로그인 설정 · (끝나고) DB 비밀번호 재설정. [Claude]가 하는 일 (설계·코드·적용): ERD 설계 · 테이블·RLS·시드 SQL 작성 · Supabase 접속 코드 작성 · 받은 연결 문자열로 마이그레이션을 실제 DB에 적용 · RLS 통합 테스트.
아래 단계마다 앞에 [사람] / [Claude] 를 붙여 두었다. [사람] 은 대시보드에서 클릭 순서대로 직접, [Claude] 는 프롬프트를 붙여 넣으면 된다.
http://localhost:3000에 뜬다.supabase.com에서 GitHub로 가입한다.supabase.com에 로그인하고 New project를 누른다.moneynote 를 적는다.ap-northeast-2).이렇게 나오면 성공: 프로젝트 대시보드 화면이 열린다.
.env.local에 넣기 (대시보드)https://<프로젝트ref>.supabase.co)
- anon public 키 — 최근 대시보드는 publishable 이라고도 부른다(같은 값).
- service_role 키 — secret 이라고도 부른다. "Reveal"을 눌러야 보인다. 매우 민감하니 노출 금지..env.local 파일에 아래처럼 넣는다(없으면 새로 만든다).NEXT_PUBLIC_SUPABASE_URL=여기에 Project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY=여기에 anon(publishable) 키
SUPABASE_SERVICE_ROLE_KEY=여기에 service_role(secret) 키
NEXT_PUBLIC_이 붙은 두 개는 화면에서 써도 되는 공개 값이고, SUPABASE_SERVICE_ROLE_KEY는 서버 전용이라 절대 NEXT_PUBLIC_을 붙이지 않는다. 이 변수 이름은 배포(10장)에서 그대로 다시 쓰므로 바꾸지 않는다.
이렇게 나오면 성공: .env.local에 세 값이 들어간다.
Claude가 만든 SQL을 Claude가 직접 DB에 적용하려면, DB에 접속할 연결 문자열이 필요하다. 이건 인증 정보라 사람이 대시보드에서 가져온다.
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에서도 되니 이걸 쓴다.
이렇게 나오면 성공: 비밀번호까지 채운 postgresql://...pooler.supabase.com:5432/postgres 연결 문자열이 손에 있다.
'DBA' 역할을 만들어줘. 데이터를 설계하고 Supabase에 실제 DB와 인증을 세운다.
DBA 역할로, docs/화면기획서.md와 docs/PRD.md를 근거로 ERD를 docs/ERD.md로 만들어줘.
엔티티: 사용자(Supabase Auth 사용), 거래(transaction: 금액·수입/지출·카테고리·날짜·메모·user_id), 카테고리(category).
관계와 필드, 상태값을 정리하고, 각 사용자는 자기 데이터만 본다는 점을 반영해줘.
이렇게 나오면 성공: docs/ERD.md가 생긴다.
DBA 역할로, docs/ERD.md대로 Supabase(Postgres) 테이블 생성 SQL과, 카테고리 기본값·예시 거래 시드 SQL을 만들어줘.
거래 테이블에는 RLS를 켜서 user_id = auth.uid() 인 행만 보게 하는 정책 SQL도 만들어줘.
SQL은 supabase/migrations 폴더에 마이그레이션 파일로 저장해줘.
Supabase 클라이언트 설정 코드는 프로젝트구조·코딩컨벤션 문서를 따라 lib에 만들되, .env.local의 변수 이름을 그대로 읽게 해줘.
이렇게 나오면 성공: supabase/migrations/에 테이블·RLS·시드 SQL이 생기고, lib에 Supabase 접속 코드가 만들어진다.
단계 3에서 만든 연결 문자열을 주며 적용을 시킨다. SQL을 직접 붙여넣는 게 아니라, Claude가 그 연결로 SQL을 실행한다.
[도구 설치] Claude가 DB에 접속해 SQL을 적용하려면 도구가 필요하다.
psql(PostgreSQL 클라이언트)이나 Supabase CLI 중 하나면 된다. 없으면 Claude에게 "없으면 설치해서 적용해줘" 라고 하면 알아서 깐다. (Supabase CLI 직접 설치: Macbrew install supabase/tap/supabase, 또는 프로젝트에npm i -D supabase.)
아래 Session pooler 연결 문자열로, supabase/migrations의 SQL을 순서대로 실제 Supabase DB에 적용해줘.
적용 후 테이블 목록과 RLS 정책, 카테고리 시드 개수를 확인해서 보여줘.
연결 문자열: postgresql://postgres.<프로젝트ref>:<비밀번호>@aws-0-<지역>.pooler.supabase.com:5432/postgres
이렇게 나오면 성공: Claude가 "테이블 2개·정책 4개·시드 11건 적용 완료"처럼 보고한다.
[사람 검증] AI 말만 믿지 말고 대시보드로 직접 확인한다. 이게 이 과정의 핵심이다 — AI가 주도하되, 사람이 눈으로 검증한다. 1. Supabase 대시보드 좌측 Table Editor 를 누른다 →
categories·transactions테이블이 보인다.categories를 누르면 시드 카테고리(카페/식비·교통·급여 등)가 행으로 들어 있다. 2. 좌측 Database → Policies 를 누른다 →transactions에 정책 4개(조회/등록/수정/삭제)가 켜져 있다. 하나라도 없으면 "본인 것만"이 뚫린 것이다. 3. (7장에서 두 계정으로 로그인하면, 서로의 거래가 안 보이는지 화면으로도 다시 확인한다.)막히면(연결 오류):
ENOTFOUND나 접속 실패가 나면 Direct가 아니라 Session pooler 문자열인지, 비밀번호가 맞는지 확인한다. 비밀번호가 기억 안 나면 Project Settings → Database → Reset database password로 새로 정하고 그 값으로 다시 만든다.
이렇게 나오면 성공: 이메일 회원가입/로그인이 켜졌고, 확인 메일 단계 없이 가입하면 바로 로그인된다.
정말 사용자끼리 데이터가 격리되는지, 만든 사람 말고 다른 눈으로 확인한다.
테스트 계정 A와 B로 각각 회원가입해서 로그인하고, 각자 거래를 1건씩 등록한 뒤,
A가 조회하면 A의 거래만, B가 조회하면 B의 거래만 보이는지(서로의 거래가 안 보이는지) 실제로 확인해줘.
또 A가 B의 user_id로 거래를 심으려 하면 거부되는지도 확인하고, 결과를 표로 정리해줘. 테스트가 끝나면 테스트 계정과 데이터는 지워줘.
이렇게 나오면 성공: A는 A거래만·B는 B거래만 보이고, 미인증 조회는 빈 결과, A가 B를 사칭한 등록은 거부(403)된다. → RLS로 사용자별 격리가 실제로 걸린 것이다.
앞으로 API 문서(6장)·화면(7장)·배포(10장)에서 매번 새로 가입하지 않도록, 정해진 테스트 계정 하나를 만들어 둔다. 이메일·비밀번호는 아래로 고정한다.
표준 테스트 계정 — 이 값을 그대로 쓴다. - 이메일:
demo@moneynote.dev- 비밀번호:moneynote1234
테스트 계정을 하나 만들어줘: 이메일 demo@moneynote.dev, 비밀번호 moneynote1234.
그리고 이 계정으로 예시 거래 3건(8월 월급 수입 300만, 스타벅스 지출 4500, 지하철 지출 1400)을 넣어줘.
이후 실습에서 이 계정으로 로그인해 확인할 거야.
이렇게 나오면 성공: demo@moneynote.dev 계정이 만들어지고 예시 거래 3건이 들어간다. 이후 [사람 검증]에서 이 계정으로 로그인하면 이 데이터가 그대로 보인다. (지우지 말고 실습 끝까지 둔다.)
.env.local에 세 키(NEXT_PUBLIC_SUPABASE_URL·NEXT_PUBLIC_SUPABASE_ANON_KEY·SUPABASE_SERVICE_ROLE_KEY)를 넣고, Session pooler 연결 문자열을 확보했다..env.local의 키가 Settings → API의 값과 정확히 같은지 확인한다. 가입은 되는데 로그인이 안 되면 단계 7의 "Confirm email 끄기"를 했는지 확인한다.