ID: key_26_30_05_26_ai_guide_01 Created date: 5월 30 2026 토요일
연관 문서
개요
이 문서는 AI Agent(Claude)와 협업하여 CIRA 프로젝트를 개발할 때 발생하는 런타임 에러를 최소화하고, 보다 정확하고 효율적인 개발 결과물을 얻기 위한 가이드다.
실제 개발 중 경험한 버그 패턴을 분석하여 도출한 원칙이며, 지속적으로 업데이트한다.
1. 서비스별 에러 최소화 방법
1.1 공통 원칙
① API 계약을 먼저 정의하라
가장 많은 버그가 발생하는 지점은 백엔드 응답과 프론트 기대값의 불일치다.
❌ 현재 방식
백엔드 구현 → 프론트 구현 → 런타임에 계약 불일치 발견
✅ 권장 방식
API 응답 JSON 예시 정의 → 백엔드/프론트 동시 구현 → 불일치 없음
요청 시 API 응답 예시를 직접 작성해서 첨부한다.
// 예시: 로그인 응답 구조를 미리 정의
{
"success": true,
"data": {
"accessToken": "eyJhbGci...",
"tokenType": "Bearer",
"expiresIn": 900,
"userId": "uuid",
"userName": "홍길동",
"email": "user@example.com"
}
}② DB 스키마의 제약 조건을 항상 명시하라
단위 테스트는 Mock을 사용하므로 DB의 NOT NULL, UNIQUE, FK 제약을 검증하지 못한다.
| 제약 유형 | 요청 시 명시 방법 |
|---|---|
NOT NULL | ”issueTypeId는 필수 필드 (NOT NULL)“ |
UNIQUE | ”projectKey는 전역 유니크” |
FK | ”projectId는 SN_CIRA_PROJECT 참조” |
| 기본값 | ”priority 미입력 시 서버에서 MEDIUM 처리” |
③ 완료 기준(Done Criteria)을 명확히 정의하라
“구현해줘”보다 “다음 조건을 만족해야 완료다”가 훨씬 정확하다.
✅ 완료 기준 예시
- 서버 재기동 후 POST /api/v1/projects/{id}/issues → 201 반환
- 이슈 목록 조회 시 생성된 이슈 포함 확인
- TypeScript 빌드 에러 없음 (npm run build 통과)
- 기존 기능(프로젝트 조회 등) 정상 동작 유지
1.2 Backend (Spring Boot)
필수 체크리스트
□ @Valid + Bean Validation으로 입력 필드 검증 선언
□ 필수 필드(NOT NULL)에 @NotBlank / @NotNull 추가
□ 서비스 계층에서 null 입력에 대한 기본값 처리 명시
□ @Transactional 범위와 내부 예외 처리 방식 설명
□ 새 Entity 추가 시 Flyway 마이그레이션 파일 함께 요청
□ 시드 데이터 필요 시 seed SQL도 함께 요청
요청 예시 (좋은 예)
이슈 생성 API를 구현해줘.
[입력 검증]
- title: 필수 (1~500자)
- issueTypeId: 필수 (NOT NULL) — 미입력 시 전역 기본 타입 자동 사용
- statusId: 필수 (NOT NULL) — 미입력 시 프로젝트 첫 번째 상태 자동 사용
- priority: 선택 — 미입력 시 "MEDIUM" 기본값
[DB 제약]
- SN_CIRA_ISSUE.ISSUE_TYPE_ID NOT NULL
- SN_CIRA_ISSUE.STATUS_ID NOT NULL
- SN_CIRA_ISSUE.PRIORITY NOT NULL
[완료 기준]
- title만 보내도 이슈 생성 성공 (나머지는 서버 기본값)
- 빌드 에러 없음
1.3 UI (Next.js)
필수 체크리스트
□ 컴포넌트 props 인터페이스를 요청에 포함
□ 새 컴포넌트 생성 시 "호출하는 페이지도 함께 수정" 명시
□ API 응답 구조를 types/ 파일에 먼저 정의 후 훅 구현 요청
□ TypeScript strict mode 준수 여부를 완료 기준에 포함
□ 기존 컴포넌트 재사용 시 현재 props 인터페이스 첨부
□ 라우팅 변경 시 관련 Link, redirect 경로 일괄 검토 요청
핵심 원칙: 컴포넌트 인터페이스를 반드시 첨부하라
// ❌ 나쁜 요청
"IssueFilter를 CIRA 페이지에 추가해줘"
// ✅ 좋은 요청
"IssueFilter를 CIRA 이슈 페이지에 추가해줘.
현재 IssueFilter props: { filters: IssueFilterParams, onChange: (f) => void }
CIRA 페이지의 상태: const [filter, setFilter] = useState<IssueFilterParams>({})"
TypeScript 활용 극대화
// tsconfig.json — strict 옵션 활성화 요청
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}strict 모드에서는 잘못된 prop명, undefined 접근 등이 빌드 에러로 잡힌다.
1.4 Mobile (React Native)
필수 체크리스트
□ API base URL 설정 방식 명시 (에뮬레이터 vs 실기기 vs 프로덕션)
□ 네트워크 에러 시 fallback UI 요구사항 명시
□ iOS / Android 양쪽 동작 확인을 완료 기준에 포함
□ 플랫폼별 동작 차이가 있는 기능 명시 (알림, 생체인증 등)
2. AI 작업 지시서 개선 방안
2.1 지시서 필수 구조
모든 개발 요청은 아래 구조를 따른다.
## [작업명]
### 목표
한 문장으로 무엇을 달성해야 하는가.
### 현재 상태 (As-Is)
- 현재 코드/구조가 어떤가
- 어떤 문제가 있는가
### 요구사항 (To-Be)
- 구체적인 변경 사항
- 입력/출력 명세
- 제약 조건
### 관련 파일
- 수정 대상: 경로/파일명
- 참고 파일: 인터페이스 확인용
### 완료 기준
- [ ] 검증 가능한 조건 1
- [ ] 검증 가능한 조건 22.2 컨텍스트 제공 레벨별 결과 차이
레벨 1 (최소) — "이슈 생성 기능 만들어줘"
→ 기본 뼈대는 나오지만 DB 제약, 기본값, 연관 컴포넌트 누락 가능
레벨 2 (중간) — "이슈 생성 API 구현. title 필수, issueTypeId/statusId NOT NULL"
→ 서버 로직은 맞지만 프론트 계약 불일치 가능
레벨 3 (권장) — 아래 항목 전부 포함
→ 런타임 에러 최소화
레벨 3 포함 항목:
| 항목 | 예시 |
|---|---|
| API 요청/응답 JSON | 위 1.1 예시 참조 |
| DB 제약 조건 | NOT NULL, UNIQUE, FK 명시 |
| 기존 코드 인터페이스 | 관련 컴포넌트 props, 훅 시그니처 |
| 연관 파일 경로 | 수정/참조할 실제 파일 경로 |
| 완료 기준 | 테스트 가능한 조건 |
| 하지 말 것 | ”기존 (main) 레이아웃은 건드리지 마” |
2.3 “하지 말 것” 명시의 중요성
AI는 문맥상 자연스러운 변경을 추가로 수행할 수 있다. 원하지 않는 변경은 명시적으로 금지한다.
✅ 예시
"CIRA 레이아웃을 추가하되, 기존 (main) 레이아웃과 app/layout.tsx는 수정하지 마라.
기존 ProjectNav 컴포넌트도 변경하지 마라."
2.4 단계별 작업 분리
큰 작업을 한 번에 요청하면 누락과 오류 가능성이 높다.
❌ 한 번에 요청
"CIRA 프로젝트 전체 UI를 Jira 스타일로 만들어줘"
✅ 단계별 요청
1단계: "레이아웃만 먼저 — CiraTopBar, CiraNavSidebar 컴포넌트"
2단계: "레이아웃 확인 후 — 프로젝트 목록 페이지"
3단계: "목록 확인 후 — 이슈 목록 + 이슈 생성"
각 단계마다 실제로 기동해서 확인한 후 다음 단계를 요청하면 에러 누적을 방지할 수 있다.
3. AI와 더 잘 협업하는 아이디어
3.1 CLAUDE.md를 살아있는 문서로 유지하라
각 레포의 CLAUDE.md는 AI가 코드를 작성할 때 읽는 핵심 컨텍스트다. 개발이 진행될수록 업데이트해야 한다.
CLAUDE.md에 포함해야 할 것
□ 현재 구현된 API 목록 (완료 표시 포함)
□ 실제 사용 중인 컴포넌트 목록과 props 요약
□ 알려진 제약 / 하지 말 것 목록
□ 개발 중 결정된 아키텍처 의사결정 (ADR)
□ 자주 발생한 버그 패턴과 해결 방법
3.2 에러 발생 시 로그를 그대로 붙여넣어라
❌ "이슈 생성이 안 돼요"
→ 원인 파악을 위해 추가 탐색 필요 → 시간 낭비
✅ 서버 로그 + 브라우저 콘솔 + 네트워크 탭 응답을 함께 첨부
→ 즉시 원인 특정 가능
로그 형식 권장:
[서버 로그]
2026-05-30 01:21:53 ERROR ... UnexpectedRollbackException ...
[브라우저 콘솔]
Failed to load resource: 500 (Internal Server Error)
[Request Body]
{"title": "테스트 이슈"}
[Response Body]
{"success": false, "message": "..."}
3.3 변경 범위를 명시적으로 합의하라
요청 전 합의할 것:
"이번 작업에서 수정할 파일 목록을 먼저 알려줘.
수정 시작 전에 승인할게."
이 방식은 의도치 않은 파일 변경을 예방하고, 변경 범위에 대한 공통 이해를 만든다.
3.4 테스트 코드를 함께 요청하라
✅ 요청 예시
"IssueService.createIssue() 구현 후,
아래 케이스에 대한 단위 테스트도 함께 작성해줘:
- 정상 케이스: title만 입력 → 201
- 실패 케이스: 프로젝트 미존재 → EntityNotFoundException
- 실패 케이스: 비회원 접근 → IllegalArgumentException"
테스트 코드가 있으면 AI가 다음 작업 시 기존 동작을 깨지 않았는지 확인할 수 있다.
3.5 용어/도메인 사전을 관리하라
프로젝트 고유 용어를 AI가 혼동하면 엉뚱한 코드가 나온다.
## 도메인 용어 사전 (예시)
- issueKey: "CIRA-1" 형식의 자동 생성 식별자
- backlog: sprintId가 null인 이슈 목록
- status: 프로젝트별 커스텀 상태 (To Do, In Progress 등)
- category: 상태의 유형 (TODO | IN_PROGRESS | DONE) — status와 다름
- tenant: 애플리케이션 레벨 격리 단위 ("TSH"), 유저별 분리 아님3.6 작업 후 회고를 짧게 남겨라
작업이 끝날 때마다 아래 내용을 기록하면 다음 작업의 컨텍스트가 된다.
## 작업 회고 템플릿
- 완료한 것:
- 발생한 이슈 및 해결:
- 다음 작업 시 주의할 것:
- CLAUDE.md 업데이트 필요 항목:체크리스트 요약
작업 요청 전
□ API 요청/응답 JSON 구조 정의
□ DB 필수 필드 (NOT NULL) 명시
□ 관련 기존 파일 경로 첨부
□ 기존 컴포넌트 props 인터페이스 첨부
□ 완료 기준 (검증 가능한 조건) 작성
□ 하지 말 것 명시
□ 작업 범위를 단계별로 분리
에러 발생 시
□ 서버 로그 전체 붙여넣기
□ 브라우저 네트워크 탭 (Request Body + Response Body)
□ 브라우저 콘솔 에러
□ "어떤 조작을 했을 때" 발생했는지 재현 조건 설명
작업 완료 후
□ 실제 기동해서 완료 기준 하나씩 확인
□ 기존 기능 regression 확인
□ CLAUDE.md 업데이트 여부 판단
□ 짧은 회고 기록