Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
ea84f90
chore: clear all contents to start a fresh project
Siul49 Apr 14, 2026
111179b
ci: github actions, husky, lint setup and pr templates
Siul49 Apr 14, 2026
b26bc4f
docs: project architecture and convention guidelines
Siul49 Apr 14, 2026
3c3bfda
build: vitest and playwright test framework setup
Siul49 Apr 14, 2026
c6b38eb
feat(schedule): 일시 교집합 알고리즘 및 TDD 검증 통과
Siul49 Apr 14, 2026
555635f
feat(ui): ui skeleton routing and style token update
Siul49 Apr 14, 2026
0e4a6ab
feat: 커밋 메시지 한글 강제 작성 규칙 및 대문자 허용 플러그인 추가
Siul49 Apr 14, 2026
221e334
feat(icloud): iCloud CalDAV 연동 기능 구현
kokkumong Apr 15, 2026
5cbe428
test(icloud): CalDAV 연동 단위 테스트 추가 및 TZID 파싱 버그 수정
kokkumong Apr 15, 2026
0d5246a
feat(google): Google Calendar OAuth 연동 기능 구현
kokkumong Apr 15, 2026
c8ade25
fix(ci): package-lock.json 동기화
kokkumong Apr 15, 2026
f93abf1
fix(ci): ESLint no-explicit-any 린트 에러 수정
kokkumong Apr 15, 2026
35d715c
feat: 코드래빗 리뷰 자동화 설정 추가 (경로별 지침·정적분석·품질게이트)
Siul49 Apr 15, 2026
fd769d8
fix(ci): 누락된 로컬 폰트를 Google Fonts로 대체 및 lock 파일 재생성
kokkumong Apr 15, 2026
a023f97
fix(ci): package-lock.json에 Linux 네이티브 바인딩 포함
kokkumong Apr 15, 2026
9621262
fix(ci): vitest.config.ts를 tsconfig exclude에 추가
kokkumong Apr 15, 2026
d2746ec
fix(ci): API 라우트에 force-dynamic 추가하여 빌드 시 프리렌더링 방지
kokkumong Apr 15, 2026
c2504da
fix(ci): CI 빌드 에러 수정
kokkumong Apr 15, 2026
27d9606
fix(ci): Supabase import 경로 수정 및 서버 클라이언트 스켈레톤 export 추가
kokkumong Apr 15, 2026
f289732
feat: HTML 프로토타입 초기 작업물 추가
yoohyun-1203 Apr 27, 2026
184e8ea
Merge pull request #3 from Siul49/feat/google-calendar-integration
Siul49 Apr 27, 2026
3a152d8
Merge pull request #2 from Siul49/feat/icloud-caldav-connection
Siul49 Apr 27, 2026
fdbed67
feat(scheduling): 캘린더 통합 가용시간 산출 프레임워크 (Date 기반 어댑터)
Siul49 May 7, 2026
b8f93d5
feat: 회원가입 API 구현 (POST /api/auth/signup)
kokkumong May 21, 2026
bb84c38
refactor: CodeRabbit 리뷰 반영 — 회원가입 API 보안 및 안정성 개선
kokkumong May 21, 2026
240d607
feat: 이메일/닉네임 기반 로그인 API 구현 (JWT 쿠키 인증)
kokkumong May 21, 2026
ca8a4a3
feat: 에브리타임 시간표 조회 기능 구현 (#21)
kokkumong May 23, 2026
92e2fc8
feat: SocialAccount 모델 추가 및 User profileCompleted 필드 추가
kokkumong May 25, 2026
6619004
feat: 카카오 로그인 API 구현 (GET /api/auth/kakao/login, /api/auth/kakao/call…
kokkumong May 25, 2026
00c054e
chore: jose 패키지 추가 및 환경변수 예시 업데이트
kokkumong May 25, 2026
161b8a0
feat(scheduling): 초대 링크 테스트 플로우 추가
Siul49 May 27, 2026
d03259a
feat: 캘린더 통합 가용시간 산출 PR #16 병합
May 27, 2026
b43fe94
feat: package.json 충돌 해결 및 PR #27 병합 완료
May 27, 2026
b6e0e5d
feat: 이메일/닉네임 로그인 API PR #26 병합
May 27, 2026
759a72a
feat: jwt.ts 충돌 해결 및 PR #29 카카오 로그인 병합 완료
May 27, 2026
d6b736a
chore: package-lock.json 의존성 최종 동기화
May 27, 2026
a4fc012
chore: prisma 통합 마이그레이션 추가 완료
May 27, 2026
e40c252
fix: 소셜 가입자의 비밀번호 로그인 시 500 에러 취약점 조치 및 검증 강화
May 27, 2026
8d8cc24
fix: 로컬 환경 파일 추적 제거
Siul49 May 27, 2026
fcee40a
chore: CI 검증 범위 보강
Siul49 May 27, 2026
1f8b880
refactor: 일정 메모리 저장소 명명 정리
Siul49 May 27, 2026
83cec4f
chore: 오래된 스켈레톤 문서 정리
Siul49 May 27, 2026
b965f9e
fix: ICS 파서와 Supabase 환경 검증 보강
Siul49 May 27, 2026
b6f3c8c
chore: package-lock 의존성 동기화
Siul49 May 27, 2026
1fab55c
chore: CI 테스트 환경 변수 추가
Siul49 May 27, 2026
9a2168c
fix: ICS 파서 타입 좁히기 보강
Siul49 May 27, 2026
99a7eb0
docs: 제품 문서 버전 구조 정리
Siul49 May 27, 2026
4e20499
chore: 의존성 보안 패치 동기화
Siul49 May 27, 2026
8920591
fix: CI clean install 재현성 보강
Siul49 May 27, 2026
194849b
chore: GitHub Actions 런타임 경고 정리
Siul49 May 27, 2026
e632bc6
fix: 레포 안정성과 문서 기준 보강
Siul49 May 28, 2026
e5c8b30
chore: jose 패키지 추가 및 .env.example 네이버 환경변수 추가
kokkumong May 28, 2026
d62f85f
feat: SocialAccount 모델 추가 및 User 필드 소셜 로그인 대응
kokkumong May 28, 2026
1776987
feat: 네이버 소셜 로그인 구현 — OAuth 클라이언트, JWT, API 라우트, 테스트
kokkumong May 28, 2026
d28f159
fix: CodeRabbit 리뷰 반영 — 네이버 로그인 안정성 및 보안 개선
kokkumong May 28, 2026
dc5606b
feat: 구글 소셜 로그인 구현 (OAuth 2.0)
kokkumong May 28, 2026
2d60858
fix: npm10 lockfile 누락 패키지 보강
Siul49 May 28, 2026
bdc04c8
feat: MOIM UI를 피그마 레퍼런스에 맞게 정리
Siul49 May 28, 2026
702b48c
chore: @supabase/ssr 패키지 추가
kokkumong May 28, 2026
2e57a7f
feat: iCloud 로그인과 소셜 추가 정보 흐름 연결
Siul49 May 28, 2026
2b46e0b
refactor: 구글 환경변수명을 로그인/캘린더 용도별로 분리
kokkumong May 28, 2026
191517b
Merge remote-tracking branch 'origin/feature/30-repo-hygiene-ci' into…
Siul49 May 30, 2026
54aa65f
Merge remote-tracking branch 'origin/feature/35-figma-ui-flow' into m…
Siul49 May 30, 2026
c458fb0
Merge remote-tracking branch 'origin/feature/38-icloud-login-ux' into…
Siul49 May 30, 2026
3db619d
Merge remote-tracking branch 'origin/feature/37-google-login' into me…
Siul49 May 30, 2026
35adb3a
Merge remote-tracking branch 'origin/feature/30-naver-login' into mer…
Siul49 May 30, 2026
1db5291
fix: 소셜 로그인 병합 경로 보강
Siul49 May 30, 2026
47c1bc5
fix: 병합 전 리뷰 지적 보강
Siul49 May 30, 2026
e717a27
fix: E2E 검증 환경 보강
Siul49 May 30, 2026
9a9cf22
fix: PR 41 리뷰 지적 보강
Siul49 May 31, 2026
63f33af
fix: CI lockfile 동기화
Siul49 May 31, 2026
959f6d4
refactor: 소셜 로그인 연동 및 스케줄 캘린더 로직 개선
Siul49 Jun 2, 2026
06fc10e
feat: 로그인 사용성 개선 및 인증 보안 고도화
Siul49 Jun 2, 2026
2b6c079
test: 캘린더 연동 과정 검증을 위한 E2E 통합 테스트 추가
Siul49 Jun 3, 2026
0e45218
feat: 캘린더 연동 해제 기능 및 보안 상태 동적 조회 고도화
Siul49 Jun 3, 2026
01a7526
feat: Pretendard 폰트 추가 및 글로벌 UI/UX 테마 스타일 개선, 소셜 로그인 연동 고도화
Siul49 Jun 6, 2026
09b853b
refactor: 인증 시스템을 Supabase Auth로 통합 (#45)
kokkumong Jun 7, 2026
5c4671b
chore: package-lock.json 동기화 (CI npm ci 실패 수정)
kokkumong Jun 7, 2026
e3c3419
fix: CodeRabbit 코드리뷰 반영 - 인증 라우트 에러 핸들링 보강
kokkumong Jun 7, 2026
6db2092
chore: Vercel 및 Supabase PostgreSQL 서버리스 배포 준비 및 설정 추가
Siul49 Jun 7, 2026
60d6f8e
chore: PostgreSQL multiSchema 및 연결 풀러 형식 적용으로 실서버 데이터베이스 연동성 개선
Siul49 Jun 7, 2026
964342f
style: UI/UX 글로벌 테마 변수 및 스타일 개선
Siul49 Jun 9, 2026
0a3387e
feat: 회원가입 후 캘린더 연동 화면을 온보딩 플로우에 연결 (#49)
kokkumong Jun 9, 2026
fc9633d
chore: Supabase Auth 인증 통합 브랜치 병합 (#45)
Siul49 Jun 9, 2026
c3aa2bf
chore: package-lock.json 동기화 (CI npm ci 실패 수정)
kokkumong Jun 9, 2026
fb9c404
fix: CodeRabbit 리뷰 반영 - 네비게이션/건너뛰기 동선 개선 (#49)
kokkumong Jun 9, 2026
559b7e6
ci: CI Pipeline에 Postgres 서비스 도입 (sqlite→postgres) (#51)
kokkumong Jun 9, 2026
f73977c
Merge pull request #50 from Siul49/feature/49-calendar-connect-onboar…
kokkumong Jun 9, 2026
aea9927
refactor(auth): Supabase Auth 인증 통합 및 기존 커스텀 OAuth 라우트 삭제
Siul49 Jun 10, 2026
d1e73fe
docs: v1 제품 요구사항 정의서(PRD) 추가 및 문서 인덱스 갱신
Siul49 Jun 10, 2026
58b826e
docs: MOIM 시안 기반 UI 수정 계획서 추가 및 인덱스 반영
Siul49 Jun 10, 2026
da8c96e
feat(ui): 모바일 최적화 화면 보완 및 가입자 대시보드 페이지 구현
Siul49 Jun 10, 2026
d8dd7e2
chore: v2 요구사항 및 수익성 관련 기획 문서 폐기 및 인덱스 정리
Siul49 Jun 10, 2026
38ac8b3
feat(schedule): 비주얼 시간표 선택기 개편 및 대시보드 creatorId 연동, 참여자 흐름 고도화
Siul49 Jun 10, 2026
9bad19a
feat(settings): 회원 선호 약속 조건 DB 저장 연동 및 Google/iCloud 캘린더 연동 동적 해제 구현
Siul49 Jun 10, 2026
7c7c6f9
feat(schedule): 호스트 모임 생성 단계를 4단계 위저드(시안 11~14) 및 캘린더 바쁜 시간 차단 기능으로 개편
Siul49 Jun 10, 2026
fe54360
feat(schedule): 참여자 시간 제출 완료 화면 개선, 모바일 터치 드래그 스크롤 간섭 해결 및 스캔 로딩 애니메이…
Siul49 Jun 10, 2026
6118d3a
fix: 애플(iCloud) 캘린더 연동을 JWT+쿠키 방식으로 재정렬 (#54)
kokkumong Jun 10, 2026
b96f121
Merge pull request #55 from Siul49/fix/54-icloud-calendar-cookie-auth
kokkumong Jun 10, 2026
ecbc1dc
test(e2e): Supabase Auth rate limit 우회 E2E Mocking 연동 및 4단계 위저드 시나리오 …
Siul49 Jun 10, 2026
35823f2
feat(dev): 개발 허브에 관리자/호스트 로그인 우회 프리패스 기능 추가
Siul49 Jun 11, 2026
c122675
chore(merge): dev 브랜치 병합 및 충돌 해결
Siul49 Jun 11, 2026
90e9c16
feat(schedule): QA 리뷰 및 이미지 피드백 반영 — 링크 분리, 세션 기반 호스트 인가, 에브리타임 user_…
Siul49 Jun 11, 2026
66526d0
fix(auth): 회원가입 소셜 로그인 버튼을 클라이언트 OAuth 연동 방식으로 수정
Siul49 Jun 11, 2026
1594878
fix(e2e): 호스트 링크 분리에 따른 E2E 테스트 검증 및 경로 오작동 수정
Siul49 Jun 11, 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
18 changes: 18 additions & 0 deletions .agents/docs/1_DOMAIN_CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# 1. Domain Context
**프로젝트 명**: AI 캠퍼스 모임 (MVP 1차)
**핵심 목표**: 에브리타임 시간표와 캘린더 연동을 통해 대학생들의 공통적인 빈 시간을 자동으로 탐색하고 일정을 잡아주는 프론트엔드 환경 구축
**핵심 스택**: `Next.js 14`, `React`, `TypeScript`, `Tailwind CSS v3`, `shadcn/ui`, `Vitest`, `Playwright`

### 주요 도메인

| 도메인 | 설명 | 핵심 파일 |
|--------|------|-----------|
| 스케줄링 | 가용시간 교집합, .ics 파싱, 시간 슬롯 관리 | `src/lib/scheduling/` |
| 인증 | 카카오/구글 소셜 로그인, Supabase Auth | `src/app/(auth)/`, `src/lib/supabase/` |
| UI 컴포넌트 | TimeGrid, ParticipantList 등 도메인 전용 | `src/components/schedule/` |

### 주요 변경 사항
- Next.js 14버전 초기화 및 App 라우터 아키텍처 스캐폴딩 구성 완료 (2026.04.14)
- TDD 기반 프로젝트 구조 수립: Vitest + RTL + Playwright 도입, PRD 기반 폴더 스켈레톤 생성 (2026.04.15)
- Tailwind v3 + shadcn/ui HSL 디자인 토큰 체계 정립 (2026.04.15)
- CI 파이프라인에 lint → test → build 검증 단계 추가 (2026.04.15)
33 changes: 33 additions & 0 deletions .agents/docs/2_EXECUTION_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 2. Execution Plan
**진행 상태**: `Phase 3 (TDD 기반 프로젝트 구조 수립 완료)`

### 완료된 작업 (Done)
- [x] PRD 구조 분석 및 핵심 기술 스택(14분기점) 추출
- [x] Next.js 14 + Tailwind + TypeScript 보일러플레이트 적용 (MOIM 리포지토리)
- [x] Socratic Auto-sync 기본 컨텍스트 1,2,3 초기화
- [x] shadcn/ui 기반 설정(components.json, utils, css var 등) 디폴트 구성 완료
- [x] GitHub Action CI/CD (lint & build test) 배포 구축
- [x] GitHub PR/이슈 템플릿 양식 추가 완료
- [x] 커밋 및 브랜치 규칙 강제화 시스템 세팅 (Husky, commitlint, lint-staged)
- [x] 초보자 친화적 `convention.md` 문서와 `.env.example` 작성 완료
- [x] 시스템적 방어벽(GitHub Actions): PR 및 이슈 템플릿 준수율 자동 검증기 추가
- [x] 테스트 프레임워크 설치 (Vitest + React Testing Library + Playwright)
- [x] PRD 기반 폴더 스켈레톤 생성 (라우팅, 컴포넌트, 비즈니스 로직, 타입)
- [x] 핵심 알고리즘 샘플 테스트 작성 (findCommonSlots — 6개 케이스 통과)
- [x] CI에 테스트 실행 단계 추가 (lint → test → build)
- [x] ARCHITECTURE.md 프로젝트 구조 가이드 작성
- [x] Tailwind v3 + shadcn HSL 디자인 토큰 호환 수정
- [x] ESLint underscore prefix 허용 규칙 추가
- [x] 보안 문제 해결 (GitHub Actions Script Injection 조치 완료)
- [x] 스켈레톤 컴포넌트 시맨틱 HTML(WAI-ARIA) 속성 사전 반영
- [x] 테스트 엣지 케이스 추가 및 Next.js 14 최신 보안 패치 적용
- [x] 랜딩 페이지(page.tsx) 기본 템플릿 제거 및 MOIM Placeholder 적용

### 향후 작업 (To-Do)
- [ ] UI 컴포넌트 실제 구현 (TimeGrid, ParticipantList, AvailabilityResult)
- [ ] Supabase 백엔드 연동 및 OAuth 기본 환경 연결
- [ ] 로그인 페이지 UI + 카카오/구글 소셜 로그인 구현
- [ ] 일정 생성 페이지 폼 UI 구현
- [ ] 참여자 입력 페이지 (캘린더 연동 / 수동 입력) 구현
- [ ] .ics 파서 TDD 구현
- [ ] E2E 테스트 작성 (호스트/참여자 플로우)
58 changes: 58 additions & 0 deletions .agents/docs/3_FILE_INDEX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 3. File Index Map
**현재 디렉터리 위치**: `C:\Users\kksu1\Dev\MOIM`

### 설정 파일 (루트)
| 파일 | 역할 |
|------|------|
| `package.json` | 의존성 & 스크립트 (dev, build, test, lint) |
| `tsconfig.json` | TypeScript 컴파일러 설정, `@/` 경로 별칭 |
| `tailwind.config.ts` | Tailwind v3 + shadcn HSL 디자인 토큰 |
| `vitest.config.ts` | 단위 테스트 러너 설정 (jsdom, 경로 별칭) |
| `playwright.config.ts` | E2E 테스트 설정 (Chromium, localhost:3000) |
| `.eslintrc.json` | ESLint 규칙 (underscore prefix 허용) |
| `commitlint.config.js` | 커밋 메시지 검증 규칙 |
| `components.json` | shadcn/ui CLI 설정 |

### 소스 코드 (`src/`)
| 경로 | 역할 |
|------|------|
| `src/app/layout.tsx` | 루트 레이아웃 (Geist 폰트, 메타데이터) |
| `src/app/page.tsx` | `/` 랜딩 페이지 |
| `src/app/globals.css` | 전역 CSS + 디자인 토큰 (HSL 변수) |
| `src/app/(auth)/layout.tsx` | 인증 전용 레이아웃 (GNB 없음) |
| `src/app/(auth)/login/page.tsx` | `/login` 소셜 로그인 페이지 |
| `src/app/schedule/create/page.tsx` | `/schedule/create` 일정 생성 |
| `src/app/schedule/[id]/page.tsx` | `/schedule/:id` 참여자 진입 |
| `src/components/ui/` | shadcn 원시 컴포넌트 |
| `src/components/schedule/TimeGrid.tsx` | When2meet 시간 그리드 (스켈레톤) |
| `src/components/schedule/ParticipantList.tsx` | 참여자 현황 (스켈레톤) |
| `src/components/schedule/AvailabilityResult.tsx` | 가용시간 결과 (스켈레톤) |
| `src/lib/scheduling/availability.ts` | ⭐ 가용시간 교집합 알고리즘 (구현 완료) |
| `src/lib/scheduling/ics-parser.ts` | .ics 파일 파서 (스켈레톤) |
| `src/lib/scheduling/time-slot.ts` | 시간 슬롯 유틸 (스켈레톤) |
| `src/lib/scheduling/__tests__/` | 단위 테스트 (availability 6개 통과) |
| `src/lib/supabase/client.ts` | Supabase 브라우저 클라이언트 (스켈레톤) |
| `src/lib/supabase/server.ts` | Supabase 서버 클라이언트 (스켈레톤) |
| `src/lib/utils.ts` | 공용 유틸리티 (cn 함수) |
| `src/types/schedule.ts` | 스케줄링 타입 (TimeSlot, ScheduleSession 등) |
| `src/types/user.ts` | 사용자/인증 타입 |
| `src/test-setup.ts` | Vitest 전역 설정 (jest-dom) |

### E2E 테스트 (`e2e/`)
| 파일 | 역할 |
|------|------|
| `e2e/host-flow.spec.ts` | 호스트 플로우 시나리오 (스켈레톤) |
| `e2e/participant-flow.spec.ts` | 참여자 플로우 시나리오 (스켈레톤) |

### CI/CD (`.github/`)
| 파일 | 역할 |
|------|------|
| `.github/workflows/pr-compliance.yml` | PR 템플릿 검사 + 코드 품질 검증 (lint→test→build) |
| `.github/workflows/issue-compliance.yml` | 이슈 템플릿 준수 검사 |

### 문서
| 파일 | 역할 |
|------|------|
| `ARCHITECTURE.md` | 프로젝트 구조 가이드 (팀원 공유용) |
| `convention.md` | 협업 컨벤션 가이드 (커밋, 브랜치, PR, 이슈) |
| `PRD.md` / `PRD.pdf` | 프로젝트 기획 및 요구사항 정의서 |
280 changes: 280 additions & 0 deletions .agents/docs/4_API_RESPONSE_FORMATS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
# 4. API Response Formats

캘린더 연동 3종(에브리타임, Google Calendar, iCloud CalDAV)의 요청/응답 형식을 정리한다.
모든 API는 JSON을 기본 응답 형식으로 사용하며, 에러 응답은 `{ "error": string }` 형태로 통일된다.

---

## 공통 타입

```typescript
// 요일 코드 — 스케줄링 도메인 전반에서 사용
type DayCode = "MON" | "TUE" | "WED" | "THU" | "FRI" | "SAT" | "SUN";

// 빈 시간 슬롯 — 세 연동 모두 최종적으로 이 형태로 변환됨
interface TimeSlot {
day: DayCode;
startHour: number; // 0-23
endHour: number; // 0-23, startHour보다 커야 함
}
```

---

## 1. 에브리타임 (Everytime)

### `POST /api/everytime/timetable`

에브리타임 공유 URL 또는 ICS 파일로 시간표를 받아 빈 시간(`TimeSlot[]`)으로 변환한다.

#### 방법 A — 공유 URL

**Request**
```
Content-Type: application/json

{
"url": "https://everytime.kr/@XXXX"
}
```

Query parameter (선택): `?days=MON,WED,FRI` (기본값: 월~금)

#### 방법 B — ICS 파일 업로드

**Request**
```
Content-Type: multipart/form-data

file: <.ics 파일>
```

#### Response `200`

```typescript
{
timetable: {
lectures: Array<{
name: string;
times: Array<{
day: 0 | 1 | 2 | 3 | 4 | 5 | 6; // 0=월, 1=화, ..., 6=일
startMinute: number; // 자정 기준 분 (예: 540 = 09:00)
endMinute: number; // 자정 기준 분 (예: 705 = 11:45)
}>;
}>;
};
freeSlots: TimeSlot[];
}
```

> **시간 단위**: 에브리타임 API의 `starttime` / `endtime` 값 × 5 = 자정 기준 분
> 예) `starttime=108` → 108 × 5 = 540분 = 09:00

#### 에러 응답

| 상태코드 | 사유 |
|---|---|
| `400` | url 필드 누락, ICS 파일 미첨부, 파일 형식 오류 |
| `415` | Content-Type이 json/multipart 외의 값 |
| `422` | 유효하지 않은 에브리타임 URL, ICS 파싱 실패 |
| `500` | 서버 내부 오류 |

---

## 2. Google Calendar

### `GET /api/google/calendars`

연결된 Google 계정의 캘린더 목록을 반환한다.

#### Response `200`

```typescript
{
calendars: Array<{
id: string;
summary: string;
description?: string;
backgroundColor?: string;
primary?: boolean;
accessRole: string;
}>;
}
```

---

### `GET /api/google/events/query`

특정 캘린더의 기간별 일정을 조회한다.

**Query parameters**

| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
| `calendarId` | string | ✅ | 캘린더 ID |
| `startDate` | string | ✅ | ISO 8601 (예: `2026-05-01T00:00:00Z`) |
| `endDate` | string | ✅ | ISO 8601, startDate보다 이후 |

#### Response `200`

```typescript
{
events: Array<{
id: string;
summary: string;
description?: string;
location?: string;
start: {
dateTime?: string; // ISO 8601 (시간 있는 이벤트)
date?: string; // YYYY-MM-DD (종일 이벤트)
timeZone?: string;
};
end: {
dateTime?: string;
date?: string;
timeZone?: string;
};
status: string;
htmlLink?: string;
}>;
}
```

---

### `POST /api/google/events/create`

**Request**
```typescript
{
calendarId: string;
summary: string; // 1-255자
startDateTime: string; // ISO 8601 (예: "2026-05-14T10:00:00+09:00")
endDateTime: string; // ISO 8601
timeZone?: string; // 예: "Asia/Seoul"
location?: string; // 최대 500자
description?: string; // 최대 8000자
}
```

#### Response `201`

```typescript
{
event: GoogleEvent; // events/query 응답의 단건 항목과 동일
}
```

#### 에러 응답

| 상태코드 | 사유 |
|---|---|
| `401` | Google 계정 미연결 또는 인증 만료 |
| `400` | 필수 파라미터 누락, 날짜 형식 오류 |
| `502` | Google Calendar API 오류 |

---

## 3. iCloud CalDAV

### `GET /api/icloud/calendars`

연결된 iCloud 계정의 캘린더 목록을 반환한다. DB 캐시 우선, 없으면 CalDAV 서버에서 조회한다.

**Query parameter**: `?connectionId=<UUID>`

#### Response `200`

```typescript
{
calendars: Array<{
id: string; // DB UUID
displayName: string;
calendarUrl: string; // CalDAV 캘린더 URL
color: string | null;
}>;
cached: boolean; // true: DB 캐시, false: CalDAV 서버에서 새로 조회
}
```

---

### `POST /api/icloud/events/query`

특정 캘린더의 기간별 일정을 조회한다.

**Request**
```typescript
{
calendarId: string; // DB UUID
startDate: string; // ISO 8601
endDate: string; // ISO 8601
}
```

#### Response `200`

```typescript
{
events: Array<{
uid: string;
title: string;
startAt: string; // ISO 8601
endAt: string; // ISO 8601
isAllDay: boolean;
location: string | null;
description: string | null;
etag: string; // CalDAV ETag (캐시 검증용)
}>;
}
```

---

### `POST /api/icloud/events/create`

**Request**
```typescript
{
calendarId: string; // DB UUID
title: string; // 1-255자
startAt: string; // ISO 8601
endAt: string; // ISO 8601
location?: string; // 최대 500자
description?: string; // 최대 2000자
}
```

#### Response `201`

```typescript
{
uid: string; // 생성된 이벤트 UID
eventUrl: string; // CalDAV href
etag: string; // CalDAV ETag
}
```

#### 에러 응답

| 상태코드 | 사유 |
|---|---|
| `401` | 인증 필요 또는 iCloud 인증 만료 |
| `403` | 캘린더 소유권 불일치 |
| `404` | calendarId 없음 |
| `400` | 입력값 검증 실패 (UUID 형식, 날짜 형식 등) |
| `502` | CalDAV 서버 오류 |

---

## 연동별 비교 요약

| 항목 | 에브리타임 | Google Calendar | iCloud CalDAV |
|---|---|---|---|
| **인증** | 없음 (공개 URL) | OAuth 2.0 (세션 토큰) | Apple ID + 앱 암호 (세션) |
| **시간 형식** | 분 단위 정수 (자정 기준) | ISO 8601 문자열 | ISO 8601 문자열 |
| **요일 표현** | 0~6 정수 (0=월) | 이벤트 날짜에 포함 | 이벤트 날짜에 포함 |
| **종일 이벤트** | 없음 (수업 시간표) | `date` 필드로 구분 | `isAllDay` 플래그 |
| **반복 일정** | 없음 (주간 고정) | recurrence 지원 | 없음 (개별 이벤트 확장) |
| **최종 출력** | `TimeSlot[]` (자동 변환) | `GoogleEvent[]` | `ParsedEvent[]` |
Loading