AI Driven Development — 따라하기AI 가계부 머니노트 만들기 · 설치부터 배포까지

9. 검증과 보안

이 단계에서 하는 것: QA 검증자 역할로 정상·경계·실패 테스트를 만들어 실행하고, 보안 검토자 역할로 비밀값·클라이언트 DB 직접 호출·RLS를 점검한다. 문제가 나오면 개발자 역할로 되돌려 고친 뒤 다시 검증한다. 다음 단계로 넘길 것: 테스트 3종이 통과하고 보안 점검에 걸리는 문제가 없는, 배포해도 되는 상태.

지금까지 화면·API·AI·인증이 이어져 동작했다. 하지만 "내 눈에 되는 것"과 "안전하게 맞게 되는 것"은 다르다. 그래서 이번에는 만드는 자리가 아니라 확인하는 자리를 세운다. QA 검증자는 정상·경계·실패를 테스트로 확인하고, 보안 검토자는 비밀값과 권한을 점검한다. 이 두 역할은 코드를 고치지 않는다. 문제를 찾으면 개발자 역할로 되돌려 고치게 하고, 고친 뒤 다시 검증한다. 이 되돌림과 재검이 피드백 루프다.

만들고 → 검증하고 → 문제는 되돌려 고친다 (피드백 루프) 개발자 역할 백엔드 · 프론트 코드를 만든다 확인하는 자리 QA · 보안 코드는 안 고친다 ① 만든 것을 검증 ② 문제는 개발자로 되돌림 "고쳐줘" QA 검증자 — 테스트 정상 · 경계(거래 0=잔액 0) · 실패(음수·남 데이터 거부) 보안 검토자 — 점검 비밀값 노출 · 클라 DB 직접호출 · RLS AI가 만들고, 사람이 초록(통과)을 눈으로 확인한다

준비 확인


따라하기

단계 1 — QA 검증자 역할로 테스트 만들고 실행하기

확인하는 자리를 먼저 세운다. QA 검증자는 테스트를 만들고 실행해 품질을 확인만 하고, 소스를 고쳐 억지로 통과시키지 않는다. 아래 프롬프트를 그대로 붙여 넣는다.

'QA 검증자' 역할을 만들어줘. 테스트를 만들고 실행해 품질을 확인만 한다. 소스를 고쳐 억지로 통과시키지 않고 문제를 보고한다.
이 역할로, "거래 생성"과 "월별 통계"에 대해 정상·경계·실패 테스트를 만들어 실행해줘.
- 정상: 수입·지출을 넣으면 목록과 잔액에 반영된다
- 경계: 거래가 없을 때 잔액 0, 통계 빈 상태가 맞게 나온다
- 실패: 금액이 음수/문자거나 남의 데이터를 요청하면 거부된다
하나(실패)는 일부러 잘못된 요청을 보내 서버가 거부하는지 확인해줘.

이렇게 나오면 성공: QA 검증자 역할이 세워지고, "거래 생성"과 "월별 통계"에 대한 정상·경계·실패 테스트가 만들어져 실행된다. 정상(수입·지출이 목록과 잔액에 반영), 경계(거래가 없을 때 잔액 0·통계 빈 상태), 실패(음수/문자 금액이나 남의 데이터 요청은 거부) 세 경우의 결과가 통과/실패로 정리되어 나온다.

[사람 검증] AI가 "통과"라고 해도, 내가 직접 테스트를 돌려 초록을 본다. 이게 AI 주도 개발의 핵심 — AI가 만들고, 사람이 검증한다. 1. 터미널 하나에서 npm run dev로 앱을 켜 둔다. (거래 등록·조회를 실제로 부르는 통합 테스트가 이 서버를 호출하기 때문. 안 켜면 그 테스트가 "연결 거부"로 빨갛게 실패한다.) 2. 다른 터미널을 열어 npx vitest run(또는 AI가 만든 npm test)을 친다. 3. 맨 아래에 Test Files N passed / Tests N passed 처럼 전부 통과(초록) 가 뜨면 됐다. 빨간 게 있으면 그 출력을 그대로 AI에게 주고 "이 실패를 고쳐줘"라고 한다(단계 3).

단계 2 — 보안 검토자 역할로 점검하기

테스트가 정상 동작을 확인했다면, 이번에는 안전한지를 본다. 보안 검토자는 보안 문제를 점검하고 보고만 한다. 아래 프롬프트를 그대로 붙여 넣는다.

'보안 검토자' 역할을 만들어줘. 보안 문제를 점검하고 보고만 한다.
- 비밀값(Supabase 서비스 키, Claude API 키)이 코드나 클라이언트에 노출되는지
- 클라이언트에서 Supabase DB를 직접 부르는 곳이 있는지(있으면 서버 API 경유로)
- RLS로 남의 데이터가 막히는지
발견되면 개발자 역할에게 되돌려 고치게 하고, 다시 검증해줘.

이렇게 나오면 성공: 세 가지 점검 결과가 항목별로 나온다. - 비밀값(Supabase 서비스 키, Claude API 키)이 코드나 클라이언트에 노출되지 않고 서버 전용 환경변수로만 쓰이는지. - 클라이언트에서 Supabase DB를 직접 부르는 곳이 없고, 모두 서버 API를 경유하는지. - RLS로 다른 사용자의 데이터 요청이 막히는지. 문제가 없으면 "이상 없음"으로 보고되고, 문제가 있으면 어디를 어떻게 고쳐야 하는지 함께 보고된다.

[사람 검증] 비밀값은 내가 직접 눈으로 한 번 본다. 1. .gitignore 파일을 열어 .env.local이 들어 있는지 확인한다(저장소에 키가 올라가면 사고). 2. AI에게 "클라이언트 번들(.next/static)에서 SUPABASE_SERVICE_ROLE·GEMINI·TOSS_SECRET 문자열을 grep해서 0건인지 보여줘"라고 시켜 결과를 눈으로 본다. (배포 후에는 공개 URL에서 브라우저 개발자도구(F12) → Sources에서 같은 문자열로 검색해도 안 나와야 한다.)

단계 3 — 문제를 되돌려 고치고 다시 검증하기

QA나 보안 점검에서 문제가 나왔다면, 확인하는 자리는 고치지 않는다. 개발자 역할로 되돌려 고치게 하고, 고친 뒤 같은 테스트·점검을 다시 돌린다. 문제가 나온 만큼만 아래처럼 되돌린다.

방금 QA 검증자와 보안 검토자가 보고한 문제를, 해당 개발자 역할(백엔드/프론트엔드)로 되돌려 고쳐줘.
고친 뒤에는 다시 QA 검증자로 같은 정상·경계·실패 테스트를, 보안 검토자로 같은 점검을 다시 실행해서 문제가 사라졌는지 확인해줘.

이렇게 나오면 성공: 개발자 역할이 지적된 부분만 고치고, 다시 돌린 테스트 3종이 통과하며 보안 점검에서 걸리는 문제가 사라진다. 문제가 처음부터 없었다면 이 단계는 건너뛴다.


이 단계 마무리

테스트가 통과하고 보안 점검이 깨끗하면, 이제 세상에 내보낼 준비가 됐다. 다음 단계에서 인프라 역할을 세워 배포한다.