Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3d379b4
과제 제출을 위한 빈 커밋 날리기
kwonjihyeon-duse Oct 27, 2025
ed9bc16
chore: 참고용 bmad 설치
kwonjihyeon-dev Oct 27, 2025
224d51a
chore: po.md 설정
kwonjihyeon-dev Oct 27, 2025
105daa6
chore: 기능 명세 agent 생성
kwonjihyeon-duse Oct 28, 2025
16eb6f2
chore: 프로젝트 매니저 agent 생성
kwonjihyeon-dev Oct 29, 2025
76be594
chore: spec-writer 설정 수정
kwonjihyeon-dev Oct 29, 2025
73788a8
chore: 모든 agent 공통 용어를 위한 glossary 문서 추가
kwonjihyeon-dev Oct 29, 2025
b84f904
chore: po agent 생성
kwonjihyeon-dev Oct 29, 2025
c22e857
feat: 테스트 케이스 생성
kwonjihyeon-dev Oct 30, 2025
cd02644
chore: bmad 삭제 및 커서 agent 파일 경로 변경
kwonjihyeon-dev Oct 30, 2025
a67a7b3
feat: 테스트 green 단계 진행 중
kwonjihyeon-dev Oct 30, 2025
0554886
폴더 구조 변경
kwonjihyeon-dev Oct 30, 2025
10edcd9
폴더 구조 변경
kwonjihyeon-dev Oct 30, 2025
c22b351
feat: 실패하는 케이스 추가
kwonjihyeon-dev Oct 30, 2025
fe20cff
feat: 실패하는 케이스 수정
kwonjihyeon-dev Oct 30, 2025
672c750
feat: 반복 일정 수정 기능 명세
kwonjihyeon-dev Oct 31, 2025
93cd3f5
feat: 반복 일정 수정 기능 명세
kwonjihyeon-dev Oct 31, 2025
5739808
feat: 반복 일정 수정 유저 스토리
kwonjihyeon-dev Oct 31, 2025
dc8df86
반복 이벤트 수정 - 테스트 케이스 작성 및 실패한 테스트 구현
kwonjihyeon-dev Oct 31, 2025
537a9ec
feat: 반복 일정 수정 유저 스토리
kwonjihyeon-dev Oct 31, 2025
459fed2
반복 이벤트 수정 - 테스트 케이스 작성 및 실패한 테스트 구현
kwonjihyeon-dev Oct 31, 2025
9078bf8
chore: agent 폴더 구조 변경
kwonjihyeon-dev Oct 31, 2025
c4a684e
feat: 테스트 코드를 통과하기 위한 기능 구현
kwonjihyeon-dev Oct 31, 2025
f49c670
feat: 실패하는 케이스 보완
kwonjihyeon-dev Oct 31, 2025
5a87009
feat: 반복 일정 삭제 기능 명세
kwonjihyeon-dev Oct 31, 2025
fc92ba0
feat: 반복 일정 삭제 기능 스토리 생성
kwonjihyeon-dev Oct 31, 2025
3deea25
불필요한 파일 삭제
kwonjihyeon-dev Oct 31, 2025
ea6e9d2
불필요한 파일 삭제
kwonjihyeon-dev Oct 31, 2025
d4f8dc7
spec-writer: 반복 일정 생성
kwonjihyeon-dev Oct 31, 2025
ebc125f
spo: 반복 일정 생성
kwonjihyeon-dev Oct 31, 2025
c534893
stest-architect: 반복 일정 생성
kwonjihyeon-dev Oct 31, 2025
8abc5bf
develop&refactor: 반복 일정 생성
kwonjihyeon-dev Oct 31, 2025
4c1cd15
sspec-writer: 반복 일정 아이콘 추가
kwonjihyeon-dev Oct 31, 2025
1094a39
spo: 반복 일정 아이콘 추가
kwonjihyeon-dev Oct 31, 2025
797fcb4
stest-architect: 반복 일정 아이콘 추가
kwonjihyeon-dev Oct 31, 2025
26b2784
sdeveloper: 반복 일정 아이콘 추가
kwonjihyeon-dev Oct 31, 2025
4db898f
srefactor: 반복 일정 아이콘 추가
kwonjihyeon-dev Oct 31, 2025
fc203b6
spec-writer: 반복 일정 삭제
kwonjihyeon-dev Nov 1, 2025
25a4893
po: 반복 일정 삭제
kwonjihyeon-dev Nov 1, 2025
f0d947a
test-architext: 반복 일정 삭제
kwonjihyeon-dev Nov 1, 2025
c8ad6bd
developer: 반복 일정 삭제
kwonjihyeon-dev Nov 1, 2025
30060a7
spec-writer: 반복 일정 수정
kwonjihyeon-dev Nov 1, 2025
3b4a264
po: 반복 일정 수정
kwonjihyeon-dev Nov 1, 2025
9a9879f
ptest-architect 반복 일정 수정
kwonjihyeon-dev Nov 1, 2025
68ce356
develop: 반복 일정 수정
kwonjihyeon-dev Nov 1, 2025
657ad92
refactor: 반복 일정 수정
kwonjihyeon-dev Nov 1, 2025
5f6ac7b
리포트 오타 수정
kwonjihyeon-dev Nov 1, 2025
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
345 changes: 345 additions & 0 deletions .cursor/artifacts/po/반복일정삭제_story.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
# User Story: 반복 일정 삭제

**Status**: User Story Complete 완료
**Next Action**: 사용자 승인되면 이 문서를 @test-architect에게 전달하여 테스트 케이스 작성을 요청합니다.

승인하시면 "확인", "승인", "ok" 중 하나로 답변해주세요.

---

## Story

**As a** 캘린더 앱을 사용하는 사용자
**I want** 반복 일정을 삭제할 때 이번 일정만 삭제할지 전체 반복 시리즈를 삭제할지 선택할 수 있기를
**So that** 의도한 범위만 정확히 삭제하여 실수로 전체 일정을 삭제하는 것을 방지할 수 있다.

---

## Description

### 배경

현재 시스템은 모든 일정을 동일한 방식으로 삭제하고 있다. 사용자는 반복 일정의 경우 특정 날짜만 취소하거나 전체 반복 시리즈를 종료하고 싶은 상황이 있다. 반복 일정에 대한 삭제 선택권을 제공하여 사용자 의도에 맞는 삭제를 수행할 수 있어야 한다.

### 사용자 여정

1. 사용자가 반복 일정의 삭제 버튼을 클릭한다.
2. 시스템이 `event.repeat.type !== 'none'`을 확인하여 반복 일정임을 인식한다.
3. "반복 일정 삭제" 다이얼로그가 나타나고 "이번 일정만 삭제하시겠습니까?" 안내 메시지가 표시된다.
4. 사용자가 "이번" 또는 "모두" 중 하나를 선택한다.
- **"이번" 선택**: 단일 인스턴스 삭제 (`DELETE /api/events/:id`)
- **"모두" 선택**: 전체 반복 시리즈 삭제 (`DELETE /api/recurring-events/:repeatId`)
5. 삭제 완료 후 일정 목록이 새로고침되고 적절한 성공 메시지가 표시된다.

### 주요 시나리오

#### 시나리오 1: 단일 인스턴스 삭제

- **상황**: 매주 회의가 있지만 이번 주만 회의를 취소하고 싶은 상황.
- **동작**: 2025-01-22 날짜의 회의 일정에서 "이번" 선택
- **결과**: 2025-01-22만 삭제되고, 2025-01-15, 2025-01-29 등 다른 주의 회의는 그대로 유지됨.

#### 시나리오 2: 전체 반복 시리즈 삭제

- **상황**: 매주 운동 계획을 전체적으로 취소하고 전체 시리즈를 종료하고 싶은 상황.
- **동작**: 어떤 날짜의 운동 일정에서 "모두" 선택
- **결과**: 전체 운동일정(2025-01-15, 2025-01-22, 2025-01-29 등)이 모두 삭제됨.

#### 시나리오 3: 일반 일정 삭제 (기존 동작 유지)

- **상황**: 일반 일정을 삭제하는 상황.
- **동작**: 일반 삭제 버튼 클릭
- **결과**: 다이얼로그 표시 없이 기존 삭제 로직이 실행됨.

---

## Acceptance Criteria

### AC-1: 반복 일정 판별 확인

**Given** 사용자가 반복 일정의 삭제 버튼을 클릭했을 때
**When** 시스템이 해당 일정의 `event.repeat.type`이 `'none'`이 아닌 경우
**Then** 반복 일정임을 인식해야함
**And** 삭제 선택 다이얼로그를 표시해야함

---

### AC-2: 반복 일정 다이얼로그 표시

**Given** 반복 일정임을 인식한 후 삭제 선택 다이얼로그를 표시할 때
**When** 삭제 선택 다이얼로그가 나타나면
**Then** 다이얼로그 제목이 "반복 일정 삭제"이어야함
**And** 다이얼로그 내용이 "이번 일정만 삭제하시겠습니까?"이어야함
**And** "이번" 버튼이 표시되어야함
**And** "모두" 버튼이 표시되어야함
**And** 취소 옵션도 제공되어야함

---

### AC-3: 단일 인스턴스 삭제 ("이번" 선택)

**Given** 삭제 선택 다이얼로그가 다이얼로그가 표시된 상태에서
**When** 사용자가 "이번" 버튼을 클릭했을때
**Then** `DELETE /api/events/:id` API가 호출되어야함
**And** 선택된 일정만 삭제되어야함
**And** 동일한 `repeat.id`를 가진 다른 인스턴스는 유지되어야함
**And** 일정 목록이 새로고침되어야함
**And** "일정이 삭제되었습니다." 성공 메시지가 표시되어야함
**And** 다이얼로그가 닫혀야함

---

### AC-4: 전체 반복 시리즈 삭제 ("모두" 선택)

**Given** 삭제 선택 다이얼로그가 다이얼로그가 표시된 상태에서
**When** 사용자가 "모두" 버튼을 클릭했을때
**Then** `DELETE /api/recurring-events/:repeatId` API가 호출되어야함
**And** 동일한 `repeat.id`를 가진 모든 인스턴스가 삭제되어야함
**And** 일정 목록이 새로고침되어야함
**And** "반복 일정 전체가 삭제되었습니다." 성공 메시지가 표시되어야함
**And** 다이얼로그가 닫혀야함

---

### AC-5: repeat.id 없는 경우 처리

**Given** 반복 일정(`repeat.type !== 'none'`)이지만 `repeat.id`가 없는 경우에
**When** 사용자가 "모두" 버튼을 클릭했을때
**Then** "반복 일정 정보를 찾을 수 없습니다." 에러 메시지가 표시되어야함
**And** 다이얼로그는 열린 상태로 유지되어야함
**And** 삭제가 실행되지 않아야함

---

### AC-6: 일반 일정 삭제 (기존 동작 유지)

**Given** 일반 일정(`repeat.type === 'none'`)의 삭제 버튼을 클릭했을 때
**When** 삭제 버튼을 클릭하면
**Then** 삭제 선택 다이얼로그가 표시되지 않아야함 (기존 삭제 로직 또는 기존 확인 다이얼로그만)
**And** 기존 삭제 로직이 실행되어야함

---

### AC-7: 다이얼로그 취소 또는 닫기 시 ESC 키

**Given** 삭제 선택 다이얼로그가 다이얼로그가 표시된 상태에서
**When** 사용자가 다이얼로그 취소 버튼을 클릭하거나 ESC 키를 눌렀을때
**Then** 다이얼로그가 닫혀야함
**And** 삭제 작업이 실행되지 않아야함 (취소됨)
**And** 일정 목록은 변화가 없어야함

---

### AC-8: 네트워크 오류 처리

**Given** 삭제 API 호출 중 네트워크 오류가 발생한 경우에
**When** 삭제 버튼을 클릭하면
**Then** "삭제 실패" 에러 메시지가 표시되어야함
**And** 다이얼로그는 열린 상태로 유지되어야함 (재시도 가능)

---

### AC-9: 삭제 대상이 이미 없는 경우

**Given** 삭제 하려는 일정이 다른 세션에서 이미 삭제된 상황에
**When** 삭제 API가 404 오류를 반환하면
**Then** "일정을 찾을 수 없습니다." 에러 메시지가 표시되어야함
**And** 일정 목록이 새로고침되어야함
**And** 다이얼로그가 닫혀야함

---

### AC-10: 전체 삭제 시 repeatId 없음

**Given** 전체 삭제 API 호출 시 해당 `repeatId`가 서버에 존재하지 않는 경우에
**When** 삭제 API가 404 오류를 반환하면
**Then** "반복 일정을 찾을 수 없습니다." 에러 메시지가 표시되어야함
**And** 일정 목록이 새로고침되어야함
**And** 다이얼로그가 닫혀야함

---

## Tasks

### Phase 1: Test Setup 단계

1. **MSW 핸들러 설정**

- `DELETE /api/events/:id` 성공 응답 핸들러 (204)
- `DELETE /api/events/:id` 실패 응답 핸들러 (404)
- `DELETE /api/recurring-events/:repeatId` 성공 응답 핸들러 (204)
- `DELETE /api/recurring-events/:repeatId` 실패 응답 핸들러 (404)
- 네트워크 오류 핸들러

2. **Mock 데이터 설정**

- 반복 일정 데이터 (`repeat.type !== 'none'`, `repeat.id` 있음)
- 반복 일정 데이터 (`repeat.type !== 'none'`, `repeat.id` 없음)
- 일반 일정 데이터 (`repeat.type === 'none'`)
- 동일한 `repeat.id`를 가진 여러 일정 인스턴스 데이터

3. **Test 유틸리티**
- 다이얼로그 표시 확인 헬퍼
- 삭제 버튼 클릭 헬퍼

---

### Phase 2: Red - Test First 단계

1. **반복 일정 판별 테스트**

- 반복 일정에서만 다이얼로그 표시 테스트
- 일반 일정에서 다이얼로그 미표시 테스트

2. **다이얼로그 UI 테스트**

- 다이얼로그 내용 및 버튼 구성 테스트
- "이번", "모두" 버튼 존재 테스트
- 취소 버튼 동작 테스트

3. **단일 삭제 테스트**

- "이번" 선택 시 API 호출 테스트
- 단일 인스턴스 삭제 후 다른 인스턴스 유지 테스트
- 성공 메시지 표시 테스트

4. **전체 삭제 테스트**

- "모두" 선택 시 API 호출 테스트
- 전체 시리즈 삭제 확인 테스트
- 성공 메시지 표시 테스트

5. **에러 처리 테스트**

- `repeat.id` 없는 경우 에러 테스트
- 네트워크 오류 처리 테스트
- 404 오류 처리 테스트

6. **다이얼로그 취소/ESC 키 테스트**
- 취소 버튼 시 다이얼로그 닫힘 테스트
- ESC 키 입력 시 다이얼로그 닫힘 테스트
- 취소 시 삭제 미실행 테스트

---

### Phase 3: Green - Implementation 단계

1. **삭제 선택 다이얼로그 컴포넌트 구현**

- `App.tsx`에 다이얼로그 상태 관리 추가
- 다이얼로그 UI 구현 (MUI Dialog 컴포넌트)
- "이번", "모두" 버튼 구현

2. **반복 일정 판별 로직 구현**

- `handleDeleteClick` 함수에 `repeat.type` 확인
- 반복 일정인 경우 다이얼로그 표시, 일반 일정인 경우 기존 삭제 로직 실행

3. **단일 삭제 기능 구현**

- `handleSingleDelete` 함수 구현
- `DELETE /api/events/:id` API 호출
- 성공 메시지 표시 및 목록 새로고침

4. **전체 삭제 기능 구현**

- `handleDeleteAll` 함수 구현
- `DELETE /api/recurring-events/:repeatId` API 호출
- `repeat.id` 존재여부 확인
- 성공 메시지 표시 및 목록 새로고침

5. **에러 처리 구현**

- `repeat.id` 없는 경우 에러 메시지
- 네트워크 오류 처리 구현
- 404 오류 처리 후 목록 새로고침

6. **다이얼로그 취소/ESC 키 처리**
- `onClose` 핸들러 구현
- ESC 키 처리 (MUI Dialog 기본 기능)

---

### Phase 4: Refactor 단계

1. **코드 정리하기**

- 삭제 로직을 `useEventOperations` 훅으로 분리 가능
- 다이얼로그 상태 관리 최적화
- 중복 코드 제거 처리

2. **성능 최적화**
- 불필요한 리렌더링 방지
- API 호출 최적화

---

### Phase 5: Documentation 단계

1. **주석 추가**

- 삭제 선택 로직에 대한 JSDoc 주석 추가
- 다이얼로그 동작에 대한 설명

2. **타입 정의**
- `DeleteDialogState` 인터페이스 문서화 (선택사항)

---

## Technical Notes

### 기술 스택

- **React**: 컴포넌트 및 상태 관리
- **TypeScript**: 타입 안정성
- **Material-UI (MUI)**: Dialog, Button 컴포넌트
- **Vitest**: 테스트 러너
- **React Testing Library**: 컴포넌트 테스트
- **MSW**: API 목킹

### 타입정의 구조

```typescript
interface Event {
id: string;
title: string;
date: string; // ISO 8601 형식
startTime: string; // HH:mm 형식
endTime: string; // HH:mm 형식
description: string;
location: string;
category: string;
repeat: RepeatInfo;
notificationTime: number;
}

interface RepeatInfo {
type: RepeatType; // 'none' | 'daily' | 'weekly' | 'monthly' | 'yearly'
interval: number;
endDate: string;
id?: string; // 반복 시리즈 식별자 필드 (선택적 필드)
}
```

### API 엔드포인트

- **단일 삭제**: `DELETE /api/events/:id`
- **전체 삭제**: `DELETE /api/recurring-events/:repeatId`

---

## Definition of Done

- [ ] 모든 테스트가 작성되어 실행 가능 (Red 단계)
- [ ] 모든기능이 정상적으로 동작 확인 (Green 단계)
- [ ] 코드품질 정리 (Refactor 단계)
- [ ] 에러 처리 완료
- [ ] 접근성 검토
- [ ] 모든 Acceptance Criteria 요구 충족
- [ ] 코드 리뷰 및 승인 완료 (동료 검토 포함)

---

**Version**: 1.0.0
**Last Updated**: 2025-01-31
**Author**: PO Agent
Loading
Loading