@startuml meeting-Todo할당
!theme mono

title Meeting Service - Todo할당 내부 시퀀스

participant "TodoController" as Controller
participant "TodoService" as Service
participant "TodoRepository" as TodoRepo
participant "MinutesRepository" as MinutesRepo
participant "CalendarService" as CalendarService
database "Meeting DB<<E>>" as DB
database "Redis Cache<<E>>" as Cache
queue "Azure Event Hubs<<E>>" as EventHub

[-> Controller: POST /todos
activate Controller

note over Controller
요청 데이터:
{
  "content": "Todo 내용",
  "assignee": "user@example.com",
  "dueDate": "2025-01-30",
  "priority": "HIGH" | "MEDIUM" | "LOW",
  "minutesId": "uuid",
  "sectionId": "uuid"  // 회의록 섹션 위치
}
사용자 정보: userId, userName, email
end note

Controller -> Controller: 입력 검증\n- content 필수\n- assignee 필수\n- minutesId 필수

Controller -> Service: createTodo(request, userId)
activate Service

note over Service
비즈니스 규칙:
- Todo 내용 최대 500자
- 마감일은 현재보다 미래여야 함
- 회의록 존재 확인
- 담당자 유효성 검증
end note

' 회의록 존재 확인
Service -> MinutesRepo: findById(minutesId)
activate MinutesRepo
MinutesRepo -> DB: 회의록 정보 조회
activate DB
DB --> MinutesRepo: 회의록 정보
deactivate DB
MinutesRepo --> Service: Minutes
deactivate MinutesRepo

Service -> Service: 회의록 존재 확인

' Todo 생성
Service -> Service: Todo 엔티티 생성\n- todoId (UUID)\n- 상태: IN_PROGRESS\n- 생성 정보

Service -> TodoRepo: save(todo)
activate TodoRepo
TodoRepo -> DB: Todo 정보 저장
activate DB
DB --> TodoRepo: Todo 저장 완료
deactivate DB
TodoRepo --> Service: Todo
deactivate TodoRepo

note over Service
회의록 양방향 연결:
- 회의록 섹션에 Todo 뱃지 추가
- Todo에서 회의록 섹션으로 링크
end note

' 회의록 섹션에 Todo 연결
Service -> MinutesRepo: linkTodoToSection(sectionId, todoId)
activate MinutesRepo
MinutesRepo -> DB: 회의록 섹션에 Todo 연결
activate DB
DB --> MinutesRepo: 업데이트 완료
deactivate DB
MinutesRepo --> Service: 연결 성공
deactivate MinutesRepo

' 마감일이 있는 경우 캘린더 연동
alt 마감일 설정됨
    Service -> CalendarService: createTodoEvent(todo)
    activate CalendarService

    note over CalendarService
    캘린더 이벤트 생성:
    - 제목: Todo 내용
    - 일시: 마감일
    - 참석자: 담당자
    - 리마인더: 마감 3일 전
    end note

    CalendarService -> CalendarService: 캘린더 이벤트 생성
    CalendarService --> Service: 이벤트 ID
    deactivate CalendarService

    Service -> TodoRepo: updateCalendarEventId(todoId, eventId)
    activate TodoRepo
    TodoRepo -> DB: 캘린더 이벤트 ID 업데이트
    activate DB
    DB --> TodoRepo: 업데이트 완료
    deactivate DB
    TodoRepo --> Service: 업데이트 성공
    deactivate TodoRepo
end

' 캐시 무효화
Service -> Cache: DELETE dashboard:{assigneeId}
activate Cache
Cache --> Service: 삭제 완료
deactivate Cache

Service -> Cache: DELETE minutes:detail:{minutesId}
activate Cache
Cache --> Service: 삭제 완료
deactivate Cache

note over Service
비동기 이벤트 발행:
- 담당자에게 즉시 알림 발송
- 회의록 실시간 업데이트 (WebSocket)
- 캘린더 초대 발송
end note

' 이벤트 발행
Service -> EventHub: publish(TodoAssigned)\n{\n  todoId, content, assignee,\n  dueDate, minutesId, sectionId,\n  assignedBy, calendarEventId\n}
activate EventHub
EventHub --> Service: 발행 완료
deactivate EventHub

Service --> Controller: TodoResponse
deactivate Service

note over Controller
응답 데이터:
{
  "todoId": "uuid",
  "content": "Todo 내용",
  "assignee": "user@example.com",
  "dueDate": "2025-01-30",
  "priority": "HIGH",
  "status": "IN_PROGRESS",
  "minutesId": "uuid",
  "sectionId": "uuid",
  "calendarEventId": "...",
  "createdAt": "2025-01-23T16:45:00"
}
end note

return 201 Created\nTodoResponse

deactivate Controller

@enduml
