Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
8985299
chore: Claude Code rules 파일 추가 (아키텍처, 테스트, 인증, 기술스택, 환경설정, 명령어, 의사결정)
ghtjr410 Feb 23, 2026
6696953
chore: Claude Code 스킬 추가 (decision-guide, rule-manage, skill-create, …
ghtjr410 Feb 23, 2026
98c688d
feat: Admin 인증 인터셉터 추가 및 인증 패키지 interfaces/api/auth로 이동
ghtjr410 Feb 23, 2026
3f79f93
fix: User API 인증 패키지 import 경로 수정
ghtjr410 Feb 24, 2026
b526baa
feat: 브랜드 등록 기능 구현
ghtjr410 Feb 24, 2026
7c35cf6
chore: rules 업데이트 - 계층별 테스트 전략 추가 및 Service 역할 정의 구체화
ghtjr410 Feb 24, 2026
2472047
feat: 브랜드 수정 기능 구현
ghtjr410 Feb 24, 2026
ede01ab
feat: 브랜드 삭제 기능 구현
ghtjr410 Feb 24, 2026
e84eb54
chore: rules 정리 - architecture 파일명 오타 수정 및 검증/예외 처리 규칙 분리
ghtjr410 Feb 24, 2026
70ef696
refactor: 브랜드 삭제 상태 검증을 Entity 책임으로 이동
ghtjr410 Feb 24, 2026
f9c3abf
feat: 브랜드 목록 조회 및 상세 조회 기능 구현
ghtjr410 Feb 24, 2026
aa8e186
chore: rules 추가 - 코드 배치 순서 컨벤션 정의
ghtjr410 Feb 24, 2026
50e84b5
feat: 사용자 브랜드 조회 API 추가 및 Service 메서드 리팩토링
ghtjr410 Feb 24, 2026
52691dc
chore: rules 및 skills 정비 - 코딩 원칙 추가, 아키텍처 규칙 개선, 스킬 보완
ghtjr410 Feb 25, 2026
d755d8c
chore: coding-principles 중복 항목 제거 및 마크다운 서식 정리
ghtjr410 Feb 25, 2026
f9946d9
chore: rules 용어 통일 - Service를 ApplicationService로 변경
ghtjr410 Feb 25, 2026
8f3657c
refactor: 템플릿 Example 도메인 제거
ghtjr410 Feb 25, 2026
d32f8ea
refactor: UserService를 domain에서 application 패키지로 이동
ghtjr410 Feb 25, 2026
14ccacc
refactor: BrandService를 domain에서 application 패키지로 이동
ghtjr410 Feb 25, 2026
26d8a29
test: Brand E2E 테스트 커버리지 갭 보완
ghtjr410 Feb 25, 2026
ab36d9a
feat: Product 등록 API 구현
ghtjr410 Feb 25, 2026
82fc60c
test: Brand E2E 엣지 케이스 테스트 추가 및 삭제 명세 멱등성 반영
ghtjr410 Feb 25, 2026
7ac3a76
feat: implement, implement-review 스킬 추가 및 워크플로우 규칙 분리
ghtjr410 Feb 25, 2026
5475200
feat: Product 수정 API 구현
ghtjr410 Feb 25, 2026
d9ac1c2
feat: Product 삭제 API 구현
ghtjr410 Feb 25, 2026
0ba7fa0
chore: implement, implement-review, test-patterns 스킬 개선
ghtjr410 Feb 25, 2026
0bce797
feat: Product 목록 조회 API 및 브랜드별 상품 일괄 삭제 구현
ghtjr410 Feb 25, 2026
f66395e
feat: Product 목록 조회 시 브랜드 일괄 조회로 N+1 문제 해결
ghtjr410 Feb 25, 2026
a6c7ba0
feat: User 코드 정렬, 검증 강화, E2E 테스트 보강
ghtjr410 Feb 25, 2026
8ad1216
feat: 상품 좋아요 등록 API 구현 및 Product 좋아요 수 차감 기능 추가
ghtjr410 Feb 25, 2026
599d580
feat: 상품 좋아요 취소 API 구현 및 E2E 테스트 작성
ghtjr410 Feb 25, 2026
98ee3cb
docs: Product·Order 클래스다이어그램 VO 제거 및 원시 타입 단순
ghtjr410 Feb 25, 2026
9354271
feat: 좋아요 상품 목록 조회 API 구현 및 통합·E2E 테스트 작성
ghtjr410 Feb 25, 2026
72c17ab
feat: 관리자 상품 상세 조회 API 구현 및 E2E 테스트 작성
ghtjr410 Feb 25, 2026
8b41ea3
docs: DTO 규칙 문서 신설 및 관련 규칙 용어 통일
ghtjr410 Feb 26, 2026
f33c7b6
feat: 주문 요청 API 구현 및 단위·통합·E2E 테스트 작성
ghtjr410 Feb 26, 2026
32e891e
refactor: User 도메인 DTO를 Request/Command 분리 규칙에 맞게 마이그레이션
ghtjr410 Feb 26, 2026
8e5b340
refactor: Brand 도메인 DTO를 Request/Command 분리 규칙에 맞게 마이그레이
ghtjr410 Feb 26, 2026
096cbca
refactor: Product 도메인 DTO를 Request/Command 분리 규칙에 맞게 마이그레이션
ghtjr410 Feb 26, 2026
c891fb1
refactor: Like 도메인 DTO를 Request/Command 분리 규칙에 맞게 마이그레이션
ghtjr410 Feb 26, 2026
93284f9
refactor: 상품 삭제를 멱등 연산으로 변경
ghtjr410 Feb 26, 2026
1a0b0f3
feat: 주문 목록 조회, 상세 조회 API 구현
ghtjr410 Feb 26, 2026
85d8732
refactor: User 도메인 Command 도입 및 테스트 보강
ghtjr410 Feb 26, 2026
3024a55
feat: 주문 목록 조회, 상세 조회 Admin API 구현
ghtjr410 Feb 26, 2026
9952173
docs: 주문 스냅샷에서 브랜드명 제거 및 상품 삭제 멱등성 AC 보강
ghtjr410 Feb 26, 2026
7e887b6
refactor: ProductFacade 브랜드 조회 개선 및 테스트 보강
ghtjr410 Feb 26, 2026
42369b1
chore: DTO 규칙 문서 Command 중첩 record 네이밍 예시 수정
ghtjr410 Feb 26, 2026
5eaac7f
refactor: Brand 도메인 Command DTO 도입 및 코드 스타일 정비
ghtjr410 Feb 26, 2026
82aa40c
refactor: Product 도메인 Command DTO 도입 및 Entity 삭제 검증 강화
ghtjr410 Feb 26, 2026
49ed583
docs: 주문 생성 스냅샷에서 브랜드명 제거 및 삭제 상품 AC 추가
ghtjr410 Feb 26, 2026
b6acf44
refactor: 좋아요 증감 시 비관적 락 적용으로 동시성 안전성 확보
ghtjr410 Feb 26, 2026
8f069a7
refactor: Facade 목록 조회 시 사전 검증 + 순수 매핑 패턴 적용
ghtjr410 Feb 26, 2026
762a764
refactor: Active 조회를 레포지토리 레벨 deletedAt 필터링으로 변경
ghtjr410 Feb 26, 2026
e45030c
refactor: E2E 테스트 공통 픽스처(E2ETestFixture) 추출로 중복 제거
ghtjr410 Feb 26, 2026
3901caa
docs: API 도메인별 HTTP 요청 파일 추가 및 예시 파일 제
ghtjr410 Feb 26, 2026
f951be3
refactor: E2ETestFixture를 @Component에서 @Import 방식으로 변경
ghtjr410 Feb 26, 2026
7ee9de7
docs: 좋아요 목록 조회 응답에서 불필요한 필드 제거
ghtjr410 Feb 26, 2026
edfcb83
refactor: Facade 트랜잭션 선언을 클래스 레벨에서 메서드 레벨로 변경
ghtjr410 Mar 3, 2026
d2fc487
refactor: Entity의 update()를 updateInfo()로 리네이밍하여 정보 수정 의도 명확화
ghtjr410 Mar 3, 2026
7790d0c
refactor: 주문 소유권 검증을 Service에서 Facade로 이동하고 조회 메서드 네이밍 통일
ghtjr410 Mar 3, 2026
2d32c59
chore: Entity 불변식 vs 사실 제공 패턴 규칙 추가 및 Facade 접근 제어 역할 명시
ghtjr410 Mar 3, 2026
558a947
chore: Request DTO 소속을 interfaces로 정정하고 검증 주체를 Controller(@Valid)로 통일
ghtjr410 Mar 3, 2026
17847d5
refactor: Request DTO를 interfaces로 이동하고 Command 네이밍을 Request와 통일
ghtjr410 Mar 3, 2026
7e932aa
chore: Request DTO를 interfaces로 이동하고 Command 네이밍을 Request와 통일
ghtjr410 Mar 3, 2026
595ba0d
refactor: 트랜잭션 메서드 레벨 개별 선언 통일 및 주문 날짜 검증을 Controller @Valid로 이동
ghtjr410 Mar 4, 2026
f75ff36
refactor: Product 도메인 락 제거
ghtjr410 Mar 4, 2026
c251ed1
fix: 좋아요 취소 시 활성 상품 검증 제거
ghtjr410 Mar 4, 2026
c10c6c4
fix: ERD ORDER_ITEM에서 미사용 brand_name 컬럼 제거
ghtjr410 Mar 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .claude/rules/conventions/code-ordering.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 코드 배치 순서

## 원칙

클래스 내 멤버는 **공개 범위 넓은 것 → 좁은 것**, 역할별로 그룹핑한다.
모든 클래스에서 private 메서드는 최하단에 배치한다.

## 계층별 적용 (ApplicationService, Facade, Controller, Repository 등)

- 구분 주석: `// Command` → `// Query` 순서

| 계층 | 순서 | 비고 |
|------|------|------|
| Controller | `// Command` → `// Query` | POST/PATCH/DELETE → GET |
| ApiSpec | `// Command` → `// Query` | Controller와 동일 순서 |
| Facade | `// Command` → `// Query` | |
| ApplicationService | `// Command` → `// Query` | |
| Repository (interface) | `// Command` → `// Query` | save → find, exists |
| RepositoryImpl | `// Command` → `// Query` | Repository 인터페이스와 동일 순서 |
| JpaRepository | `// Query` 만 | 상속 메서드 생략, 직접 정의한 메서드만 기재 |
| Request (interfaces) | `// Command` → `// Query` | Place, Cancel → ListByUser |
| Command | 구분 주석 없음 | 기능별 나열 |
| V1Dto | `// Response` 만 | Response 전용 |

## Entity 멤버 순서

Entity는 Command/Query 구분 대신 역할별 순서를 따른다.

| 순서 | 역할 | 예시 |
|------|------|------|
| 1 | 상수 | `NAME_MAX_LENGTH` |
| 2 | 필드 | `name`, `description` |
| 3 | 생성자 | protected 기본 생성자 → private 생성자 순 |
| 4 | 정적 팩토리 메서드 | `create()` |
| 5 | 명령 메서드 | `update()`, `softDelete()` |
| 6 | 조회 메서드 | `isDeleted()`, `isOrderable()` |
| 7 | 검증 메서드 (public) | `validateNotDeleted()` |
| 8 | private 메서드 | `validateName()`, `validateDescription()` |

## 주석 형식

- 계층별 구분 주석: `// Command`, `// Query`, `// Response`
- Entity는 구분 주석 불필요 — 순서 자체가 규칙
- 메서드 그룹 사이에 빈 줄 하나
137 changes: 137 additions & 0 deletions .claude/rules/conventions/dto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
# DTO

## DTO 종류와 소속 계층

| DTO | 소속 | 역할 | 형태 |
|-----|------|------|------|
| `Request` | interfaces | Controller 입력 (명령 + 조회) | `Place`, `Cancel`, `ListByUser` 등 |
| `Command` | application | Facade/Service 입력 (비즈니스 보강) | `Create`, `Update` 등 |
| `Info` | application | Facade 출력 → Controller | 도메인 데이터의 읽기 전용 표현 |
| `V1Dto` | interfaces | HTTP 응답 전용 | `XxxResponse` |

- 모든 DTO는 Java record로 정의한다 (불변 보장)
- Entity는 application 계층 밖으로 노출하지 않는다

## 데이터 흐름
```
Controller Facade Service
@Valid Request.Place →
request.toCommand() → Command.Place →
Command.Create → Command.Create → Entity
Info ← Entity ←
V1Dto.Response ← Info
```

1. **Controller**: `Request`를 `@Valid`로 검증 후, 명령은 `request.toCommand()`로 Command 변환하여 Facade에 전달, 조회는 개별 파라미터를 추출하여 Facade에 전달
2. **Facade → Service**: Command를 DB 조회 등으로 보강하여 Service에 전달
3. **Service → Facade**: Entity 반환
4. **Facade → Controller**: Entity를 `Info`로 변환하여 반환
5. **Controller → 클라이언트**: `Info`를 `V1Dto.Response`로 변환

## Request 구조

Request는 도메인별로 하나의 클래스에 중첩 record로 정의한다.
Controller에서 `@Valid`로 검증하고, Command Request에는 `toCommand()` 메서드를 정의한다.
```java
public record OrderRequest() {

// Command
public record Place(
@NotNull @Size(min = 1, max = 100)
List<@Valid PlaceItem> orderItems
) {
public OrderCommand.Place toCommand() {
List<OrderCommand.PlaceItem> items = orderItems.stream()
.map(item -> OrderCommand.PlaceItem.of(item.productId(), item.quantity()))
.toList();
return OrderCommand.Place.of(items);
}
}
public record PlaceItem(
@NotNull Long productId,
@NotNull @Min(1) @Max(9999999) Integer quantity
) {}
public record Cancel(String cancelReason) {
public OrderCommand.Cancel toCommand(Long userId, Long orderId) {
return OrderCommand.Cancel.of(userId, orderId, cancelReason);
}
}

// Query
public record ListByUser(LocalDate startDate, LocalDate endDate, Integer page, Integer size) {}
}
```

| 구분 | 용도 | 데이터 특성 |
|------|------|-------------|
| `// Command` | 명령 요청 (POST/PATCH/DELETE) | 사용자 입력값 (ID, 수량 등) |
| `// Query` | 조회 파라미터 (GET) | 필터, 페이징 등 |

## Command 구조

Command는 도메인별로 하나의 클래스에 중첩 record로 정의한다.
Controller에서 `Request.toCommand()`로 생성하거나, Facade가 DB 조회 결과 등으로 보강하여 생성한다.
`of(...)` 정적 팩토리 메서드로 생성한다.
```java
public record OrderCommand() {
public record Create(Long userId, List<CreateItem> items) {
public static Create of(Long userId, List<CreateItem> items) {
return new Create(userId, items);
}
}
public record CreateItem(Long productId, String productName, BigDecimal price, int quantity) {
public static CreateItem of(Long productId, String productName, BigDecimal price, int quantity) {
return new CreateItem(productId, productName, price, quantity);
}
}
public record Cancel(Long userId, Long orderId, String cancelReason) {
public static Cancel of(Long userId, Long orderId, String cancelReason) {
return new Cancel(userId, orderId, cancelReason);
}
}
}
```

| 구분 | 용도 | 데이터 특성 |
|------|------|-------------|
| `Create`, `Update` 등 | Facade → Service | 비즈니스 데이터 포함 (이름, 가격 등) |

## Command 네이밍 규칙

| 생성 경로 | 이름 기준 | 예시 |
|----------|----------|------|
| `toCommand()`로 생성 (Facade 진입) | Request 이름과 동일 | `Place`, `Register`, `Cancel` |
| Facade가 보강하여 생성 (Service 진입) | 도메인 동작 | `Create`, `Update` |
| 보강 불필요 시 | 하나의 Command가 관통 | `SignUp`, `ChangePassword` |

## Info 구조

Info는 도메인별로 하나의 record에 중첩 record로 정의한다.
```java
public record OrderInfo(
Long id,
BigDecimal totalAmount,
List<OrderItemInfo> orderItems,
ZonedDateTime createdAt
) {
public record OrderItemInfo(...) {}

public static OrderInfo from(Order order) { ... }
}
```

- `from(Entity)` 정적 팩토리 메서드로 Entity → Info 변환
- Facade에서 변환 책임을 가진다

## V1Dto 구조

V1Dto는 Response 전용이다. Request는 같은 interfaces 계층의 `Request`를 사용한다.
```java
public class OrderV1Dto {

// Response
public record OrderResponse(...) {
public static OrderResponse from(OrderInfo info) { ... }
}
}
```
20 changes: 20 additions & 0 deletions .claude/rules/conventions/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 테스트

## 테스트 분류
- 단위 테스트: 도메인 모델 검증
- 통합 테스트: ApplicationService + Repository (TestContainers)
- E2E 테스트: API 엔드포인트 전체 흐름

## 계층별 테스트 전략

| 계층 | 테스트 유형 | 이유 |
|------|-----------|------|
| Entity, VO, Domain Service | 단위 테스트 | 순수 객체, Mock 없이 빠른 피드백 |
| ApplicationService | 통합 테스트 | Repository를 통한 DB 검증(중복 체크, 존재 확인)이 핵심 |
| Facade | 별도 테스트 없음 | 얇은 오케스트레이션 — ApplicationService 통합 + E2E로 커버 |
| Controller | E2E 테스트 | HTTP 요청/응답, 상태 코드, 인증 전체 흐름 검증 |

## 테스트 유틸리티
- `DatabaseCleanUp`: 테스트마다 테이블 정리
- TestContainers: 실제 MySQL, Redis, Kafka 인스턴스 제공
- 테스트 픽스처: `supports/` 모듈
41 changes: 41 additions & 0 deletions .claude/rules/conventions/validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 검증 및 예외 처리

## 검증 위치와 역할

| 위치 | 역할 | 예시 |
|---|---|---|
| Controller (`@Valid`) | Fail-Fast 형식 검증 | `@NotNull`, `@NotBlank`, `@Size`, `@Positive`, `@PositiveOrZero` |
| Entity | 자기 데이터의 모든 비즈니스 검증 | 길이, 범위, 상태 전이 규칙, 불변 조건 |
| ApplicationService | DB 조회가 필요한 검증 | 유일성, 존재 여부, 권한 |

- Controller가 `@Valid`로 Request를 검증하고, `toCommand()`로 Command 변환 후 Facade에 전달
- `@Valid`는 Entity 검증 중 일부를 앞단에서 선처리하는 것 (중복 검증 허용)
- Entity가 검증의 최종 방어선 — Request 검증이 빠져도 Entity에서 반드시 잡아야 함

## Entity의 두 가지 표현: 불변식 강제 vs 사실 제공

### 판별 기준

> **"이 조건이 깨지면 Entity 자체가 유효하지 않은 상태가 되는가?"**
> - Yes → **불변식** → Entity가 예외를 던진다
> - No → **사실 제공** → Entity는 boolean만 반환, 호출자(Facade)가 맥락에 맞게 판단한다

### 역할 비교

| 역할 | Entity 행동 | 판단 주체 | 예시 |
|------|-----------|----------|------|
| 불변식 강제 | 검증 + 예외 (`CoreException`) | Entity | 재고 차감 시 음수 방지, 주문 상품 중복 방지, 이름 빈 문자열 방지 |
| 사실 제공 | boolean 반환 | 호출자 (Facade) | `isOwnedBy()`, `isActive()`, `isExpired()` |

### 접근 제어를 Facade가 판단하는 이유

접근 제어는 유스케이스마다 해석이 달라질 수 있다 (예: 관리자는 소유자 확인 불필요).
따라서 유스케이스를 소유하는 Facade가 판단한다.

## 예외 처리

- 비즈니스 예외는 `CoreException`으로 통일
- `CoreException(ErrorType, message)` 형태로 사용
- 글로벌 핸들러(`@RestControllerAdvice`)에서 일괄 처리
- Controller에서 try-catch 금지
- ErrorType은 HTTP 상태코드와 매핑되는 enum으로 관리 (`BAD_REQUEST`, `NOT_FOUND`, `FORBIDDEN` 등)
12 changes: 12 additions & 0 deletions .claude/rules/conventions/workflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# 구현 워크플로우

## 원칙
- 기능 구현 전 해당 기능의 requirements, spec, design이 있으면 반드시 먼저 읽는다
- spec의 AC와 테스트는 1:1 매핑한다
- 구현 순서: domain → infrastructure → application → interfaces
- 테스트 순서: 단위 → 통합 → E2E
- 컴파일 + 테스트 통과 후 AC 매핑 보고로 마무리한다
- 검증과 커밋은 사용자가 수행한다

## 참고 스킬
- spec 기반 기능 구현 → implement
89 changes: 89 additions & 0 deletions .claude/rules/core/coding-principles.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# 코딩 원칙

**트레이드오프:** 이 가이드라인은 속도보다 **신중함(caution)**에 무게를 둔다. 사소한 작업에는 스스로 판단하라.

## §0. 선호하는 언어

- **한국어(Korean)**로 응답하라. 코드는 예외이다.
- 커밋 메시지 또한 되도록 한글로 명확하게 기능을 설명할 수 있어야 한다.

## §1. 코딩 전에 생각하라

**추측하지 마라. 혼란을 숨기지 마라. 트레이드오프를 드러내라.**

구현하기 전에:
- 더 **단순한 접근법(simpler approach)**이 있다면 말하라. 필요하면 반론을 제기하라.
- **읽기 우선(Read Before Write)**: 수정 대상 코드를 반드시 먼저 읽어라. 읽지 않고 수정하지 마라.
- **환각 금지(No Hallucination)**: 존재하지 않는 API, 패키지, 파일 경로, 설정 옵션을 지어내지 마라. 확실하지 않으면 먼저 확인하라.

## §2. 단순함 우선 (Simplicity First)

**문제를 해결하는 최소한의 코드. 짐작으로 쓴 코드는 금지.**

- 한 번만 쓰이는 코드에 **추상화(abstraction)**를 만들지 마라.
- 요청되지 않은 "유연성"이나 "설정 가능성"을 넣지 마라.
- 발생할 수 없는 시나리오에 대한 **에러 핸들링(error handling)**을 하지 마라.
- 200줄로 썼는데 50줄로 가능하면 다시 작성하라.

자문하라: "시니어 엔지니어가 이거 **오버엔지니어링(over-engineering)**이라고 할까?" 그렇다면 단순화하라.

## §3. 외과적 변경 (Surgical Changes)

**건드려야 할 것만 건드려라. 본인이 남긴 부산물만 정리하라.**

기존 코드를 수정할 때:
- 주변 코드, 주석, 포매팅을 "개선"하지 마라.
- 고장나지 않은 것을 **리팩토링(refactoring)**하지 마라.
- 다르게 할 수 있더라도 **기존 스타일(existing style)**에 맞춰라.
- 관련 없는 **데드코드(dead code)**를 발견하면 언급만 하라 — 삭제하지 마라.

본인의 변경으로 사용되지 않게 된 **import/변수/함수**는 제거하라.

검증 기준: **변경된 모든 라인은 사용자의 요청에 직접 연결**되어야 한다.

## §4. 목표 중심 실행 (Goal-Driven Execution)

**성공 기준을 정의하라. 검증될 때까지 확장 사고(extended thinking)로 자가점검하며 반복하라.**

작업을 **검증 가능한 목표(verifiable goals)**로 변환하라:
- "유효성 검사 추가" → "잘못된 입력에 대한 테스트를 작성하고, 통과시켜라"
- "버그 수정" → "재현하는 테스트를 작성하고, 통과시켜라"
- "X 리팩토링" → "리팩토링 전후로 테스트가 통과하는지 확인하라"

다단계 작업에는 간략한 계획을 제시하라:
```
[단계] → 검증: [확인사항]
[단계] → 검증: [확인사항]
[단계] → 검증: [확인사항]
```

강한 **성공 기준(success criteria)**이 있으면 자율적으로 루프를 돌 수 있다. 약한 기준("되게 해줘")은 끊임없는 확인이 필요하다.

## §5. 점진적 실행 (Incremental Execution)

**대규모 변경을 한 번에 하지 마라. 작은 단위로 나눠서 각 단계마다 검증하라.**

- 여러 파일을 동시에 변경하기보다, 한 단위씩 변경하고 **중간 검증(intermediate verification)**을 수행하라.
- 뭔가 깨졌을 때 원인을 특정할 수 있도록 **변경 범위(blast radius)**를 최소화하라.

## §6. 실패 대응 (Failure Response)

**에러가 나면 원인부터 파악하라. 같은 시도를 반복하지 마라.**

- 에러 발생 시 증상만 고치지 말고 **근본 원인(root cause)**을 분석하라.
- 같은 명령을 재시도하기 전에 왜 실패했는지 먼저 이해하라.
- 방향이 틀렸으면 고치려 하지 말고 과감히 버리고 다시 작성하라. **매몰 비용(sunk cost)**에 집착하지 마라.

## §7. 피드백 반영 (Self-Correction)

**사용자가 실수를 지적하면 기록하라.**

- 1회 지적 → **MEMORY.md**에 교훈을 기록하라.
- 2회 이상 반복 → **`~/.claude/rules/corrections.md`**로 승격하고, 사용자에게 알려라.

기록 포맷:
```
### [금지 행동 한 줄 요약]
상황: [어떤 맥락에서 발생했는지]
교훈: [앞으로 어떻게 해야 하는지]
```
10 changes: 10 additions & 0 deletions .claude/rules/core/decision-making.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# 의사결정 규칙

- AI는 제안하고, 최종 결정은 개발자가 한다
- 요청하지 않은 기능 구현, 테스트 삭제, 반복적 동작 시 즉시 중단하고 보고
- 누락, 불명확, 다수의 유효한 접근법이 있으면 스스로 결정하지 말고 반드시 물어볼 것
- 되돌리기 어려운 결정(아키텍처, DB 스키마, 외부 API 설계)은 반드시 확인받을 것
- 빠른 선택은 AskUserQuestion, 깊은 논의가 필요하면 대화로 풀 것

## 참고 스킬
- 의사결정 판단 기준 → decision-guide
Loading