UFR-AI-040 관련 회의록 자동 연결 기능 추가

- 05-회의진행.html에 관련 회의록 자동 연결 기능 구현
- AI 기반 회의록 유사도 분석 및 자동 연결
- 유사도 점수별 색상 구분 (85%↑ 녹색, 75-84% 파란색, 70-74% 회색)
- 관련 회의록 카드 UI 구현 (제목, 날짜, 참석자, 키워드, 요약)
- Collapsible 섹션으로 공간 효율적 설계
- 클릭 시 회의록 상세 화면 이동 기능
- Toast 메시지로 AI 분석 완료 피드백
- Material Symbols 아이콘 사용
- Mobile First 반응형 디자인 적용
- 보완결과.md 기준 준수

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kimjh 2025-10-21 14:01:32 +09:00
parent afbfc7f947
commit e95ae60deb
3 changed files with 602 additions and 1 deletions

View File

@ -0,0 +1,169 @@
# 클라우드 아키텍처패턴선정 가이드
## 개요
이 가이드는 마이크로서비스 기반 클라우드 시스템을 위한 아키텍처 패턴 선정 방법론을 제공합니다. 체계적인 분석과 정량적 평가를 통해 최적의 패턴을 선정할 수 있습니다.
## 1. 요구사항 분석
### 1.1 유저스토리 분석
각 서비스별로 기능적/비기능적 요구사항을 명확히 도출합니다.
**기능적 요구사항**:
- 각 유저스토리에서 요구하는 핵심 기능
- 서비스 간 데이터 교환 요구사항
- 비즈니스 로직의 복잡도와 특성
**비기능적 요구사항**:
- 성능 요구사항 (응답시간, 처리량)
- 가용성 및 신뢰성 요구사항
- 확장성 및 유지보수성 요구사항
- 보안 및 컴플라이언스 요구사항
### 1.2 UI/UX설계 분석
Wireframe을 통해 사용자 인터랙션 패턴과 데이터 플로우를 파악합니다.
**분석 항목**:
- 사용자 인터랙션 패턴 (동기/비동기 처리 필요성)
- 데이터 조회/변경 패턴
- 화면 간 전환 흐름
- 실시간 업데이트 요구사항
### 1.3 통합 분석
유저스토리와 UI/UX 설계를 연계하여 **기술적 도전과제를 식별**합니다.
**도전과제 식별**:
- 복잡한 비즈니스 트랜잭션
- 대용량 데이터 처리
- 실시간 처리 요구사항
- 외부 시스템 연동 복잡성
- 서비스 간 의존성 관리
## 2. 패턴 선정
### 2.1 평가 기준
다음 5가지 기준으로 각 패턴을 정량적으로 평가합니다.
| 기준 | 가중치 | 평가 내용 |
|------|--------|-----------|
| **기능 적합성** | 35% | 요구사항을 직접 해결하는 능력 |
| **성능 효과** | 25% | 응답시간 및 처리량 개선 효과 |
| **운영 복잡도** | 20% | 구현 및 운영의 용이성 |
| **확장성** | 15% | 미래 요구사항에 대한 대응력 |
| **비용 효율성** | 5% | 개발/운영 비용 대비 효과(ROI) |
### 2.2 정량적 평가 방법
**평가 척도**: 1-10점 (10점이 가장 우수)
**패턴별 평가 매트릭스 예시**:
| 패턴 | 기능 적합성<br/>(35%) | 성능 효과<br/>(25%) | 운영 복잡도<br/>(20%) | 확장성<br/>(15%) | 비용 효율성<br/>(5%) | **총점** |
|------|:---:|:---:|:---:|:---:|:---:|:---:|
| API Gateway | 8 × 0.35 = 2.8 | 7 × 0.25 = 1.75 | 8 × 0.20 = 1.6 | 9 × 0.15 = 1.35 | 7 × 0.05 = 0.35 | **7.85** |
| CQRS | 9 × 0.35 = 3.15 | 9 × 0.25 = 2.25 | 5 × 0.20 = 1.0 | 8 × 0.15 = 1.2 | 6 × 0.05 = 0.3 | **7.90** |
| Event Sourcing | 7 × 0.35 = 2.45 | 8 × 0.25 = 2.0 | 4 × 0.20 = 0.8 | 9 × 0.15 = 1.35 | 5 × 0.05 = 0.25 | **6.85** |
### 2.3 단계별 적용 로드맵
MVP → 확장 → 고도화 3단계로 구분하여 점진적 적용 계획을 수립합니다.
**Phase 1: MVP (Minimum Viable Product)**
- 핵심 비즈니스 기능 중심
- 단순하고 안정적인 패턴 우선
- 빠른 출시를 위한 최소 기능
**Phase 2: 확장 (Scale-up)**
- 사용자 증가에 따른 성능 최적화
- 고급 패턴 도입
- 모니터링 및 운영 자동화
**Phase 3: 고도화 (Advanced)**
- 복잡한 비즈니스 요구사항 대응
- 최신 기술 및 패턴 적용
- 글로벌 확장 대비
## 3. 문서 작성
### 3.1 구조화된 작성 순서
1. **요구사항 분석 결과**
2. **패턴 평가** (평가 매트릭스 포함)
3. **적용 설계** (Mermaid 다이어그램)
4. **구현 계획** (Phase별 로드맵)
### 3.2 Mermaid 다이어그램 작성
서비스 아키텍처와 패턴 적용을 시각적으로 표현합니다.
```mermaid
graph TB
Client[클라이언트] --> Gateway[API Gateway]
Gateway --> Auth[인증 서비스]
Gateway --> UserSvc[사용자 서비스]
Gateway --> OrderSvc[주문 서비스]
OrderSvc --> EventBus[이벤트 버스]
EventBus --> PaymentSvc[결제 서비스]
EventBus --> NotificationSvc[알림 서비스]
UserSvc --> UserDB[(사용자 DB)]
OrderSvc --> OrderDB[(주문 DB)]
PaymentSvc --> PaymentDB[(결제 DB)]
```
### 3.3 실용적 내용 포함
- **코드 예시**: 패턴 구현을 위한 구체적인 코드 스니펫
- **구현 시 고려사항**: 실제 개발 시 주의할 점
- **예상 효과**: 정량적 성과 지표 (응답시간 개선, 처리량 증가 등)
## 참고 자료
- **유저스토리**
- UI/UX설계서
- **클라우드아키텍처패턴요약표**
## 결과 파일
선정된 아키텍처 패턴은 다음과 같이 문서화됩니다:
### 파일명
design/pattern/architecture-pattern.md
### 필수 포함 내용
1. **요구사항 분석 결과**
- 기능적/비기능적 요구사항 상세 분석
- 기술적 도전과제 식별
2. **패턴 선정 매트릭스 (평가표)**
- 후보 패턴별 정량적 평가 점수
- 선정 근거 및 이유
3. **서비스별 패턴 적용 설계 (Mermaid)**
- 전체 아키텍처 구조
- 패턴별 적용 영역 표시
4. **Phase별 구현 로드맵**
- 단계별 적용 계획
- 마일스톤 및 목표 설정
5. **예상 성과 지표**
- 성능 개선 예상치
- 비용 절감 효과
- 개발 생산성 향상
## 체크리스트
작성 완료 후 다음 항목들을 검토하세요:
- [ ] **각 유저스토리가 어떤 패턴으로 해결되는지 명시했는가?**
- [ ] **패턴 선정 이유를 정량적으로 설명했는가?**
- [ ] **패턴 간 상호작용과 통합 아키텍처를 표현했는가?**
- [ ] **구현 우선순위와 단계별 목표가 명확한가?**
- [ ] **실무자가 바로 활용할 수 있는 수준인가?**
## 작성 시 주의사항
1. **객관적 평가**: 주관적 판단보다는 정량적 데이터 기반 선정
2. **현실성**: 팀의 기술 수준과 프로젝트 일정을 고려한 실현 가능한 패턴 선정
3. **확장성**: 현재 요구사항뿐만 아니라 미래 확장성까지 고려
4. **비용 효율성**: 과도한 엔지니어링 지양, 비즈니스 가치 중심 선정
5. **문서화**: 선정 과정과 근거를 명확히 문서화하여 후속 의사결정 지원
## 완료 후 mermaid 스크립트 테스트 방법 안내
- https://mermaid.live/edit 에 접근
- 스크립트 내용을 붙여넣어 확인

View File

@ -0,0 +1,104 @@
# 클라우드 디자인 패턴 개요
## 전체 분류 현황
총 **42개의 클라우드 디자인 패턴**
- **DB 성능개선**: 1개
- **읽기 최적화**: 4개
- **핵심업무 집중**: 6개
- **안정적 현대화**: 2개
- **효율적 분산처리**: 13개
- **안정성**: 6개
- **보안**: 3개
- **운영**: 7개
---
## 패턴 목록
### 1. DB 성능개선 (1개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 1 | Sharding | 데이터 양 줄이기 | 데이터 저장소를 수평적으로 분할(shard)하여 대규모 데이터 저장 및 접근 시 확장성을 높이는 패턴 |
### 2. 읽기 최적화 (4개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 2 | Index Table | NoSQL DB Query 최적화 | 데이터 저장소에서 자주 참조되는 필드에 대한 인덱스를 생성하여 쿼리 성능을 개선하는 패턴 |
| 3 | Cache-Aside | 성능 향상 및 데이터 일관성 유지 | 데이터 저장소에서 캐시에 데이터를 필요에 따라 로드하여 성능을 개선하고, 캐시와 데이터 저장소 간의 일관성을 유지하는 패턴 |
| 4 | Materialized View | 쿼리 성능 최적화 | 데이터를 미리 변환하여 준비된 뷰를 생성함으로써 쿼리 성능을 높이고 데이터 추출을 효율화하는 패턴 |
| 5 | CQRS | 읽기/쓰기 분리 | 데이터 저장소의 읽기와 쓰기 작업을 분리하여 성능, 확장성, 보안성을 높이는 패턴 |
### 3. 핵심업무 집중 (6개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 6 | Gateway Offloading | 횡단관심사 분리 | SSL 인증서 관리, 인증, 로깅 등의 공통 기능을 게이트웨이로 분리하여 애플리케이션의 복잡도를 낮추는 패턴 |
| 7 | Gateway Routing | 라우팅 중앙 처리 | 단일 엔드포인트를 통해 요청을 받아 백엔드 서비스나 인스턴스로 라우팅하는 패턴 |
| 8 | Gateway Aggregation | 클라이언트 요청 수 줄이기 | 단일 엔드포인트에서 클라이언트 요청을 받아 여러 백엔드 서비스로 분배하고 응답을 취합하는 패턴 |
| 9 | Backends for Frontends | 프론트엔드 유형별 전용처리 | 특정 프런트엔드에 특화된 백엔드 서비스를 별도로 구축하는 패턴 |
| 10 | Sidecar | 공통 기능 분리 | 애플리케이션의 일부 컴포넌트를 별도 프로세스나 컨테이너로 분리하여 격리와 확장성을 제공하는 패턴 |
| 11 | Ambassador | 네트워크 통신의 안정성과 보안 강화 | 클라이언트를 대신해 네트워크 요청을 처리하는 헬퍼 서비스를 생성하는 패턴 |
### 4. 안정적 현대화 (2개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 12 | Strangler Fig | 현대화의 위험 최소화와 점진적 전환 | 레거시 시스템을 점진적으로 새로운 애플리케이션 및 서비스로 교체하는 패턴 |
| 13 | Anti-Corruption Layer | 시스템 간 안정적 인터페이스 | 서로 다른 하위 시스템 간의 의미적 차이를 조정하기 위해 중간 계층을 구현하는 패턴 |
### 5. 효율적 분산처리 (13개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 14 | Pipes and Filters | 작업 단계 모듈화로 재사용성과 성능 향상 | 복잡한 작업을 독립적인 단계(필터)로 분리하고 메시지(파이프)로 연결하여 모듈성과 유연성을 높이는 패턴 |
| 15 | Scheduler Agent Supervisor | 워크플로우의 신뢰성 향상 | 작업 단계를 스케줄러, 에이전트, 감독자로 분리하여 신뢰성과 확장성을 높이는 패턴 |
| 16 | Leader Election | 분산 작업의 충돌 방지와 안정성 향상 | 분산 시스템에서 여러 작업 인스턴스 중 하나를 리더로 선출하여 조정 역할을 맡기는 패턴 |
| 17 | Saga | 데이터 일관성 보장 | 각 서비스의 로컬 트랜잭션을 사용하여 분산 트랜잭션의 일관성을 보장하는 패턴 |
| 18 | Compensating Transaction | 오류 복구로 데이터 일관성 보장 | 분산 트랜잭션에서 실패한 작업을 보상하기 위해 이전 작업을 취소하거나 상쇄하는 트랜잭션을 실행하는 패턴 |
| 19 | Priority Queue | 중요 작업의 우선 처리 보장 | 메시지의 우선순위에 따라 처리 순서를 조정하는 큐를 사용하는 패턴 |
| 20 | Queue-Based Load Leveling | 부하의 균등한 분산으로 안정성 확보 | 메시지 큐를 사용하여 작업과 서비스 간의 부하를 균등하게 분산시키는 패턴 |
| 21 | Sequential Convoy | 처리순서 보장 | 관련 메시지 집합을 순서대로 처리하되 다른 메시지 처리를 차단하지 않도록 하는 패턴 |
| 22 | Claim Check | 메시지 크기 최소화 및 성능과 보안 향상 | 메시지에서 페이로드를 분리하여 외부 저장소에 저장하고 참조키(클레임 체크)를 사용하는 패턴 |
| 23 | Publisher-Subscriber | 단일 이벤트 메시지의 복수 서비스 처리 보장 | 다수의 소비자(Consumer)에게 이벤트를 발행하는 패턴 |
| 24 | Asynchronous Request-Reply | 장시간 처리 작업의 응답시간 단축 | 프런트엔드(클라이언트)와 백엔드 간 비동기로 요청과 응답을 분리하여 응답 시간을 단축하는 패턴 |
| 25 | Competing Consumers | 병렬처리로 작업 처리 속도 향상 | 동일 메시지 채널에서 여러 소비자가 경쟁적으로 메시지를 처리하여 병렬성을 높이는 패턴 |
| 26 | Choreography | 중앙집중 처리의 병목현상 방지 | 중앙 조정자 없이 각 서비스가 자율적으로 이벤트를 구독하고 반응하여 전체 워크플로를 수행하는 패턴 |
### 6. 안정성 (6개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 27 | Rate Limiting | 요청 폭주 방지로 안정성 유지 | 일정 기간 동안 허용되는 요청 수를 제한하여 과부하를 방지하고 서비스 안정성을 높이는 패턴 |
| 28 | Throttling | 요청 폭주 방지로 안정성 유지 | 시스템의 부하 상태에 따라 요청 처리량을 동적으로 조절하여 과부하를 방지하는 패턴 |
| 29 | Bulkhead | 자원풀 격리로 장애 전파 방지 | 애플리케이션 요소를 격리된 풀로 분할하여 하나의 장애가 전체로 전파되는 것을 방지하는 패턴 |
| 30 | Circuit Breaker | 장애전파 방지 | 장애가 발생한 구성 요소를 빠르게 감지하고 요청 실패를 최소화하는 패턴 |
| 31 | Retry | 일시적 오류시 처리 보장 | 일시적인 오류에 대해 실패한 요청을 재시도하여 복원력을 높이는 패턴 |
| 32 | Event Sourcing | 데이터 멱등성 보장과 변경 기록 제공 | 데이터에 대한 모든 변경사항을 이벤트로 저장하고, 이벤트를 재생하여 데이터의 상태를 복원하는 패턴 |
### 7. 보안 (3개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 33 | Federated Identity | 사용자 인증 및 관리 효율화 | 인증을 외부 ID 제공자에 위임하여 사용자 관리를 간소화하고 SSO를 구현하는 패턴 |
| 34 | Gatekeeper | 데이터 접근 제어와 보안 강화 | 신뢰할 수 있는 호스트에 보안 관련 기능을 집중시켜 스토리지나 서비스의 보안을 강화하는 패턴 |
| 35 | Valet Key | 네트워크 대역폭 감소 | 클라이언트가 특정 리소스에 제한된 직접 접근을 할 수 있도록 토큰을 사용하는 패턴 |
### 8. 운영 (7개)
| No. | 패턴명 | 목적 | 설명 |
|-----|--------|------|------|
| 36 | Geodes | 글로벌 서비스 가용성과 성능 최적화 | 백엔드 서비스를 여러 지역에 분산 배치하여 지연 시간을 줄이고 가용성을 높이는 패턴 |
| 37 | Deployment Stamps | 멀티 테넌트 관리 | 리소스 그룹을 복제하여 작업이나 테넌트 단위로 격리된 운영 환경을 제공하는 패턴 |
| 38 | Health Endpoint Monitoring | 서비스 가용성 상태 점검 | 애플리케이션의 상태를 모니터링하기 위한 전용 API 엔드포인트를 노출하는 패턴 |
| 39 | Compute Resource Consolidation | 자원 사용 효율성과 비용 절감 | 여러 작업이나 운영을 단일 컴퓨팅 단위로 통합하여 효율성과 비용을 최적화하는 패턴 |
| 40 | Static Content Hosting | 정적 자원 제공, 비용절감과 성능 향상 | 정적 콘텐츠를 클라우드 스토리지에 배포하여 클라이언트에 직접 제공함으로써 컴퓨팅 인스턴스 사용을 줄이는 패턴 |
| 41 | External Configuration Store | 환경설정 중앙관리와 재배포 없이 설정 변경 적용 | 애플리케이션의 설정 정보를 중앙화하여 관리 효율성을 높이고 설정 값 변경 시 재배포 없이 적용하는 패턴 |
| 42 | Edge Workload Configuration | 엣지컴퓨팅의 효율적 관리 | 장치와 시스템이 혼재된 엣지 환경에서 워크로드 구성을 효율적으로 관리하여 지연 시간 단축과 네트워크 비용 절감을 하는 패턴 |
---
> **참고**: 이 문서는 클라우드 환경에서 자주 사용되는 디자인 패턴들을 체계적으로 분류하여 정리한 것입니다. 각 패턴은 특정 목적과 상황에 맞게 적용될 수 있으며, 실제 구현 시에는 프로젝트의 요구사항과 제약사항을 충분히 고려해야 합니다.

View File

@ -135,6 +135,195 @@
background: var(--gray-50);
border-radius: 4px;
}
/* UFR-AI-040: 관련 회의록 자동 연결 스타일 */
.related-meetings-section {
background: linear-gradient(135deg, var(--accent-50) 0%, var(--primary-50) 100%);
border-radius: 12px;
padding: 16px;
margin-bottom: 16px;
border: 1px solid var(--accent-200);
}
.related-meetings-header {
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
user-select: none;
margin-bottom: 0;
transition: all var(--transition-normal);
}
.related-meetings-header:hover {
opacity: 0.8;
}
.related-meetings-title {
display: flex;
align-items: center;
gap: 8px;
}
.related-meetings-title h3 {
font-size: 16px;
font-weight: 600;
color: var(--gray-900);
margin: 0;
}
.ai-badge-small {
background: var(--accent-500);
color: var(--white);
font-size: 11px;
font-weight: 600;
padding: 3px 8px;
border-radius: 12px;
text-transform: uppercase;
}
.chevron-icon {
transition: transform 0.3s ease;
color: var(--gray-600);
}
.chevron-icon.expanded {
transform: rotate(180deg);
}
.related-meetings-content {
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-in-out;
margin-top: 0;
}
.related-meetings-content.expanded {
max-height: 800px;
margin-top: 12px;
}
.related-meeting-card {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 8px;
padding: 12px;
margin-bottom: 10px;
cursor: pointer;
transition: all var(--transition-normal);
}
.related-meeting-card:last-child {
margin-bottom: 0;
}
.related-meeting-card:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transform: translateY(-2px);
border-color: var(--primary-500);
}
.related-meeting-card:active {
transform: translateY(0);
}
.meeting-card-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 8px;
}
.meeting-card-title {
font-size: 14px;
font-weight: 600;
color: var(--gray-900);
margin: 0;
flex: 1;
line-height: 1.4;
}
.relevance-score {
font-size: 11px;
font-weight: 700;
padding: 4px 8px;
border-radius: 12px;
white-space: nowrap;
margin-left: 8px;
flex-shrink: 0;
}
.relevance-high {
background-color: var(--success-bg);
color: var(--success);
}
.relevance-medium {
background-color: var(--primary-50);
color: var(--primary-500);
}
.relevance-low {
background-color: var(--gray-100);
color: var(--gray-700);
}
.meeting-card-meta {
font-size: 12px;
color: var(--gray-600);
margin-bottom: 6px;
display: flex;
align-items: center;
gap: 4px;
}
.meeting-card-attendees {
font-size: 12px;
color: var(--gray-700);
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 4px;
}
.meeting-card-keywords {
display: flex;
flex-wrap: wrap;
gap: 4px;
margin-top: 8px;
}
.keyword-tag {
background-color: var(--accent-100);
color: var(--accent-700);
font-size: 11px;
font-weight: 500;
padding: 3px 8px;
border-radius: 4px;
}
.meeting-card-summary {
font-size: 12px;
color: var(--gray-600);
margin-top: 8px;
line-height: 1.4;
border-top: 1px solid var(--gray-100);
padding-top: 8px;
}
.no-related-meetings {
text-align: center;
padding: 24px;
color: var(--gray-500);
font-size: 13px;
}
.no-related-meetings .material-symbols-outlined {
font-size: 48px;
opacity: 0.3;
margin-bottom: 8px;
display: block;
}
</style>
</head>
<body>
@ -173,6 +362,22 @@
<span>AI가 발언 내용을 분석하여 회의록을 작성하고 있습니다</span>
</div>
<!-- UFR-AI-040: 관련 회의록 자동 연결 섹션 -->
<div class="related-meetings-section">
<div class="related-meetings-header" onclick="toggleRelatedMeetings()">
<div class="related-meetings-title">
<span class="ai-badge-small">AI</span>
<h3>관련 회의록 <span style="color: var(--gray-600); font-weight: normal;" id="relatedCount">(분석 중...)</span></h3>
</div>
<span class="material-symbols-outlined chevron-icon" id="chevronIcon">expand_more</span>
</div>
<div class="related-meetings-content" id="relatedMeetingsContent">
<div id="relatedMeetingsList">
<!-- JavaScript로 동적 생성 -->
</div>
</div>
</div>
<!-- 회의록 섹션들 -->
<div id="sectionList">
<!-- JavaScript로 동적 생성 -->
@ -213,7 +418,41 @@
let startTime = Date.now();
let elapsedInterval;
// 프롬프트 유형 정의 (NEW - UFR-AI-030)
// UFR-AI-040: 관련 회의록 데이터 (AI가 자동으로 찾아서 연결)
const RELATED_MEETINGS = [
{
id: 'MTG-2025-001',
title: '프로젝트 초기 기획 회의',
date: '2025-10-15',
attendees: ['김철수', '이영희', '박민수'],
relevanceScore: 87,
keywords: ['프로젝트', 'Mobile First', '기획', '킥오프'],
summary: '프로젝트 초기 방향성 논의 및 Mobile First 전략 수립. 개발 기간과 주요 마일스톤 확정.',
folder: '프로젝트/회의록'
},
{
id: 'MTG-2025-002',
title: '마이크로서비스 아키텍처 설계 회의',
date: '2025-10-18',
attendees: ['김철수', '정도현', '이영희'],
relevanceScore: 78,
keywords: ['마이크로서비스', '아키텍처', 'API', '설계'],
summary: '서비스 분리 기준 및 API 설계 방향 논의. 데이터베이스 구조와 통신 프로토콜 결정.',
folder: '프로젝트/회의록'
},
{
id: 'MTG-2025-003',
title: 'UI/UX 디자인 리뷰 회의',
date: '2025-10-19',
attendees: ['이영희', '최유진', '박민수'],
relevanceScore: 72,
keywords: ['UI/UX', 'Mobile', '디자인', '사용자경험'],
summary: 'Mobile First 디자인 시스템 및 사용자 경험 개선 방안. 프로토타입 피드백 반영.',
folder: '프로젝트/회의록'
}
];
// 프롬프트 유형 정의 (UFR-AI-030)
const PROMPT_TYPES = {
onePage: {
id: 'onePage',
@ -288,6 +527,92 @@
elapsedInterval = setInterval(updateElapsedTime, 1000);
// UFR-AI-040: 관련 회의록 토글
function toggleRelatedMeetings() {
const content = document.getElementById('relatedMeetingsContent');
const chevron = document.getElementById('chevronIcon');
content.classList.toggle('expanded');
chevron.classList.toggle('expanded');
// 처음 열 때만 렌더링
if (content.classList.contains('expanded') && !content.dataset.rendered) {
renderRelatedMeetings();
content.dataset.rendered = 'true';
}
}
// UFR-AI-040: 관련 회의록 렌더링
function renderRelatedMeetings() {
const container = document.getElementById('relatedMeetingsList');
if (RELATED_MEETINGS.length === 0) {
container.innerHTML = `
<div class="no-related-meetings">
<span class="material-symbols-outlined">search_off</span>
<p>관련된 회의록을 찾을 수 없습니다</p>
</div>
`;
return;
}
container.innerHTML = RELATED_MEETINGS.map(meeting => {
const scoreClass = getRelevanceClass(meeting.relevanceScore);
const scoreLabel = meeting.relevanceScore + '%';
return `
<div class="related-meeting-card" onclick="navigateToRelatedMeeting('${meeting.id}')">
<div class="meeting-card-header">
<h4 class="meeting-card-title">${meeting.title}</h4>
<span class="relevance-score ${scoreClass}">${scoreLabel}</span>
</div>
<div class="meeting-card-meta">
<span class="material-symbols-outlined" style="font-size: 14px;">calendar_today</span>
${meeting.date}
</div>
<div class="meeting-card-attendees">
<span class="material-symbols-outlined" style="font-size: 14px;">group</span>
${meeting.attendees.join(', ')}
</div>
<div class="meeting-card-keywords">
${meeting.keywords.map(keyword =>
`<span class="keyword-tag">${keyword}</span>`
).join('')}
</div>
<div class="meeting-card-summary">
${meeting.summary}
</div>
</div>
`;
}).join('');
// 관련 회의록 개수 업데이트
document.getElementById('relatedCount').textContent = `(${RELATED_MEETINGS.length}건)`;
}
// UFR-AI-040: 유사도 점수에 따른 색상 클래스 반환
function getRelevanceClass(score) {
if (score >= 85) return 'relevance-high'; // 85-100%: 녹색 (높은 관련성)
if (score >= 75) return 'relevance-medium'; // 75-84%: 파란색 (중간 관련성)
return 'relevance-low'; // 70-74%: 회색 (낮은 관련성)
}
// UFR-AI-040: 관련 회의록으로 이동
function navigateToRelatedMeeting(meetingId) {
UIComponents.showToast(`회의록 상세 화면으로 이동: ${meetingId}`, 'info');
// TODO: 실제로는 회의록 상세 화면(10-회의록상세조회.html)으로 이동
// NavigationHelper.navigate('MEETING_DETAIL', { meetingId });
}
// UFR-AI-040: 관련 회의록 AI 분석 시뮬레이션
function simulateRelatedMeetingsAnalysis() {
// 2초 후 관련 회의록 개수 표시
setTimeout(() => {
document.getElementById('relatedCount').textContent = `(${RELATED_MEETINGS.length}건)`;
UIComponents.showToast(`AI가 ${RELATED_MEETINGS.length}건의 관련 회의록을 찾았습니다`, 'success', 3000);
}, 2000);
}
// 섹션 렌더링
function renderSections() {
const container = document.getElementById('sectionList');
@ -648,6 +973,9 @@
// 초기 렌더링
renderSections();
// UFR-AI-040: 관련 회의록 AI 분석 시작
simulateRelatedMeetingsAnalysis();
// 실시간 발언 시뮬레이션
const speeches = [
{ speaker: '김철수', text: '프로젝트 킥오프 회의를 시작하겠습니다...' },