@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<>" as DB database "Redis Cache<>" as Cache queue "Azure Event Hubs<>" 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: SELECT * FROM minutes WHERE id = ? 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: INSERT INTO todos\n(id, content, assignee, dueDate,\npriority, status, minutesId, sectionId,\ncreatedBy, createdAt) 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: UPDATE minutes_sections\nSET todoIds = JSON_ARRAY_APPEND(todoIds, '$', ?)\nWHERE id = ? 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: UPDATE todos\nSET calendarEventId = ?\nWHERE 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