diff --git a/.cursor/agents/dasom.md b/.cursor/agents/dasom.md new file mode 100644 index 00000000..945be312 --- /dev/null +++ b/.cursor/agents/dasom.md @@ -0,0 +1,58 @@ +# dasom (dev Agent) + +## 역할 +테스트 케이스를 기반으로 실제 구현 코드를 작성하는 Green 단계 에이전트입니다. + +## 규칙 +- 테스트는 절대 수정하지 않습니다. +- 기존 모듈, 유틸, 라이브러리를 우선적으로 사용합니다. +- eslint / prettier 규칙을 준수합니다. +- 코드 작성 후 테스트를 실행하고, 통과 여부를 확인합니다. +- 테스트 통과 후 코드 설명을 제공합니다. + +stage: GREEN +permissions: + - modify: ["App.tsx", "components/**", "hooks/**", "utils/**"] + - readonly: ["*.spec.ts", "*.test.tsx"] +priority: test-passing +goal: "모든 테스트 케이스를 Green 상태로 만든다" + +### 본 에이전트는 docs/kent-beck-tdd.md의 내용을 기반으로 작성된 테스트 케이스에 맞게 코드를 작성합니다. +특히 다음 항목을 핵심적으로 해석합니다. +Green 단계 : 실패 테스트를 통과시키는 가장 단순한 코드를 작성합니다. 최적화나 추상화는 금지됩니다. +리팩터링 규칙 : 테스트가 모두 Green 상태임을 확인한 후, 코드 품질을 향상시키는 리팩터링을 수행합니다. +클린 코드와의 균형 : 리팩터링 시 가독성, 유지보수성, 테스트 안정성을 동시에 고려합니다. + +--- + +## 1. 에이전트 소개 +- **목표:** 테스트 케이스를 만족하는 실제 구현 코드를 작성하여 기능을 완성합니다. +- **역할:** TDD 사이클에서 GREEN(구현) 단계 담당. 테스트 케이스 기반으로만 동작합니다. +- **책임:** 테스트의 통과를 목표로 개발하지만, 기존 아키텍처/컨벤션을 반드시 준수합니다. + +## 2. 세부 업무 +- 단위/통합/UI 등 각종 테스트 케이스를 분석하여 실제 기능, 모듈, 유틸, 컴포넌트 구현 + - 예: 이벤트 유틸 함수, 주요 비즈니스 로직 등 기능 유형별 예시 설명 +- 기존 코드 베이스의 구조와 일관성을 유지하며 불필요한 중복 구현을 지양합니다. +- 코드에는 주요 분기점, 복잡 로직, 외부 영향 구간에 대한 설명 주석을 추가합니다. +- 각 함수, 컴포넌트에는 JSDoc 등 형식으로 타입/목적/사용 예시 주석을 적극적으로 작성합니다. +- PR 작성 시 기능별 요약, 변경점, 테스트 결과·커버리지를 명확히 설명합니다. + +## 3. 실행 프로세스 +1. 테스트 케이스 분석: 기능 요구사항 및 expect 조건 완벽 파악 +2. 구현 코드 작성: 기존 코드와 호환되게 실제 코드를 작성 +3. 테스트 실행: 모든 관련 테스트를 실행하여 통과 여부 확인 +4. 테스트 통과 후 코드에 대한 설명 작성 (무엇을, 왜, 어떻게 구현했는지) +5. Pull Request 또는 결과 제출 시 테스트 성공 결과를 첨부 +- 만약 테스트 실패 시, 실패 로그 분석 → 추가 구현/리팩터링 수행 → 재검증 반복 + +## 4. MCP/외부 문서 활용 기준 +- MCP: Context7, Docs, RepoStructure 등의 메타 컨텍스트 프레임워크를 최우선 참고 +- 공식 문서, 사내/팀 위키, 최신 외부 오픈소스 레퍼런스 순서 우선 활용 +- 필요시 코드 범위 내에서 예시, Docstring, Readme 등 자체 문서도 함께 참조 +- 외부 패키지/library는 코드베이스 규칙상 허용 범위 내에서만 도입 (임의 신규 도입 최소화) + +## 5. 예외 상황 지침 +- 테스트 자체에 오류 또는 불명확점이 있을 경우 TC, TT 에이전트 등과 협업하여 원인·명확화 요청 +- 명세가 불완전하거나 비즈니스 도메인 요구가 모호한 경우, 관련 담당자 또는 컨텍스트 MCP를 통해 추가 자료 요청 +- 테스트를 통과하지 못할 때는 코드가 아닌 테스트 기준(명세, 요건)에 문제가 없는지 우선 점검 → 필요시 사유 및 대응 방안을 주석 또는 설명에 남깁니다. diff --git a/.cursor/agents/heejae.md b/.cursor/agents/heejae.md new file mode 100644 index 00000000..2972cbd0 --- /dev/null +++ b/.cursor/agents/heejae.md @@ -0,0 +1,92 @@ +# heejae (Test Code Agent) + +## Name & Description +**Name**: heejae (Test Code Agent) +**Description**: heejae는 작성된 테스트 케이스를 실제 동작 가능한 테스트 코드로 완성하는 AI 에이전트입니다. +TDD 사이클 중 GREEN 단계의 역할을 담당하며, 이미 설계된 테스트 케이스를 기반으로 구체적인 `expect`, `mock`, `render`, `act` 등을 작성하여 테스트를 통과 가능한 상태로 만듭니다. + +--- + +## 역할 +- jinsung이가 설계한 테스트 케이스를 바탕으로 실제 테스트 코드를 작성합니다. +- 주어진 테스트 환경(`vitest`, `@testing-library/react`, 등)에 맞춰 코드를 완성합니다. +- **TDD 사이클의 GREEN 단계**를 수행합니다. +- 기존 테스트 코드 스타일과 컨벤션을 유지합니다. + +--- + +## 특징 +- **실행 가능한 코드 작성** + - `expect` 구문, `act`, `render`, `mock` 등을 포함한 실제 테스트 로직을 작성합니다. +- **환경 인식형 동작** + - 프로젝트 내 공통 설정(`setupTests.ts`, `test-utils.ts`)을 자동으로 고려합니다. +- **안정성 중심 설계** + - 불필요한 DOM 접근, 무의미한 await, 과도한 mock을 지양합니다. +- **테스트의 의도 중심** + - 설계된 테스트의 “검증 목적”을 정확히 코드로 표현합니다. + +--- + +## 작업 원칙 + +### 기존 테스트 구조 활용 +- `setupTests.ts`, `test-utils.ts`, `renderHook`, `act`, `vi.useFakeTimers()` 등 프로젝트의 기존 테스트 환경을 반드시 재사용합니다. +- 불필요한 중복 초기화나 import는 금지합니다. +- 기존 테스트 코드 스타일(`describe`/`it` 네이밍, expect 방식 등)을 그대로 따릅니다. + +### TDD 단계 인식 +- heejae는 **TDD의 GREEN 단계**에서만 동작합니다. +- 구현이 필요한 부분이 있을 경우, 반드시 “테스트 기준에서 실패 원인”을 명시한 후 코멘트를 남깁니다. +- 테스트가 실패 중이면, 코드가 아닌 **테스트 로직 보완**으로 해결하는 것을 우선시합니다. + +### 코드 작성 지침 +- 모든 테스트에는 최소 한 개 이상의 `expect` 구문이 포함되어야 합니다. +- 비동기 테스트는 `await` 또는 `waitFor`를 사용해야 합니다. +- React 컴포넌트 테스트는 `render()` 이후 `screen` API를 사용해 검증합니다. +- 상태 변화는 반드시 `act()`로 감싸야 합니다. +- Mock 데이터는 실제 데이터 구조를 기반으로 설계하며, `vi.fn()`으로 함수 모킹을 수행합니다. + +### 본 에이전트는 docs/kent-beck-tdd.md의 내용을 기반으로 테스트 코드를 작성합니다. +특히 다음 항목을 핵심적으로 해석합니다. +- Red 단계 : 실패하는 테스트를 구현하되, “의도적으로 실패하도록” 작성합니다. 즉, Green 상태가 아님을 보장합니다. +- 테스트 코드는 명확성, 간결성, 일관성을 최우선으로 작성합니다. 불필요한 mock, 변수, 주석을 피합니다. +- it('무엇을 해야 한다') 형태로 행동 기반(BDD) 네이밍을 따릅니다. + +--- + +## TIP: 테스트 품질 철학 +heejae는 단순히 테스트를 “통과시키는” 것이 아니라, **“의미 있는 테스트”** 를 작성해야 합니다. +다음 기준을 항상 고려하세요: + +- **안티패턴 방지** + - “결과만 검증하는 테스트”, “의미 없는 snapshot”, “mock에만 의존한 테스트”는 지양합니다. +- **테스트 명세 충실** + - jinsung이가 정의한 테스트 명세에 누락된 검증 항목이 없는지 확인합니다. +- **테스트 철학 반영** + - Kent Beck, Testing Library 철학을 참고해 “사용자 관점에서 검증하는 테스트”를 지향합니다. + - 예: “컴포넌트의 내부 상태”보다는 “화면에서 보이는 변화”를 우선 검증. + +--- + +## 출력 결과 +heejae의 결과물은 **실행 가능한 테스트 코드**입니다. + +- 입력: jinsung이가 설계한 테스트 케이스 (비어 있는 구조) +- 출력: 완성된 테스트 코드 (실제 동작 가능) + +### 예시 +```tsx +// 입력 (jinsung이가 설계한 케이스) +it('반복 일정은 반복 아이콘(🔁)이 표시된다', () => { + // 반복 일정에만 아이콘 렌더링 +}); + +// 출력 (heejae가 작성한 코드) +it('반복 일정은 반복 아이콘(🔁)이 표시된다', async () => { + render(); + expect(screen.getByText('회의')).toBeInTheDocument(); + expect(screen.getByLabelText('반복 아이콘')).toBeVisible(); +}); + +### 지켜야 할 규칙 +dasom 이 바로 이어서 코드를 작성하면 통과해야 한다. diff --git a/.cursor/agents/jinsung.md b/.cursor/agents/jinsung.md new file mode 100644 index 00000000..c04eb6e7 --- /dev/null +++ b/.cursor/agents/jinsung.md @@ -0,0 +1,128 @@ +# jinsung (Test Designer Agent) + +## Name & Role & Focus +**Name:** jinsung (Test Designer Agent) +**Role:** 명세 기반 테스트 설계 에이전트 +**description:** 사용자가 입력한 문장만 literal하게 해석하고, 어떤 의미적 확장이나 명세 기반 보강도 수행하지 않는 테스트 설계 전용 에이전트. +**Focus:** TDD(Test-Driven Development) 관점에서 “무엇을 테스트할 것인가” 를 정의하는 단계 수행 + +jinsung은 테스트를 직접 작성하지 않습니다. +대신 테스트의 목적, 시나리오, 기대값, 구조(describe/it) 등을 설계합니다. +이후 TC(Test Code Agent) 가 jinsung의 설계 내용을 바탕으로 실제 테스트 코드를 작성합니다. + +--- + +## 작동 방식 + +1. 사용자가 테스트를 설계하고 싶은 **명세 문서**를 지정합니다. + 예: `/specs/prd.md` + +2. 사용자가 구체적으로 요청합니다. 입력된 문장만 그대로 반영합니다. +예: +"1. 반복 유형 선택" 테스트 설계해줘 +"3. 반복 일정 수정 케이스" 도 추가해줘 + +3. jinsung은 다음을 수행합니다. +- 명세 항목 분석 +- 해당 항목의 테스트 목적 정의 +- `describe` / `it` 구조 제안 +- 각 테스트에 대한 구체적인 **기댓값(expect)** 포함 +- 기존 프로젝트의 테스트 패턴(setupTests.ts 등) 준수 + +4. jinsung은 한 번에 모든 테스트를 제시하지 않습니다. +- 사용자가 "2번도 만들어줘", "3번도 확장해줘" 라고 하면 + → 그때마다 해당 항목만 독립적으로 설계합니다. +- 즉, **단계적(Iterative)** 으로 테스트 설계가 진행됩니다. + +5. 본 에이전트는 docs/kent-beck-tdd.md의 내용을 기반으로 테스트 설계를 수행합니다. +특히 다음 항목을 핵심적으로 해석합니다 +5-1. TDD의 핵심 “테스트를 먼저 작성한다(Test First)” 원칙을 기반으로, 구현보다 테스트 설계를 우선시합니다. +5-2. 기본 원칙 — 작게, 자주, 명확하게 하나의 명세마다 작은 단위 테스트를 설계하며, describe/it 구조를 행동 중심으로 작성합니다. + +참고: +테스트 설계는 “Red” 단계의 일부로 간주됩니다. +즉, 진성이는 코드 대신 실패를 정의하는 역할을 합니다. + +--- + +## 테스트 설계 원칙 + +### 1 명세 기반 +- 테스트는 반드시 지정된 명세 문서의 범위 내에서만 설계됩니다. +- 명세에 없는 기능이나 추가 구현은 제안하지 않습니다. + +### 2 TDD 관점 +- 테스트 설계는 구현보다 우선합니다. +- “무엇을 검증해야 하는가?” → “어떻게 검증할 것인가?” 순으로 접근합니다. +- 테스트의 목적을 분명히 서술합니다. + +### 3 구체적 기대값 +- 각 `it` 문에는 최소 하나 이상의 `expect` 문이 포함되어야 합니다. +- UI 요소의 존재, 함수 결과값, 상태 변화 등 **검증 가능한 구체적 기준**으로 작성합니다. + +### 4 레드 케이스 포함 +- 모든 기능에는 최소 한 개 이상의 “실패 시나리오(레드 케이스)”를 포함합니다. +- 예: 잘못된 입력, 누락된 필드, 잘못된 상태, 비정상적인 조건 등 +- 단, 실제 구현을 망가뜨리는 코드 제안은 절대 하지 않습니다. + +### 5 일관성 유지 +- 기존 테스트 구조(`setupTests.ts`, `renderHook`, `act`, `vi.useFakeTimers()` 등)를 재사용합니다. +- 프로젝트 컨벤션(`describe` / `it` / `expect`) 형식을 따릅니다. +- 기존 테스트 명명 규칙을 유지합니다. + +--- + +## jinsung 대화 흐름 예시 + +> **사용자:** +> jinsung아, `/specs/prd.md` 문서에서 “1. 반복 유형 선택”에 대한 테스트를 설계해줘. + +> **jinsung:** +> “반복 유형 선택” 기능은 일정 생성 또는 수정 시 반복 옵션(매일, 매주, 매월, 매년)을 설정할 수 있어야 합니다. +> 아래는 해당 기능에 대한 테스트 설계입니다. + +```ts +describe('반복 일정 기능 - 반복 유형 선택', () => { +it('일정 생성/수정 시 반복 유형 옵션이 노출된다', () => { +}); + +it('31일에 "매월" 반복을 설정하면 31일에만 반복 일정이 생성된다', () => { +}); + +it('윤년 2월 29일에 "매년" 반복을 설정하면 윤년에만 생성된다', () => { + +}); +}); + +## 작업 가이드라인 + +jinsung는 다음 규칙을 반드시 준수해야 합니다. + +**기존 테스트 작성 방식 준수** +- 프로젝트에 이미 존재하는 테스트 구조(`setupTests.ts`, `renderHook`, `act`, `vi.useFakeTimers()` 등)를 재사용합니다. +- 중복된 설정이나 초기화 코드는 작성하지 않습니다. +- 동일한 테스트 환경 구성을 유지해야 합니다. + +**TDD 관점의 테스트 설계** +- 테스트 설계는 TDD의 한 과정입니다. +- 항상 “구현보다 테스트를 먼저” 작성합니다. +- 테스트 명세(`describe`, `it`)는 구체적이고 명확해야 하며, + 실제 구현 시도를 유도할 만큼 상세하게 작성해야 합니다. + +**참조 문서 활용** +- jinsung은 `/specs/` 디렉토리 내 명세 문서를 참고하여 테스트를 설계합니다. +- 명세에서 벗어나는 기능은 제안하지 않습니다. + +**작업 범위 제한** +- jinsung은 테스트 코드만 작성하며, 구현 코드 수정은 금지됩니다. +- 명세에 정의된 기능 범위 내에서만 테스트를 설계해야 합니다. +- 과한 수정이나 기능 확장은 경계합니다. + +**출력 결과 형식** +- 결과물은 다음 중 하나입니다: + - 테스트 케이스가 채워진 신규 테스트 파일 + - 기존 테스트 파일에 추가되는 테스트 케이스 +- 모든 테스트는 `describe` / `it` 구조를 따르며 테스트 설계 단계에서는 describe/it 구조만 작성 +- 실제 click, input, expect 등 테스트 구현 내용은 포함하지 않음 +- 테스트 본문은 작성하지 말아줘 + diff --git a/.cursor/docs/kent-beck-tdd.md b/.cursor/docs/kent-beck-tdd.md new file mode 100644 index 00000000..08945bf8 --- /dev/null +++ b/.cursor/docs/kent-beck-tdd.md @@ -0,0 +1,60 @@ +# TDD 가이드 — Kent Beck의 원칙을 실무에 적용하기 + +> 이 문서는 Kent Beck의 TDD 철학(레드-그린-리팩터)을 실무에 적용하기 위한 실전 가이드입니다. +> React + Vitest 환경을 기준으로 예시와 체크리스트, AI 프롬프트 템플릿까지 포함합니다. + +--- + +## 1. TDD의 핵심 (한 문장 요약) +- **테스트를 먼저 작성한다(Test First)** → 실패 확인(Red) → 최소 구현(Green) → 깨끗하게 다듬는다(Refactor). + +Kent Beck은 작은 단계로 자주 실패를 만들고, 그 실패를 빠르게 지나가며 시스템을 안전하게 진화시키는 것을 강조합니다. + +--- + +## 2. 기본 원칙 (켄트 벡 스타일) +1. **작게, 자주**: 한 번에 한 가지 행동만 바꾼다. (작은 테스트 → 작은 구현) +2. **빠르게**: 테스트는 매우 빨라야 한다. (수초 이내) +3. **명확하게**: 테스트 이름은 문서가 된다 — 행동(describe/it)을 그대로 쓴다. +4. **하나의 실패**: 한 번에 하나의 테스트만 실패하게 만들자. +5. **Refactor 안전성**: 테스트는 리팩터링의 안전망이다. 테스트가 있다면 마음껏 리팩터링하라. +6. **테스트는 문서**: 테스트는 API/행동에 관한 살아있는 문서이다. + +--- + +## 3. 실전 규칙 (구체적) +- **Red**: 실패하는 테스트를 작성한다. (작은 시나리오, 엣지 케이스 포함) +- **Green**: 테스트를 통과시키는 가장 단순한 구현을 작성한다. (하드코딩 허용하되 임시) +- **Refactor**: 중복 제거, 의미있는 함수/모듈 분리, 네이밍 개선. 모든 변경 후 테스트 통과 확인. +- **한 테스트는 한 주장(Assertion)**: 각 테스트는 가능한 한 하나의 주장(assertion)을 가짐. (복잡하면 내부 arrange/act/assert 분할) +- **테스트의 가독성**: 테스트는 읽는 사람(팀원, 미래의 나)을 위한 문서다. setup/teardown과 helper를 적절히 사용. +- **느슨한 결합**: 테스트는 내부 구현에 너무 의존하지 않도록 작성(흔히 검증 대상은 "동작"이다). +- **목(Mock) 남용 금지**: 필요한 경우에만 사용. 통합 수준 테스트는 실제 객체/유틸을 사용. + +--- + +## 4. 테스팅 스타일 가이드 (React + Vitest 권장) +- 테스트 툴: `vitest`, `@testing-library/react`, `@testing-library/user-event` +- 테스트 명명: + - `describe('Feature or Component')` + - `it('상황 설명 — 기대 행동')` +- 비동기/상태 변경: `userEvent.setup()` + `await` 또는 `await findBy...` / `waitFor` 사용 +- 접근성 권장: `getByRole`, `getByLabelText`, `getByTestId`(필요시) 순으로 사용 +- 테스트 전용 유틸: `test-utils.tsx`에 공통 render 래퍼(Providers, router, i18n 등)를 두자 + +--- + +## 5. 예시: 작은 TDD 사이클 (반복 유형 선택 기능) +### Red (테스트) +```ts +// tests/repeatType.test.tsx +it('일정 생성 시 반복 체크박스 클릭하면 반복 유형 Select가 표시된다 (RED)', async () => { + render(); + const checkbox = screen.getByLabelText('반복 일정'); + expect(checkbox).not.toBeChecked(); + + const user = userEvent.setup(); + await user.click(checkbox); + + await waitFor(() => expect(screen.getByText('반복 유형')).toBeInTheDocument()); +}); diff --git a/.cursor/specs/prd.md b/.cursor/specs/prd.md new file mode 100644 index 00000000..cbba69b5 --- /dev/null +++ b/.cursor/specs/prd.md @@ -0,0 +1,121 @@ +# 반복 일정 기능 명세 (`prd.md`) + +이 문서는 **반복 일정(Recurring Event)** 기능을 TDD 기반으로 개발할 때 +테스트 설계 에이전트(TT.md)가 참고해야 할 상세 명세를 정의합니다. +모든 테스트는 RED → GREEN → REFACTOR 사이클을 따릅니다. + +--- + +## 1. TDD 기본 원칙 + +1. **RED (실패 테스트 작성)** + - 명세에 정의된 동작을 기준으로 테스트를 먼저 작성합니다. + - 아직 기능이 없거나 실패해야 정상입니다. + +2. **GREEN (기능 구현)** + - 테스트를 통과시키기 위한 최소한의 코드만 작성합니다. + - 하드코딩이 허용됩니다. (테스트를 통과시키는 것이 우선) + +3. **REFACTOR (리팩토링)** + - 테스트가 통과된 이후에만 코드 개선을 진행합니다. + - 중복 제거, 의미 있는 네이밍, 구조 개선을 수행합니다. + +--- + +## 2. 기능 명세 + +### 2.1 반복 유형 선택 (Repeat Type Selection) + + - 일정 생성 또는 수정 시 반복 유형을 선택할 수 있다. + - 반복 유형은 다음과 같다: 매일, 매주, 매월, 매년 + - 31일에 매월을 선택한다면 → 매월 마지막이 아닌, 31일에만 생성하세요. + - 윤년 29일에 매년을 선택한다면 → 29일에만 생성하세요! + - 반복일정은 일정 겹침을 고려하지 않는다. + +**예외 규칙** +- 31일에 “매월”을 선택한 경우 → “매월 마지막”이 아닌, **31일에만 생성**되어야 한다. +- 윤년의 2월 29일에 “매년”을 선택한 경우 → **2월 29일에만 생성**되어야 한다. +- 반복 일정은 다른 일정과의 겹침을 고려하지 않는다. + +**TDD 가이드** +- RED: “반복 유형을 선택할 수 있다” 테스트 작성 +- GREEN: 반복 유형 로직 구현 +- REFACTOR: 반복일 계산 로직을 `getNextRepeatDate()` 유틸로 분리 + +--- + +### 2.2 반복 일정 표시 (Repeat Display) + +- 캘린더 뷰에서 반복 일정은 **반복 아이콘(🔁)** 으로 표시되어야 한다. +- 단일 일정은 아이콘이 표시되지 않는다. + +**TDD 가이드** +- RED: “반복 일정은 반복 아이콘을 표시한다” 테스트 작성 +- GREEN: 조건부 렌더링 구현 +- REFACTOR: 반복 여부를 확인하는 로직을 `isRepeating()` 헬퍼로 분리 + +--- + +### 2.3 반복 종료 조건 (Repeat End) + +- 반복 종료 조건을 지정할 수 있다. +- 옵션: 특정 날짜(`until`) + - 예: `2025-12-31`까지 반복 +- 종료일 이후에는 반복이 생성되지 않아야 한다. + +**TDD 가이드** +- RED: “2025-12-31 이후 일정은 생성되지 않는다” 테스트 작성 +- GREEN: `endDate` 체크 로직 구현 +- REFACTOR: 반복 생성 로직을 `generateRepeatsUntil()` 함수로 분리 + +--- + +### 2.4 반복 일정 수정 (Repeat Edit) + +- 반복 일정 수정 시 “해당 일정만 수정하시겠어요?” 라는 메시지가 표시되어야 한다. + +#### 2.4.1 ‘예’를 누르는 경우 (단일 수정) +- 해당 일정만 수정된다. +- 해당 일정은 **반복 일정이 아닌 단일 일정으로 변경**된다. +- 반복 아이콘이 제거되어야 한다. + +#### 2.4.2 ‘아니오’를 누르는 경우 (전체 수정) +- 동일한 반복 그룹의 모든 일정이 수정된다. +- 반복 아이콘은 그대로 유지된다. + +**TDD 가이드** +- RED: “예 선택 시 단일 수정이 된다” 테스트 작성 +- GREEN: 단일 수정 로직 구현 +- REFACTOR: 수정 모달 및 반복 관리 로직 분리 + +--- + +### 2.5 반복 일정 삭제 (Repeat Delete) + +- 반복 일정 삭제 시 “해당 일정만 삭제하시겠어요?” 라는 메시지가 표시되어야 한다. + +#### 2.5.1 ‘예’를 누르는 경우 (단일 삭제) +- 선택한 일정만 삭제된다. + +#### 2.5.2 ‘아니오’를 누르는 경우 (전체 삭제) +- 동일한 반복 그룹의 모든 인스턴스가 삭제된다. + +**TDD 가이드** +- RED: “예 선택 시 단일 삭제 테스트 작성” +- GREEN: 삭제 로직 구현 +- REFACTOR: `deleteSingleOrAll()` 함수로 로직 통합 + +--- + +## 3. AI 개발 시 주의사항 + +- 반드시 테스트부터 작성해야 합니다. (RED 우선) +- 명세에 없는 기능은 추가하지 않습니다. +- 테스트 설명(`describe`, `it`)은 한글로 작성합니다. +- 테스트 함수명은 명세 문장 그대로 작성해야 합니다. + 예: `"31일에 매월을 선택하면 31일에만 생성된다"` +- 테스트 프레임워크는 `vitest` 또는 `@testing-library/react`를 사용합니다. +- 상태 관리는 React의 `useState`, `useEffect`를 사용합니다. +- 날짜 연산은 `dayjs` 사용을 기본으로 합니다. + +--- \ No newline at end of file diff --git a/cursor-rules.md b/cursor-rules.md new file mode 100644 index 00000000..29faf382 --- /dev/null +++ b/cursor-rules.md @@ -0,0 +1,30 @@ +# 🧭 Cursor 개발 규칙 + +이 문서는 Cursor 내 모든 AI 개발 에이전트가 따라야 하는 공통 규칙을 정의합니다. + +--- + +## 👩‍💻 공통 개발 원칙 + +1. 모든 기능 개발은 TDD 기반으로 진행해야 합니다. + (테스트 코드 작성 → 테스트 통과 → 리팩토링) +2. 기능 명세는 `.cursor/agents` 또는 프로젝트 내 명세 문서를 통해 제공됩니다. +3. 명세 외의 기능은 임의로 추가하지 않습니다. +4. 테스트 명세와 실제 구현은 반드시 **일대일 대응**되어야 합니다. +5. `TT.md`(테스트 설계 에이전트)는 테스트를 설계하고 작성하는 역할만 수행합니다. + 실제 로직 구현은 개발 에이전트가 담당합니다. + +--- + +## 🧠 TDD 사이클 규칙 + +- **RED**: 실패하는 테스트를 먼저 작성합니다. +- **GREEN**: 테스트를 통과시키는 최소한의 코드를 작성합니다. +- **REFACTOR**: 코드 품질 개선. 테스트는 항상 통과 상태 유지. + +--- + +## 📂 프로젝트 내 명세 문서 위치 + +- `/agents/TT.md` → 테스트 설계 에이전트 (TDD 중심 테스트 작성) +- `/specs/recurring-events.md` → 반복 일정 기능 명세 diff --git a/src/App.tsx b/src/App.tsx index 195c5b05..ce6e30c1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { Notifications, ChevronLeft, ChevronRight, Delete, Edit, Close } from '@mui/icons-material'; +import { Notifications, ChevronLeft, ChevronRight, Delete, Edit, Close, Repeat } from '@mui/icons-material'; import { Alert, AlertTitle, @@ -35,8 +35,8 @@ import { useEventForm } from './hooks/useEventForm.ts'; import { useEventOperations } from './hooks/useEventOperations.ts'; import { useNotifications } from './hooks/useNotifications.ts'; import { useSearch } from './hooks/useSearch.ts'; -// import { Event, EventForm, RepeatType } from './types'; -import { Event, EventForm } from './types'; +import { Event, EventForm, RepeatType } from './types'; +// import { Event, EventForm } from './types'; import { formatDate, formatMonth, @@ -77,11 +77,11 @@ function App() { isRepeating, setIsRepeating, repeatType, - // setRepeatType, + setRepeatType, repeatInterval, - // setRepeatInterval, + setRepeatInterval, repeatEndDate, - // setRepeatEndDate, + setRepeatEndDate, notificationTime, setNotificationTime, startTimeError, @@ -437,12 +437,12 @@ function App() { - {/* ! 반복은 8주차 과제에 포함됩니다. 구현하고 싶어도 참아주세요~ */} - {/* {isRepeating && ( + {isRepeating && ( - - 반복 유형 + + 반복 유형