openapi: 3.0.3 info: title: AI Service API description: | 회의록 작성 및 공유 개선 서비스의 AI Service API **주요 기능:** - 회의록 자동 작성 (LLM 기반) - Todo 자동 추출 및 담당자 식별 - 프롬프팅 기반 회의록 개선 - 관련 회의록 자동 연결 (RAG) - 전문용어 감지 및 맥락 기반 설명 (RAG) - 논의사항/결정사항 실시간 제안 version: 1.0.0 contact: name: AI Service Team email: ai-service@example.com servers: - url: https://virtserver.swaggerhub.com/ai-service/1.0.0 description: SwaggerHub Mock Server - url: http://localhost:8083/api description: Local Development Server - url: https://dev-api.hgzero.com/ai/api description: Development Server - url: https://api.hgzero.com/ai/api description: Production Server tags: - name: Transcript description: 회의록 자동 작성 관련 API - name: Todo description: Todo 자동 추출 관련 API - name: Section description: 섹션 AI 요약 재생성 관련 API - name: Relation description: 관련 회의록 연결 관련 API - name: Term description: 전문용어 감지 및 설명 관련 API - name: Suggestion description: 논의사항/결정사항 제안 관련 API paths: /transcripts/process: post: tags: - Transcript summary: 회의록 자동 작성 description: | STT에서 변환된 텍스트를 받아 LLM 기반으로 회의록을 자동 작성합니다. 회의 맥락을 고려하여 구조화된 회의록 초안을 생성합니다. operationId: processTranscript x-user-story: UFR-AI-010 x-controller: TranscriptController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TranscriptProcessRequest' responses: '200': description: 회의록 자동 작성 성공 content: application/json: schema: $ref: '#/components/schemas/TranscriptProcessResponse' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' /todos/extract: post: tags: - Todo summary: Todo 자동 추출 description: | 회의록에서 액션 아이템을 자동으로 추출하고 담당자를 식별합니다. 추출된 Todo는 Meeting Service로 전달됩니다. operationId: extractTodos x-user-story: UFR-AI-020 x-controller: TodoController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TodoExtractionRequest' responses: '200': description: Todo 추출 성공 content: application/json: schema: $ref: '#/components/schemas/TodoExtractionResponse' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /sections/{sectionId}/regenerate-summary: post: tags: - Section summary: 섹션 AI 요약 재생성 description: | 사용자가 작성한 섹션 내용을 기반으로 AI 요약을 재생성합니다. 회의록 작성/수정 중에 사용됩니다. operationId: regenerateSectionSummary x-user-story: UFR-AI-035 x-controller: SectionController parameters: - name: sectionId in: path required: true schema: type: string format: uuid description: 섹션 ID requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SectionSummaryRequest' responses: '200': description: AI 요약 재생성 성공 content: application/json: schema: $ref: '#/components/schemas/SectionSummaryResponse' '400': $ref: '#/components/responses/BadRequest' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /transcripts/{meetingId}/related: get: tags: - Relation summary: 관련 회의록 조회 description: | 벡터 유사도 검색을 통해 관련된 회의록을 찾아 반환합니다. 주제 유사도, 키워드 일치도, 참석자 중복도 등을 종합하여 계산합니다. operationId: findRelatedTranscripts x-user-story: UFR-AI-040 x-controller: RelationController parameters: - name: meetingId in: path required: true schema: type: string format: uuid description: 회의 ID - name: transcriptId in: query required: true schema: type: string format: uuid description: 회의록 ID - name: limit in: query schema: type: integer default: 5 minimum: 1 maximum: 10 description: 반환할 최대 개수 responses: '200': description: 관련 회의록 조회 성공 content: application/json: schema: $ref: '#/components/schemas/RelatedTranscriptsResponse' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /terms/detect: post: tags: - Term summary: 전문용어 감지 description: | 회의록 텍스트에서 전문용어를 자동으로 감지합니다. 조직별/산업별 용어 사전과 비교하여 신뢰도 점수를 계산합니다. operationId: detectTerms x-user-story: UFR-RAG-010 x-controller: TermController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/TermDetectionRequest' responses: '200': description: 전문용어 감지 성공 content: application/json: schema: $ref: '#/components/schemas/TermDetectionResponse' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' /terms/{term}/explain: get: tags: - Term summary: 맥락 기반 용어 설명 description: | 전문용어에 대한 맥락 기반 설명을 생성합니다. RAG를 통해 과거 회의록, 사내 문서, 업무 이력을 검색하여 실용적인 설명을 제공합니다. operationId: explainTerm x-user-story: UFR-RAG-020 x-controller: ExplanationController parameters: - name: term in: path required: true schema: type: string description: 용어명 - name: meetingId in: query required: true schema: type: string format: uuid description: 회의 ID - name: context in: query schema: type: string description: 현재 회의 맥락 (선택) responses: '200': description: 용어 설명 생성 성공 content: application/json: schema: $ref: '#/components/schemas/TermExplanationResponse' '404': $ref: '#/components/responses/NotFound' '500': $ref: '#/components/responses/InternalServerError' /suggestions/discussion: post: tags: - Suggestion summary: 논의사항 제안 description: | 현재 회의 진행 상황을 분석하여 추가로 논의하면 좋을 주제를 제안합니다. 회의 안건 대비 빠진 항목이나 중요한 논의를 식별합니다. operationId: suggestDiscussion x-user-story: UFR-AI-010 x-controller: SuggestionController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DiscussionSuggestionRequest' responses: '200': description: 논의사항 제안 성공 content: application/json: schema: $ref: '#/components/schemas/DiscussionSuggestionResponse' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' /suggestions/decision: post: tags: - Suggestion summary: 결정사항 제안 description: | 회의록 텍스트에서 결정사항 패턴을 감지하여 제안합니다. "~하기로 함", "~로 결정" 등의 패턴을 분석합니다. operationId: suggestDecision x-user-story: UFR-AI-010 x-controller: SuggestionController requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DecisionSuggestionRequest' responses: '200': description: 결정사항 제안 성공 content: application/json: schema: $ref: '#/components/schemas/DecisionSuggestionResponse' '400': $ref: '#/components/responses/BadRequest' '500': $ref: '#/components/responses/InternalServerError' components: schemas: # ======================================== # Request Schemas # ======================================== TranscriptProcessRequest: type: object required: - meetingId - transcriptText properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" transcriptText: type: string description: STT에서 변환된 텍스트 example: "안녕하세요. 오늘 회의는 신규 프로젝트 킥오프 미팅입니다..." userId: type: string description: 사용자 ID example: "user123" userName: type: string description: 사용자 이름 example: "김철수" context: $ref: '#/components/schemas/MeetingContext' TodoExtractionRequest: type: object required: - meetingId - minutesContent properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" userId: type: string description: 요청자 ID example: "user123" minutesContent: type: string description: | 회의록 전체 내용 (Markdown 형식) AI가 TODO를 추출하기 위해 필요한 전체 맥락을 포함합니다. example: | # 신규 프로젝트 킥오프 미팅 ## 참석자 - 김철수, 이영희, 박민수 ## 논의사항 1. 프로젝트 개요 - React + Spring Boot 기반 개발 ## 결정사항 1. API 설계서는 박민수님이 1월 30일까지 작성 2. 프론트엔드는 이영희님이 2월 5일까지 개발 ## 보류사항 - 배포 일정은 다음 회의에서 논의 SectionSummaryRequest: type: object required: - sectionContent properties: sectionContent: type: string description: 사용자가 작성/수정한 섹션 내용 (Markdown 형식) example: | **논의 사항:** - AI 기반 회의록 자동화 서비스 출시 결정 - 타겟 고객: 중소기업, 스타트업 - 주요 기능: 음성인식, AI 요약, Todo 자동 추출 - 차별화 포인트: 실시간 검증, 협업 기능 **결정 사항:** - 베타 버전 출시일: 2025년 12월 1일 - 초기 목표 사용자: 100개 팀 meetingId: type: string format: uuid description: 회의 ID (맥락 이해용, 선택적) example: "550e8400-e29b-41d4-a716-446655440000" TermDetectionRequest: type: object required: - meetingId - text properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" text: type: string description: 분석할 회의록 텍스트 example: "MSA 아키텍처로 설계하고, API Gateway를 통해 라우팅합니다..." organizationId: type: string description: 조직 ID example: "org123" DiscussionSuggestionRequest: type: object required: - meetingId - transcriptText properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" transcriptText: type: string description: 현재까지의 회의록 텍스트 example: "프로젝트 일정에 대해 논의했습니다..." DecisionSuggestionRequest: type: object required: - meetingId - transcriptText properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" transcriptText: type: string description: 현재까지의 회의록 텍스트 example: "React로 프론트엔드를 개발하기로 했습니다..." # ======================================== # Response Schemas # ======================================== TranscriptProcessResponse: type: object properties: transcriptId: type: string format: uuid description: 생성된 회의록 ID example: "660e8400-e29b-41d4-a716-446655440001" meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" content: $ref: '#/components/schemas/TranscriptContent' suggestions: $ref: '#/components/schemas/RealtimeSuggestions' createdAt: type: string format: date-time description: 생성 시간 example: "2025-01-23T10:30:00Z" status: type: string enum: [DRAFT, COMPLETED] description: 회의록 상태 example: "DRAFT" TodoExtractionResponse: type: object properties: meetingId: type: string format: uuid description: 회의 ID example: "550e8400-e29b-41d4-a716-446655440000" todos: type: array items: $ref: '#/components/schemas/ExtractedTodo' totalCount: type: integer description: 추출된 Todo 개수 example: 5 extractedAt: type: string format: date-time description: 추출 시간 example: "2025-01-23T11:00:00Z" SectionSummaryResponse: type: object properties: summary: type: string description: 생성된 AI 요약 (2-3문장) example: "AI 기반 회의록 자동화 서비스로 결정. 타겟은 중소기업 및 스타트업이며, 주요 기능은 음성인식, AI 요약, Todo 추출입니다. 경쟁사 대비 차별점은 실시간 검증 및 협업 기능입니다." generatedAt: type: string format: date-time description: 생성 시간 example: "2025-01-23T11:00:00Z" RelatedTranscriptsResponse: type: object properties: relatedTranscripts: type: array items: $ref: '#/components/schemas/RelatedTranscript' totalCount: type: integer description: 관련 회의록 개수 example: 3 TermDetectionResponse: type: object properties: detectedTerms: type: array items: $ref: '#/components/schemas/DetectedTerm' totalCount: type: integer description: 감지된 용어 개수 example: 8 highlightInfo: type: array items: $ref: '#/components/schemas/HighlightInfo' TermExplanationResponse: type: object properties: term: type: string description: 용어명 example: "MSA" basicDefinition: type: string description: 간단한 정의 example: "Microservices Architecture의 약자로, 애플리케이션을 작은 독립적인 서비스로 나누는 아키텍처 패턴" contextualMeaning: type: string description: 현재 회의 맥락에서의 의미 example: "이번 프로젝트에서는 확장성과 독립 배포를 위해 MSA를 적용하기로 결정" useCases: type: array items: type: string description: 실제 사용 사례 example: - "2024년 프로젝트 X에서 주문/결제/배송 서비스를 독립적으로 구성" - "서비스별 독립 배포로 배포 시간 70% 단축" relatedProjects: type: array items: $ref: '#/components/schemas/RelatedProject' pastDiscussions: type: array items: $ref: '#/components/schemas/PastDiscussion' references: type: array items: $ref: '#/components/schemas/Reference' DiscussionSuggestionResponse: type: object properties: suggestions: type: array items: $ref: '#/components/schemas/DiscussionSuggestion' totalCount: type: integer description: 제안 개수 example: 3 timestamp: type: string format: date-time description: 생성 시각 example: "2025-01-23T10:35:00Z" DecisionSuggestionResponse: type: object properties: suggestions: type: array items: $ref: '#/components/schemas/DecisionSuggestion' totalCount: type: integer description: 제안 개수 example: 4 timestamp: type: string format: date-time description: 생성 시각 example: "2025-01-23T10:35:00Z" # ======================================== # Common Schemas # ======================================== MeetingContext: type: object description: 회의 맥락 정보 properties: title: type: string description: 회의 제목 example: "신규 프로젝트 킥오프 미팅" participants: type: array items: type: string description: 참석자 목록 example: ["김철수", "이영희", "박민수"] agenda: type: array items: type: string description: 회의 안건 example: ["프로젝트 개요", "일정 논의", "역할 분담"] previousContent: type: string description: 이전 회의록 내용 example: "지난 회의에서 기술 스택을 논의했습니다..." TranscriptContent: type: object description: 회의록 내용 properties: summary: type: string description: 전체 요약 example: "프로젝트 킥오프 미팅에서 기술 스택과 일정을 확정했습니다." discussions: type: array items: $ref: '#/components/schemas/DiscussionItem' decisions: type: array items: $ref: '#/components/schemas/DecisionItem' pendingItems: type: array items: type: string description: 보류 사항 example: ["추가 예산 검토 필요", "외주 업체 선정 보류"] DiscussionItem: type: object properties: topic: type: string description: 논의 주제 example: "기술 스택 선정" speaker: type: string description: 발언자 example: "김철수" content: type: string description: 논의 내용 example: "프론트엔드는 React, 백엔드는 Spring Boot를 사용하기로 제안" DecisionItem: type: object properties: content: type: string description: 결정 내용 example: "React로 프론트엔드 개발" decisionMaker: type: string description: 결정자 example: "이영희" category: type: string enum: [기술, 일정, 리소스, 정책, 기타] description: 결정 카테고리 example: "기술" RealtimeSuggestions: type: object description: 실시간 추천사항 properties: discussionTopics: type: array items: $ref: '#/components/schemas/DiscussionSuggestion' decisions: type: array items: $ref: '#/components/schemas/DecisionSuggestion' DiscussionSuggestion: type: object properties: id: type: string format: uuid description: 제안 ID example: "880e8400-e29b-41d4-a716-446655440003" topic: type: string description: 논의 주제 example: "보안 요구사항 검토" reason: type: string description: 제안 이유 example: "안건에 포함되어 있으나 아직 논의되지 않음" priority: type: string enum: [HIGH, MEDIUM, LOW] description: 우선순위 example: "HIGH" relatedAgenda: type: string description: 관련 안건 example: "프로젝트 개요" estimatedTime: type: integer description: 예상 소요 시간 (분) example: 15 DecisionSuggestion: type: object properties: id: type: string format: uuid description: 제안 ID example: "990e8400-e29b-41d4-a716-446655440004" content: type: string description: 결정 내용 example: "React로 프론트엔드 개발" category: type: string enum: [기술, 일정, 리소스, 정책, 기타] description: 결정 카테고리 example: "기술" decisionMaker: type: string description: 결정자 example: "김철수" participants: type: array items: type: string description: 참여자 example: ["김철수", "이영희"] confidence: type: number format: float minimum: 0 maximum: 1 description: 신뢰도 점수 example: 0.85 extractedFrom: type: string description: 원문 발췌 example: "프론트엔드는 React로 개발하기로 했습니다" context: type: string description: 결정 배경 example: "팀원 대부분이 React 경험이 있어 개발 속도가 빠를 것으로 예상" ExtractedTodo: type: object properties: content: type: string description: Todo 내용 example: "API 설계서 작성" assignee: type: string description: 담당자 example: "박민수" dueDate: type: string format: date description: 마감일 example: "2025-01-30" priority: type: string enum: [HIGH, MEDIUM, LOW] description: 우선순위 example: "HIGH" sectionReference: type: string description: 관련 회의록 섹션 example: "결정사항 #3" RelatedTranscript: type: object properties: transcriptId: type: string format: uuid description: 회의록 ID example: "aa0e8400-e29b-41d4-a716-446655440005" title: type: string description: 회의 제목 example: "프로젝트 X 주간 회의" date: type: string format: date description: 회의 날짜 example: "2025-01-15" participants: type: array items: type: string description: 참석자 example: ["김철수", "이영희"] relevanceScore: type: number format: float description: 관련도 점수 (0-100%) example: 85.5 commonKeywords: type: array items: type: string description: 공통 키워드 example: ["MSA", "API Gateway", "Spring Boot"] link: type: string description: 회의록 링크 example: "/transcripts/aa0e8400-e29b-41d4-a716-446655440005" DetectedTerm: type: object properties: term: type: string description: 용어명 example: "MSA" position: $ref: '#/components/schemas/TextPosition' confidence: type: number format: float minimum: 0 maximum: 1 description: 신뢰도 점수 example: 0.92 category: type: string enum: [기술, 업무, 도메인] description: 용어 카테고리 example: "기술" highlight: type: boolean description: 하이라이트 여부 example: true TextPosition: type: object description: 텍스트 위치 정보 properties: line: type: integer description: 줄 번호 example: 5 offset: type: integer description: 시작 오프셋 example: 42 HighlightInfo: type: object properties: term: type: string description: 용어명 example: "API Gateway" position: $ref: '#/components/schemas/TextPosition' style: type: string description: 하이라이트 스타일 example: "background-color: yellow" tooltip: type: string description: 툴팁 텍스트 example: "용어 설명 로딩 중..." RelatedProject: type: object properties: name: type: string description: 프로젝트명 example: "프로젝트 X" relevance: type: string description: 연관성 설명 example: "동일한 MSA 아키텍처 적용" PastDiscussion: type: object properties: date: type: string format: date description: 논의 날짜 example: "2024-12-15" participants: type: array items: type: string description: 참석자 example: ["김철수", "이영희"] summary: type: string description: 논의 요약 example: "MSA 아키텍처의 장단점을 비교하고 적용 방안을 논의" link: type: string description: 회의록 링크 example: "/transcripts/bb0e8400-e29b-41d4-a716-446655440006" Reference: type: object properties: title: type: string description: 문서 제목 example: "MSA 아키텍처 가이드" type: type: string enum: [위키, 매뉴얼, 회의록, 보고서] description: 문서 유형 example: "위키" link: type: string description: 문서 URL example: "https://wiki.example.com/msa-guide" ErrorResponse: type: object properties: error: type: string description: 에러 코드 example: "INVALID_REQUEST" message: type: string description: 에러 메시지 example: "meetingId는 필수 항목입니다" timestamp: type: string format: date-time description: 에러 발생 시각 example: "2025-01-23T10:30:00Z" responses: BadRequest: description: 잘못된 요청 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: "BAD_REQUEST" message: "필수 파라미터가 누락되었습니다" timestamp: "2025-01-23T10:30:00Z" NotFound: description: 리소스를 찾을 수 없음 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: "NOT_FOUND" message: "해당 회의록을 찾을 수 없습니다" timestamp: "2025-01-23T10:30:00Z" InternalServerError: description: 서버 내부 오류 content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: "INTERNAL_SERVER_ERROR" message: "서버 처리 중 오류가 발생했습니다" timestamp: "2025-01-23T10:30:00Z" securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: JWT 토큰 기반 인증 security: - BearerAuth: []