diff --git a/.github/agents/01-Feature-Design-Agent.md b/.github/agents/01-Feature-Design-Agent.md new file mode 100644 index 00000000..88172e5b --- /dev/null +++ b/.github/agents/01-Feature-Design-Agent.md @@ -0,0 +1,118 @@ +# 기능 설계 에이전트 (Feature Design Agent) + +**목표** +기존 캘린더 서비스에 “반복 일정” 기능을 추가하기 위한 **작업 범위(스코프)와 상세 명세**를 생성한다. +새 기능을 추가하지 않으며, 영향 범위를 명확히 규정하고 문서화한다. + +--- + +## 입력 (Inputs) + +- 기존 프로젝트 분석 자료 + - UI/UX 흐름: `App.tsx`의 폼/뷰 구조 (week / month) + - 서버 API 계약: `server.js` (REST 엔드포인트, payload 스키마) + - 현재 테스트 패턴: `medium.integration.spec.tsx` (msw, RTL, vi.setSystemTime 등) + - 과제 체크리스트: `PULL_REQUEST_TEMPLATE.md` (반복 유형, 수정/삭제 정책 등) +- 신규 요구 + - 반복 유형: 매일/매주/매월/매년 + - 종료 조건: 특정 날짜까지 (예: 2025-12-31) + - 수정/삭제 정책: 단일 vs 전체 (아이콘 변동 포함) + - 일정 겹침: 고려하지 않음 (명세 상) + +--- + +## 출력 (Outputs) + +- `SPEC.md` 스타일의 **기능 명세서 (Markdown)** + - 문제 정의 / 용어 정의 / 범위 / 비범위(Out-of-Scope) + - 유즈케이스 / 시나리오 / 엣지케이스 + - 데이터 모델(반복 id, interval, type, endDate) + - API 계약서 (요청/응답 / 예외) + - 화면 변경점 (아이콘, 질문 모달 문구) + - 수용 기준(AC) 체크리스트 +- **질문 리스트(Q&A)**: 영향 범위를 점검하기 위한 질문과 확정 답변 +- **체크리스트**: 리뷰/PR용 + +> 최종 산출물은 **마크다운**. 계층화(Heading/TOC) 명확히, 예시 포함. + +--- + +## 규칙 (Rules) + +1. **프로젝트 분석 후 범위 확정**: 새 기능 추가 금지. 기존 과제 명세만 구체화. +2. **명세는 테스트 가능해야 함**: 각 요구사항은 구체적 입력/출력 예시를 동반. +3. **서버/클라이언트 인터페이스 분리**: API 계약은 구체적으로 정의. +4. **시간/윤년/말일 규칙 명시**: 31일/2월/윤년 예외를 명확히. +5. **i18n/스타일링 등은 비범위**: 기능 동작에 필수인 부분만. + +--- + +## 절차 (Workflow) + +1. **프로젝트 구조 파악** (`App.tsx`, `server.js`, 테스트 파일 스캔) +2. **요구 정리** (반복 유형, 종료 조건, 수정/삭제, 아이콘, 겹침 정책) +3. **질문 작성 → 답변 수집 → 명세 업데이트** +4. **데이터 모델/계약 정의** (예: `repeat: { id?, type, interval, endDate }`) +5. **유즈케이스/시나리오/엣지케이스 작성** +6. **수용 기준(AC) 체크리스트 정리** +7. 산출물 **Markdown**으로 제출 + +--- + +## 체크리스트 (Review) + +- [ ] 스코프가 기존 명세를 벗어나지 않았는가? +- [ ] 각 요구에 **입력/출력 예시**가 있는가? +- [ ] 윤년/말일/월 이동 로직이 명확한가? +- [ ] 단일 수정/전체 수정/삭제 정책과 아이콘 규칙이 일치하는가? +- [ ] 서버 API 계약이 모호함 없이 정의되었는가? + +--- + +## 예시 Q&A (샘플) + +- Q. 매월 31일 반복은 30일/28일/29일에 이동하나요? + A. **아니요.** 명세에 따라 **31일에만 생성**합니다. + +- Q. 윤년 2/29 연간 반복은 평년에는 생성하나요? + A. **아니요.** **2/29에만 생성**합니다. + +--- + +## 예시: API 계약 (초안) + +### POST `/api/events-list` +- Body +```json +{ + "events": [ + { + "title": "팀 회의", + "date": "2025-10-02", + "startTime": "09:00", + "endTime": "10:00", + "description": "주간 점검", + "location": "A", + "category": "업무", + "repeat": { "type": "monthly", "interval": 1, "endDate": "2025-12-31" } + } + ] +} +``` +- Response: 생성된 각 이벤트에 `id`와 반복 시리즈에는 공통 `repeat.id` 부여 + +### PUT `/api/recurring-events/:repeatId` +- 시리즈 전체 수정 (단일 수정은 개별 `/api/events/:id`) + +### DELETE `/api/recurring-events/:repeatId` +- 시리즈 전체 삭제 + +--- + +## 수용 기준(AC) 샘플 + +- [ ] 매월 31일 시작 일정은 31일에만 생성된다. +- [ ] 2/29 연간 반복은 윤년에만 생성된다. +- [ ] “해당 일정만 수정” 선택 시 반복 아이콘이 제거된다. +- [ ] “전체 수정” 선택 시 반복 아이콘을 유지한다. +- [ ] 반복 종료일을 넘는 일정은 생성되지 않는다. \ No newline at end of file diff --git a/.github/agents/02-Test-Design-Agent.md b/.github/agents/02-Test-Design-Agent.md new file mode 100644 index 00000000..4e0dad3d --- /dev/null +++ b/.github/agents/02-Test-Design-Agent.md @@ -0,0 +1,94 @@ +# 테스트 설계 에이전트 (Test Design Agent) + +**목표** +기능 명세를 바탕으로 TDD의 RED 단계를 견고하게 만들 **테스트 명세와 테스트 시나리오**를 작성한다. + +--- + +## 입력 (Inputs) + +- 기능 명세 문서 (Feature Design Agent 산출물) +- 기존 테스트 스타일/유틸 + - `medium.integration.spec.tsx`의 패턴 (RTL, msw, vi.setSystemTime) + - 서버 모킹 핸들러 패턴 (`__mocks__` 유틸) +- 과제 규칙 (`PULL_REQUEST_TEMPLATE.md`) + +--- + +## 출력 (Outputs) + +- **테스트 명세서 (Markdown)**: 목적, 범위, 시나리오, 엣지케이스, 실패 메시지 가이드 +- **테스트 파일 스켈레톤**: 비어있는 `it(...)` 케이스 집합 + - `recurrence.feature.spec.tsx` (통합) + - `recurrence.rule.spec.ts` (도메인 규칙 유닛) + - `recurrence.api.contract.spec.ts` (계약) +- **Given-When-Then 표기**로 구체 예시 포함 + +--- + +## 규칙 (Rules) + +1. **행동 기반 명세(Behavior-Driven)**: 사용자 관점의 문장화. +2. **독립성**: 각 케이스는 독립적으로 의미 있는 실패 메시지 제공. +3. **결정론**: 시간/랜덤 고정 (e.g., `vi.setSystemTime`, `randomUUID` mock). +4. **범위 고정**: 명세 밖 시나리오 금지. + +--- + +## 테스트 카테고리 + +1. **반복 생성 규칙** + - 매일/매주/매월/매년 + - 31일 규칙, 윤년 2/29 규칙 + - 종료일 컷오프 +2. **반복 표시** + - 캘린더와 리스트에서 반복 아이콘 노출 +3. **반복 수정/삭제** + - 단일 vs 전체, 아이콘 토글 +4. **API 계약** + - events-list 생성/수정/삭제 요청 스키마/응답 스키마 +5. **회귀 방지** + - 기존 CRUD/검색/알림 영향 없음 + +--- + +## 예시: 통합 테스트 스켈레톤 + +```ts +describe('반복 일정 - 생성', () => { + it('매월 31일 반복은 31일에만 생성된다 (30일/2월 미생성)', async () => { + // Given: 2025-01-31 시작, 종료 2025-12-31 + // When: 반복 생성 + // Then: 1,3,5,7,8,10,12월 31일만 존재 + }); + + it('윤년 2/29 연간 반복은 윤년에만 생성된다', async () => { + // Given: 2024-02-29 시작, 종료 2028-12-31 + // Then: 2024, 2028에만 생성 + }); +}); + +describe('반복 일정 - 수정/삭제', () => { + it('해당 일정만 수정 시 반복 아이콘이 제거된다', async () => {}); + it('전체 수정 시 반복 아이콘이 유지된다', async () => {}); + it('해당 일정만 삭제 시 해당 인스턴스만 삭제된다', async () => {}); + it('전체 삭제 시 시리즈 전체가 삭제된다', async () => {}); +}); +``` + +--- + +## 실패 메시지 가이드 + +- “매월 31일 반복이 4,6,9,11월 30일에 생성되었습니다” (❌) +- “2/29 연간 반복이 평년에 생성되었습니다” (❌) +- “단일 수정 후 아이콘이 남아있습니다” (❌) + +--- + +## 체크리스트 + +- [ ] RED에서 의미 있게 실패하는가? +- [ ] GREEN 최소 구현으로 통과 가능한가? +- [ ] REFACTOR에도 깨지지 않는가? (행동 중심) +- [ ] vi.setSystemTime / mock이 누락되지 않았는가? \ No newline at end of file diff --git a/.github/agents/03-Test-Writer-Agent.md b/.github/agents/03-Test-Writer-Agent.md new file mode 100644 index 00000000..d8339a90 --- /dev/null +++ b/.github/agents/03-Test-Writer-Agent.md @@ -0,0 +1,70 @@ +# 테스트 코드 작성 에이전트 (Test Writer Agent) + +**목표** +테스트 설계 에이전트가 정의한 **비어있는 테스트 케이스**를 구체 코드로 채운다. + +--- + +## 입력 (Inputs) + +- 테스트 스켈레톤 (`*.spec.ts(x)`) +- 기능 명세서 +- 프로젝트 테스트 유틸 (RTL/msw/vi) + +--- + +## 출력 (Outputs) + +- 채워진 테스트 파일 + - `recurrence.feature.spec.tsx` + - `recurrence.rule.spec.ts` + - `recurrence.api.contract.spec.ts` +- **테스트만 수정** (구현 코드/기존 테스트 수정 금지) + +--- + +## 규칙 (Rules) + +1. **프로젝트 컨벤션 준수** (`medium.integration.spec.tsx`의 setup 패턴, msw 사용) +2. **시간 고정**: `vi.setSystemTime` 적극 활용 +3. **명확한 셋업/정리**: `beforeEach/afterEach`로 핸들러/타이머 초기화 +4. **가독성**: Given/When/Then 주석 유지, 실패 메시지 개선 + +--- + +## 패턴 예시 + +```ts +const setup = () => { + const user = userEvent.setup(); + render( + + + + + + + ); + return { user }; +}; + +it('매월 31일 반복은 31일에만 생성된다', async () => { + // Given + vi.setSystemTime(new Date('2025-01-31')); + setupMockHandlerCreation([]); + + const { user } = setup(); + + // When: 폼 입력 + 반복 monthly/interval=1/endDate=2025-12-31 + 저장 + // Then: month view에서 1,3,5,7,8,10,12월 31일에만 노출 +}); +``` + +--- + +## 체크리스트 + +- [ ] 비결정성 제거(시간/랜덤) +- [ ] UI 텍스트 기반 검증 (DOM 구조 의존 X) +- [ ] 실패 시 메시지 명확 +- [ ] 네이밍에 “결과” 포함 \ No newline at end of file diff --git a/.github/agents/04-Code-Writer-Agent.md b/.github/agents/04-Code-Writer-Agent.md new file mode 100644 index 00000000..d59cb471 --- /dev/null +++ b/.github/agents/04-Code-Writer-Agent.md @@ -0,0 +1,62 @@ +# 코드 작성 에이전트 (Code Writer Agent) + +**목표** +작성된 테스트를 통과하는 최소 구현 코드를 작성한다. **테스트는 절대 수정하지 않는다.** + +--- + +## 입력 (Inputs) + +- 채워진 테스트 파일 +- 기능 명세서 +- 사용 가능한 API 목록 (`server.js` 엔드포인트) + +--- + +## 출력 (Outputs) + +- 기능 구현 코드 (클라이언트/서버 범위 내) +- 필요한 경우 **신규 모듈/훅/유틸** 추가 (프로젝트 구조/컨벤션 준수) +- 변경 내역 설명 (무엇을, 왜) + +--- + +## 사용 가능한 API (현 프로젝트 기준) + +- `GET /api/events` 초기 로드 +- `POST /api/events` 단일 일정 생성 +- `PUT /api/events/:id` 단일 일정 수정 +- `DELETE /api/events/:id` 단일 일정 삭제 +- `POST /api/events-list` **반복 일정 일괄 생성** (반복 시리즈에는 동일 `repeat.id` 부여됨) +- `PUT /api/events-list` 여러 이벤트 일부 필드 일괄 수정 +- `PUT /api/recurring-events/:repeatId` 시리즈 전체 수정 +- `DELETE /api/recurring-events/:repeatId` 시리즈 전체 삭제 + +> **주의**: 반복 규칙(31일/윤년)은 클라이언트 도메인 로직으로 결정 후 서버에 전송. + +--- + +## 구현 지침 + +1. **도메인 유틸 분리**: `generateRecurrenceInstances`, `isLeapYear`, `isValidMonthly31st`, etc. +2. **UI 상태 최소 변경**: 기존 `App.tsx` 폼/뷰 패턴 유지 +3. **아이콘/질문 모달**: 단일/전체 수정/삭제 분기 +4. **검색/알림/겹침 로직 영향 금지** + +--- + +## 절차 + +1. 테스트 실행 → RED 확인 +2. 최소 도메인 유틸부터 구현 → GREEN +3. UI 연결 (아이콘/모달) → GREEN +4. 코드 정리 → REFACTOR 전까지 테스트 유지 + +--- + +## 체크리스트 + +- [ ] 테스트 수정 없음 +- [ ] 반복 규칙 정확 +- [ ] API 계약 준수 +- [ ] 기존 기능 회귀 없음 \ No newline at end of file diff --git a/.github/agents/05-Refactor-Agent.md b/.github/agents/05-Refactor-Agent.md new file mode 100644 index 00000000..12c85b87 --- /dev/null +++ b/.github/agents/05-Refactor-Agent.md @@ -0,0 +1,36 @@ +# 리팩토링 에이전트 (Refactoring Agent) + +**목표** +새로 추가된 코드 범위를 중심으로 **가독성/응집도/복잡도/중복/성능**을 개선한다. 테스트는 모두 통과해야 한다. + +--- + +## 입력 (Inputs) + +- 통과 중인 테스트 스위트 +- 새로 추가된 코드 (diff 기반) + +--- + +## 출력 (Outputs) + +- 리팩토링 커밋 (동작 동일) +- 변경 요약 문서: 개선 전/후, 근거, 사이드이펙트 검증 포인트 + +--- + +## 규칙 (Rules) + +1. **스코프 제한**: 새로 추가된 코드(반복 기능)로 한정 +2. **도메인/표현 분리**: 날짜 계산 로직은 순수 함수로 +3. **이름/인터페이스 개선**: 의도 드러나는 네이밍 +4. **성능 고려**: 대량 인스턴스 생성 시 O(n) 유지, 불필요 렌더 방지 + +--- + +## 체크리스트 + +- [ ] 도메인 유틸 순수성 (부수효과 없음) +- [ ] 복잡도 감소 (함수 길이, 조건 중첩 줄이기) +- [ ] 중복 제거 +- [ ] 테스트 100% 통과 \ No newline at end of file diff --git a/.github/agents/06-Orchestrator-Agent.md b/.github/agents/06-Orchestrator-Agent.md new file mode 100644 index 00000000..72de114c --- /dev/null +++ b/.github/agents/06-Orchestrator-Agent.md @@ -0,0 +1,49 @@ +# 전체 오케스트레이션 에이전트 (End-to-End Orchestrator) + +**목표** +6단계를 자동으로 조합해 **RED → GREEN → REFACTOR** 사이클을 일괄 실행한다. 각 단계 종료 후 커밋. + +--- + +## 파이프라인 + +1. **기능 설계 에이전트** → `SPEC.md` 산출 +2. **테스트 설계 에이전트** → 테스트 명세 + 스켈레톤 +3. **테스트 코드 작성 에이전트** → 테스트 구현 (RED) +4. **코드 작성 에이전트** → 최소 구현 (GREEN) +5. **리팩토링 에이전트** → 구조 개선 (REFACTOR) +6. **회귀 실행** → 모든 테스트 통과 확인 + +--- + +## 규칙 + +- 각 단계 종료 시 `git commit -m "step: - summary"` +- 실패 시 직전 단계로 롤백 후 재시도 (수정점 로그) +- 테스트는 **절대 수정 금지** (테스트 설계 단계 산출물만 수정 가능) + +--- + +## 자동화 프롬프트 템플릿 + +- 각 에이전트 호출 시 전달: + - 프로젝트 경로/구조, 사용 API, 컨벤션, ESLint/Prettier 규칙 + - 과제 체크리스트 (PRD/AC) + - 산출물 경로 규약 (docs/specs, tests, src/domain 등) + +--- + +## 산출물 + +- 단계별 로그/히스토리 +- 커밋 기록 +- 최종 `PR`: 체크리스트 자동 채움 + +--- + +## 체크리스트 + +- [ ] 단계별 산출물 존재 +- [ ] 커밋 내역 분리 +- [ ] 실패 재시도 전략 기록 +- [ ] 테스트 100% 통과 \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..1036b410 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,113 @@ +# AI Calendar Application - Copilot Instructions + +## Project Overview +This is a Korean calendar application built with React + TypeScript, featuring event management, notifications, and calendar views. The app uses a full-stack architecture with Express.js backend and file-based storage. + +## Architecture & Key Components + +### Frontend Structure +- **App.tsx**: Main component with form, calendar views (week/month), and event list +- **Hooks Pattern**: Custom hooks for separated concerns: + - `useEventOperations`: API calls and CRUD operations + - `useCalendarView`: View state and navigation logic + - `useEventForm`: Form state and validation + - `useNotifications`: Time-based notification system + - `useSearch`: Event filtering and search +- **Utils**: Pure functions for date operations, overlap detection, validation + +### Backend (server.js) +- Express server with REST API (`/api/events`, `/api/events-list`, `/api/recurring-events`) +- File-based storage using JSON files in `src/__mocks__/response/` +- Environment-based DB switching (`e2e.json` vs `realEvents.json`) +- UUID generation for event IDs + +### State Management Pattern +No external state management - uses React hooks with prop drilling and custom hooks for shared logic. + +## Development Workflows + +### Running the Application +```bash +pnpm dev # Runs both server and client with hot reload +pnpm server # Backend only +pnpm start # Frontend only +``` + +### Testing Strategy +```bash +pnpm test # Vitest with watch mode +pnpm test:ui # Visual test runner +pnpm test:coverage # Coverage reports +``` + +**Test Setup**: Uses MSW (Mock Service Worker) with handlers in `src/__mocks__/handlers.ts`. All tests run with: +- Fixed system time: `2025-10-01` +- UTC timezone +- `expect.hasAssertions()` requirement in every test + +### Testing Patterns +- **Unit tests**: Pure function testing (utils) +- **Hook tests**: Using `renderHook` from `@testing-library/react` +- **Integration tests**: Full component testing with MSW +- **Test data**: Centralized in `src/__mocks__/response/events.json` + +## Project-Specific Conventions + +### TypeScript Types +- `Event`: Has `id`, extends `EventForm` +- `EventForm`: Form data without ID +- `RepeatInfo`: Nested repeat configuration (type, interval, endDate) + +### Date/Time Handling +- All dates stored as ISO strings (`YYYY-MM-DD`) +- Time stored as 24-hour format strings (`HH:MM`) +- Date operations centralized in `utils/dateUtils.ts` +- Holiday fetching from external API for each month + +### Validation & Error Handling +- Form validation happens on blur events +- Time validation with custom error messages +- Overlap detection before saving events +- User confirmation dialogs for overlapping events + +### UI Patterns +- Material-UI components throughout +- Korean language interface +- Notification system using notistack +- Visual indicators for notified events (red styling) +- Fixed layout: form (20%), calendar (50%), event list (30%) + +### Event Operations +- Create/Read/Update/Delete through REST API +- Bulk operations for recurring events +- File system persistence (not database) +- Automatic refetch after mutations + +## Key Integration Points + +### API Endpoints +- `GET /api/events` - Fetch all events +- `POST /api/events` - Create single event +- `PUT /api/events/:id` - Update single event +- `DELETE /api/events/:id` - Delete single event +- Bulk endpoints for recurring event management + +### Mock Setup (Testing) +MSW intercepts API calls. Test data in `src/__mocks__/response/events.json` with predefined events for consistent testing. + +### Build & Deployment +- Vite for bundling and dev server +- TypeScript compilation with strict mode +- ESLint + Prettier configuration +- Proxy setup for API calls (`/api` → `localhost:3000`) + +## Development Notes + +### Commented Features +Recurring events UI is commented out but backend logic exists - intentionally incomplete per assignment requirements. + +### Korean Localization +All user-facing text in Korean. Categories: `['업무', '개인', '가족', '기타']` + +### Time Zones +Fixed to UTC in tests, but production handles local timezone. diff --git a/.github/docs/SPEC.md b/.github/docs/SPEC.md new file mode 100644 index 00000000..c11ceef2 --- /dev/null +++ b/.github/docs/SPEC.md @@ -0,0 +1,262 @@ +# 반복 일정 기능 명세서 (SPEC.md) + +## 1. 개요 + +### 1.1 기능 설명 +사용자가 반복되는 일정을 생성하고 관리할 수 있는 기능입니다. 기존 단일 일정 생성 기능을 확장하여 반복 패턴을 설정할 수 있습니다. + +### 1.2 기술적 제약사항 +- 반복 일정은 기존 Event 타입의 repeat 필드를 활용 +- 백엔드 API는 이미 구현됨 (/api/events-list, /api/recurring-events/:repeatId) +- UI는 현재 주석 처리된 상태로 존재 + +## 2. 데이터 구조 + +### 2.1 타입 정의 +```typescript +// 기존 타입 (변경 없음) +export type RepeatType = 'none' | 'daily' | 'weekly' | 'monthly' | 'yearly'; + +export interface RepeatInfo { + type: RepeatType; + interval: number; + endDate?: string; + id?: string; // 반복 시리즈 식별자 +} + +export interface Event extends EventForm { + id: string; + repeat: RepeatInfo; +} +``` + +## 3. 사용자 인터페이스 + +### 3.1 반복 일정 생성 폼 +기존 일정 생성 폼에 다음 필드 추가: + +#### 3.1.1 반복 설정 체크박스 +- **위치**: 카테고리 선택 후, 알림 설정 전 +- **레이블**: "반복 일정" +- **기본값**: 체크 해제 상태 + +#### 3.1.2 반복 유형 선택 +```tsx + +``` + +#### 3.1.3 반복 간격 입력 +- **타입**: number +- **최소값**: 1 +- **기본값**: 1 +- **예시**: 2 (2일마다, 2주마다 등) + +#### 3.1.4 반복 종료일 (선택사항) +- **타입**: date +- **제약**: 시작일보다 이후 날짜여야 함 +- **빈 값**: 무제한 반복 + +### 3.2 반복 일정 표시 + +#### 3.2.1 캘린더 뷰 +- 반복 일정은 각 발생 날짜에 개별 표시 +- 시각적 구분을 위한 아이콘 추가: 🔄 (반복 아이콘) + +#### 3.2.2 이벤트 리스트 +반복 정보 표시 형식: +``` +반복: {interval}{단위}마다 (종료: {endDate}) +``` + +**예시**: +- "반복: 1일마다" +- "반복: 2주마다 (종료: 2025-12-31)" +- "반복: 1월마다" + +## 4. 반복 규칙 + +### 4.1 날짜 계산 규칙 + +#### 4.1.1 월별 반복 - 31일 처리 +- **31일 기준 일정**: 해당 월에 31일이 없으면 마지막 날로 조정 +- **예시**: 1월 31일 → 2월 28일(평년)/29일(윤년) → 3월 31일 + +#### 4.1.2 윤년 처리 +- **2월 29일 기준**: 평년에는 2월 28일로 조정 +- **예시**: 2024년 2월 29일 → 2025년 2월 28일 → 2026년 2월 28일 + +#### 4.1.3 연별 반복 - 윤일 처리 +- **2월 29일 기준**: 평년에는 2월 28일로 조정 +- **윤년 복귀**: 다시 윤년이 되면 2월 29일로 복귀 + +### 4.2 종료일 컷오프 +- **종료일 설정 시**: 해당 날짜 이후 반복 중단 +- **종료일 포함**: 종료일 당일까지 포함 +- **예시**: 종료일이 2025-03-15면, 2025-03-15까지 반복 + +## 5. 수정 및 삭제 기능 + +### 5.1 단일 일정 수정 +- **대상**: 반복 시리즈 중 특정 일정 하나만 +- **동작**: 해당 일정을 반복 시리즈에서 분리하여 개별 일정으로 변경 +- **API**: `PUT /api/events/:id` + +### 5.2 전체 시리즈 수정 +- **대상**: 반복 시리즈 전체 +- **동작**: 모든 반복 일정에 동일한 변경사항 적용 +- **API**: `PUT /api/recurring-events/:repeatId` + +### 5.3 단일 일정 삭제 +- **대상**: 반복 시리즈 중 특정 일정 하나만 +- **동작**: 해당 일정만 삭제, 나머지는 유지 +- **API**: `DELETE /api/events/:id` + +### 5.4 전체 시리즈 삭제 +- **대상**: 반복 시리즈 전체 +- **동작**: 모든 반복 일정 삭제 +- **API**: `DELETE /api/recurring-events/:repeatId` + +## 6. 사용자 상호작용 + +### 6.1 수정/삭제 확인 다이얼로그 +반복 일정 수정/삭제 시 선택지 제공: + +``` +이 일정을 어떻게 수정/삭제하시겠습니까? + +○ 이 일정만 수정/삭제 +○ 전체 반복 일정 수정/삭제 + +[취소] [확인] +``` + +### 6.2 아이콘 정책 + +#### 6.2.1 반복 일정 표시 아이콘 +- **아이콘**: 🔄 또는 Material-UI의 `Repeat` 아이콘 +- **위치**: 일정 제목 앞 +- **색상**: 기본 테마 색상 + +#### 6.2.2 수정/삭제 버튼 +- **단일 수정**: `Edit` 아이콘 (기존과 동일) +- **전체 수정**: `EditNote` 아이콘 또는 `Edit` + 작은 🔄 +- **단일 삭제**: `Delete` 아이콘 (기존과 동일) +- **전체 삭제**: `DeleteSweep` 아이콘 또는 `Delete` + 작은 🔄 + +## 7. 입출력 예시 + +### 7.1 반복 일정 생성 요청 +```typescript +// 입력 데이터 +const repeatEvent: EventForm = { + title: "주간 팀 미팅", + date: "2025-01-06", // 월요일 + startTime: "10:00", + endTime: "11:00", + description: "매주 월요일 팀 미팅", + location: "회의실 A", + category: "업무", + repeat: { + type: "weekly", + interval: 1, + endDate: "2025-12-31" + }, + notificationTime: 10 +}; + +// API 호출 +POST /api/events-list +{ + "events": [ + // 2025년 매주 월요일 일정들 (52개) + { + "title": "주간 팀 미팅", + "date": "2025-01-06", + // ... 기타 필드 + "repeat": { + "type": "weekly", + "interval": 1, + "endDate": "2025-12-31", + "id": "repeat-uuid-123" + } + }, + { + "title": "주간 팀 미팅", + "date": "2025-01-13", + // ... 기타 필드 + "repeat": { + "type": "weekly", + "interval": 1, + "endDate": "2025-12-31", + "id": "repeat-uuid-123" + } + } + // ... 나머지 반복 일정들 + ] +} +``` + +### 7.2 31일 처리 예시 +```typescript +// 매월 31일 반복 일정 +const monthlyEvent = { + date: "2025-01-31", + repeat: { type: "monthly", interval: 1 } +}; + +// 생성되는 일정들: +// 2025-01-31 (31일 존재) +// 2025-02-28 (31일 없음 → 마지막 날) +// 2025-03-31 (31일 존재) +// 2025-04-30 (31일 없음 → 마지막 날) +``` + +### 7.3 윤년 처리 예시 +```typescript +// 2월 29일 연간 반복 +const yearlyEvent = { + date: "2024-02-29", // 윤년 + repeat: { type: "yearly", interval: 1 } +}; + +// 생성되는 일정들: +// 2024-02-29 (윤년) +// 2025-02-28 (평년 → 2월 28일) +// 2026-02-28 (평년 → 2월 28일) +// 2027-02-28 (평년 → 2월 28일) +// 2028-02-29 (윤년 → 다시 2월 29일) +``` + +## 8. 기존 코드 활용 + +### 8.1 주석 해제 대상 +[src/App.tsx](src/App.tsx) 파일의 447-476라인 반복 설정 UI 주석 해제 + +### 8.2 기존 API 엔드포인트 활용 +- `POST /api/events-list`: 반복 일정 생성 +- `PUT /api/events-list`: 반복 일정 일괄 수정 +- `DELETE /api/events-list`: 반복 일정 일괄 삭제 +- `PUT /api/recurring-events/:repeatId`: 시리즈 수정 +- `DELETE /api/recurring-events/:repeatId`: 시리즈 삭제 + +### 8.3 타입 활용 +기존 [`RepeatType`](src/types.ts)과 [`RepeatInfo`](src/types.ts) 타입 그대로 사용 + +## 9. 검증 규칙 + +### 9.1 입력 검증 +- 반복 간격: 1 이상의 정수 +- 종료일: 시작일 이후 날짜 (선택사항) +- 반복 유형: 'daily', 'weekly', 'monthly', 'yearly' 중 하나 + +### 9.2 비즈니스 규칙 +- 종료일이 설정된 경우 해당 날짜까지만 반복 +- 월/년 반복 시 존재하지 않는 날짜는 해당 월의 마지막 날로 조정 +- 반복 시리즈는 동일한 repeat.id로 그룹화 + +이 명세서는 기존 코드베이스의 구조를 유지하면서 반복 일정 기능을 구체화한 것입니다. 새로운 기능 추가 없이 기존 주석 처리된 코드와 API를 활용하여 구현 가능합니다. \ No newline at end of file