Skip to content

Latest commit

Β 

History

History
733 lines (572 loc) Β· 22.2 KB

File metadata and controls

733 lines (572 loc) Β· 22.2 KB

μΊ˜λ¦°λ” API

μΊ˜λ¦°λ” 일정(CalendarEvent)κ³Ό μ‚¬μš©μž μΊ˜λ¦°λ”(UserCalendar) APIμž…λ‹ˆλ‹€. μΌμ •μ˜ 생성/쑰회/μˆ˜μ •/μ‚­μ œ, 반볡 일정 ν™•μž₯, μˆ˜μ—… 동기화, μ‚¬μš©μž μΊ˜λ¦°λ” 관리 κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.

라우트 파일: backend/src/routes/calendarEvents.js, backend/src/routes/userCalendars.js, backend/src/routes/memos.js 컨트둀러 파일: backend/src/controllers/calendarEvents.js, backend/src/controllers/userCalendars.js, backend/src/controllers/memos.js λͺ¨λΈ 파일: backend/src/models/CalendarEvent.js, backend/src/models/UserCalendar.js (λ©”λͺ¨λŠ” Registration.memos)


μ—”λ“œν¬μΈνŠΈ μš”μ•½

CalendarEvent

λ©”μ„œλ“œ 경둜 μ„€λͺ… κΆŒν•œ
POST /api/calendar-events 일정 생성 isLoggedIn (admin|manager - 학ꡐ λ²”μœ„)
GET /api/calendar-events 일정 λͺ©λ‘ 쑰회 isLoggedIn
PUT /api/calendar-events/:_id 일정 μˆ˜μ • isLoggedIn (μ†Œμœ μž λ˜λŠ” admin|manager)
DELETE /api/calendar-events/:_id 일정 μ‚­μ œ isLoggedIn (μ†Œμœ μž λ˜λŠ” admin|manager)
POST /api/calendar-events/sync μˆ˜μ—… 일정 동기화 isLoggedIn

UserCalendar

λ©”μ„œλ“œ 경둜 μ„€λͺ… κΆŒν•œ
POST /api/user-calendars μ‚¬μš©μž μΊ˜λ¦°λ” 생성 isLoggedIn (admin|manager - 학ꡐ λ²”μœ„)
GET /api/user-calendars μ‚¬μš©μž μΊ˜λ¦°λ” λͺ©λ‘ 쑰회 isLoggedIn
PUT /api/user-calendars/:_id μ‚¬μš©μž μΊ˜λ¦°λ” μˆ˜μ • isLoggedIn (μ†Œμœ μž λ˜λŠ” admin|manager)
DELETE /api/user-calendars/:_id μ‚¬μš©μž μΊ˜λ¦°λ” μ‚­μ œ isLoggedIn (μ†Œμœ μž λ˜λŠ” admin|manager)

Registration Memo (/api/memos)

등둝(registration)에 λΆ™λŠ” 개인 μ‹œκ°„ν‘œ λ©”λͺ¨μž…λ‹ˆλ‹€. μˆ˜κ°• enrollment의 memo ν•„λ“œμ™€λŠ” λ³„κ°œμ΄λ©°, μΊ˜λ¦°λ” sync의 sourceType: "memo" μ›μ²œμ΄ λ©λ‹ˆλ‹€.

λ©”μ„œλ“œ 경둜 μ„€λͺ… κΆŒν•œ
POST /api/memos λ©”λͺ¨ μΆ”κ°€ isLoggedIn (본인 registration)
PUT /api/memos/:_id λ©”λͺ¨ μˆ˜μ • isLoggedIn (본인 registration)
DELETE /api/memos/:_id λ©”λͺ¨ μ‚­μ œ isLoggedIn (본인 registration)

일정 생성

μΊ˜λ¦°λ” 일정을 μƒμ„±ν•©λ‹ˆλ‹€. scopeκ°€ "school"인 경우 admin λ˜λŠ” manager κΆŒν•œμ΄ ν•„μš”ν•˜λ©°, school ν•„λ“œκ°€ ν•„μˆ˜μž…λ‹ˆλ‹€.

POST /api/calendar-events

κΆŒν•œ: isLoggedIn (학ꡐ λ²”μœ„ 일정 생성 μ‹œ admin λ˜λŠ” manager)

μš”μ²­ λ³Έλ¬Έ

ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
title string O 일정 제λͺ©
start string (ISO 8601) O μ‹œμž‘ μΌμ‹œ
end string (ISO 8601) O μ’…λ£Œ μΌμ‹œ
scope string O "school" λ˜λŠ” "personal"
description string X 일정 μ„€λͺ… (κΈ°λ³Έκ°’: "")
isAllDay boolean X 쒅일 일정 μ—¬λΆ€ (κΈ°λ³Έκ°’: false)
school ObjectId 쑰건뢀 학ꡐ ID (scopeκ°€ "school"일 λ•Œ ν•„μˆ˜)
recurrence object X 반볡 μ„€μ •
recurrence.type string X "none" | "daily" | "weekly" | "monthly" (κΈ°λ³Έκ°’: "none")
recurrence.endDate string (ISO 8601) X 반볡 μ’…λ£ŒμΌ
recurrence.days number[] X 반볡 μš”μΌ (0=일, 1=μ›”, ..., 6=ν† ). weekly νƒ€μž…μ—μ„œ μ‚¬μš©
color string X 일정 색상 (κΈ°λ³Έκ°’: "#4285f4")
calendarId ObjectId X μ†Œμ† μ‚¬μš©μž μΊ˜λ¦°λ” ID
reminder object X μ•Œλ¦Ό μ„€μ •
reminder.enabled boolean X μ•Œλ¦Ό ν™œμ„±ν™” μ—¬λΆ€ (κΈ°λ³Έκ°’: false)
reminder.minutesBefore number X μ•Œλ¦Ό μ‹œκ°„ (λΆ„ λ‹¨μœ„)
reminder.useDefault boolean X κΈ°λ³Έ μ•Œλ¦Ό μ‚¬μš© μ—¬λΆ€ (κΈ°λ³Έκ°’: true)

μš”μ²­ μ˜ˆμ‹œ

{
  "title": "νŒ€ λ―ΈνŒ…",
  "start": "2024-03-15T10:00:00.000Z",
  "end": "2024-03-15T11:00:00.000Z",
  "scope": "personal",
  "description": "μ£Όκ°„ νŒ€ λ―ΈνŒ…",
  "isAllDay": false,
  "recurrence": {
    "type": "weekly",
    "endDate": "2024-06-30T23:59:59.000Z",
    "days": [1, 3, 5]
  },
  "color": "#34a853",
  "reminder": {
    "enabled": true,
    "minutesBefore": 10,
    "useDefault": false
  }
}

응닡 (200)

{
  "calendarEvent": {
    "_id": "507f1f77bcf86cd799439011",
    "title": "νŒ€ λ―ΈνŒ…",
    "description": "μ£Όκ°„ νŒ€ λ―ΈνŒ…",
    "start": "2024-03-15T10:00:00.000Z",
    "end": "2024-03-15T11:00:00.000Z",
    "isAllDay": false,
    "scope": "personal",
    "user": "507f1f77bcf86cd799439022",
    "recurrence": {
      "type": "weekly",
      "endDate": "2024-06-30T23:59:59.000Z",
      "days": [1, 3, 5]
    },
    "color": "#34a853",
    "reminder": {
      "enabled": true,
      "minutesBefore": 10,
      "useDefault": false
    },
    "sourceType": "manual",
    "createdAt": "2024-03-10T09:00:00.000Z",
    "updatedAt": "2024-03-10T09:00:00.000Z"
  }
}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
400 FIELD_REQUIRED({ν•„λ“œλͺ…}) ν•„μˆ˜ ν•„λ“œ λˆ„λ½ (title, start, end, scope, school)
400 FIELD_INVALID(scope) scope 값이 "school" λ˜λŠ” "personal"이 μ•„λ‹˜
403 PERMISSION_DENIED 학ꡐ λ²”μœ„ 일정 생성 μ‹œ κΆŒν•œ λΆ€μ‘±

일정 λͺ©λ‘ 쑰회

μ§€μ •λœ λ‚ μ§œ λ²”μœ„ λ‚΄μ˜ 일정을 μ‘°νšŒν•©λ‹ˆλ‹€. 반볡 일정은 μžλ™μœΌλ‘œ κ°œλ³„ μΈμŠ€ν„΄μŠ€λ‘œ ν™•μž₯λ©λ‹ˆλ‹€. scopeλ₯Ό μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ 개인 일정과 학ꡐ 일정을 λͺ¨λ‘ μ‘°νšŒν•©λ‹ˆλ‹€.

GET /api/calendar-events

κΆŒν•œ: isLoggedIn

쿼리 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ μ„€λͺ…
startDate string (ISO 8601) O 쑰회 μ‹œμž‘μΌ
endDate string (ISO 8601) O 쑰회 μ’…λ£ŒμΌ
scope string X "school" λ˜λŠ” "personal". λ―Έμ§€μ • μ‹œ 전체
school ObjectId X 학ꡐ ID ν•„ν„°
user ObjectId X λŒ€μƒ μ‚¬μš©μž ID (λ―Έμ§€μ • μ‹œ 둜그인 μ‚¬μš©μž)

μš”μ²­ μ˜ˆμ‹œ

GET /api/calendar-events?startDate=2024-03-01T00:00:00.000Z&endDate=2024-03-31T23:59:59.000Z&school=507f1f77bcf86cd799439033

응닡 (200)

반볡 일정은 쑰회 λ²”μœ„ λ‚΄μ—μ„œ κ°œλ³„ μΈμŠ€ν„΄μŠ€λ‘œ ν™•μž₯λ˜μ–΄ λ°˜ν™˜λ©λ‹ˆλ‹€. ν™•μž₯된 μΈμŠ€ν„΄μŠ€μ—λŠ” isRecurrenceInstance: true와 recurrenceParentId ν•„λ“œκ°€ μΆ”κ°€λ©λ‹ˆλ‹€.

{
  "calendarEvents": [
    {
      "_id": "507f1f77bcf86cd799439011",
      "title": "기말고사",
      "description": "1ν•™κΈ° 기말고사",
      "start": "2024-03-20T09:00:00.000Z",
      "end": "2024-03-22T18:00:00.000Z",
      "isAllDay": true,
      "scope": "school",
      "school": "507f1f77bcf86cd799439033",
      "user": "507f1f77bcf86cd799439022",
      "recurrence": { "type": "none" },
      "color": "#4285f4",
      "sourceType": "manual",
      "createdAt": "2024-03-01T09:00:00.000Z",
      "updatedAt": "2024-03-01T09:00:00.000Z"
    },
    {
      "_id": "507f1f77bcf86cd799439012",
      "title": "νŒ€ λ―ΈνŒ…",
      "start": "2024-03-18T10:00:00.000Z",
      "end": "2024-03-18T11:00:00.000Z",
      "isAllDay": false,
      "scope": "personal",
      "user": "507f1f77bcf86cd799439022",
      "recurrence": {
        "type": "weekly",
        "endDate": "2024-06-30T23:59:59.000Z",
        "days": [1, 3, 5]
      },
      "color": "#34a853",
      "sourceType": "manual",
      "isRecurrenceInstance": true,
      "recurrenceParentId": "507f1f77bcf86cd799439012",
      "createdAt": "2024-03-10T09:00:00.000Z",
      "updatedAt": "2024-03-10T09:00:00.000Z"
    }
  ]
}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
400 FIELD_REQUIRED(startDate) startDate λ˜λŠ” endDate λˆ„λ½

일정 μˆ˜μ •

κΈ°μ‘΄ μΊ˜λ¦°λ” 일정을 μˆ˜μ •ν•©λ‹ˆλ‹€. 개인 일정은 μ†Œμœ μžλ§Œ, 학ꡐ 일정은 admin λ˜λŠ” manager만 μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

PUT /api/calendar-events/:_id

κΆŒν•œ: isLoggedIn (개인 일정: μ†Œμœ μž, 학ꡐ 일정: admin λ˜λŠ” manager)

경둜 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… μ„€λͺ…
_id ObjectId 일정 ID

μš”μ²­ λ³Έλ¬Έ

ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
title string X 일정 제λͺ©
description string X 일정 μ„€λͺ…
start string (ISO 8601) X μ‹œμž‘ μΌμ‹œ
end string (ISO 8601) X μ’…λ£Œ μΌμ‹œ
isAllDay boolean X 쒅일 일정 μ—¬λΆ€
recurrence object X 반볡 μ„€μ •
recurrence.type string X "none" | "daily" | "weekly" | "monthly"
recurrence.endDate string (ISO 8601) X 반볡 μ’…λ£ŒμΌ
recurrence.days number[] X 반볡 μš”μΌ (0-6)
color string X 일정 색상
calendarId ObjectId X μ†Œμ† μ‚¬μš©μž μΊ˜λ¦°λ” ID
reminder object X μ•Œλ¦Ό μ„€μ •
reminder.enabled boolean X μ•Œλ¦Ό ν™œμ„±ν™” μ—¬λΆ€
reminder.minutesBefore number X μ•Œλ¦Ό μ‹œκ°„ (λΆ„ λ‹¨μœ„)
reminder.useDefault boolean X κΈ°λ³Έ μ•Œλ¦Ό μ‚¬μš© μ—¬λΆ€

μš”μ²­ μ˜ˆμ‹œ

{
  "title": "νŒ€ λ―ΈνŒ… (λ³€κ²½)",
  "start": "2024-03-15T14:00:00.000Z",
  "end": "2024-03-15T15:30:00.000Z",
  "color": "#ff9800"
}

응닡 (200)

{
  "calendarEvent": {
    "_id": "507f1f77bcf86cd799439011",
    "title": "νŒ€ λ―ΈνŒ… (λ³€κ²½)",
    "description": "μ£Όκ°„ νŒ€ λ―ΈνŒ…",
    "start": "2024-03-15T14:00:00.000Z",
    "end": "2024-03-15T15:30:00.000Z",
    "isAllDay": false,
    "scope": "personal",
    "user": "507f1f77bcf86cd799439022",
    "recurrence": {
      "type": "weekly",
      "endDate": "2024-06-30T23:59:59.000Z",
      "days": [1, 3, 5]
    },
    "color": "#ff9800",
    "sourceType": "manual",
    "createdAt": "2024-03-10T09:00:00.000Z",
    "updatedAt": "2024-03-15T12:00:00.000Z"
  }
}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
403 PERMISSION_DENIED μˆ˜μ • κΆŒν•œ μ—†μŒ
404 calendarEvent_NOT_FOUND 일정을 찾을 수 μ—†μŒ

일정 μ‚­μ œ

μΊ˜λ¦°λ” 일정을 μ‚­μ œν•©λ‹ˆλ‹€. 개인 일정은 μ†Œμœ μžλ§Œ, 학ꡐ 일정은 admin λ˜λŠ” manager만 μ‚­μ œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

DELETE /api/calendar-events/:_id

κΆŒν•œ: isLoggedIn (개인 일정: μ†Œμœ μž, 학ꡐ 일정: admin λ˜λŠ” manager)

경둜 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… μ„€λͺ…
_id ObjectId 일정 ID

응닡 (200)

{}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
403 PERMISSION_DENIED μ‚­μ œ κΆŒν•œ μ—†μŒ
404 calendarEvent_NOT_FOUND 일정을 찾을 수 μ—†μŒ

μˆ˜μ—… 일정 동기화

μˆ˜κ°• 정보(enrollment), κ°•μ˜ 정보(syllabus), λ©”λͺ¨(memo)λ₯Ό μΊ˜λ¦°λ” μΌμ •μœΌλ‘œ λ™κΈ°ν™”ν•©λ‹ˆλ‹€. 등둝(registration)의 κΈ°κ°„ 정보λ₯Ό 기반으둜 λ§€μ£Ό 반볡 일정을 μƒμ„±ν•˜λ©°, sourceType/sourceIdλ₯Ό μ‚¬μš©ν•œ upsert μ „λž΅μœΌλ‘œ 쀑볡을 λ°©μ§€ν•©λ‹ˆλ‹€.

POST /api/calendar-events/sync

κΆŒν•œ: isLoggedIn (λ‹€λ₯Έ μ‚¬μš©μž λŒ€μƒ 동기화 μ‹œ admin, manager λ˜λŠ” teacher)

μš”μ²­ λ³Έλ¬Έ

ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
season ObjectId O ν•™κΈ° ID
targetUser ObjectId X 동기화 λŒ€μƒ μ‚¬μš©μž ID (λ―Έμ§€μ • μ‹œ 둜그인 μ‚¬μš©μž)

μš”μ²­ μ˜ˆμ‹œ

{
  "season": "507f1f77bcf86cd799439044"
}

동기화 상세

동기화 μ‹œ λ‹€μŒ μ„Έ κ°€μ§€ μ†ŒμŠ€μ—μ„œ 일정이 μƒμ„±λ©λ‹ˆλ‹€:

μ†ŒμŠ€ sourceType 색상 μ„€λͺ…
μˆ˜κ°• 정보 "enrollment" #4285f4 (νŒŒλž‘) ν•™μƒμ˜ μˆ˜κ°• μ‹œκ°„ν‘œ
κ°•μ˜ 정보 "syllabus" #34a853 (초둝) κ΅μ‚¬μ˜ κ°•μ˜ μ‹œκ°„ν‘œ
λ©”λͺ¨ "memo" #ff9800 (μ£Όν™©) 등둝 λ©”λͺ¨μ˜ μ‹œκ°„ν‘œ

동기화 κ³Όμ •:

  1. 등둝(registration)의 κΈ°κ°„(period) 정보 쑰회
  2. μˆ˜κ°•/κ°•μ˜/λ©”λͺ¨μ˜ μ‹œκ°„ 정보λ₯Ό 기반으둜 λ§€μ£Ό 반볡 일정 데이터 생성
  3. sourceIdλ₯Ό ν‚€λ‘œ upsert μ‹€ν–‰ (enrollment/syllabusλŠ” $set, memoλŠ” $setOnInsert)
  4. 더 이상 μœ νš¨ν•˜μ§€ μ•Šμ€ κ³ μ•„ 이벀트 μ‚­μ œ
  5. 동일 sourceId의 쀑볡 이벀트 정리 (μ΅œμ‹  1건만 μœ μ§€)

μ°Έκ³ : sourceId ν˜•μ‹μ€ {sourceType}_{documentId}_{timeIndex} μž…λ‹ˆλ‹€ (예: enrollment_507f1f77_0).

응닡 (200)

{
  "synced": 5,
  "removed": 2,
  "total": 8
}
ν•„λ“œ νƒ€μž… μ„€λͺ…
synced number μƒˆλ‘œ μƒμ„±λœ 일정 수
removed number μ‚­μ œλœ κ³ μ•„/쀑볡 일정 수
total number 동기화 λŒ€μƒ 전체 일정 수

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
400 FIELD_REQUIRED(season) season ν•„λ“œ λˆ„λ½
403 PERMISSION_DENIED λ‹€λ₯Έ μ‚¬μš©μž λŒ€μƒ 동기화 μ‹œ κΆŒν•œ λΆ€μ‘±
404 registration_NOT_FOUND ν•΄λ‹Ή ν•™κΈ°/μ‚¬μš©μžμ˜ 등둝 정보λ₯Ό 찾을 수 μ—†μŒ

μ‚¬μš©μž μΊ˜λ¦°λ” 생성

μ‚¬μš©μž μΊ˜λ¦°λ”(μΊ˜λ¦°λ” κ·Έλ£Ή)λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 일정을 μΊ˜λ¦°λ”λ³„λ‘œ λΆ„λ₯˜ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

POST /api/user-calendars

κΆŒν•œ: isLoggedIn (학ꡐ λ²”μœ„ μΊ˜λ¦°λ” 생성 μ‹œ admin λ˜λŠ” manager)

μš”μ²­ λ³Έλ¬Έ

ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
name string O μΊ˜λ¦°λ” 이름
color string X μΊ˜λ¦°λ” 색상 (κΈ°λ³Έκ°’: "#4285f4")
scope string X "school" λ˜λŠ” "personal" (κΈ°λ³Έκ°’: "personal")
school ObjectId 쑰건뢀 학ꡐ ID (scopeκ°€ "school"일 λ•Œ ν•„μˆ˜)

μš”μ²­ μ˜ˆμ‹œ

{
  "name": "개인 ν•™μŠ΅",
  "color": "#e91e63"
}

응닡 (200)

{
  "userCalendar": {
    "_id": "507f1f77bcf86cd799439055",
    "user": "507f1f77bcf86cd799439022",
    "name": "개인 ν•™μŠ΅",
    "color": "#e91e63",
    "scope": "personal",
    "isDefault": false,
    "createdAt": "2024-03-10T09:00:00.000Z",
    "updatedAt": "2024-03-10T09:00:00.000Z"
  }
}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
400 FIELD_REQUIRED(name) name ν•„λ“œ λˆ„λ½
400 FIELD_REQUIRED(school) 학ꡐ λ²”μœ„μ—μ„œ school ν•„λ“œ λˆ„λ½
403 PERMISSION_DENIED 학ꡐ λ²”μœ„ μΊ˜λ¦°λ” 생성 μ‹œ κΆŒν•œ λΆ€μ‘±

μ‚¬μš©μž μΊ˜λ¦°λ” λͺ©λ‘ 쑰회

둜그인 μ‚¬μš©μžμ˜ 개인 μΊ˜λ¦°λ”μ™€ 학ꡐ μΊ˜λ¦°λ”λ₯Ό μ‘°νšŒν•©λ‹ˆλ‹€. κΈ°λ³Έ μΊ˜λ¦°λ”(isDefault)κ°€ λ¨Όμ € μ •λ ¬λ˜λ©°, 이후 μƒμ„±μΌμ‹œ 순으둜 μ •λ ¬λ©λ‹ˆλ‹€.

GET /api/user-calendars

κΆŒν•œ: isLoggedIn

쿼리 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… ν•„μˆ˜ μ„€λͺ…
school ObjectId X 학ꡐ ID (학ꡐ λ²”μœ„ μΊ˜λ¦°λ” ν•„ν„°)

μš”μ²­ μ˜ˆμ‹œ

GET /api/user-calendars?school=507f1f77bcf86cd799439033

응닡 (200)

{
  "userCalendars": [
    {
      "_id": "507f1f77bcf86cd799439055",
      "user": "507f1f77bcf86cd799439022",
      "name": "κΈ°λ³Έ μΊ˜λ¦°λ”",
      "color": "#4285f4",
      "scope": "personal",
      "isDefault": true,
      "createdAt": "2024-01-01T00:00:00.000Z",
      "updatedAt": "2024-01-01T00:00:00.000Z"
    },
    {
      "_id": "507f1f77bcf86cd799439056",
      "user": "507f1f77bcf86cd799439022",
      "name": "개인 ν•™μŠ΅",
      "color": "#e91e63",
      "scope": "personal",
      "isDefault": false,
      "createdAt": "2024-03-10T09:00:00.000Z",
      "updatedAt": "2024-03-10T09:00:00.000Z"
    },
    {
      "_id": "507f1f77bcf86cd799439057",
      "user": "507f1f77bcf86cd799439030",
      "school": "507f1f77bcf86cd799439033",
      "name": "학ꡐ 행사",
      "color": "#ff5722",
      "scope": "school",
      "isDefault": false,
      "createdAt": "2024-02-01T09:00:00.000Z",
      "updatedAt": "2024-02-01T09:00:00.000Z"
    }
  ]
}

μ‚¬μš©μž μΊ˜λ¦°λ” μˆ˜μ •

μ‚¬μš©μž μΊ˜λ¦°λ”μ˜ 이름과 색상을 μˆ˜μ •ν•©λ‹ˆλ‹€.

PUT /api/user-calendars/:_id

κΆŒν•œ: isLoggedIn (μ†Œμœ μž λ˜λŠ” admin/manager)

경둜 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… μ„€λͺ…
_id ObjectId μ‚¬μš©μž μΊ˜λ¦°λ” ID

μš”μ²­ λ³Έλ¬Έ

ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
name string X μΊ˜λ¦°λ” 이름
color string X μΊ˜λ¦°λ” 색상

μš”μ²­ μ˜ˆμ‹œ

{
  "name": "개인 ν•™μŠ΅ (μˆ˜μ •)",
  "color": "#9c27b0"
}

응닡 (200)

{
  "userCalendar": {
    "_id": "507f1f77bcf86cd799439055",
    "user": "507f1f77bcf86cd799439022",
    "name": "개인 ν•™μŠ΅ (μˆ˜μ •)",
    "color": "#9c27b0",
    "scope": "personal",
    "isDefault": false,
    "createdAt": "2024-03-10T09:00:00.000Z",
    "updatedAt": "2024-03-15T12:00:00.000Z"
  }
}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
403 PERMISSION_DENIED μˆ˜μ • κΆŒν•œ μ—†μŒ
404 userCalendar_NOT_FOUND μΊ˜λ¦°λ”λ₯Ό 찾을 수 μ—†μŒ

μ‚¬μš©μž μΊ˜λ¦°λ” μ‚­μ œ

μ‚¬μš©μž μΊ˜λ¦°λ”λ₯Ό μ‚­μ œν•©λ‹ˆλ‹€. κΈ°λ³Έ μΊ˜λ¦°λ”(isDefault: true)λŠ” μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€.

DELETE /api/user-calendars/:_id

κΆŒν•œ: isLoggedIn (μ†Œμœ μž λ˜λŠ” admin/manager)

경둜 νŒŒλΌλ―Έν„°

νŒŒλΌλ―Έν„° νƒ€μž… μ„€λͺ…
_id ObjectId μ‚¬μš©μž μΊ˜λ¦°λ” ID

응닡 (200)

{}

μ—λŸ¬ 응닡

μƒνƒœ μ½”λ“œ λ©”μ‹œμ§€ μ„€λͺ…
400 κΈ°λ³Έ μΊ˜λ¦°λ”λŠ” μ‚­μ œν•  수 μ—†μŠ΅λ‹ˆλ‹€. κΈ°λ³Έ μΊ˜λ¦°λ” μ‚­μ œ μ‹œλ„
403 PERMISSION_DENIED μ‚­μ œ κΆŒν•œ μ—†μŒ
404 userCalendar_NOT_FOUND μΊ˜λ¦°λ”λ₯Ό 찾을 수 μ—†μŒ

데이터 λͺ¨λΈ

CalendarEvent

ν•„λ“œ νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
_id ObjectId μžλ™ - 고유 ID
title string O - 일정 제λͺ©
description string X "" 일정 μ„€λͺ…
start Date O - μ‹œμž‘ μΌμ‹œ
end Date O - μ’…λ£Œ μΌμ‹œ
isAllDay boolean X false 쒅일 일정 μ—¬λΆ€
scope string O - "school" | "personal"
school ObjectId X - 학ꡐ ID
user ObjectId O - μƒμ„±μž ID
recurrence.type string X "none" "none" | "daily" | "weekly" | "monthly"
recurrence.endDate Date X - 반볡 μ’…λ£ŒμΌ
recurrence.days number[] X [] 반볡 μš”μΌ (0-6)
color string X "#4285f4" 일정 색상
reminder.enabled boolean X false μ•Œλ¦Ό ν™œμ„±ν™”
reminder.minutesBefore number X - μ•Œλ¦Ό μ‹œκ°„ (λΆ„)
reminder.useDefault boolean X true κΈ°λ³Έ μ•Œλ¦Ό μ‚¬μš©
sourceType string X "manual" "manual" | "enrollment" | "syllabus" | "memo"
sourceId string X - 동기화 좜처 ID
syllabusId ObjectId X - μ—°κ²°λœ κ°•μ˜ κ³„νš ID
calendarId ObjectId X - μ†Œμ† μ‚¬μš©μž μΊ˜λ¦°λ” ID
createdAt Date μžλ™ - 생성 μΌμ‹œ
updatedAt Date μžλ™ - μˆ˜μ • μΌμ‹œ

인덱슀:

인덱슀 ν•„λ“œ
school_1_scope_1 { school: 1, scope: 1 }
user_1_scope_1 { user: 1, scope: 1 }
user_1_sourceType_1_sourceId_1 { user: 1, sourceType: 1, sourceId: 1 }
user_1_recurrence.type_1_start_1_end_1 { user: 1, "recurrence.type": 1, start: 1, end: 1 }
school_1_recurrence.type_1_start_1_end_1 { school: 1, "recurrence.type": 1, start: 1, end: 1 }

UserCalendar

ν•„λ“œ νƒ€μž… ν•„μˆ˜ κΈ°λ³Έκ°’ μ„€λͺ…
_id ObjectId μžλ™ - 고유 ID
user ObjectId O - μ†Œμœ μž ID
school ObjectId X - 학ꡐ ID
name string O - μΊ˜λ¦°λ” 이름
color string X "#4285f4" μΊ˜λ¦°λ” 색상
scope string X "personal" "school" | "personal"
isDefault boolean X false κΈ°λ³Έ μΊ˜λ¦°λ” μ—¬λΆ€ (μ‚­μ œ λΆˆκ°€)
createdAt Date μžλ™ - 생성 μΌμ‹œ
updatedAt Date μžλ™ - μˆ˜μ • μΌμ‹œ

인덱슀:

인덱슀 ν•„λ“œ
user_1 { user: 1 }
user_1_school_1 { user: 1, school: 1 }

Registration Memo API

μ‹œκ°„ν‘œμš© 개인 λ©”λͺ¨λ₯Ό Registration.memos 배열에 μΆ”κ°€Β·μˆ˜μ •Β·μ‚­μ œν•©λ‹ˆλ‹€. 본인 λ“±λ‘λ§Œ μˆ˜μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

생성

POST /api/memos
ν•„λ“œ νƒ€μž… ν•„μˆ˜ μ„€λͺ…
registration string O 등둝 ObjectId
title string X 제λͺ©
day number/string X μš”μΌ
start string X μ‹œμž‘ μ‹œκ°
end string X μ’…λ£Œ μ‹œκ°
classroom string X κ°•μ˜μ‹€
memo string X λ©”λͺ¨ λ³Έλ¬Έ

응닡 (200)

{ "memos": [ { "_id": "…", "title": "μžμœ¨ν•™μŠ΅", "day": 1, "start": "14:00", "end": "15:00", "memo": "" } ] }

μˆ˜μ • / μ‚­μ œ

PUT    /api/memos/:_id   // body에 registration + ν•„λ“œ
DELETE /api/memos/:_id?registration=

등둝이 μ—†κ±°λ‚˜ 본인 것이 μ•„λ‹ˆλ©΄ 401/404μž…λ‹ˆλ‹€.


ν”„λ‘ νŠΈμ—”λ“œ API ν•¨μˆ˜ (useAPIv2)

CalendarEventAPI

ν•¨μˆ˜λͺ… λ©”μ„œλ“œ 경둜 μ„€λͺ…
CCalendarEvent POST /api/calendar-events 일정 생성
RCalendarEvents GET /api/calendar-events 일정 λͺ©λ‘ 쑰회
UCalendarEvent PUT /api/calendar-events/:_id 일정 μˆ˜μ •
DCalendarEvent DELETE /api/calendar-events/:_id 일정 μ‚­μ œ
SyncCalendarEvents POST /api/calendar-events/sync μˆ˜μ—… 일정 동기화

UserCalendarAPI

ν•¨μˆ˜λͺ… λ©”μ„œλ“œ 경둜 μ„€λͺ…
CUserCalendar POST /api/user-calendars μ‚¬μš©μž μΊ˜λ¦°λ” 생성
RUserCalendars GET /api/user-calendars μ‚¬μš©μž μΊ˜λ¦°λ” λͺ©λ‘ 쑰회
UUserCalendar PUT /api/user-calendars/:_id μ‚¬μš©μž μΊ˜λ¦°λ” μˆ˜μ •
DUserCalendar DELETE /api/user-calendars/:_id μ‚¬μš©μž μΊ˜λ¦°λ” μ‚­μ œ