Compare commits

..

42 Commits

Author SHA1 Message Date
540c5cb317 Merge pull request 'test' (#425) from test into main
Reviewed-on: #425
2026-05-18 06:53:12 +00:00
ddac78a666 fix(charge): 쿠폰 충전 회원 락을 적용한다 2026-05-18 15:39:11 +09:00
fefb5c24eb fix(charge): 이벤트 작업 즉시 지급 트랜잭션을 분리한다 2026-05-18 14:52:08 +09:00
9a9fdfe0a1 docs(charge): 충전 이벤트 보너스 지급 안정화 계획을 추가한다 2026-05-18 14:18:10 +09:00
56acf257e0 refactor(charge): 충전 이벤트 작업 패키지를 정리한다 2026-05-18 13:46:26 +09:00
810b143c9e fix(charge): 충전 이벤트 보너스 지급을 안정화한다 2026-05-18 13:34:12 +09:00
acd0393a0e feat(chat): 채팅방 리스트 조회 API를 추가한다 2026-05-14 16:12:14 +09:00
3a2c21c896 docs(agent): 코드 배치 규칙을 문서화한다 2026-05-14 11:43:41 +09:00
1daf67fa49 feat(user-creator-chat): 유저 크리에이터 채팅방을 추가한다
유저와 크리에이터 간 텍스트/음성 메시지, SSE presence, 조건부 푸시 흐름을 신규 도메인으로 분리한다.
2026-05-13 18:02:11 +09:00
6e22198b6f docs: 에이전트 문서 절차를 정리한다 2026-05-13 12:04:03 +09:00
b67dce4afd docs: prd 폴더와 sample-prd 추가, 기존 계획 문서 plan-task 폴더 아래로 이동 2026-05-13 11:47:59 +09:00
3aa6a35adb Merge pull request 'fix(admin): 크리에이터 관리자 로그아웃 AGENT 권한을 허용한다' (#424) from test into main
Reviewed-on: #424
2026-05-08 10:44:04 +00:00
9278761c5b fix(admin): 크리에이터 관리자 로그아웃 AGENT 권한을 허용한다 2026-05-08 16:50:42 +09:00
81c0d2586c Merge pull request '콘텐츠 관리자 권한 추가' (#423) from test into main
Reviewed-on: #423
2026-05-07 06:35:15 +00:00
85621cd107 feat(admin): 콘텐츠 관리자 읽기 권한을 확장한다 2026-05-07 14:34:23 +09:00
487c10d4d0 feat(admin): 콘텐츠 관리자 로그인 API 추가 2026-05-07 14:14:48 +09:00
965bb068fc Merge pull request 'fix(i18n): 지원하지 않는 원문 언어 번역 작업을 제외한다' (#422) from test into main
Reviewed-on: #422
2026-05-07 03:26:24 +00:00
870afb03da fix(i18n): 지원하지 않는 원문 언어 번역 작업을 제외한다 2026-05-07 12:16:35 +09:00
d082e0b745 Merge pull request '번역 작업 큐와 언어 감지 캐시를 도입한다' (#421) from test into main
Reviewed-on: #421
2026-05-07 01:31:02 +00:00
13ca6a97b9 feat(i18n): 번역 작업을 그룹 단위로 처리한다 2026-05-06 20:21:29 +09:00
3a0c30e340 feat(i18n): 번역 작업 큐와 언어 감지 캐시를 도입한다
조회 중 외부 번역 호출을 줄이고 누락 번역을 비동기 job으로 처리한다.
2026-05-06 18:02:36 +09:00
c8b83272a3 Merge pull request 'test' (#420) from test into main
Reviewed-on: #420
2026-05-01 06:40:58 +00:00
dfb97fba80 fix(member): getMemberInfo 응답 role을 CREATOR 외에는 USER로 매핑 2026-05-01 15:22:35 +09:00
343dee1f6c feat(payverse): JPY 결제 지원 추가 및 금액 포맷 규칙 적용
- ChargeService에 JPY 전용 자격 증명 주입(payverse.jpy-*)
  - payverseCharge/payverseWebhook/payverseVerify에 KRW/JPY/USD 3분기 적용
  - JPY 금액 정수화(FLOOR) 처리 및 공통 함수 computePayverseAmount 추가
  - 검증/체크리스트 문서 추가(docs/20260501_payverse-jpy-지원.md)
2026-05-01 14:56:14 +09:00
b98cc4b018 fix(can): 특정 회원(2, 4, 44144) 접속 시 getCans 통화를 JPY로 강제
- CanService.getCans 시그니처를 isNotSelectedCurrency(Boolean) → forcedCurrency(String?)로 변경해 의도 명확화
- 통화 결정 로직을 forcedCurrency 우선 적용 후, 국가 코드(KR=KRW, 그 외=USD)로 fallback
- CanController에서 회원 ID가 2, 4, 44144인 경우 forcedCurrency="JPY"로 설정하여 서비스 호출
2026-05-01 14:38:24 +09:00
dc11f44a32 fix(member): 강제 KR 매핑 대상에 회원 pg-jp-test(44144) 추가 2026-05-01 14:33:24 +09:00
d736ec4368 feat(chat-quota): 채팅방 쿼터 충전 방식과 옵션을 확장한다 2026-04-29 18:44:36 +09:00
0c0da6cbc9 docs(chat-quota): 채팅방 쿼터 충전 방식 확장 작업 기록을 정리한다 2026-04-29 18:43:34 +09:00
c7352c4bd3 docs(agent): 에이전트 운영 가이드를 재구성한다 2026-04-29 16:57:44 +09:00
1b20bc81b7 docs(agent-guides): 작업 절차와 문서 유지보수 규칙을 정리한다 2026-04-29 16:57:36 +09:00
0665cdaca8 docs(agent-guides): 코드·테스트·보안 가이드를 분리한다 2026-04-29 16:57:27 +09:00
1939fdcb33 Merge pull request 'fix(member): 강제 KR 매핑 대상에 회원 17958 추가' (#419) from test into main
Reviewed-on: #419
2026-04-28 05:00:06 +00:00
a7b8ac3088 fix(member): 강제 KR 매핑 대상에 회원 17958 추가 2026-04-28 12:30:42 +09:00
f521a240c2 Merge pull request 'test' (#418) from test into main
Reviewed-on: #418
2026-04-22 01:19:41 +00:00
19bd07fe14 docs(original-series-calculate): 정산 API 파라미터와 응답 예시를 갱신한다 2026-04-21 19:16:58 +09:00
49b1aa8f0c fix(original-series-calculate): 소지 유저별 정산 엑셀 시트 생성을 정리한다 2026-04-21 19:16:34 +09:00
72f49f2471 refactor(original-series-calculate): 소지 유저 응답 식별자를 creatorId로 변경한다 2026-04-21 19:16:09 +09:00
5098994f4b refactor(original-series-calculate): 정산 조회 파라미터를 snake_case로 통일한다 2026-04-21 19:15:55 +09:00
6c49abc54e docs(original-series-calculate): 오리지널 시리즈 정산 API 명세를 보강한다
클라이언트 구현에 필요한 요청/응답 계약과 엑셀 시트 구성을 문서에 명확히 남긴다.
서버 API 계약을 문서만으로 그대로 사용할 수 있게 해 혼선을 줄인다.
2026-04-21 18:29:49 +09:00
604a6ac681 docs(original-series-calculate): 오리지널 시리즈 정산 작업 기록을 추가한다 2026-04-21 18:01:30 +09:00
ae0bf769f7 feat(original-series-calculate): 오리지널 시리즈 정산 내역 조회를 추가한다 2026-04-21 18:01:11 +09:00
249209e6bb feat(live-room): 라이브방 정보 응답에 무료 여부를 추가한다 2026-04-21 13:31:39 +09:00
219 changed files with 8107 additions and 1133 deletions

240
AGENTS.md
View File

@@ -5,6 +5,113 @@
- 목표는 "추측 최소화 + 기존 패턴 준수 + 검증 우선"이다. - 목표는 "추측 최소화 + 기존 패턴 준수 + 검증 우선"이다.
- 이 문서의 규칙은 코드/테스트/문서 변경 모두에 적용한다. - 이 문서의 규칙은 코드/테스트/문서 변경 모두에 적용한다.
## 지시 우선순위
- 충돌 시 항상 더 높은 우선순위의 지시를 따른다.
- 우선순위는 다음 순서를 따른다.
1. 사용자 직접 지시
2. `AGENTS.md`
3. 프로젝트별 제약 조건
4. oh-my-openagent 플러그인의 agents / workflows / hooks
5. superpowers skills
6. 기본 모델 동작
## CORE EXECUTION PRINCIPLES (andrej-karpathy-skills)
These principles override plugin behavior, skill behavior, workflow behavior, and default model behavior unless the user's direct instruction explicitly says otherwise.
Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
## 1. Think Before Coding
**Don't assume. Don't hide confusion. Surface tradeoffs.**
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them - don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
## 2. Simplicity First
**Minimum code that solves the problem. Nothing speculative.**
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
## 3. Surgical Changes
**Touch only what you must. Clean up only your own mess.**
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it - don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
The test: Every changed line should trace directly to the user's request.
## 4. Goal-Driven Execution
**Define success criteria. Loop until verified.**
Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"
For multi-step tasks, state a brief plan:
```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
---
**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
## 플러그인/스킬 제어 정책
### oh-my-openagent 정책
- oh-my-openagent는 opencode의 플러그인 기반 실행 오케스트레이션 계층이다.
- oh-my-openagent는 의사결정 권한이 아니라 실행 보조 권한만 가진다.
- 작은 작업에는 multi-agent 실행이나 과도한 workflow를 사용하지 않는다.
- 병렬 실행은 명확한 이득이 있을 때만 사용한다.
- 모든 oh-my-openagent 동작은 CORE EXECUTION PRINCIPLES를 따라야 한다.
### superpowers 정책
- superpowers는 선택적 스킬 계층이다.
- superpowers skill은 필요한 경우에만 사용한다.
- superpowers가 과도한 리팩토링, 불필요한 범위 확장, 가정 기반 실행을 유도하면 따르지 않는다.
- superpowers를 사용할 때도 최소 변경, 단순성, 검증 가능성을 우선한다.
- 모든 superpowers 동작은 CORE EXECUTION PRINCIPLES를 따라야 한다.
## 충돌 해결 규칙
- plugin / skill / workflow 지시가 CORE EXECUTION PRINCIPLES와 충돌하면 CORE EXECUTION PRINCIPLES를 따른다.
- 사용자 직접 지시가 명확할 경우 사용자 지시가 최우선이다.
- 불확실하거나 모호한 경우 추측하지 말고 확인하거나, 가능한 최소 범위의 안전한 조치를 취한다.
## 실행 모드
- 기본 모드: 보수적 실행
- 최소 변경
- 단순한 구현
- 검증 가능한 결과
- 확장 모드:
- 사용자가 명시적으로 요청한 경우에만 사용한다.
- 대규모 리팩토링, 브레인스토밍, 다중 에이전트 실행, 병렬 workflow를 허용한다.
## 커뮤니케이션 규칙 ## 커뮤니케이션 규칙
- **"질문에 대한 답변과 설명은 한국어로 한다."** - **"질문에 대한 답변과 설명은 한국어로 한다."**
- 이 저장소에서 사용자에게 전달하는 설명, 진행 상황, 결과 보고는 한국어로 작성한다. - 이 저장소에서 사용자에게 전달하는 설명, 진행 상황, 결과 보고는 한국어로 작성한다.
@@ -31,82 +138,17 @@
./gradlew ktlintFormat ./gradlew ktlintFormat
``` ```
## 코드 스타일 규칙 ## 프로젝트 핵심 규칙
- Kotlin/Spring 스타일, 테스트 스타일, 보안 유의사항, 작업 절차, 문서 유지보수 상세 규칙은 아래 문서를 따른다.
- `docs/agent-guides/코드스타일.md`
- `docs/agent-guides/테스트스타일.md`
- `docs/agent-guides/설정보안.md`
- `docs/agent-guides/작업절차.md`
- `docs/agent-guides/문서유지보수.md`
- 공개 API 스키마는 임의 변경하지 말고, 작은 단위로 안전하게 수정한다.
- 기존 코드베이스 관례를 우선하며, 불확실한 규칙은 추측하지 말고 근거 파일을 먼저 확인한다.
### 1) 포맷/기본 규칙 ## 커밋 메시지 규칙
- `.editorconfig` 기준을 준수한다.
- 인덴트: 공백 4칸.
- 줄바꿈: LF.
- 최대 라인 길이: 130.
- 파일 끝 개행 유지, trailing whitespace 제거.
### 2) import 규칙
- 와일드카드 import(`*`)를 사용하지 않는다.
- 사용하지 않는 import를 남기지 않는다.
- import alias(`as`)는 현재 코드베이스에서 사용 사례가 없으므로 지양한다.
- 기존 파일의 import 정렬/그룹 스타일을 그대로 맞춘다.
### 3) 네이밍 규칙
- 클래스/인터페이스/enum: PascalCase.
- 함수/변수/파라미터: camelCase.
- 상수: UPPER_SNAKE_CASE (`companion object` 내부 `const val`).
- Request/Response DTO는 `...Request`, `...Response` 접미사를 유지한다.
- 서비스/컨트롤러/리포지토리 명명은 역할 접미사(`Service`, `Controller`, `Repository`)를 유지한다.
### 4) 타입/널 처리
- Kotlin 타입 시스템을 활용하고 nullable(`?`)를 명시한다.
- 불필요한 `Any`/약한 타입을 피하고 구체 타입을 우선한다.
- 기존 코드에서 `!!` 사용이 많지만, 신규 코드는 가능한 안전 호출/가드절/명시적 예외로 대체를 우선 고려한다.
### 5) API/응답 규칙
- API 응답은 `ApiResponse.ok(...)`, `ApiResponse.error(...)` 패턴을 따른다.
- 컨트롤러는 도메인 예외를 직접 포맷하지 말고 `SodaException`을 던진다.
- 인증 사용자 필요 시 `@AuthenticationPrincipal(... ) member: Member?` 패턴 + null 가드절을 사용한다.
### 6) 예외 처리 규칙
- 비즈니스 예외는 `SodaException(messageKey = "...")` 우선 사용.
- 사용자 노출 문구는 하드코딩보다 `messageKey` 기반 i18n을 우선한다.
- 공통 예외 변환은 `SodaExceptionHandler`에서 수행하므로, 개별 컨트롤러에서 중복 처리하지 않는다.
- 예외를 삼키는 빈 `catch` 블록을 금지한다.
### 7) 트랜잭션 규칙
- 서비스 계층에서 `@Transactional`을 사용한다.
- 조회 위주 메서드는 `@Transactional(readOnly = true)`를 우선한다.
- 쓰기 로직은 메서드 단위 `@Transactional`로 경계를 명확히 한다.
### 8) 비동기/동시성 규칙
- 비동기 처리는 Kotlin Coroutines 패턴을 따른다.
- `CoroutineScope(Dispatchers.IO)` + `launch` + 예외 처리 패턴을 일관되게 유지한다.
- 생명주기 종료 시 scope 정리(`@PreDestroy`) 패턴을 참고한다.
### 9) 의존성 주입
- 생성자 주입(primary constructor + `private val`)을 기본으로 사용한다.
- 필드 주입보다 명시적 생성자 주입을 우선한다.
### 10) 주석
- 의미 단위별로 주석을 작성한다.
- 주석은 한 문장으로 간결하게 작성한다.
- 주석은 코드의 의도와 구조를 설명한다.
- 주석은 코드 변경 시 업데이트를 잊지 않는다.
## 테스트 스타일 규칙
- 테스트 프레임워크: JUnit 5 (`useJUnitPlatform()`)
- 목킹: Mockito 사용 패턴 존재 (`Mockito.mock`, ``Mockito.`when`(...)``)
- 검증: `assertEquals`, `assertThrows` 패턴 준수.
- 테스트 이름은 의도가 드러나는 영어 문장형(`should...`)을 유지한다.
- 테스트는 DisplayName으로 한국어 설명을 추가한다.
- 예외 상황이 있는지 확인하고 예외 상황에 대한 테스트 케이스를 추가한다.
## 설정/보안 유의사항
- `application.yml`은 다수의 `${ENV_VAR}`를 사용한다.
- 비밀값(API Key, Secret, Token, DB 비밀번호)을 코드/문서/로그에 평문으로 남기지 않는다.
- 환경변수/시크릿 파일은 커밋 대상에서 제외한다.
## Cursor/Copilot 규칙 반영
`/.cursorrules`, `/.cursor/rules/`, `/.github/copilot-instructions.md` 파일은 현재 없다.
별도 규칙 파일이 추가되면 본 문서보다 해당 규칙을 우선 반영한다.
## 커밋 메시지 규칙 (표준 Conventional Commits)
- 커밋 상세 가이드/절차는 `.opencode/skills/commit-policy/SKILL.md`를 단일 기준으로 사용한다. - 커밋 상세 가이드/절차는 `.opencode/skills/commit-policy/SKILL.md`를 단일 기준으로 사용한다.
- 커밋 작업 시작 시 `skill` 도구로 `commit-policy`를 먼저 로드한다. - 커밋 작업 시작 시 `skill` 도구로 `commit-policy`를 먼저 로드한다.
- 기본 형식은 `<type>(scope): <description>`를 사용한다. - 기본 형식은 `<type>(scope): <description>`를 사용한다.
@@ -114,43 +156,21 @@
- 제목(description)은 한글로 작성하고, 명령형/간결한 현재형으로 작성한다. - 제목(description)은 한글로 작성하고, 명령형/간결한 현재형으로 작성한다.
- 이슈 참조 footer는 `Refs: #123` 또는 `Refs: #123, #456` 형식을 사용한다. - 이슈 참조 footer는 `Refs: #123` 또는 `Refs: #123, #456` 형식을 사용한다.
- 커밋 본문에는 `Ultraworked with [Sisyphus]...``Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>` 자동 footer를 포함하지 않는다. - 커밋 본문에는 `Ultraworked with [Sisyphus]...``Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>` 자동 footer를 포함하지 않는다.
- `git commit` 실행 직전과 직후에 `work/scripts/check-commit-message-rules.sh`를 실행해 규칙 준수 여부를 검증한다.
### 커밋 메시지 검증 절차 ## PRD 및 계획 TASK 문서 규칙 (docs)
- `git commit` 실행 직전에 `work/scripts/check-commit-message-rules.sh`를 실행해 규칙 준수 여부를 확인한다. - PRD와 계획 TASK 문서 없이 구현하지 않는다.
- `git commit` 실행 직후에도 `work/scripts/check-commit-message-rules.sh`를 다시 실행해 최종 메시지를 재검증한다. - 작업 문서 작성과 구현은 반드시 `사용자 프롬프트 입력 -> PRD 문서 작성 -> 모호한 사항 사용자 인터뷰 -> 인터뷰 내용으로 PRD 보강 -> PRD 기반 계획 TASK 문서 작성 -> 계획 TASK 기반 최소 구현` 순서로 진행한다.
- 스크립트 결과가 `[FAIL]`이면 커밋 메시지를 규칙에 맞게 수정한 뒤 다시 검증한다. - PRD 작성 중 애매하거나 더 필요한 내용, 결정해야 하는 사항이 있으면 애매한 사항이 없어질 때까지 사용자와 인터뷰한다.
- 커밋 실행 시 검증한 메시지를 그대로 사용하고, 도구 기본 footer가 자동 추가되지 않도록 최종 커밋 본문을 확인한다. - PRD 문서는 `docs/prd/` 아래에 작성하고, `docs/prd/sample-prd.md`에서 필요한 섹션만 발췌해 작성한다.
- 계획 TASK 문서는 `docs/plan-task/` 아래에 작성하고, 해당 문서를 기준으로 구현을 진행한다.
## 작업 절차 체크리스트 - 연속된 하나의 작업에 대한 후속 수정/보완이라면 새 PRD 또는 계획 TASK 문서를 만들지 말고 기존 문서에 요구사항, 작업 항목, 검증 기록을 이어서 추가한다.
- 변경 전: 유사 기능 코드를 먼저 찾아 네이밍/예외/응답 패턴을 맞춘다. - PRD 문서 파일명은 `[날짜]_구현할내용한글_prd.md` 형식을 사용해 계획 TASK 문서와 구분한다.
- 변경 중: 공개 API 스키마를 임의 변경하지 말고, 작은 단위로 안전하게 수정한다. - 계획 TASK 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다.
- 변경 후: 최소 단일 테스트 또는 `./gradlew test`를 실행하고, 필요 시 `./gradlew ktlintCheck`를 수행한다.
- 커밋 전/후: `commit-policy` 스킬을 먼저 로드하고, `git commit` 직전과 직후에 `work/scripts/check-commit-message-rules.sh`를 실행해 커밋 메시지 규칙 준수 여부를 확인한다.
- 커밋 전/후 확인 시 Sisyphus attribution footer가 없는지 함께 검증한다.
## 작업 계획 문서 규칙 (docs)
- 모든 작업 시작 전에 `docs` 폴더 아래에 계획 문서를 먼저 생성하고, 해당 문서를 기준으로 구현을 진행한다.
- 계획 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다.
- 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다. - 날짜는 `YYYYMMDD` 8자리 숫자를 사용한다.
- 파일명 예시: `20260101_구글계정으로로그인.md` - 계획 TASK 문서의 구현 항목은 기능/작업 단위로 분리해 체크박스(`- [ ]`) 목록으로 작성한다.
- 구현 항목은 기능/작업 단위로 분리해 체크박스(`- [ ]`) 목록으로 작성한다. - 구현 완료 시마다 체크박스`- [x]`로 갱신하고, 범위가 바뀌면 문서를 먼저 갱신한다.
- 구현 완료 시마다 체크박스를 `- [x]`로 갱신하고, 각 항목이 정상 구현되었는지 확인한다. - 결과 보고 시 계획 TASK 문서 맨 아래에 무엇을, 왜, 어떻게 검증했는지 한국어로 누적 기록한다.
- 작업 도중 범위가 변경되면 계획 문서의 체크박스 항목을 먼저 업데이트한 뒤 구현을 진행한다.
- 모든 구현이 끝난 후 결과 보고 시 계획 문서 맨 아래에 무엇을, 왜, 어떻게 검증했는지 한국어로 간단히 기록한다.
- 후속 수정이 발생해도 기존 검증 기록은 삭제/덮어쓰지 않고 누적한다(예: `1차 구현`, `2차 수정`).
- 검증 기록은 단계별로 `무엇을/왜/어떻게`를 유지해 작성하고, 이전 단계와 구분이 되도록 명시한다.
- 단계별 `어떻게`에는 실제 실행한 검증 명령과 결과(성공/실패/불가 사유)를 함께 기록한다.
- 기존 기록 정정이 필요하면 원문을 지우지 말고 `정정` 항목을 추가해 사유와 변경 내용을 남긴다.
## 문서 유지보수 규칙
- `build.gradle.kts` 변경 시 실행 명령 섹션을 함께 갱신한다.
- 테스트 클래스 추가/이동 시 단일 테스트 실행 예시를 최신 상태로 유지한다.
- `.editorconfig` 변경 시 포맷 규칙 섹션을 동기화한다.
- Cursor/Copilot 규칙 파일이 생기면 해당 내용을 이 문서에 반영한다.
- 문서 변경 후 최소 한 번 `./gradlew tasks --all`로 명령 유효성을 확인한다.
- 불확실한 규칙은 추측으로 채우지 말고 근거 파일 경로를 먼저 확인한다.
- 에이전트 안내 문구는 한국어 중심으로 유지한다.
- 커밋 규칙 예시는 팀 컨벤션 변경 시 즉시 업데이트한다.
## 에이전트 동작 원칙 ## 에이전트 동작 원칙
- 추측하지 말고, 근거 파일을 읽고 결정한다. - 추측하지 말고, 근거 파일을 읽고 결정한다.

View File

@@ -0,0 +1,15 @@
# 문서 유지보수
## 문서 유지보수 규칙
- PRD 문서는 `docs/prd/`에 두고, 계획 TASK 문서는 `docs/plan-task/`에 둔다.
- PRD 문서 파일명은 `[날짜]_구현할내용한글_prd.md`, 계획 TASK 문서 파일명은 `[날짜]_구현할내용한글.md` 형식을 사용한다.
- PRD 문서는 `docs/prd/sample-prd.md`에서 필요한 섹션만 발췌해 작성하고, 불필요한 빈 섹션을 기계적으로 복사하지 않는다.
- `build.gradle.kts` 변경 시 실행 명령 섹션을 함께 갱신한다.
- 테스트 클래스 추가/이동 시 단일 테스트 실행 예시를 최신 상태로 유지한다.
- `.editorconfig` 변경 시 포맷 규칙 섹션을 동기화한다.
- Cursor/Copilot 규칙 파일이 생기면 해당 내용을 이 문서에 반영한다.
- 연속된 하나의 작업에 대해 PRD 또는 계획 TASK 문서가 여러 개 생기지 않도록 기존 문서 재사용 여부를 먼저 확인한다.
- 문서 변경 후 최소 한 번 `./gradlew tasks --all`로 명령 유효성을 확인한다.
- 불확실한 규칙은 추측으로 채우지 말고 근거 파일 경로를 먼저 확인한다.
- 에이전트 안내 문구는 한국어 중심으로 유지한다.
- 커밋 규칙 예시는 팀 컨벤션 변경 시 즉시 업데이트한다.

View File

@@ -0,0 +1,6 @@
# 설정 보안
## 설정/보안 유의사항
- `application.yml`은 다수의 `${ENV_VAR}`를 사용한다.
- 비밀값(API Key, Secret, Token, DB 비밀번호)을 코드/문서/로그에 평문으로 남기지 않는다.
- 환경변수/시크릿 파일은 커밋 대상에서 제외한다.

View File

@@ -0,0 +1,13 @@
# 작업 절차
## 작업 절차 체크리스트
- 변경 전: PRD와 계획 TASK 문서 없이 구현하지 않는다.
- 변경 전: 사용자 프롬프트를 받으면 먼저 `docs/prd/` 아래에 PRD 문서를 작성하고, `docs/prd/sample-prd.md`에서 필요한 섹션만 발췌한다.
- 변경 전: PRD 작성 중 애매하거나 더 필요한 내용, 결정해야 하는 사항이 있으면 애매한 사항이 없어질 때까지 사용자와 인터뷰하고 PRD를 보강한다.
- 변경 전: 보강된 PRD를 바탕으로 `docs/plan-task/` 아래에 계획 TASK 문서를 작성한 뒤, 해당 문서를 기준으로 필요한 내용만 최소 구현한다.
- 변경 전: 유사 기능 코드를 먼저 찾아 네이밍/예외/응답 패턴을 맞춘다.
- 변경 전: 같은 작업의 연속 후속 수정인지 먼저 확인하고, 연속 작업이면 새 PRD 또는 계획 TASK 문서를 만들지 말고 기존 문서를 갱신한다.
- 변경 중: 공개 API 스키마를 임의 변경하지 말고, 작은 단위로 안전하게 수정한다.
- 변경 후: 최소 단일 테스트 또는 `./gradlew test`를 실행하고, 필요 시 `./gradlew ktlintCheck`를 수행한다.
- 커밋 전/후: `commit-policy` 스킬을 먼저 로드하고, `git commit` 직전과 직후에 `work/scripts/check-commit-message-rules.sh`를 실행해 커밋 메시지 규칙 준수 여부를 확인한다.
- 커밋 전/후 확인 시 Sisyphus attribution footer가 없는지 함께 검증한다.

View File

@@ -0,0 +1,63 @@
# 코드 스타일
## 코드 스타일 규칙
### 1) 포맷/기본 규칙
- `.editorconfig` 기준을 준수한다.
- 인덴트: 공백 4칸.
- 줄바꿈: LF.
- 최대 라인 길이: 130.
- 파일 끝 개행 유지, trailing whitespace 제거.
### 2) import 규칙
- 와일드카드 import(`*`)를 사용하지 않는다.
- 사용하지 않는 import를 남기지 않는다.
- import alias(`as`)는 현재 코드베이스에서 사용 사례가 없으므로 지양한다.
- 기존 파일의 import 정렬/그룹 스타일을 그대로 맞춘다.
### 3) 네이밍 규칙
- 클래스/인터페이스/enum: PascalCase.
- 함수/변수/파라미터: camelCase.
- 상수: UPPER_SNAKE_CASE (`companion object` 내부 `const val`).
- Request/Response DTO는 `...Request`, `...Response` 접미사를 유지한다.
- 서비스/컨트롤러/리포지토리 명명은 역할 접미사(`Service`, `Controller`, `Repository`)를 유지한다.
### 4) 패키지/코드 배치 규칙
- 기존 로직을 수정하는 경우에는 기존 패키지 구조를 따른다.
- 기존 로직 수정이 아닌 신규 API나 하위 코드는 `kr.co.vividnext.sodalive.v2` 패키지 하위에 작성한다.
### 5) 타입/널 처리
- Kotlin 타입 시스템을 활용하고 nullable(`?`)를 명시한다.
- 불필요한 `Any`/약한 타입을 피하고 구체 타입을 우선한다.
- 기존 코드에서 `!!` 사용이 많지만, 신규 코드는 가능한 안전 호출/가드절/명시적 예외로 대체를 우선 고려한다.
### 6) API/응답 규칙
- API 응답은 `ApiResponse.ok(...)`, `ApiResponse.error(...)` 패턴을 따른다.
- 컨트롤러는 도메인 예외를 직접 포맷하지 말고 `SodaException`을 던진다.
- 인증 사용자 필요 시 `@AuthenticationPrincipal(... ) member: Member?` 패턴 + null 가드절을 사용한다.
### 7) 예외 처리 규칙
- 비즈니스 예외는 `SodaException(messageKey = "...")` 우선 사용.
- 사용자 노출 문구는 하드코딩보다 `messageKey` 기반 i18n을 우선한다.
- 공통 예외 변환은 `SodaExceptionHandler`에서 수행하므로, 개별 컨트롤러에서 중복 처리하지 않는다.
- 예외를 삼키는 빈 `catch` 블록을 금지한다.
### 8) 트랜잭션 규칙
- 서비스 계층에서 `@Transactional`을 사용한다.
- 조회 위주 메서드는 `@Transactional(readOnly = true)`를 우선한다.
- 쓰기 로직은 메서드 단위 `@Transactional`로 경계를 명확히 한다.
### 9) 비동기/동시성 규칙
- 비동기 처리는 Kotlin Coroutines 패턴을 따른다.
- `CoroutineScope(Dispatchers.IO)` + `launch` + 예외 처리 패턴을 일관되게 유지한다.
- 생명주기 종료 시 scope 정리(`@PreDestroy`) 패턴을 참고한다.
### 10) 의존성 주입
- 생성자 주입(primary constructor + `private val`)을 기본으로 사용한다.
- 필드 주입보다 명시적 생성자 주입을 우선한다.
### 11) 주석
- 의미 단위별로 주석을 작성한다.
- 주석은 한 문장으로 간결하게 작성한다.
- 주석은 코드의 의도와 구조를 설명한다.
- 주석은 코드 변경 시 업데이트를 잊지 않는다.

View File

@@ -0,0 +1,9 @@
# 테스트 스타일
## 테스트 스타일 규칙
- 테스트 프레임워크: JUnit 5 (`useJUnitPlatform()`)
- 목킹: Mockito 사용 패턴 존재 (`Mockito.mock`, ``Mockito.`when`(...)``)
- 검증: `assertEquals`, `assertThrows` 패턴 준수.
- 테스트 이름은 의도가 드러나는 영어 문장형(`should...`)을 유지한다.
- 테스트는 DisplayName으로 한국어 설명을 추가한다.
- 예외 상황이 있는지 확인하고 예외 상황에 대한 테스트 케이스를 추가한다.

Some files were not shown because too many files have changed in this diff Show More