mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 21:56:24 +00:00
✅ 구현 완료 - AI Python Service (FastAPI, Claude API, 8087 포트) - POST /api/v1/transcripts/consolidate - 참석자별 회의록 → AI 통합 분석 - 키워드/안건별 요약/Todo 추출 - Meeting Service AI 통합 - EndMeetingService (@Primary) - AIServiceClient (RestTemplate, 30초 timeout) - AI 분석 결과 저장 (meeting_analysis, todos) - 회의 상태 COMPLETED 처리 - DTO 구조 (간소화) - ConsolidateRequest/Response - MeetingEndDTO - Todo 제목만 포함 (담당자/마감일 제거) 📝 기술스택 - Python: FastAPI, anthropic 0.71.0, psycopg2 - Java: Spring Boot, RestTemplate - Claude: claude-3-5-sonnet-20241022 🔧 주요 이슈 해결 - 포트 충돌: 8086(feature/stt-ai) → 8087(feat/meeting-ai) - Bean 충돌: @Primary 추가 - YAML 문법: ai.service.url 구조 수정 - anthropic 라이브러리 업그레이드 📚 테스트 가이드 및 스크립트 작성 - claude/MEETING-AI-TEST-GUIDE.md - test-meeting-ai.sh 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
81 lines
3.0 KiB
Python
81 lines
3.0 KiB
Python
"""Todo Models"""
|
|
from pydantic import BaseModel, Field
|
|
from typing import List, Optional
|
|
from datetime import datetime, date
|
|
from enum import Enum
|
|
|
|
|
|
class PriorityLevel(str, Enum):
|
|
"""우선순위"""
|
|
HIGH = "HIGH"
|
|
MEDIUM = "MEDIUM"
|
|
LOW = "LOW"
|
|
|
|
|
|
class TodoExtractRequest(BaseModel):
|
|
"""Todo 자동 추출 요청"""
|
|
meeting_id: str = Field(..., description="회의 ID")
|
|
transcript_text: str = Field(..., description="전체 회의록 텍스트")
|
|
participants: List[str] = Field(..., description="참석자 목록")
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"meeting_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"transcript_text": "안건 1: 신제품 기획...\n결정사항: API 설계서는 박민수님이 1월 30일까지 작성...",
|
|
"participants": ["김민준", "박서연", "이준호", "박민수"]
|
|
}
|
|
}
|
|
|
|
|
|
class ExtractedTodo(BaseModel):
|
|
"""추출된 Todo"""
|
|
title: str = Field(..., description="Todo 제목")
|
|
description: Optional[str] = Field(None, description="상세 설명")
|
|
assignee: str = Field(..., description="담당자 이름")
|
|
due_date: Optional[date] = Field(None, description="마감일")
|
|
priority: PriorityLevel = Field(default=PriorityLevel.MEDIUM, description="우선순위")
|
|
section_reference: str = Field(..., description="섹션 참조 (예: '결정사항 #1')")
|
|
confidence_score: float = Field(..., ge=0.0, le=1.0, description="신뢰도 점수")
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"title": "API 설계서 작성",
|
|
"description": "신규 프로젝트 API 설계서 작성 완료",
|
|
"assignee": "박민수",
|
|
"due_date": "2025-01-30",
|
|
"priority": "HIGH",
|
|
"section_reference": "결정사항 #1",
|
|
"confidence_score": 0.92
|
|
}
|
|
}
|
|
|
|
|
|
class TodoExtractResponse(BaseModel):
|
|
"""Todo 자동 추출 응답"""
|
|
meeting_id: str = Field(..., description="회의 ID")
|
|
todos: List[ExtractedTodo] = Field(..., description="추출된 Todo 목록")
|
|
total_count: int = Field(..., description="전체 Todo 개수")
|
|
extracted_at: datetime = Field(default_factory=datetime.utcnow, description="추출 시각")
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"meeting_id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"todos": [
|
|
{
|
|
"title": "API 설계서 작성",
|
|
"description": "신규 프로젝트 API 설계서 작성 완료",
|
|
"assignee": "박민수",
|
|
"due_date": "2025-01-30",
|
|
"priority": "HIGH",
|
|
"section_reference": "결정사항 #1",
|
|
"confidence_score": 0.92
|
|
}
|
|
],
|
|
"total_count": 5,
|
|
"extracted_at": "2025-01-23T10:30:00Z"
|
|
}
|
|
}
|