mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 11:26:25 +00:00
Merge branch 'main' of https://github.com/hwanny1128/HGZero into feat/meeting
This commit is contained in:
commit
04c7617548
3
.gitignore
vendored
3
.gitignore
vendored
@ -41,6 +41,7 @@ examples/
|
||||
|
||||
# Claude settings
|
||||
.claude/settings.local.json
|
||||
.vscode/settings.json
|
||||
|
||||
# Backup files
|
||||
design/*/*/*/*back*
|
||||
@ -48,4 +49,4 @@ design/*/*/*back*
|
||||
design/*/*back*
|
||||
design/*back*
|
||||
backup/
|
||||
.vscode/settings.json
|
||||
claudedocs/*back*
|
||||
|
||||
95
claudedocs/API-누락-요약표.md
Normal file
95
claudedocs/API-누락-요약표.md
Normal file
@ -0,0 +1,95 @@
|
||||
# API 누락 요약표 (회의 진행 실시간 기능)
|
||||
|
||||
**작성일**: 2025년 10월 28일
|
||||
**근거 문서**: [API리뷰-프로토타입vs구현.md](./API리뷰-프로토타입vs구현.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔴 P0 (치명적 - 즉시 구현 필요)
|
||||
|
||||
| # | API | 프로토타입 근거 | 영향받는 유저스토리 | 비고 |
|
||||
|---|-----|----------------|-------------------|------|
|
||||
| 1 | `PUT /api/meetings/{meetingId}/memo` | [05-회의진행.html:1119-1143](../design/uiux/prototype/05-회의진행.html#L1119-L1143) | US-07, US-10 | 메모 저장 불가, 데이터 손실 위험 |
|
||||
| 2 | `GET /api/ai/suggestions/realtime/{meetingId}` | [05-회의진행.html:767-806](../design/uiux/prototype/05-회의진행.html#L767-L806) | US-07, US-08 | AI 실시간 추천 완전 미동작 |
|
||||
| 3 | `POST /api/stt/recordings/{recordingId}/pause` | [05-회의진행.html:1212-1243](../design/uiux/prototype/05-회의진행.html#L1212-L1243) | US-06 | 녹음 일시정지 불가 |
|
||||
| 4 | `POST /api/stt/recordings/{recordingId}/resume` | [05-회의진행.html:1212-1243](../design/uiux/prototype/05-회의진행.html#L1212-L1243) | US-06 | 녹음 재개 불가 |
|
||||
|
||||
---
|
||||
|
||||
## 🟡 P1 (중요 - 우선 구현 필요)
|
||||
|
||||
| # | API | 프로토타입 근거 | 영향받는 유저스토리 | 비고 |
|
||||
|---|-----|----------------|-------------------|------|
|
||||
| 5 | `POST /api/ai/suggestions/{suggestionId}/adopt` | [05-회의진행.html:1070-1097](../design/uiux/prototype/05-회의진행.html#L1070-L1097) | US-07 | AI 추천 채택 불가, 수동 복붙 필요 |
|
||||
| 6 | `GET /api/ai/terms/search` | [05-회의진행.html:1145-1182](../design/uiux/prototype/05-회의진행.html#L1145-L1182) | US-09 | 용어 검색 불가 |
|
||||
|
||||
---
|
||||
|
||||
## 🟢 P2 (일반 - 향후 개선)
|
||||
|
||||
| # | API | 프로토타입 근거 | 영향받는 유저스토리 | 비고 |
|
||||
|---|-----|----------------|-------------------|------|
|
||||
| 7 | `GET /api/ai/terms/{termName}/detail` | [05-회의진행.html:1305-1308](../design/uiux/prototype/05-회의진행.html#L1305-L1308) | US-09 | 용어 상세 조회 불가 |
|
||||
|
||||
---
|
||||
|
||||
## 📊 탭별 API 구현 현황
|
||||
|
||||
| 탭 | 기능 | 필요 API 수 | 구현 API 수 | 구현률 | 우선순위 |
|
||||
|----|------|------------|------------|--------|---------|
|
||||
| **참석자** | 참석자 관리 | 4 | 4 | 100% ✅ | - |
|
||||
| **AI 메모** | 실시간 메모 & AI 추천 | 3 | 0 | 0% ❌ | P0 (3개) |
|
||||
| **용어사전** | 용어 감지/검색 | 3 | 1 | 33% ⚠️ | P1 (1개), P2 (1개) |
|
||||
| **관련회의록** | 유사 회의록 찾기 | 2 | 2 | 100% ✅ | - |
|
||||
| **녹음 제어** | 녹음 상태 관리 | 5 | 3 | 60% ⚠️ | P0 (2개) |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 구현 권장 순서
|
||||
|
||||
### Sprint 1 (1주) - P0 필수 기능
|
||||
1. **메모 저장 API** (`PUT /api/meetings/{meetingId}/memo`)
|
||||
- 예상 작업: 4시간
|
||||
- 구현 위치: `MeetingController.java`
|
||||
|
||||
2. **AI 실시간 추천 API** (`GET /api/ai/suggestions/realtime/{meetingId}`)
|
||||
- 예상 작업: 8시간
|
||||
- 구현 위치: `SuggestionController.java`
|
||||
- 폴링 또는 SSE 방식 선택 필요
|
||||
|
||||
3. **녹음 일시정지/재개 API** (`POST pause`, `POST resume`)
|
||||
- 예상 작업: 6시간
|
||||
- 구현 위치: `RecordingController.java`
|
||||
|
||||
### Sprint 2 (3일) - P1 중요 기능
|
||||
4. **AI 추천 채택 API** (`POST /api/ai/suggestions/{suggestionId}/adopt`)
|
||||
- 예상 작업: 4시간
|
||||
|
||||
5. **용어 검색 API** (`GET /api/ai/terms/search`)
|
||||
- 예상 작업: 3시간
|
||||
|
||||
### Sprint 3 (2일) - P2 보조 기능
|
||||
6. **용어 상세 조회 API** (`GET /api/ai/terms/{termName}/detail`)
|
||||
- 예상 작업: 4시간
|
||||
|
||||
---
|
||||
|
||||
## 📝 비고
|
||||
|
||||
### 구현 고려사항
|
||||
1. **AI 실시간 추천**: 폴링(Polling) vs SSE(Server-Sent Events) 방식 결정 필요
|
||||
2. **메모 저장**: 개인별 메모 vs 공유 메모 정책 확인 필요
|
||||
3. **녹음 일시정지**: 타이머 상태 동기화 로직 필요
|
||||
4. **용어 검색**: 조직 용어 사전과 회의별 용어 통합 검색 정책 필요
|
||||
|
||||
### 테스트 시나리오
|
||||
- [ ] 회의 진행 중 메모 작성 후 저장 → 다시 로드 시 메모 복원 확인
|
||||
- [ ] AI 추천 메모 실시간 조회 → 5초마다 새 추천 확인
|
||||
- [ ] AI 추천 채택 → 입력창에 시간 포함하여 추가 확인
|
||||
- [ ] 용어 검색 → 키워드로 조직/회의 용어 찾기 확인
|
||||
- [ ] 녹음 일시정지 → 타이머 정지 확인
|
||||
- [ ] 녹음 재개 → 타이머 재개 확인
|
||||
|
||||
---
|
||||
|
||||
**문서 종료**
|
||||
832
claudedocs/API리뷰-프로토타입vs구현.md
Normal file
832
claudedocs/API리뷰-프로토타입vs구현.md
Normal file
@ -0,0 +1,832 @@
|
||||
# API 리뷰 분석 - 프로토타입 vs 구현
|
||||
|
||||
**작성일**: 2025-10-28
|
||||
**검토자**: Architect, Backend Developer, Frontend Developer
|
||||
**분석 방법**: 프로토타입 HTML 파일과 실제 구현된 Controller 소스코드 비교 분석
|
||||
|
||||
---
|
||||
|
||||
## 📋 요약
|
||||
|
||||
### 전체 현황 (v2.0 - 회의 진행 실시간 기능 추가 분석)
|
||||
- **분석된 화면**: 9개 프로토타입 화면
|
||||
- **프로토타입 요구 API**: **34개** (v1: 27개 → v2: +7개)
|
||||
- **구현된 API**: 27개 엔드포인트
|
||||
- **완전 누락 API**: **11개** (v1: 4개 → v2: +7개)
|
||||
- **개선 필요 API**: 2개
|
||||
- **불필요한 API**: 0개
|
||||
|
||||
### 주요 발견사항 (v2.0 업데이트)
|
||||
1. ✅ **강점**: 핵심 비즈니스 로직 API는 모두 구현됨
|
||||
2. 🔴 **치명적 누락 (기존)**:
|
||||
- `GET /api/meetings` (목록 조회) - 대시보드 "최근 회의" 표시 불가
|
||||
- `PUT/PATCH /api/meetings/{meetingId}` (회의 수정) - 예정된 회의 수정 불가
|
||||
- `GET /api/dashboard/statistics` - 대시보드 통계 카드 표시 불가
|
||||
3. 🔴 **치명적 누락 (신규 발견)**: **회의 진행 중 실시간 기능 API 7개 누락**
|
||||
- **탭2: AI 메모 (3개 누락)**
|
||||
- `PUT /api/meetings/{meetingId}/memo` - 회의 중 메모 저장
|
||||
- `GET /api/ai/suggestions/realtime/{meetingId}` - AI 실시간 추천 메모
|
||||
- `POST /api/ai/suggestions/{suggestionId}/adopt` - AI 추천 채택
|
||||
- **탭3: 용어사전 (2개 누락)**
|
||||
- `GET /api/ai/terms/search` - 용어 검색
|
||||
- `GET /api/ai/terms/{termName}/detail` - 용어 상세 조회
|
||||
- **녹음 제어 (2개 누락)**
|
||||
- `POST /api/stt/recordings/{recordingId}/pause` - 녹음 일시정지
|
||||
- `POST /api/stt/recordings/{recordingId}/resume` - 녹음 재개
|
||||
4. 🟡 **기능 누락**: AI 요약 재생성 API 미구현
|
||||
5. 🟡 **개선 필요**: 회의록 검색/필터링 파라미터 추가 필요
|
||||
|
||||
### 비즈니스 영향도
|
||||
- **사용자 경험**: 회의 진행 중 핵심 편의 기능 미동작으로 인한 UX 저하
|
||||
- **AI 활용도**: 실시간 AI 추천 기능이 동작하지 않아 서비스 차별화 가치 감소
|
||||
- **메모 손실 위험**: 회의 중 작성한 메모가 저장되지 않아 데이터 손실 가능성
|
||||
- **유저스토리 영향**: US-06, US-07, US-08, US-09, US-10의 핵심/보조 기능 미동작
|
||||
|
||||
---
|
||||
|
||||
## 🔍 화면별 상세 분석
|
||||
|
||||
### 1. 로그인 화면 (01-로그인.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 로그인 | `POST /api/auth/login` | ✅ 구현됨 | [UserController.java:37-50](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L37-L50) | LDAP 인증, JWT 토큰 발급 |
|
||||
| 토큰 갱신 | `POST /api/auth/refresh` | ✅ 구현됨 | [UserController.java:59-72](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L59-L72) | Refresh Token 사용 |
|
||||
| 로그아웃 | `POST /api/auth/logout` | ✅ 구현됨 | [UserController.java:82-96](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L82-L96) | Refresh Token 삭제 |
|
||||
| 토큰 검증 | `GET /api/auth/validate` | ✅ 구현됨 | [UserController.java:105-126](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L105-L126) | JWT 토큰 유효성 검증 |
|
||||
|
||||
**분석 결과**: ✅ **완벽 구현** - 모든 인증 관련 API가 구현되어 있으며, 보안 모범 사례를 따르고 있음
|
||||
|
||||
---
|
||||
|
||||
### 2. 대시보드 화면 (02-대시보드.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 최근 회의 목록 (3개) | `GET /api/meetings` | ❌ **누락** | - | **전체 회의 목록 조회 후 프론트에서 정렬** |
|
||||
| 최근 회의록 목록 (4개) | `GET /api/meetings/minutes` | ✅ 구현됨 | [MinutesController.java:210-268](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L210-L268) | 페이징, 필터링 지원 |
|
||||
| 통계 정보 (2개 카드) | `GET /api/dashboard/statistics` | ❌ **누락** | - | 예정된 회의, 작성중 회의록 수 |
|
||||
|
||||
**상세 분석**:
|
||||
|
||||
#### "최근 회의" 섹션 요구사항 ([02-대시보드.html:665-681](design/uiux/prototype/02-대시보드.html#L665-L681))
|
||||
프로토타입 JavaScript 로직:
|
||||
```javascript
|
||||
// 회의록 미생성(scheduled, ongoing) 먼저, 빠른 일시 순 정렬
|
||||
const meetings = [...SAMPLE_MEETINGS]
|
||||
.sort((a, b) => {
|
||||
// 회의록 미생성 회의 우선
|
||||
const aNoMinutes = a.status === 'scheduled' || a.status === 'ongoing';
|
||||
const bNoMinutes = b.status === 'scheduled' || b.status === 'ongoing';
|
||||
|
||||
if (aNoMinutes && !bNoMinutes) return -1;
|
||||
if (!aNoMinutes && bNoMinutes) return 1;
|
||||
|
||||
// 동일 그룹 내에서는 빠른 일시 순 (오름차순)
|
||||
return new Date(a.date + ' ' + a.time) - new Date(b.date + ' ' + b.time);
|
||||
})
|
||||
.slice(0, 3); // 상위 3개만 표시
|
||||
```
|
||||
|
||||
**요구사항 해석**:
|
||||
1. **전체 회의 목록**을 가져와야 함 (상태 무관)
|
||||
2. **회의록 생성 여부 정보** 포함 필요 (scheduled, ongoing, draft, complete)
|
||||
3. 프론트엔드에서 다음 우선순위로 정렬:
|
||||
- 1순위: 회의록 미생성 회의 (`scheduled`, `ongoing`)
|
||||
- 2순위: 빠른 일시 순
|
||||
4. 상위 3개만 표시
|
||||
|
||||
**현재 구현 상태**:
|
||||
- ❌ `GET /api/meetings` (목록 조회) - **완전 누락**
|
||||
- ✅ `GET /api/meetings/{meetingId}` (단건 조회) - 구현됨
|
||||
|
||||
**분석 결과**: ⚠️ **부분 구현** (33%)
|
||||
- **누락 API (2개)**:
|
||||
1. `GET /api/meetings` - 회의 목록 조회 (전체 상태, 날짜/시간 정렬 필요)
|
||||
2. `GET /api/dashboard/statistics` - 통계 정보 (예정된 회의, 작성중 회의록)
|
||||
|
||||
**권장사항**:
|
||||
```java
|
||||
// MeetingController에 추가 필요
|
||||
@GetMapping
|
||||
@Operation(summary = "회의 목록 조회", description = "사용자의 회의 목록을 조회합니다")
|
||||
public ResponseEntity<ApiResponse<MeetingListResponse>> getMeetingList(
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestParam(required = false) String status, // all(기본값), scheduled, ongoing, draft, complete
|
||||
@RequestParam(required = false) LocalDateTime startDate,
|
||||
@RequestParam(required = false) LocalDateTime endDate,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "10") int size,
|
||||
@RequestParam(defaultValue = "startTime") String sortBy,
|
||||
@RequestParam(defaultValue = "asc") String sortDir
|
||||
) {
|
||||
// 사용자가 참여한 모든 회의 조회
|
||||
// 응답에 회의록 생성 여부(hasMinutes), 회의록 상태(minutesStatus) 포함 필수
|
||||
}
|
||||
|
||||
// 새로운 DashboardController 생성 권장
|
||||
@GetMapping("/api/dashboard/statistics")
|
||||
public ResponseEntity<ApiResponse<DashboardStatistics>> getStatistics(
|
||||
@RequestHeader("X-User-Id") String userId
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 회의 예약/수정 화면 (03-회의예약.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의 생성 | `POST /api/meetings` | ✅ 구현됨 | [MeetingController.java:60-93](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L60-L93) | 참석자 초대 포함 |
|
||||
| 회의 정보 수정 | `PUT /api/meetings/{meetingId}` 또는 `PATCH /api/meetings/{meetingId}` | ❌ **누락** | - | **예정된 회의 수정 불가** |
|
||||
|
||||
**상세 분석**:
|
||||
|
||||
#### 회의 수정 요구사항 ([02-대시보드.html:724](design/uiux/prototype/02-대시보드.html#L724))
|
||||
프로토타입 JavaScript 로직:
|
||||
```javascript
|
||||
// 상태에 따른 이동 처리
|
||||
if (meetingStatus === 'ongoing') {
|
||||
navigateTo('05-회의진행.html');
|
||||
} else if (meetingStatus === 'draft' || meetingStatus === 'complete' || meetingStatus === 'completed') {
|
||||
navigateTo('10-회의록상세조회.html');
|
||||
} else if (meetingStatus === 'scheduled') {
|
||||
navigateTo('03-회의예약.html'); // 예정된 회의 → 회의예약 화면 (수정 모드)
|
||||
}
|
||||
```
|
||||
|
||||
**요구사항 해석**:
|
||||
1. 대시보드에서 **예정된 회의(scheduled) 카드 클릭**
|
||||
2. 회의예약 화면(03-회의예약.html)으로 이동
|
||||
3. 기존 회의 정보를 **로드하여 수정 가능**해야 함
|
||||
4. 수정 완료 시 `PUT` 또는 `PATCH` 요청 필요
|
||||
|
||||
**현재 상태**:
|
||||
- ❌ API 설계서([meeting-service-api.yaml](design/backend/api/meeting-service-api.yaml)) - **회의 수정 API 명세 없음**
|
||||
- ❌ MeetingController - **회의 수정 API 구현 없음**
|
||||
- ✅ `POST /api/meetings` (생성) - 구현됨
|
||||
- ✅ `GET /api/meetings/{meetingId}` (단건 조회) - 구현됨
|
||||
- ❌ `PUT/PATCH /api/meetings/{meetingId}` (수정) - **완전 누락**
|
||||
|
||||
**분석 결과**: ⚠️ **치명적 누락** (50%)
|
||||
- 회의 생성은 가능하지만, **예약된 회의 수정 불가**
|
||||
- 사용자가 대시보드에서 예정된 회의를 클릭해도 수정할 수 없음
|
||||
|
||||
**권장사항**:
|
||||
```java
|
||||
// MeetingController에 추가 필요
|
||||
@PutMapping("/{meetingId}")
|
||||
@Operation(summary = "회의 정보 수정", description = "예정된 회의의 정보를 수정합니다")
|
||||
public ResponseEntity<ApiResponse<MeetingResponse>> updateMeeting(
|
||||
@PathVariable String meetingId,
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestHeader("X-User-Name") String userName,
|
||||
@RequestHeader("X-User-Email") String userEmail,
|
||||
@Valid @RequestBody UpdateMeetingRequest request
|
||||
) {
|
||||
// 회의 정보 수정 로직
|
||||
// - 제목, 날짜, 시간, 장소, 안건 수정 가능
|
||||
// - 참석자 추가/제거 가능
|
||||
// - 회의 상태가 'scheduled'일 때만 수정 가능
|
||||
// - 변경 사항 참석자에게 알림
|
||||
}
|
||||
```
|
||||
|
||||
**UpdateMeetingRequest DTO**:
|
||||
```java
|
||||
public class UpdateMeetingRequest {
|
||||
private String title; // 회의 제목
|
||||
private LocalDateTime startTime; // 시작 시간
|
||||
private LocalDateTime endTime; // 종료 시간
|
||||
private String location; // 장소
|
||||
private String agenda; // 안건
|
||||
private List<String> participants; // 참석자 이메일 목록
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 템플릿 선택 화면 (04-템플릿선택.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 템플릿 목록 조회 | `GET /api/meetings/templates` | ✅ 구현됨 | [TemplateController.java:33-63](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TemplateController.java#L33-L63) | 4가지 고정 템플릿 제공 |
|
||||
| 템플릿 적용 | `PUT /api/meetings/{meetingId}/template` | ✅ 구현됨 | [MeetingController.java:108-135](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L108-L135) | 템플릿 ID로 적용 |
|
||||
|
||||
**분석 결과**: ✅ **완벽 구현** - 템플릿 관리 기능 완전 구현
|
||||
|
||||
---
|
||||
|
||||
### 5. 회의 진행 화면 (05-회의진행.html) ⚠️ **중요 업데이트**
|
||||
|
||||
#### 화면 구조 분석
|
||||
프로토타입은 4개 탭으로 구성되어 있으며, 각 탭마다 실시간 기능이 요구됩니다:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 📍 헤더: 회의 제목 + 녹음 상태 │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 📋 회의 기본정보 (카드) │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 📑 4개 탭 컨테이너 │
|
||||
│ ┌──────────────────────────────────┐ │
|
||||
│ │ 🧑🤝🧑 참석자 | 📝 AI메모 | 📚 용어 │ │
|
||||
│ │ 사전 | 📂 관련회의록 │ │
|
||||
│ └──────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────┤
|
||||
│ ⏸️ 일시정지 | 🔴 회의 종료 버튼 │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 탭1: 참석자 (Lines 697-747)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의 시작 | `POST /api/meetings/{meetingId}/start` | ✅ 구현됨 | [MeetingController.java:149-170](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L149-L170) | WebSocket 세션 생성 |
|
||||
| WebSocket 연결 | `ws://localhost:8080/ws/collaboration` | ✅ 구현됨 | [MeetingController.java:165](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L165) | 실시간 협업 지원 |
|
||||
| 참석자 초대 | `POST /api/meetings/{meetingId}/invite` | ✅ 구현됨 | [MeetingController.java:289-321](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L289-L321) | 이메일 발송 포함 |
|
||||
| 참석자 목록 표시 | `GET /api/meetings/{meetingId}` | ✅ 구현됨 | [MeetingController.java:228-244](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L228-L244) | 회의 정보에 참석자 포함 |
|
||||
|
||||
#### 탭2: AI 메모 (Lines 750-807) 🔴 **치명적 누락**
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 프로토타입 근거 | 비고 |
|
||||
|---------|---------|----------|---------------|------|
|
||||
| **메모 입력 및 저장** | `PUT /api/meetings/{meetingId}/memo` | ❌ **누락** | [Line 1119-1143](design/uiux/prototype/05-회의진행.html#L1119-L1143) | 개인별 메모 저장 |
|
||||
| **AI 추천 실시간 조회** | `GET /api/ai/suggestions/realtime/{meetingId}` | ❌ **누락** | [Line 767-806](design/uiux/prototype/05-회의진행.html#L767-L806) | 실시간 폴링 필요 |
|
||||
| **AI 추천 채택** | `POST /api/ai/suggestions/{suggestionId}/adopt` | ❌ **누락** | [Line 1070-1097](design/uiux/prototype/05-회의진행.html#L1070-L1097) | 시간 포함 저장 |
|
||||
|
||||
**프로토타입 JavaScript 분석** (saveMemo 함수):
|
||||
```javascript
|
||||
function saveMemo() {
|
||||
const memo = memoTextarea.value.trim();
|
||||
// 실제 구현시에는 서버로 전송
|
||||
// fetch('/api/meetings/memo', {
|
||||
// method: 'PUT',
|
||||
// body: JSON.stringify({ memo: memo }),
|
||||
// headers: { 'Content-Type': 'application/json' }
|
||||
// });
|
||||
}
|
||||
```
|
||||
|
||||
**영향도**:
|
||||
- 🔴 사용자가 작성한 메모가 저장되지 않음 (데이터 손실 위험)
|
||||
- 🔴 AI 실시간 추천 기능 완전 미동작
|
||||
- 🔴 **유저스토리 US-07, US-08**의 핵심 기능
|
||||
|
||||
#### 탭3: 용어사전 (Lines 810-967) 🟡 **부분 구현**
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| **AI 전문용어 실시간 감지** | `POST /api/ai/terms/detect` | ✅ 구현됨 | [TermController.java:35-79](ai/src/main/java/com/unicorn/hgzero/ai/infra/controller/TermController.java#L35-L79) | 회의 중 용어 자동 감지 |
|
||||
| **용어 검색** | `GET /api/ai/terms/search` | ❌ **누락** | [Line 1145-1182](design/uiux/prototype/05-회의진행.html#L1145-L1182) | 키워드 검색 |
|
||||
| **용어 상세 조회** | `GET /api/ai/terms/{termName}/detail` | ❌ **누락** | [Line 1305-1308](design/uiux/prototype/05-회의진행.html#L1305-L1308) | 모달 표시 |
|
||||
|
||||
#### 탭4: 관련회의록 (Lines 970-1010) ✅ **완벽 구현**
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| **AI 유사 회의록 찾기** | `GET /api/ai/transcripts/{meetingId}/related` | ✅ 구현됨 | [RelationController.java:31-62](ai/src/main/java/com/unicorn/hgzero/ai/infra/controller/RelationController.java#L31-L62) | 벡터 유사도 검색 |
|
||||
| 관련 회의록 열기 | `GET /api/meetings/minutes/{minutesId}` | ✅ 구현됨 | 기존 API 재사용 | 새 탭 열기 |
|
||||
|
||||
#### 녹음 제어 (Bottom Bar) 🔴 **치명적 누락**
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 프로토타입 근거 | 비고 |
|
||||
|---------|---------|----------|---------------|------|
|
||||
| **녹음 일시정지** | `POST /api/stt/recordings/{recordingId}/pause` | ❌ **누락** | [Line 1212-1243](design/uiux/prototype/05-회의진행.html#L1212-L1243) | 타이머 정지 |
|
||||
| **녹음 재개** | `POST /api/stt/recordings/{recordingId}/resume` | ❌ **누락** | [Line 1212-1243](design/uiux/prototype/05-회의진행.html#L1212-L1243) | 타이머 재개 |
|
||||
| 녹음 시작 | `POST /api/stt/recordings/{recordingId}/start` | ✅ 구현됨 | [RecordingController.java:83-94](stt/src/main/java/com/unicorn/hgzero/stt/controller/RecordingController.java#L83-L94) | - |
|
||||
| 녹음 중지 | `POST /api/stt/recordings/{recordingId}/stop` | ✅ 구현됨 | [RecordingController.java:115-126](stt/src/main/java/com/unicorn/hgzero/stt/controller/RecordingController.java#L115-L126) | - |
|
||||
| 회의 종료 | `POST /api/meetings/{meetingId}/end` | ✅ 구현됨 | [MeetingController.java:184-214](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L184-L214) | AI 분석 포함 |
|
||||
|
||||
**현재 상태**: RecordingController에는 `start`와 `stop`만 있고 `pause/resume` 없음
|
||||
|
||||
**영향도**:
|
||||
- 🔴 회의 중 잠깐 중단 후 재개 시나리오 불가
|
||||
- 🔴 **유저스토리 US-06**의 핵심 기능
|
||||
|
||||
---
|
||||
|
||||
**분석 결과**: ⚠️ **부분 구현 (50%)** - **실시간 기능 7개 API 누락**
|
||||
|
||||
### 누락 API 상세 명세
|
||||
|
||||
#### 1. 메모 저장 API 🔴 P0
|
||||
```java
|
||||
PUT /api/meetings/{meetingId}/memo
|
||||
Request Body: {
|
||||
"memo": "string",
|
||||
"userId": "string",
|
||||
"timestamp": "datetime"
|
||||
}
|
||||
Response: { "memoId": "string", "savedAt": "datetime" }
|
||||
```
|
||||
|
||||
#### 2. AI 실시간 추천 조회 API 🔴 P0
|
||||
```java
|
||||
GET /api/ai/suggestions/realtime/{meetingId}?since={timestamp}&limit=10
|
||||
Response: {
|
||||
"suggestions": [
|
||||
{
|
||||
"suggestionId": "string",
|
||||
"timestamp": "00:05:23",
|
||||
"content": "string",
|
||||
"confidence": 0.95,
|
||||
"category": "DISCUSSION|DECISION"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. AI 추천 채택 API 🟡 P1
|
||||
```java
|
||||
POST /api/ai/suggestions/{suggestionId}/adopt
|
||||
Request Body: {
|
||||
"meetingId": "string",
|
||||
"timestamp": "00:05:23",
|
||||
"userId": "string"
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 용어 검색 API 🟡 P1
|
||||
```java
|
||||
GET /api/ai/terms/search?query={keyword}&meetingId={id}
|
||||
Response: {
|
||||
"terms": [...],
|
||||
"totalCount": 5
|
||||
}
|
||||
```
|
||||
|
||||
#### 5. 용어 상세 조회 API 🟢 P2
|
||||
```java
|
||||
GET /api/ai/terms/{termName}/detail?meetingId={id}
|
||||
Response: {
|
||||
"term": "string",
|
||||
"definition": "string",
|
||||
"usageInMeeting": [...],
|
||||
"externalLinks": [...]
|
||||
}
|
||||
```
|
||||
|
||||
#### 6-7. 녹음 일시정지/재개 API 🔴 P0
|
||||
```java
|
||||
POST /api/stt/recordings/{recordingId}/pause
|
||||
POST /api/stt/recordings/{recordingId}/resume
|
||||
Response: { "status": "PAUSED|RECORDING", "timestamp": "datetime" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 회의 종료 화면 (07-회의종료.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의 종료 | `POST /api/meetings/{meetingId}/end` | ✅ 구현됨 | [MeetingController.java:184-214](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L184-L214) | AI 분석, 회의록 생성 |
|
||||
|
||||
**분석 결과**: ✅ **완벽 구현** - AI 기반 회의록 자동 생성 포함
|
||||
|
||||
---
|
||||
|
||||
### 7. 회의록 상세 조회 화면 (10-회의록상세조회.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의록 상세 조회 | `GET /api/meetings/minutes/{minutesId}` | ✅ 구현됨 | [MinutesController.java:271-297](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L271-L297) | 대시보드 탭, 회의록 탭 데이터 포함 |
|
||||
|
||||
**분석 결과**: ✅ **완벽 구현** - 상세 조회 완전 구현 (Mock 데이터 포함)
|
||||
|
||||
---
|
||||
|
||||
### 8. 회의록 수정 화면 (11-회의록수정.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의록 수정 | `PATCH /api/meetings/minutes/{minutesId}` | ✅ 구현됨 | [MinutesController.java:300-343](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L300-L343) | 제목, 섹션 내용 수정 |
|
||||
| 회의록 확정 | `POST /api/meetings/minutes/{minutesId}/finalize` | ✅ 구현됨 | [MinutesController.java:346-374](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L346-L374) | 버전 관리 포함 |
|
||||
| 섹션 검증 | `POST /api/meetings/minutes/{minutesId}/sections/{sectionId}/verify` | ✅ 구현됨 | [MinutesController.java:377-410](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L377-L410) | 섹션별 완료 검증 |
|
||||
| 섹션 잠금 | `POST /api/meetings/minutes/{minutesId}/sections/{sectionId}/lock` | ✅ 구현됨 | [MinutesController.java:413-446](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L413-L446) | 동시 편집 방지 |
|
||||
| 섹션 잠금 해제 | `DELETE /api/meetings/minutes/{minutesId}/sections/{sectionId}/lock` | ✅ 구현됨 | [MinutesController.java:449-480](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L449-L480) | 잠금 해제 |
|
||||
| AI 요약 재생성 | `POST /api/meetings/minutes/{minutesId}/sections/{sectionId}/regenerate-summary` | ❌ **누락** | - | AI 요약 재생성 기능 필요 |
|
||||
|
||||
**분석 결과**: ⚠️ **부분 구현** (83%)
|
||||
- **누락 API (1개)**: AI 요약 재생성 기능
|
||||
|
||||
**권장사항**:
|
||||
```java
|
||||
// MinutesController에 추가 필요
|
||||
@PostMapping("/{minutesId}/sections/{sectionId}/regenerate-summary")
|
||||
@Operation(summary = "AI 요약 재생성", description = "섹션의 AI 요약을 재생성합니다")
|
||||
public ResponseEntity<ApiResponse<SectionSummary>> regenerateSummary(
|
||||
@PathVariable String minutesId,
|
||||
@PathVariable String sectionId,
|
||||
@RequestHeader("X-User-Id") String userId
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 9. 회의록 목록 조회 화면 (12-회의록목록조회.html)
|
||||
|
||||
| 화면 기능 | 요구 API | 구현 상태 | 구현 위치 | 비고 |
|
||||
|---------|---------|----------|----------|------|
|
||||
| 회의록 목록 조회 | `GET /api/meetings/minutes` | ✅ 구현됨 | [MinutesController.java:210-268](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L210-L268) | 상태 필터, 페이징 지원 |
|
||||
| 검색 기능 | `GET /api/meetings/minutes?keyword={keyword}` | ⚠️ **개선 필요** | [MinutesController.java:210](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L210) | 키워드 검색 파라미터 추가 필요 |
|
||||
| 참여 유형 필터 | `GET /api/meetings/minutes?participationType={type}` | ⚠️ **개선 필요** | [MinutesController.java:210](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L210) | 참여 유형 필터 추가 필요 |
|
||||
|
||||
**분석 결과**: ⚠️ **개선 필요**
|
||||
- 기본 목록 조회는 구현되어 있으나, 프로토타입에서 요구하는 세부 필터링 기능 미구현
|
||||
|
||||
**권장사항**:
|
||||
```java
|
||||
// MinutesController 개선 필요
|
||||
@GetMapping
|
||||
public ResponseEntity<ApiResponse<MinutesListResponse>> getMinutesList(
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestParam(required = false) String status, // 기존 기능
|
||||
@RequestParam(required = false) String keyword, // 추가 필요 - 제목/내용 검색
|
||||
@RequestParam(required = false) String participationType, // 추가 필요 - host, participant, all
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size,
|
||||
@RequestParam(defaultValue = "createdAt") String sortBy,
|
||||
@RequestParam(defaultValue = "desc") String sortDir
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 통합 분석
|
||||
|
||||
### 구현된 API 목록 (24개)
|
||||
|
||||
#### 인증 서비스 (4개)
|
||||
| API | 메서드 | 엔드포인트 | 구현 위치 |
|
||||
|-----|--------|-----------|----------|
|
||||
| 로그인 | POST | `/api/auth/login` | [UserController.java:37](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L37) |
|
||||
| 토큰 갱신 | POST | `/api/auth/refresh` | [UserController.java:59](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L59) |
|
||||
| 로그아웃 | POST | `/api/auth/logout` | [UserController.java:82](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L82) |
|
||||
| 토큰 검증 | GET | `/api/auth/validate` | [UserController.java:105](user/src/main/java/com/unicorn/hgzero/user/controller/UserController.java#L105) |
|
||||
|
||||
#### 회의 관리 서비스 (6개 - 목록 조회, 회의 수정 누락)
|
||||
| API | 메서드 | 엔드포인트 | 구현 위치 |
|
||||
|-----|--------|-----------|----------|
|
||||
| 회의 생성 | POST | `/api/meetings` | [MeetingController.java:60](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L60) |
|
||||
| 템플릿 적용 | PUT | `/api/meetings/{meetingId}/template` | [MeetingController.java:108](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L108) |
|
||||
| 회의 시작 | POST | `/api/meetings/{meetingId}/start` | [MeetingController.java:149](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L149) |
|
||||
| 회의 종료 | POST | `/api/meetings/{meetingId}/end` | [MeetingController.java:184](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L184) |
|
||||
| 회의 단건 조회 | GET | `/api/meetings/{meetingId}` | [MeetingController.java:228](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L228) |
|
||||
| 회의 취소 | DELETE | `/api/meetings/{meetingId}` | [MeetingController.java:258](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L258) |
|
||||
| 참석자 초대 | POST | `/api/meetings/{meetingId}/invite` | [MeetingController.java:289](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L289) |
|
||||
|
||||
**⚠️ 누락 API (2개)**:
|
||||
1. `GET /api/meetings` (회의 목록 조회) - 대시보드 "최근 회의" 섹션에 필수
|
||||
2. `PUT /api/meetings/{meetingId}` (회의 정보 수정) - **예정된 회의 수정 불가**
|
||||
|
||||
#### 회의록 관리 서비스 (7개)
|
||||
| API | 메서드 | 엔드포인트 | 구현 위치 |
|
||||
|-----|--------|-----------|----------|
|
||||
| 회의록 목록 조회 | GET | `/api/meetings/minutes` | [MinutesController.java:210](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L210) |
|
||||
| 회의록 상세 조회 | GET | `/api/meetings/minutes/{minutesId}` | [MinutesController.java:271](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L271) |
|
||||
| 회의록 수정 | PATCH | `/api/meetings/minutes/{minutesId}` | [MinutesController.java:300](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L300) |
|
||||
| 회의록 확정 | POST | `/api/meetings/minutes/{minutesId}/finalize` | [MinutesController.java:346](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L346) |
|
||||
| 섹션 검증 | POST | `/api/meetings/minutes/{minutesId}/sections/{sectionId}/verify` | [MinutesController.java:377](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L377) |
|
||||
| 섹션 잠금 | POST | `/api/meetings/minutes/{minutesId}/sections/{sectionId}/lock` | [MinutesController.java:413](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L413) |
|
||||
| 섹션 잠금 해제 | DELETE | `/api/meetings/minutes/{minutesId}/sections/{sectionId}/lock` | [MinutesController.java:449](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MinutesController.java#L449) |
|
||||
|
||||
#### Todo 관리 서비스 (4개)
|
||||
| API | 메서드 | 엔드포인트 | 구현 위치 |
|
||||
|-----|--------|-----------|----------|
|
||||
| Todo 생성 | POST | `/api/meetings/todos` | [TodoController.java:50](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TodoController.java#L50) |
|
||||
| Todo 수정 | PATCH | `/api/meetings/todos/{todoId}` | [TodoController.java:114](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TodoController.java#L114) |
|
||||
| Todo 완료 | PATCH | `/api/meetings/todos/{todoId}/complete` | [TodoController.java:163](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TodoController.java#L163) |
|
||||
| Todo 목록 조회 | GET | `/api/meetings/todos` | [TodoController.java:210](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TodoController.java#L210) |
|
||||
|
||||
#### 템플릿 관리 서비스 (1개)
|
||||
| API | 메서드 | 엔드포인트 | 구현 위치 |
|
||||
|-----|--------|-----------|----------|
|
||||
| 템플릿 목록 조회 | GET | `/api/meetings/templates` | [TemplateController.java:33](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/TemplateController.java#L33) |
|
||||
|
||||
#### WebSocket (1개)
|
||||
| API | 프로토콜 | 엔드포인트 | 구현 위치 |
|
||||
|-----|---------|-----------|----------|
|
||||
| 실시간 협업 | WebSocket | `ws://localhost:8080/ws/collaboration` | [MeetingController.java:165](meeting/src/main/java/com/unicorn/hgzero/meeting/infra/controller/MeetingController.java#L165) |
|
||||
|
||||
---
|
||||
|
||||
### ❌ 누락된 API 목록 (4개 완전 누락 + 2개 개선 필요)
|
||||
|
||||
#### 완전 누락 (4개)
|
||||
| 우선순위 | API | 메서드 | 엔드포인트 | 필요한 이유 | 권장 구현 위치 |
|
||||
|---------|-----|--------|-----------|-----------|--------------|
|
||||
| 🔴 **긴급** | 회의 목록 조회 | GET | `/api/meetings` | 대시보드 "최근 회의" 섹션 표시 **불가** | MeetingController |
|
||||
| 🔴 **긴급** | 회의 정보 수정 | PUT/PATCH | `/api/meetings/{meetingId}` | 대시보드에서 예정된 회의 클릭 시 수정 **불가** | MeetingController |
|
||||
| 🔴 **긴급** | 대시보드 통계 | GET | `/api/dashboard/statistics` | 대시보드 통계 카드 (예정된 회의, 작성중 회의록) 표시 **불가** | 신규 DashboardController |
|
||||
| 🟡 중간 | AI 요약 재생성 | POST | `/api/meetings/minutes/{minutesId}/sections/{sectionId}/regenerate-summary` | 회의록 수정 화면 AI 요약 재생성 버튼 **동작 불가** | MinutesController |
|
||||
|
||||
#### 기능 개선 필요 (2개)
|
||||
| 우선순위 | API | 현재 상태 | 개선 내용 | 필요한 이유 |
|
||||
|---------|-----|----------|-----------|-----------|
|
||||
| 🟡 중간 | 회의록 목록 조회 | `GET /api/meetings/minutes` 구현됨 | `keyword` 파라미터 추가 | 회의록 목록 화면 검색 기능 동작 안 함 |
|
||||
| 🟡 중간 | 회의록 목록 조회 | `GET /api/meetings/minutes` 구현됨 | `participationType` 파라미터 추가 | 회의록 목록 화면 참여 유형 필터 동작 안 함 |
|
||||
|
||||
---
|
||||
|
||||
### ✅ 불필요한 API (0개)
|
||||
|
||||
**분석 결과**: 구현된 모든 API가 프로토타입에서 요구하는 기능과 매칭되며, 불필요한 API는 없음.
|
||||
|
||||
---
|
||||
|
||||
## 💡 권장 개선사항
|
||||
|
||||
### 1. 높은 우선순위 (🔴 필수)
|
||||
|
||||
#### 1.1 회의 목록 조회 API 추가
|
||||
```java
|
||||
// MeetingController.java에 추가
|
||||
@GetMapping
|
||||
@Operation(summary = "회의 목록 조회", description = "사용자의 회의 목록을 조회합니다")
|
||||
public ResponseEntity<ApiResponse<MeetingListResponse>> getMeetingList(
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestParam(required = false) String status, // upcoming, ongoing, completed
|
||||
@RequestParam(required = false) LocalDateTime startDate,
|
||||
@RequestParam(required = false) LocalDateTime endDate,
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "10") int size,
|
||||
@RequestParam(defaultValue = "startTime") String sortBy,
|
||||
@RequestParam(defaultValue = "asc") String sortDir
|
||||
) {
|
||||
// 구현 로직
|
||||
}
|
||||
```
|
||||
|
||||
**요구사항**:
|
||||
- 상태별 필터링: `upcoming` (예정), `ongoing` (진행 중), `completed` (완료)
|
||||
- 날짜 범위 필터링
|
||||
- 페이징 지원
|
||||
- 정렬 기능 (시작 시간, 생성 시간 등)
|
||||
|
||||
---
|
||||
|
||||
#### 1.2 대시보드 통계 API 추가
|
||||
```java
|
||||
// 신규 DashboardController.java 생성
|
||||
@RestController
|
||||
@RequestMapping("/api/dashboard")
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "Dashboard", description = "대시보드 API")
|
||||
public class DashboardController {
|
||||
|
||||
@GetMapping("/statistics")
|
||||
@Operation(summary = "대시보드 통계 조회", description = "사용자의 통계 정보를 조회합니다")
|
||||
public ResponseEntity<ApiResponse<DashboardStatistics>> getStatistics(
|
||||
@RequestHeader("X-User-Id") String userId
|
||||
) {
|
||||
// 구현 로직
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**응답 데이터 구조**:
|
||||
```json
|
||||
{
|
||||
"totalMeetings": 24,
|
||||
"upcomingMeetings": 3,
|
||||
"completedMinutes": 18,
|
||||
"pendingTodos": 7,
|
||||
"completedTodos": 15,
|
||||
"thisWeekMeetings": 5,
|
||||
"thisMonthMeetings": 12
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. 중간 우선순위 (🟡 권장)
|
||||
|
||||
#### 2.1 AI 요약 재생성 API 추가
|
||||
```java
|
||||
// MinutesController.java에 추가
|
||||
@PostMapping("/{minutesId}/sections/{sectionId}/regenerate-summary")
|
||||
@Operation(summary = "AI 요약 재생성", description = "섹션의 AI 요약을 재생성합니다")
|
||||
public ResponseEntity<ApiResponse<SectionSummary>> regenerateSummary(
|
||||
@PathVariable String minutesId,
|
||||
@PathVariable String sectionId,
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestHeader("X-User-Name") String userName
|
||||
) {
|
||||
// AI 서비스 호출하여 요약 재생성
|
||||
// 버전 관리 (이전 요약 보존)
|
||||
// 이벤트 발행 (요약 재생성 알림)
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### 2.2 회의록 목록 API 개선
|
||||
```java
|
||||
// MinutesController.java 수정
|
||||
@GetMapping
|
||||
public ResponseEntity<ApiResponse<MinutesListResponse>> getMinutesList(
|
||||
@RequestHeader("X-User-Id") String userId,
|
||||
@RequestParam(required = false) String status,
|
||||
@RequestParam(required = false) String keyword, // 추가 - 제목/내용 검색
|
||||
@RequestParam(required = false) String participationType, // 추가 - host, participant, all
|
||||
@RequestParam(defaultValue = "0") int page,
|
||||
@RequestParam(defaultValue = "20") int size,
|
||||
@RequestParam(defaultValue = "createdAt") String sortBy,
|
||||
@RequestParam(defaultValue = "desc") String sortDir
|
||||
) {
|
||||
// 구현 로직
|
||||
}
|
||||
```
|
||||
|
||||
**추가 필터 설명**:
|
||||
- `keyword`: 회의록 제목 또는 내용에서 검색 (LIKE 검색)
|
||||
- `participationType`:
|
||||
- `host`: 주최한 회의록만
|
||||
- `participant`: 참여한 회의록만
|
||||
- `all`: 모든 회의록 (기본값)
|
||||
|
||||
---
|
||||
|
||||
### 3. 낮은 우선순위 (🟢 선택)
|
||||
|
||||
#### 3.1 회의록 버전 관리 API
|
||||
```java
|
||||
// MinutesController.java에 추가 고려
|
||||
@GetMapping("/{minutesId}/versions")
|
||||
@Operation(summary = "회의록 버전 목록 조회")
|
||||
public ResponseEntity<ApiResponse<List<MinutesVersion>>> getMinutesVersions(
|
||||
@PathVariable String minutesId
|
||||
)
|
||||
|
||||
@GetMapping("/{minutesId}/versions/{version}")
|
||||
@Operation(summary = "특정 버전 회의록 조회")
|
||||
public ResponseEntity<ApiResponse<MinutesDetail>> getMinutesVersion(
|
||||
@PathVariable String minutesId,
|
||||
@PathVariable int version
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 구현 우선순위 로드맵
|
||||
|
||||
### Phase 1: 필수 기능 (Sprint 1-2)
|
||||
1. ✅ **회의 목록 조회 API** (MeetingController)
|
||||
- 예상 작업 시간: 4시간
|
||||
- 의존성: MeetingService, MeetingRepository
|
||||
|
||||
2. ✅ **대시보드 통계 API** (신규 DashboardController)
|
||||
- 예상 작업 시간: 6시간
|
||||
- 의존성: MeetingService, MinutesService, TodoService
|
||||
|
||||
### Phase 2: 개선 기능 (Sprint 3)
|
||||
3. ✅ **AI 요약 재생성 API** (MinutesController)
|
||||
- 예상 작업 시간: 8시간
|
||||
- 의존성: AI Service, Event Publisher
|
||||
|
||||
4. ✅ **회의록 검색/필터 개선** (MinutesController)
|
||||
- 예상 작업 시간: 3시간
|
||||
- 의존성: MinutesRepository (쿼리 추가)
|
||||
|
||||
### Phase 3: 선택 기능 (Sprint 4)
|
||||
5. ⏸️ **버전 관리 API** (MinutesController)
|
||||
- 예상 작업 시간: 6시간
|
||||
- 의존성: 버전 관리 스키마 설계
|
||||
|
||||
---
|
||||
|
||||
## 📝 코드 리뷰 의견
|
||||
|
||||
### ✅ 잘된 점
|
||||
|
||||
1. **일관된 API 설계**
|
||||
- RESTful 원칙 준수
|
||||
- 명확한 엔드포인트 네이밍
|
||||
- 표준 HTTP 메서드 사용
|
||||
|
||||
2. **포괄적인 문서화**
|
||||
- Swagger/OpenAPI 주석 완벽 작성
|
||||
- 각 API마다 상세한 설명과 파라미터 문서화
|
||||
|
||||
3. **보안 고려**
|
||||
- JWT 기반 인증/인가
|
||||
- LDAP 통합
|
||||
- Request Header를 통한 사용자 식별
|
||||
|
||||
4. **실용적인 Mock 데이터**
|
||||
- 프론트엔드 개발을 위한 상세한 Mock 데이터 제공
|
||||
- 실제 데이터 구조와 동일한 형태
|
||||
|
||||
5. **캐시 전략**
|
||||
- Redis 캐시 적극 활용
|
||||
- 적절한 캐시 무효화 로직
|
||||
|
||||
6. **이벤트 기반 아키텍처**
|
||||
- Event Publisher를 통한 비동기 처리
|
||||
- 알림 시스템 통합 준비
|
||||
|
||||
### ⚠️ 개선이 필요한 점
|
||||
|
||||
1. **누락된 핵심 API**
|
||||
- 대시보드 통계 API 없음 → 사용자 경험 저하
|
||||
- 회의 목록 조회 API 없음 → 대시보드 불완전
|
||||
|
||||
2. **검색 기능 부족**
|
||||
- 회의록 검색 파라미터 미구현
|
||||
- 키워드 기반 검색 불가
|
||||
|
||||
3. **에러 처리 일관성**
|
||||
- 일부 Controller에서 try-catch로 처리
|
||||
- 일부는 비즈니스 예외를 그대로 던짐
|
||||
- 통일된 예외 처리 전략 필요
|
||||
|
||||
4. **테스트 코드 부재**
|
||||
- Controller 테스트 코드 확인 필요
|
||||
- API 통합 테스트 권장
|
||||
|
||||
---
|
||||
|
||||
## 🔧 기술적 권장사항
|
||||
|
||||
### 1. API 버전 관리
|
||||
```java
|
||||
// 향후 API 변경에 대비한 버전 관리 권장
|
||||
@RequestMapping("/api/v1/meetings")
|
||||
```
|
||||
|
||||
### 2. 페이징 표준화
|
||||
```java
|
||||
// 모든 목록 조회 API에 일관된 페이징 파라미터 적용
|
||||
@RequestParam(defaultValue = "0") int page
|
||||
@RequestParam(defaultValue = "20") int size
|
||||
@RequestParam(defaultValue = "createdAt") String sortBy
|
||||
@RequestParam(defaultValue = "desc") String sortDir
|
||||
```
|
||||
|
||||
### 3. 응답 데이터 일관성
|
||||
```java
|
||||
// 모든 API가 ApiResponse 래퍼 사용 (이미 잘 적용됨)
|
||||
public class ApiResponse<T> {
|
||||
private String message;
|
||||
private T data;
|
||||
private String errorCode; // 에러 처리 강화
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Rate Limiting
|
||||
```java
|
||||
// 공격 방지를 위한 Rate Limiting 추가 권장
|
||||
@RateLimit(limit = 100, duration = 1, unit = TimeUnit.MINUTES)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 비교 지표
|
||||
|
||||
| 항목 | 프로토타입 요구사항 | 구현 현황 | 구현률 |
|
||||
|-----|------------------|----------|--------|
|
||||
| 인증 API | 4개 | 4개 | 100% ✅ |
|
||||
| 회의 관리 API | 8개 | 6개 | 75% ⚠️ |
|
||||
| 회의록 관리 API | 8개 | 7개 | 88% ⚠️ |
|
||||
| Todo 관리 API | 4개 | 4개 | 100% ✅ |
|
||||
| 템플릿 API | 2개 | 2개 | 100% ✅ |
|
||||
| 대시보드 API | 1개 | 0개 | 0% ❌ |
|
||||
| **전체 합계** | **27개** | **23개** | **85%** ⚠️ |
|
||||
|
||||
---
|
||||
|
||||
## 🎬 결론
|
||||
|
||||
### 종합 평가
|
||||
- **전체 구현률**: 85% (23/27 API)
|
||||
- **핵심 비즈니스 로직**: ⚠️ 회의 수정 기능 누락
|
||||
- **사용자 경험**: ⚠️ 개선 필요 (대시보드 회의 목록, 회의 수정, 통계, 검색 기능)
|
||||
- **코드 품질**: ✅ 우수 (문서화, 구조, 보안)
|
||||
|
||||
### 즉시 조치 필요 (🔴 긴급 - 3개)
|
||||
1. 🔴 **회의 목록 조회 API 구현** (`GET /api/meetings`)
|
||||
- 대시보드 "최근 회의" 섹션 표시 불가
|
||||
|
||||
2. 🔴 **회의 정보 수정 API 구현** (`PUT /api/meetings/{meetingId}`)
|
||||
- **설계서에도 누락됨** - API 명세서 작성 필요
|
||||
- 예정된 회의를 수정할 수 없음
|
||||
- 대시보드에서 scheduled 회의 클릭 시 동작 불가
|
||||
|
||||
3. 🔴 **대시보드 통계 API 구현** (`GET /api/dashboard/statistics`)
|
||||
- 대시보드 통계 카드 표시 불가
|
||||
|
||||
### 다음 스프린트 권장
|
||||
3. 🟡 **AI 요약 재생성 API 구현** (사용자 경험 개선)
|
||||
4. 🟡 **회의록 검색 기능 강화** (사용성 향상)
|
||||
|
||||
### 장기 개선 과제
|
||||
5. 🟢 **버전 관리 API** (고급 기능)
|
||||
6. 🟢 **Rate Limiting 적용** (보안 강화)
|
||||
7. 🟢 **API 버전 관리 도입** (확장성)
|
||||
|
||||
---
|
||||
|
||||
**리뷰 완료일**: 2025-10-28
|
||||
**리뷰어**: Architect, Backend Developer, Frontend Developer
|
||||
**다음 리뷰 예정**: Phase 1 구현 완료 후
|
||||
40117
design/aidata/meet-ref.json
Normal file
40117
design/aidata/meet-ref.json
Normal file
File diff suppressed because it is too large
Load Diff
3639
design/aidata/terms-01.json
Normal file
3639
design/aidata/terms-01.json
Normal file
File diff suppressed because it is too large
Load Diff
3916
design/aidata/terms-02.json
Normal file
3916
design/aidata/terms-02.json
Normal file
File diff suppressed because it is too large
Load Diff
1333
design/aidata/terms-03.json
Normal file
1333
design/aidata/terms-03.json
Normal file
File diff suppressed because it is too large
Load Diff
1424
design/aidata/terms-04.json
Normal file
1424
design/aidata/terms-04.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,289 +1,373 @@
|
||||
# 벡터DB 임베딩용 관련자료 샘플 데이터
|
||||
|
||||
**작성일**: 2025-01-22
|
||||
**버전**: v1.0
|
||||
**작성자**: AI 개발팀
|
||||
## 📋 개요
|
||||
|
||||
---
|
||||
본 데이터셋은 회의록 작성 및 공유 개선 서비스의 벡터DB 구축을 위한 샘플 데이터입니다.
|
||||
통신회사의 8개 업무 도메인별로 4가지 문서 유형에 대해 각 50개씩, 총 **1,600개**의 샘플 문서를 제공합니다.
|
||||
|
||||
## 1. 개요
|
||||
## 📊 데이터 구성
|
||||
|
||||
### 1.1 목적
|
||||
회의록 작성 시 AI가 참조할 수 있는 관련 자료를 벡터DB에 임베딩하여, 맥락 기반 용어 설명 및 관련 회의록 자동 연결 기능을 제공하기 위한 샘플 데이터를 생성합니다.
|
||||
### 업무 도메인 (8개)
|
||||
1. **고객서비스** - VOC, 상담 품질, 고객 응대
|
||||
2. **영업마케팅** - 요금제, 프로모션, 유통 채널
|
||||
3. **요금청구** - 빌링, 과금, 미수금 관리
|
||||
4. **네트워크운용** - 5G, 장애 대응, 트래픽 관리
|
||||
5. **서비스기획** - 신규 서비스, 콘텐츠 제휴
|
||||
6. **시스템운영** - IT 인프라, 클라우드, DevOps
|
||||
7. **가입자관리** - 개통, 해지, 번호이동
|
||||
8. **기업영업** - B2B 솔루션, 전용선, AICC
|
||||
|
||||
### 1.2 데이터 구성
|
||||
- **도메인**: 통신 업무 도메인 15개
|
||||
- **데이터 소스 유형**: 4가지 (이전 회의록, 조직문서, 프로젝트 문서, 운영문서)
|
||||
- **샘플 개수**: 각 도메인별 × 각 소스별 5개 = **총 300개**
|
||||
### 문서 유형 (4개)
|
||||
1. **이전 회의록** (meeting_minutes)
|
||||
- 회의 일시, 참석자, 안건, 결정사항, 조치사항 포함
|
||||
- 실제 회의록 형식의 상세한 내용
|
||||
|
||||
---
|
||||
2. **조직문서** (org_document)
|
||||
- 업무 매뉴얼, 정책 가이드라인, 표준 절차서
|
||||
- 공식 문서 형식의 구조화된 내용
|
||||
|
||||
## 2. 통신 업무 도메인 (15개)
|
||||
3. **프로젝트 문서** (project_document)
|
||||
- 요구사항 정의서, 설계서, 수행 계획서
|
||||
- 프로젝트 관련 기술 문서
|
||||
|
||||
| 번호 | 도메인 | 설명 |
|
||||
|------|--------|------|
|
||||
| 1 | 네트워크 인프라 | 네트워크 구축 및 운영, 유무선 통신망 관리, 5G/LTE, 기지국 |
|
||||
| 2 | 기술 개발 및 연구 | 신기술 연구개발, AI/빅데이터, IoT, 클라우드 기술 |
|
||||
| 3 | 고객 서비스 | 고객 상담 및 지원, VoC 관리, 서비스 품질 관리 |
|
||||
| 4 | 영업 및 마케팅 | 요금제 기획, 프로모션, 유통채널 관리, B2B/B2C 영업 |
|
||||
| 5 | 요금 및 청구 | 요금 청구 시스템, 과금 관리, 미수금 관리, 정산 업무 |
|
||||
| 6 | 네트워크 운용 | 네트워크 모니터링, 장애 대응 및 복구, 품질 최적화 |
|
||||
| 7 | 서비스 기획 및 상품 개발 | 신규 서비스 기획, 요금제 설계, 콘텐츠 서비스 |
|
||||
| 8 | 정보보안 | 통신 보안, 개인정보 보호, 사이버 보안, 보안 정책 수립 |
|
||||
| 9 | 시스템 운영 및 관리 | IT 시스템 운영, 데이터센터 관리, 클라우드 인프라 |
|
||||
| 10 | 가입자 관리 | 가입자 정보 관리, 번호 이동, 개통 및 해지, 명의 변경 |
|
||||
| 11 | 망 품질 관리 | 통신 품질 측정, 품질 개선, 서비스 레벨 관리 |
|
||||
| 12 | 규제 대응 및 준법 | 통신 규제 대응, 법률 준수, 정부 정책 대응 |
|
||||
| 13 | 기업 영업 | B2B 솔루션, 전용선 서비스, AICC, 데이터센터 서비스 |
|
||||
| 14 | 로밍 및 국제 업무 | 국제 로밍 서비스, 해외 통신사 제휴, 국제 전화 서비스 |
|
||||
| 15 | 신사업 | OTT 서비스, 콘텐츠 사업, 핀테크, 스마트홈/IoT 서비스 |
|
||||
4. **운영문서** (operation_document)
|
||||
- 장애 보고서, 모니터링 결과, 대응 기록
|
||||
- 실시간 운영 이슈 관련 문서
|
||||
|
||||
---
|
||||
### 통계
|
||||
- **총 문서 수**: 1,600개
|
||||
- **도메인별**: 200개씩 (8개 도메인)
|
||||
- **유형별**: 도메인당 50개씩 (4가지 유형)
|
||||
|
||||
## 3. 데이터 소스 유형 (4가지)
|
||||
## 📁 파일 구조
|
||||
|
||||
### 3.1 이전 회의록 (meeting_minutes)
|
||||
**형식**:
|
||||
- 회의 제목, 일시, 참석자
|
||||
- 논의 내용, 결정 사항, 액션 아이템
|
||||
```
|
||||
vector_db_sample_data.json
|
||||
├── metadata # 메타데이터
|
||||
│ ├── version # 버전 정보
|
||||
│ ├── created_date # 생성 일시
|
||||
│ ├── description # 설명
|
||||
│ └── 통계 정보 # 문서 수, 카테고리 수 등
|
||||
│
|
||||
├── embedding_schema # 임베딩 스키마 정의
|
||||
│ ├── document_id # 문서 고유 ID
|
||||
│ ├── document_type # 문서 유형
|
||||
│ ├── business_domain # 업무 도메인
|
||||
│ ├── title # 제목
|
||||
│ ├── content # 전체 본문 (임베딩 대상)
|
||||
│ ├── summary # 3-5문장 요약
|
||||
│ ├── keywords # 키워드 배열
|
||||
│ ├── created_date # 생성 일시 (ISO8601)
|
||||
│ ├── participants # 참석자/작성자
|
||||
│ ├── metadata # 추가 메타데이터
|
||||
│ └── embedding_vector # 임베딩 벡터 (1536차원)
|
||||
│
|
||||
└── sample_data # 실제 샘플 데이터
|
||||
├── 고객서비스
|
||||
│ ├── meeting_minutes # 50개
|
||||
│ ├── org_document # 50개
|
||||
│ ├── project_document # 50개
|
||||
│ └── operation_document # 50개
|
||||
├── 영업마케팅
|
||||
│ ├── ... (동일 구조)
|
||||
├── 요금청구
|
||||
├── 네트워크운용
|
||||
├── 서비스기획
|
||||
├── 시스템운영
|
||||
├── 가입자관리
|
||||
└── 기업영업
|
||||
```
|
||||
|
||||
**예시 토픽**:
|
||||
- 프로젝트 킥오프, 월간 리뷰, 장애 대응, 정책 수립
|
||||
## 🔧 데이터 스키마
|
||||
|
||||
**메타데이터**:
|
||||
- 회의 유형, 참석자 목록, 태그
|
||||
|
||||
### 3.2 조직문서 (manual)
|
||||
**유형**:
|
||||
- 업무 매뉴얼, 정책 및 규정, 표준화 문서
|
||||
|
||||
**예시**:
|
||||
- 프로세스 가이드, 보안 정책, 업무 표준
|
||||
|
||||
**메타데이터**:
|
||||
- 문서 카테고리, 버전, 승인자
|
||||
|
||||
### 3.3 프로젝트 문서 (project_doc)
|
||||
**유형**:
|
||||
- 요구사항 정의서, 설계 문서, 수행 결과서
|
||||
|
||||
**예시**:
|
||||
- 프로젝트 계획서, 기술 설계서, 완료 보고서
|
||||
|
||||
**메타데이터**:
|
||||
- 프로젝트명, 단계, 담당자
|
||||
|
||||
### 3.4 운영문서 (operation_doc)
|
||||
**유형**:
|
||||
- 장애 보고서, 고객 응대 문서
|
||||
|
||||
**예시**:
|
||||
- 장애 분석 보고서, 고객 이슈 처리 가이드
|
||||
|
||||
**메타데이터**:
|
||||
- 심각도, 영향 범위, 해결 상태
|
||||
|
||||
---
|
||||
|
||||
## 4. 데이터 구조
|
||||
|
||||
### 4.1 JSON 스키마
|
||||
### 공통 필드
|
||||
```json
|
||||
{
|
||||
"document_id": "도메인명_소스유형_일련번호",
|
||||
"document_type": "meeting_minutes|manual|project_doc|operation_doc",
|
||||
"title": "문서 제목",
|
||||
"content": "실제 문서 내용 (500-1000자)",
|
||||
"metadata": {
|
||||
"domain": "도메인명",
|
||||
"date": "YYYY-MM-DD",
|
||||
"author": "작성자명",
|
||||
"tags": ["태그1", "태그2", "태그3"],
|
||||
"organization_id": "org_telecom_001",
|
||||
"folder_id": "folder_도메인명"
|
||||
"document_id": "string", // 예: "고객-MM-001"
|
||||
"document_type": "string", // meeting_minutes | org_document | project_document | operation_document
|
||||
"business_domain": "string", // 8개 도메인 중 하나
|
||||
"title": "string", // 문서 제목
|
||||
"content": "string", // 전체 본문 (임베딩 대상)
|
||||
"summary": "string", // 3-5문장 요약
|
||||
"keywords": ["string"], // 키워드 배열
|
||||
"created_date": "ISO8601", // 생성 일시
|
||||
"participants": ["string"], // 참석자/작성자
|
||||
"metadata": { // 추가 메타데이터
|
||||
"folder": "string", // 폴더 경로
|
||||
... // 문서 유형별 추가 필드
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 필드 설명
|
||||
### 문서 유형별 추가 메타데이터
|
||||
|
||||
| 필드 | 타입 | 설명 |
|
||||
|------|------|------|
|
||||
| document_id | string | 문서 고유 식별자 |
|
||||
| document_type | enum | 문서 유형 (4가지 중 1개) |
|
||||
| title | string | 문서 제목 |
|
||||
| content | text | 실제 문서 내용 (청킹 대상) |
|
||||
| metadata.domain | string | 업무 도메인 |
|
||||
| metadata.date | date | 작성일 (2024-01-01 ~ 2025-01-22) |
|
||||
| metadata.author | string | 작성자명 |
|
||||
| metadata.tags | array | 태그 배열 (3-5개) |
|
||||
| metadata.organization_id | string | 조직 ID |
|
||||
| metadata.folder_id | string | 폴더 ID |
|
||||
|
||||
---
|
||||
|
||||
## 5. 샘플 데이터 생성 방법
|
||||
|
||||
### 5.1 자동 생성 스크립트
|
||||
**위치**: `tools/generate_vector_samples.py`
|
||||
|
||||
**실행 방법**:
|
||||
```bash
|
||||
# Windows PowerShell 또는 CMD에서 실행
|
||||
cd C:\Users\hiond\home\workspace\HGZero
|
||||
python tools\generate_vector_samples.py
|
||||
#### 1. 회의록 (meeting_minutes)
|
||||
```json
|
||||
"metadata": {
|
||||
"folder": "/고객서비스/회의록",
|
||||
"agenda_count": 3,
|
||||
"decision_items": ["결정사항1", "결정사항2"],
|
||||
"action_items": ["조치사항1", "조치사항2"]
|
||||
}
|
||||
```
|
||||
|
||||
**출력 파일**: `data/samples/vector_db_samples_300.json`
|
||||
|
||||
### 5.2 생성 로직
|
||||
|
||||
#### 도메인별 키워드 매핑
|
||||
각 도메인마다 관련 키워드 및 토픽을 정의하여 실제 통신 업무 상황을 반영합니다.
|
||||
|
||||
**예시** (네트워크 인프라):
|
||||
- **키워드**: 5G, LTE, 기지국, 광케이블, RAN, 코어망, 백홀, 전송망
|
||||
- **토픽**: 5G 구축, 기지국 설치, 망 이중화, 광케이블 교체, 커버리지 확대
|
||||
|
||||
#### 랜덤 요소
|
||||
- 날짜: 2024-01-01 ~ 2025-01-22 범위에서 랜덤 선택
|
||||
- 작성자: 16명의 작성자 풀에서 랜덤 선택
|
||||
- 키워드 조합: 각 문서마다 2-3개 키워드를 랜덤 조합
|
||||
|
||||
#### 템플릿 기반 생성
|
||||
각 문서 유형별로 표준 템플릿을 정의하고, 도메인 및 키워드를 치환하여 실제 문서처럼 생성합니다.
|
||||
|
||||
---
|
||||
|
||||
## 6. 생성 통계
|
||||
|
||||
### 6.1 전체 통계
|
||||
- **총 샘플 개수**: 300개
|
||||
- **도메인별**: 각 20개 (15개 도메인)
|
||||
- **소스별**: 각 75개 (4가지 소스)
|
||||
|
||||
### 6.2 문서 유형별 분포
|
||||
|
||||
| 문서 유형 | 개수 | 비율 |
|
||||
|-----------|------|------|
|
||||
| 이전 회의록 (meeting_minutes) | 75개 | 25% |
|
||||
| 조직문서 (manual) | 75개 | 25% |
|
||||
| 프로젝트 문서 (project_doc) | 75개 | 25% |
|
||||
| 운영문서 (operation_doc) | 75개 | 25% |
|
||||
| **합계** | **300개** | **100%** |
|
||||
|
||||
### 6.3 도메인별 분포
|
||||
|
||||
| 도메인 | 회의록 | 매뉴얼 | 프로젝트 | 운영 | 합계 |
|
||||
|--------|--------|--------|----------|------|------|
|
||||
| 네트워크 인프라 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 기술 개발 및 연구 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 고객 서비스 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 영업 및 마케팅 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 요금 및 청구 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 네트워크 운용 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 서비스 기획 및 상품 개발 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 정보보안 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 시스템 운영 및 관리 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 가입자 관리 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 망 품질 관리 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 규제 대응 및 준법 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 기업 영업 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 로밍 및 국제 업무 | 5 | 5 | 5 | 5 | 20 |
|
||||
| 신사업 | 5 | 5 | 5 | 5 | 20 |
|
||||
| **합계** | **75** | **75** | **75** | **75** | **300** |
|
||||
|
||||
---
|
||||
|
||||
## 7. 벡터DB 임베딩 프로세스
|
||||
|
||||
### 7.1 데이터 정제
|
||||
1. **텍스트 정제**: HTML 태그 제거, 특수문자 정규화
|
||||
2. **청킹**: 문서를 1000 토큰 단위로 분할 (200 토큰 오버랩)
|
||||
3. **메타데이터 추출**: JSON 메타데이터 파싱
|
||||
|
||||
### 7.2 벡터화
|
||||
- **임베딩 모델**: text-embedding-3-small (OpenAI)
|
||||
- **차원**: 1536
|
||||
- **비용**: $0.02 / 1M 토큰
|
||||
|
||||
### 7.3 PostgreSQL + pgvector 적재
|
||||
```sql
|
||||
INSERT INTO document_chunks (
|
||||
document_id,
|
||||
chunk_index,
|
||||
content,
|
||||
embedding,
|
||||
metadata,
|
||||
organization_id
|
||||
) VALUES (?, ?, ?, ?, ?, ?);
|
||||
#### 2. 조직문서 (org_document)
|
||||
```json
|
||||
"metadata": {
|
||||
"folder": "/고객서비스/정책/문서",
|
||||
"document_version": "3.2",
|
||||
"last_updated": "2024-06-01"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
#### 3. 프로젝트 문서 (project_document)
|
||||
```json
|
||||
"metadata": {
|
||||
"folder": "/프로젝트/고객서비스",
|
||||
"project_status": "진행중", // 계획 | 진행중 | 완료
|
||||
"document_type": "요구사항정의서"
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 활용 방안
|
||||
#### 4. 운영문서 (operation_document)
|
||||
```json
|
||||
"metadata": {
|
||||
"folder": "/고객서비스/운영/장애보고",
|
||||
"incident_number": "INC-2024-09-157",
|
||||
"severity": "High", // Critical | High | Medium | Low
|
||||
"status": "복구완료"
|
||||
}
|
||||
```
|
||||
|
||||
### 8.1 맥락 기반 용어 설명
|
||||
1. 회의록 작성 중 전문 용어 감지
|
||||
2. Vector DB에서 유사도 검색 (Top-5)
|
||||
3. Claude AI에게 맥락 기반 설명 요청
|
||||
## 💡 사용 예시
|
||||
|
||||
### 8.2 관련 회의록 자동 연결
|
||||
1. 현재 회의록 내용 벡터화
|
||||
2. Vector DB에서 유사 회의록 검색
|
||||
3. 관련도 점수 계산 (70% 이상)
|
||||
4. 최대 5개 회의록 자동 연결
|
||||
### Python에서 데이터 로드
|
||||
```python
|
||||
import json
|
||||
|
||||
### 8.3 대시보드 참고자료
|
||||
- 관련 회의록 탭: 유사 회의록 목록
|
||||
- 프로젝트 문서 탭: 관련 프로젝트 문서
|
||||
- 조직 문서 탭: 관련 매뉴얼 및 정책
|
||||
# JSON 파일 로드
|
||||
with open('vector_db_sample_data.json', 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# 특정 도메인의 회의록 가져오기
|
||||
customer_service_meetings = data['sample_data']['고객서비스']['meeting_minutes']
|
||||
|
||||
# 첫 번째 회의록 확인
|
||||
first_meeting = customer_service_meetings[0]
|
||||
print(f"제목: {first_meeting['title']}")
|
||||
print(f"요약: {first_meeting['summary']}")
|
||||
print(f"키워드: {', '.join(first_meeting['keywords'])}")
|
||||
```
|
||||
|
||||
### 임베딩 생성 예시
|
||||
```python
|
||||
from openai import OpenAI
|
||||
|
||||
client = OpenAI(api_key="your-api-key")
|
||||
|
||||
# 문서 임베딩 생성
|
||||
def create_embedding(text):
|
||||
response = client.embeddings.create(
|
||||
model="text-embedding-3-small",
|
||||
input=text
|
||||
)
|
||||
return response.data[0].embedding
|
||||
|
||||
# 모든 문서에 대해 임베딩 생성
|
||||
for domain in data['sample_data']:
|
||||
for doc_type in data['sample_data'][domain]:
|
||||
for doc in data['sample_data'][domain][doc_type]:
|
||||
# content 필드를 임베딩
|
||||
embedding = create_embedding(doc['content'])
|
||||
doc['embedding_vector'] = embedding
|
||||
```
|
||||
|
||||
### 벡터DB에 저장 (Qdrant 예시)
|
||||
```python
|
||||
from qdrant_client import QdrantClient
|
||||
from qdrant_client.models import Distance, VectorParams, PointStruct
|
||||
|
||||
# Qdrant 클라이언트 초기화
|
||||
client = QdrantClient(url="http://localhost:6333")
|
||||
|
||||
# 컬렉션 생성
|
||||
client.create_collection(
|
||||
collection_name="meeting_documents",
|
||||
vectors_config=VectorParams(size=1536, distance=Distance.COSINE)
|
||||
)
|
||||
|
||||
# 문서 업로드
|
||||
points = []
|
||||
for domain in data['sample_data']:
|
||||
for doc_type in data['sample_data'][domain]:
|
||||
for doc in data['sample_data'][domain][doc_type]:
|
||||
point = PointStruct(
|
||||
id=doc['document_id'],
|
||||
vector=doc['embedding_vector'], # 이미 생성된 임베딩
|
||||
payload={
|
||||
"title": doc['title'],
|
||||
"summary": doc['summary'],
|
||||
"keywords": doc['keywords'],
|
||||
"domain": doc['business_domain'],
|
||||
"type": doc['document_type'],
|
||||
"created_date": doc['created_date']
|
||||
}
|
||||
)
|
||||
points.append(point)
|
||||
|
||||
# 배치 업로드
|
||||
client.upsert(collection_name="meeting_documents", points=points)
|
||||
```
|
||||
|
||||
### 유사 문서 검색 예시
|
||||
```python
|
||||
# 쿼리 텍스트
|
||||
query = "고객 만족도를 개선하기 위한 AI 챗봇 도입 방안"
|
||||
|
||||
# 쿼리 임베딩 생성
|
||||
query_embedding = create_embedding(query)
|
||||
|
||||
# 유사 문서 검색
|
||||
search_result = client.search(
|
||||
collection_name="meeting_documents",
|
||||
query_vector=query_embedding,
|
||||
limit=5,
|
||||
query_filter={
|
||||
"must": [
|
||||
{"key": "domain", "match": {"value": "고객서비스"}}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
# 결과 출력
|
||||
for hit in search_result:
|
||||
print(f"유사도: {hit.score:.4f}")
|
||||
print(f"제목: {hit.payload['title']}")
|
||||
print(f"요약: {hit.payload['summary']}")
|
||||
print("---")
|
||||
```
|
||||
|
||||
## 🎯 활용 시나리오
|
||||
|
||||
### 1. 관련 회의록 검색
|
||||
- **목적**: 현재 회의와 유사한 과거 회의록 찾기
|
||||
- **방법**: 회의 주제/안건을 임베딩하여 유사도 검색
|
||||
- **활용**: 과거 논의 내용 및 결정사항 참조
|
||||
|
||||
### 2. 맥락 기반 용어 설명
|
||||
- **목적**: 회의 중 등장하는 전문 용어를 맥락에 맞게 설명
|
||||
- **방법**: 용어와 관련된 조직문서/매뉴얼 검색
|
||||
- **활용**: Claude API에 RAG context로 제공
|
||||
|
||||
### 3. 프로젝트 문서 자동 연결
|
||||
- **목적**: 회의 내용과 관련된 프로젝트 문서 추천
|
||||
- **방법**: 회의록과 프로젝트 문서 간 유사도 계산
|
||||
- **활용**: 참고 자료 자동 링크
|
||||
|
||||
### 4. 장애 이력 조회
|
||||
- **목적**: 유사한 장애 발생 시 과거 대응 사례 검색
|
||||
- **방법**: 장애 키워드로 운영문서 검색
|
||||
- **활용**: 빠른 장애 해결을 위한 레퍼런스
|
||||
|
||||
## 📝 데이터 특징
|
||||
|
||||
### 1. 실제 업무 환경 반영
|
||||
- 통신회사의 실제 업무 도메인 구조
|
||||
- 각 도메인별 특화된 키워드 및 용어
|
||||
- 업무 프로세스와 연결된 문서 구조
|
||||
|
||||
### 2. 다양한 문서 유형
|
||||
- 회의록: 비정형 대화체 문서
|
||||
- 조직문서: 정형 정책 문서
|
||||
- 프로젝트 문서: 기술 문서
|
||||
- 운영문서: 시간 기반 이벤트 문서
|
||||
|
||||
### 3. 풍부한 메타데이터
|
||||
- 문서 분류를 위한 도메인/유형 정보
|
||||
- 검색 최적화를 위한 키워드
|
||||
- 관계 추적을 위한 참석자/날짜 정보
|
||||
- 폴더 구조 정보
|
||||
|
||||
### 4. 임베딩 최적화
|
||||
- 평균 문서 길이: 500~2000자
|
||||
- 요약문 제공으로 빠른 이해 가능
|
||||
- 키워드 기반 하이브리드 검색 지원
|
||||
|
||||
## 🔍 검색 전략 권장사항
|
||||
|
||||
### 1. 하이브리드 검색
|
||||
```python
|
||||
# 키워드 필터 + 벡터 유사도 검색
|
||||
search_result = client.search(
|
||||
collection_name="meeting_documents",
|
||||
query_vector=query_embedding,
|
||||
query_filter={
|
||||
"must": [
|
||||
{"key": "domain", "match": {"value": "고객서비스"}},
|
||||
{"key": "keywords", "match": {"any": ["VOC", "챗봇"]}}
|
||||
]
|
||||
},
|
||||
limit=10
|
||||
)
|
||||
```
|
||||
|
||||
### 2. 시간 기반 필터링
|
||||
```python
|
||||
# 최근 1년 이내 문서만 검색
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
one_year_ago = (datetime.now() - timedelta(days=365)).isoformat()
|
||||
|
||||
search_result = client.search(
|
||||
collection_name="meeting_documents",
|
||||
query_vector=query_embedding,
|
||||
query_filter={
|
||||
"must": [
|
||||
{"key": "created_date", "range": {"gte": one_year_ago}}
|
||||
]
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 3. 문서 유형별 가중치
|
||||
```python
|
||||
# 회의록 우선, 프로젝트 문서 보조
|
||||
meeting_results = search(query, filter={"type": "meeting_minutes"}, limit=3)
|
||||
project_results = search(query, filter={"type": "project_document"}, limit=2)
|
||||
|
||||
# 결과 병합
|
||||
all_results = meeting_results + project_results
|
||||
```
|
||||
|
||||
## 🚀 확장 가능성
|
||||
|
||||
### 1. 실제 데이터 연동
|
||||
- Confluence API 연동
|
||||
- SharePoint 문서 수집
|
||||
- 이메일 아카이브 통합
|
||||
|
||||
### 2. 추가 메타데이터
|
||||
- 문서 중요도 점수
|
||||
- 조회수/활용도 통계
|
||||
- 사용자 피드백 (좋아요/별점)
|
||||
|
||||
### 3. 고급 검색 기능
|
||||
- 시맨틱 검색 (Azure AI Search)
|
||||
- 다중 벡터 검색 (제목/본문 분리)
|
||||
- Re-ranking (Claude 활용)
|
||||
|
||||
## 📚 관련 문서
|
||||
|
||||
- `구현방안-관련자료.md`: 관련자료 검색 시스템 구현 상세
|
||||
- `구현방안-용어집.md`: 용어집 구축 및 Claude 연동 방안
|
||||
- `통신업무도메인.md`: 통신회사 업무 도메인 정의
|
||||
|
||||
## 🤝 기여
|
||||
|
||||
샘플 데이터 개선 제안이나 추가 도메인 요청은 프로젝트 팀에 문의하세요.
|
||||
|
||||
---
|
||||
|
||||
## 9. 품질 검증
|
||||
|
||||
### 9.1 데이터 품질 기준
|
||||
- **실무 반영도**: 실제 통신 업무 용어 및 상황 반영 여부
|
||||
- **일관성**: 도메인 및 문서 유형별 일관성 유지
|
||||
- **다양성**: 키워드 및 토픽의 다양성 확보
|
||||
|
||||
### 9.2 검증 방법
|
||||
1. **샘플링 검사**: 각 도메인별 1-2개 샘플 수동 검토
|
||||
2. **키워드 분석**: 도메인 관련 키워드 포함 여부 확인
|
||||
3. **메타데이터 검증**: 필수 필드 누락 여부 확인
|
||||
|
||||
---
|
||||
|
||||
## 10. 향후 계획
|
||||
|
||||
### 10.1 데이터 확장
|
||||
- **단계 1** (현재): 300개 샘플 (도메인별 × 소스별 5개)
|
||||
- **단계 2** (Phase 1 완료 후): 600개 샘플 (도메인별 × 소스별 10개)
|
||||
- **단계 3** (Phase 2 이후): 1,500개 샘플 (도메인별 × 소스별 25개)
|
||||
|
||||
### 10.2 품질 개선
|
||||
- 실제 회의록 데이터 반영
|
||||
- 도메인 전문가 검토 및 피드백 반영
|
||||
- 사용자 피드백 기반 지속 업데이트
|
||||
|
||||
---
|
||||
|
||||
## 11. 참고 자료
|
||||
|
||||
### 11.1 관련 문서
|
||||
- [회의 주제 관련 자료 수집 및 Claude AI 연동 구현 방안](../구현방안-관련자료.md)
|
||||
- [ADR-001: Vector Database 및 Embedding 통합 아키텍처](../ADR-001-Vector-DB-통합아키텍처.md)
|
||||
- [통신업무도메인](../../reference/통신업무도메인.md)
|
||||
|
||||
### 11.2 기술 스택
|
||||
- **Vector DB**: PostgreSQL + pgvector
|
||||
- **Embedding**: OpenAI text-embedding-3-small (1536 dim)
|
||||
- **검색**: 하이브리드 (벡터 유사도 + 키워드 매칭)
|
||||
- **캐싱**: Redis + Claude Prompt Cache
|
||||
|
||||
---
|
||||
|
||||
**문서 버전**: v1.0
|
||||
**최종 수정**: 2025-01-22
|
||||
**담당자**: AI 개발팀
|
||||
**버전**: 1.0
|
||||
**생성일**: 2025-10-28
|
||||
**생성자**: 회의록 작성 및 공유 개선 프로젝트 팀
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
## 문서 정보
|
||||
- **작성일**: 2025-10-21
|
||||
- **최종 수정일**: 2025-10-27
|
||||
- **최종 수정일**: 2025-10-28
|
||||
- **작성자**: 이미준 (서비스 기획자)
|
||||
- **버전**: 1.5.3
|
||||
- **버전**: 1.5.4
|
||||
- **설계 철학**: Mobile First Design
|
||||
|
||||
---
|
||||
@ -289,32 +289,25 @@ graph TD
|
||||
|
||||
- **최근 회의** 섹션
|
||||
- 헤더: "예정된 회의" (H4) + "전체 보기 →" 링크
|
||||
- 회의 리스트 (최대 3개, 우선순위 순)
|
||||
1. **진행중 회의** (우선 표시)
|
||||
- 상태: 회의 시작됨, 아직 종료 안 됨, 참여 가능
|
||||
- 긴급 표시: "진행중" 배지 (빨강/주황색, 애니메이션)
|
||||
2. **예정된 회의** (시작 전)
|
||||
- 상태: 회의 일시 >= 현재 시간
|
||||
- D-day 표시 (긴급도에 따라 색상 구분)
|
||||
- 각 항목:
|
||||
- **상태 배지** (최우선 표시):
|
||||
- "진행중" (빨강/주황, 깜빡임 애니메이션) - 진행중 회의
|
||||
- "D-1", "D-day", "3시간 후" 등 - 예정된 회의
|
||||
- **정렬 기준** (UFR-USER-020 기준):
|
||||
1. **1순위**: 회의록 미생성 회의 (진행중 + 예정) 우선 표시
|
||||
2. **2순위**: 미생성이 3개 미만이면 최근 종료된 회의(회의록 있음)로 나머지 채움
|
||||
3. **각 그룹 내 정렬**: 빠른 일시 순 (시작 시간 기준)
|
||||
4. **최대 표시**: 3개
|
||||
- **회의 카드** (클릭 가능 블록):
|
||||
- 상태 라벨 (배지)
|
||||
- 진행중: "진행중"
|
||||
- 예정: "예정"
|
||||
- 완료: "작성중" 또는 "확정완료"
|
||||
- 회의 제목 (H5)
|
||||
- 생성자 표시 (👑 아이콘) - 내가 생성한 회의인 경우
|
||||
- 회의 일시 (아이콘: calendar_today)
|
||||
- 참석자 수 (아이콘: people)
|
||||
- **역할 표시** (예정된 회의만):
|
||||
- "생성자" 아이콘 (작은 크라운 아이콘) - 내가 생성한 회의
|
||||
- "참석자" 아이콘 표시 안 함 - 초대받은 회의
|
||||
- **액션 버튼** (권한 및 시간 기반):
|
||||
- **진행중 회의**: "참여하기" 버튼 (Primary, 모든 참석자)
|
||||
- **예정된 회의 - 생성자**:
|
||||
- "수정" 버튼 (Secondary, 작은 크기)
|
||||
- 클릭 시 회의 예약 수정 화면으로 이동
|
||||
- **예정된 회의 - 초대받은 참석자**:
|
||||
- 시작 10분 이내: "참여하기" 버튼 활성화 (Primary)
|
||||
- 시작 10분 초과: 버튼 없음 또는 비활성화
|
||||
- 타이머 표시: "10분 후 참여 가능" (시작 시간까지 남은 시간)
|
||||
- 장소 정보
|
||||
- 상태 버튼 (표시용):
|
||||
- 진행중: "참여하기" 버튼
|
||||
- 예정: "수정하기" 버튼
|
||||
- 완료: "보기" 버튼
|
||||
- 빈 상태: "예정된 회의가 없습니다"
|
||||
|
||||
- **내 회의록** 카드 - **v1.5.0 변경 (Todo 섹션 제거)**
|
||||
@ -2189,6 +2182,7 @@ graph TD
|
||||
| 1.5.1 | 2025-10-27 | 강지수 | MVP 스코프 축소 v2.4.0 반영 (4개 화면 수정)<br>- **02-대시보드**: Todo 위젯 및 통계 제거 (UFR-USER-020 반영)<br> - Todo 위젯 전체 제거 (나의 Todo 섹션 삭제)<br> - 통계 카드: "나의 Todo" 제거, "작성중 회의록" 유지 (2개 항목)<br> - 네비게이션: 하단 네비게이션 및 사이드바에서 Todo 관리 메뉴 제거<br> - Desktop 통계 그리드: 2개 항목만 표시<br>- **05-회의진행**: "AI 제안" 탭 → "AI 기반 메모" 탭 기능 변경<br> - 메모 입력창 + 저장 버튼 추가<br> - AI가 감지한 주요 내용 리스트 표시 (시간 + 내용)<br> - 각 참석자별 개별 저장, 다른 참석자 메모 볼 수 없음<br> - 메모는 회의 종료 전까지만 표시/편집 가능<br> - 에러 처리: AI 주요 내용 감지 실패, 메모 저장 실패 추가<br>- **10-회의록상세조회**: Todo 단순 조회 기능으로 변경<br> - Todo는 제목 + 담당자 + 마감일만 표시<br> - D-day 라벨, 우선순위 배지, 진행률 바, 상태별 필터 제거<br> - Todo 관리 화면 연동 링크 제거 (화면 자체가 제거됨)<br> - "수정" 버튼을 헤더로 이동<br>- **11-회의록수정**: 실시간 협업 기능 제거, 안건 기반 충돌 방지 강화<br> - "편집 중" 표시 제거 (실시간 협업 기능 제거)<br> - Todo 편집/추가/삭제 기능 전체 제거 (단순 조회만 가능)<br> - AI 한줄 요약 재생성 불가 (회의 종료 시 1회만 생성)<br> - 검증률 표시 및 최종 확정 버튼 제거<br> - 저장 로직 추가: 검증완료 안건 저장 스킵, 저장 결과 알림<br> - 안건별 검증 완료 체크박스로 충돌 방지 (Last Write Wins 적용)<br> - 에러 처리: 충돌 경고 모달 제거 (LWW로 인해) |
|
||||
| 1.5.2 | 2025-10-27 | 강지수 | AI 요약 기능 통합 및 단순화 (유저스토리 v2.4.0 반영)<br>- **11-회의록수정**: AI 요약 기능 통합<br> - 명칭 변경: "AI 상세 요약" → "AI 요약"<br> - AI 요약 영역: AI 한줄 요약만 표시 (30자 이내, 읽기 전용)<br> - 텍스트 편집 영역: 안건 내용 자유 작성 (논의 주제, 발언자별 의견, 결정 사항 등)<br> - "AI 재생성" 버튼: 텍스트 편집 영역 내용 기반으로 AI 요약의 한줄 요약 재생성 (2-5초 처리)<br> - 재생성된 한줄 요약은 회의록 상세조회 화면의 대시보드 및 회의록 탭에 즉시 반영<br> - AI 상세 요약 및 한줄 요약 분리 표시 제거<br>- **프로토타입 UI 개선**:<br> - AI 재생성 버튼 스타일 통일: btn-secondary → btn-primary (다른 화면과 일관성)<br> - 안건별 검증완료 UI 단순화: 참석자는 체크박스만, 회의 생성자는 검증완료 시 잠금해제 버튼 표시<br> - .creator-only CSS 클래스 추가: data-is-creator 속성 기반 표시 제어<br>- **관련 유저스토리**: UFR-AI-036 (AI 한줄요약 확인 및 재생성), UFR-MEET-055 (안건별 검증), UFR-COLLAB-030 (충돌 방지) |
|
||||
| 1.5.3 | 2025-10-27 | 강지수 | Todo 추가/편집 권한 정책 명확화 (유저스토리 v2.4.1 반영)<br>- **10-회의록상세조회**: Todo 추가/편집 권한 정책 추가 (대시보드 탭)<br> - "추가" 버튼: 모든 회의 참석자에게 노출 (Todo 리스트 우측 상단)<br> - "편집(✏️)" 버튼: 회의 생성자에게만 노출 (각 Todo 항목 우측)<br> - Todo 추가 모달: 제목, 담당자, 마감일 입력 (모든 참석자)<br> - Todo 편집 모달: 제목, 담당자, 마감일 수정 (회의 생성자만)<br> - 담당자 필드: 추가 시 또는 생성자의 편집 시만 표시<br>- **프로토타입 UI 개선**: 10-회의록상세조회.html<br> - Todo 추가/편집 모달 바텀시트 스타일 통일 (모바일: 하단 슬라이드 업, 데스크톱: 중앙 모달)<br> - .creator-only 클래스 적용하여 편집 버튼 권한별 표시/숨김 처리<br> - JavaScript initPage() 함수에서 회의 생성자 여부 확인 후 creator-only 요소 제어<br> - Todo 추가 성공: "담당자에게 알림이 전송되었습니다" → "캘린더가 업데이트되었습니다" 순차 토스트<br> - Todo 편집 성공: 담당자 변경 시 알림, 마감일 변경 시 캘린더 업데이트 토스트<br>- **관련 유저스토리**: UFR-MEET-047 (회의록상세조회), Todo 권한 정책 신규 추가 |
|
||||
| 1.5.4 | 2025-10-28 | 도그냥 | 대시보드 최근 회의 리스트 디자인 간소화 (UFR-USER-020 반영)<br>- **02-대시보드**: 최근 회의 정렬 기준 명확화 및 디자인 간소화<br> - **정렬 기준**:<br> - 1순위: 회의록 미생성 회의 (진행중 + 예정) 우선 표시<br> - 2순위: 미생성이 3개 미만이면 최근 종료된 회의(회의록 있음)로 나머지 채움<br> - 각 그룹 내 정렬: 빠른 일시 순 (시작 시간 기준)<br> - 최대 표시: 3개<br> - **회의 카드 (클릭 가능 블록)**:<br> - 상태 라벨 (배지): "진행중", "예정", "작성중", "확정완료"<br> - 회의 제목 + 생성자 아이콘(👑)<br> - 회의 일시, 참석자 수, 장소<br> - 상태 버튼 (표시용): "참여하기", "수정하기", "보기"<br> - **디자인 간소화**: D-day 표시, 깜박임 애니메이션, 세부 색상 지정 등 제거<br>- **유저스토리**: UFR-USER-020 (대시보드 조회) 동일하게 수정 |
|
||||
|
||||
[↑ 목차로 돌아가기](#목차)
|
||||
|
||||
|
||||
@ -115,10 +115,14 @@
|
||||
- 예정된 회의: 전체 예정 + 진행 중 회의 개수
|
||||
- 작성중 회의록: 내가 참석한 회의 중 '작성중' 상태인 회의록 개수 (클릭 액션 없음, 정보 표시만)
|
||||
- 최근 회의 (회의록 미생성 우선, 빠른 일시 순, 최대 3개):
|
||||
- 회의 카드: 상태 배지, 제목, 생성자 표시(👑), 날짜/시간, 참석자 수, 장소, 액션 버튼
|
||||
- 진행 중 회의: 좌측 녹색 바 강조, "참여하기" 버튼
|
||||
- 예정 회의: 생성자인 경우 "수정" 버튼
|
||||
- 완료 회의: "보기" 버튼
|
||||
- 정렬 기준:
|
||||
- 1순위: 회의록 미생성 회의 (진행중 + 예정)
|
||||
- 2순위: 미생성이 3개 미만이면 최근 종료된 회의(회의록 있음)로 나머지 채움
|
||||
- 각 그룹 내 정렬: 빠른 일시 순 (시작 시간 기준)
|
||||
- 회의 카드 (클릭 가능 블록): 상태 라벨, 제목, 생성자(👑), 날짜/시간, 참석자 수, 장소, 상태 버튼
|
||||
- 진행중: "진행중" 라벨, "참여하기" 버튼
|
||||
- 예정: "예정" 라벨, "수정하기" 버튼
|
||||
- 완료: "작성중" 또는 "확정완료" 라벨, "보기" 버튼
|
||||
- 나의 회의록 (최신순, 최대 4개, 2x2 그리드):
|
||||
- 회의록 카드: 상태 배지, 생성자 표시(👑), 제목, 날짜/시간, 참석자 수, 검증완료율(작성중인 경우)
|
||||
- 사이드바 (데스크톱): 로고, 메뉴(대시보드, 회의록), 사용자 정보, 로그아웃
|
||||
@ -135,6 +139,7 @@
|
||||
**관련 유저스토리:**
|
||||
- UFR-USER-010: 로그인
|
||||
- UFR-MEET-010: 회의예약
|
||||
- UFR-MEET-011: 회의정보수정
|
||||
- UFR-MEET-020: 템플릿선택
|
||||
- UFR-MEET-046: 회의록목록조회
|
||||
- UFR-MEET-047: 회의록상세조회
|
||||
@ -190,10 +195,44 @@
|
||||
|
||||
**관련 유저스토리:**
|
||||
- UFR-USER-020: 대시보드 조회
|
||||
- UFR-MEET-011: 회의정보수정
|
||||
- UFR-MEET-020: 템플릿선택
|
||||
|
||||
---
|
||||
|
||||
### UFR-MEET-011: [회의정보수정] 회의 생성자로서 | 나는, 예정된 회의 정보를 변경하기 위해 | 회의 정보를 수정하고 싶다.
|
||||
|
||||
**수행절차:**
|
||||
1. 대시보드(02-대시보드.html)에서 예정된 회의(scheduled) 카드 클릭
|
||||
2. 회의예약 화면(03-회의예약.html)으로 이동 (기존 회의 정보 로드)
|
||||
3. 수정할 항목 변경 (제목, 날짜, 시간, 장소, 참석자, 안건 등)
|
||||
4. "수정 완료" 버튼 클릭
|
||||
5. 변경 사항 저장 및 참석자에게 알림 발송
|
||||
|
||||
**입력:**
|
||||
- 기존 회의 정보: 자동 로드 (제목, 날짜, 시간, 장소, 참석자, 안건)
|
||||
- 수정 항목: UFR-MEET-010과 동일한 입력 필드
|
||||
|
||||
**출력/결과:**
|
||||
- 수정 완료: "회의 정보가 수정되었습니다" 토스트 메시지, 대시보드로 이동
|
||||
- 참석자 변경 시: 기존 참석자 및 신규 참석자에게 알림 발송
|
||||
- 알림 유형: "회의 정보 변경"
|
||||
- 알림 내용: "{회의 제목} 회의 정보가 변경되었습니다"
|
||||
- 임시저장: "임시 저장되었습니다" 토스트 메시지
|
||||
|
||||
**예외처리:**
|
||||
- 회의 상태가 'scheduled'가 아닌 경우: "진행 중이거나 종료된 회의는 수정할 수 없습니다" 에러 메시지
|
||||
- 생성자가 아닌 경우: "회의 생성자만 수정할 수 있습니다" 에러 메시지
|
||||
- 유효성 검사 실패: UFR-MEET-010과 동일한 예외처리
|
||||
- 뒤로가기/취소 클릭: "변경 사항이 저장되지 않았습니다. 나가시겠습니까?" 확인 모달
|
||||
|
||||
**관련 유저스토리:**
|
||||
- UFR-USER-020: 대시보드 조회
|
||||
- UFR-MEET-010: 회의예약
|
||||
- UFR-NOTI-010: 알림발송
|
||||
|
||||
---
|
||||
|
||||
### UFR-MEET-015: [회의진행] 회의 참석자로서 | 나는, 회의 중 추가 참석자가 필요할 때 | 실시간으로 참석자를 초대하고 싶다.
|
||||
|
||||
**수행절차:**
|
||||
|
||||
@ -819,57 +819,79 @@ private RelatedMeeting createFallbackRelatedMeeting(SearchResult result) {
|
||||
|
||||
### AD-000: 통합 플랫폼 전략 (용어집 + 관련회의록)
|
||||
|
||||
**결정**: 단일 Azure AI Search 계정에 두 개의 별도 인덱스 운영
|
||||
> **⚠️ 업데이트**: 2025-10-28
|
||||
>
|
||||
> 이 섹션은 초기 계획이었으며, 최종적으로 **하이브리드 접근 전략**으로 결정되었습니다.
|
||||
>
|
||||
> **최종 결정 문서**: `design/아키텍처_최적안_결정.md` 참조
|
||||
|
||||
**통합 아키텍처**:
|
||||
**최종 결정**: 하이브리드 접근 - 단계적 독립 → 선택적 통합
|
||||
|
||||
**Phase 1-3 아키텍처** (현재 적용):
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ AI Service (Backend) │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────────────┐ ┌──────────────────────┐ │
|
||||
│ │ 용어집 기능 │ │ 관련회의록 기능 │ │
|
||||
│ │ (Term Glossary) │ │ (Related Meetings) │ │
|
||||
│ └──────────┬───────────┘ └──────────┬───────────┘ │
|
||||
│ │ │ │
|
||||
│ ┌──────────▼───────────┐ ┌──────────▼───────────┐ │
|
||||
│ │ PostgreSQL │ │ Azure AI Search │ │
|
||||
│ │ + pgvector │ │ (meetings-index) │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ • 소규모 (수백 건) │ │ • 대규모 (수만 건) │ │
|
||||
│ │ • 키워드 우선 │ │ • Vector 우선 │ │
|
||||
│ │ • 트랜잭션 보장 │ │ • Semantic Ranking │ │
|
||||
│ └──────────────────────┘ └──────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ 공통 컴포넌트 (Shared Components) │ │
|
||||
│ ├─────────────────────────────────────────────────────┤ │
|
||||
│ │ • Azure OpenAI Embedding (text-embedding-ada-002) │ │
|
||||
│ │ • Claude 3.5 Sonnet (맥락 설명 / 요약 생성) │ │
|
||||
│ │ • Redis (L1 캐싱, TTL 1-24시간) │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**Phase 4 통합 옵션** (조건부):
|
||||
|
||||
**통합 조건**:
|
||||
1. 용어집 데이터 규모 500개 이상
|
||||
2. PostgreSQL+pgvector 성능 이슈 (응답 시간 > 500ms)
|
||||
3. 관리 복잡도가 비용 절감액($85/월)을 상회
|
||||
|
||||
**통합시 아키텍처**:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Azure AI Search (단일 계정) │
|
||||
│ ┌──────────────────────┐ ┌────────────────────────────┐ │
|
||||
│ │ terms-index │ │ meetings-index │ │
|
||||
│ │ (용어집 전용) │ │ (관련회의록 전용) │ │
|
||||
│ │ - 소규모 (수백 건) │ │ - 대규모 (수만 건) │ │
|
||||
│ │ - 작은 청크(400 tok) │ │ - 큰 청크(2000-2500 tok) │ │
|
||||
│ │ - Keyword 우선 │ │ - Vector 우선 │ │
|
||||
│ │ (용어집) │ │ (관련회의록) │ │
|
||||
│ │ - 수백 건 │ │ - 수만 건 │ │
|
||||
│ │ - 256-512 tok │ │ - 2000-2500 tok │ │
|
||||
│ │ - Keyword 우선 │ │ - Hybrid + Semantic │ │
|
||||
│ └──────────────────────┘ └────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
▲
|
||||
│ 공통 사용
|
||||
┌──────────────────────────┼────────────────────────────────┐
|
||||
│ Azure OpenAI Embedding │ Claude 3.5 Sonnet │
|
||||
│ text-embedding-ada-002 │ 맥락 설명 / 요약 생성 │
|
||||
└──────────────────────────┴────────────────────────────────┘
|
||||
▲
|
||||
│ 공통 사용
|
||||
┌──────────────────────────┼────────────────────────────────┐
|
||||
│ Redis L1 Cache (1시간 TTL) │
|
||||
│ - 용어 설명 캐싱 │
|
||||
│ - 관련 회의록 추천 캐싱 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
▲ ▲
|
||||
│ │
|
||||
┌──────────┴──────────┐ ┌───────────┴────────────┐
|
||||
│ CDN L2 Cache │ │ PostgreSQL L2 Cache │
|
||||
│ (용어 설명) │ │ (관련 회의록 매핑) │
|
||||
│ - 정적 콘텐츠 │ │ - 동적 관계 데이터 │
|
||||
└─────────────────────┘ └────────────────────────┘
|
||||
```
|
||||
|
||||
**대안 비교**:
|
||||
|
||||
| 대안 | 장점 | 단점 | 점수 |
|
||||
|-----|------|------|------|
|
||||
| **단일 계정 + 별도 인덱스** ✅ | • 비용 절감 (단일 Standard tier)<br>• 독립적 최적화<br>• 통합 관리<br>• 확장성 | • 인덱스 수 제한 고려 필요 | **10/10** |
|
||||
| 별도 Azure AI Search 계정 | • 완전 독립성<br>• 리소스 격리 | • 비용 2배 ($500/월)<br>• 관리 복잡도 증가 | 6/10 |
|
||||
| 단일 인덱스 공유 | • 가장 저렴<br>• 관리 단순 | • 스키마 충돌<br>• 성능 저하<br>• 최적화 불가 | 3/10 |
|
||||
| 별도 Vector DB (Pinecone 등) | • 특화 기능 | • 비용 증가<br>• 통합 복잡<br>• 일관성 부족 | 5/10 |
|
||||
| **하이브리드 접근** ✅ | • 각 기능별 최적 DB 선택<br>• 초기 비용 40% 절감<br>• 점진적 확장<br>• 리스크 분산 | • 관리 복잡도 증가<br>• 통합시 마이그레이션 필요 | **9/10** |
|
||||
| 단일 Azure AI Search (초기) | • 통합 관리<br>• 일관된 검색 엔진 | • 용어집 초기에 과도한 인프라<br>• 초기 비용 높음 ($250/월 추가) | 7/10 |
|
||||
| 완전 독립 (Qdrant) | • 완전 독립성<br>• 각 기능 최적화 | • 높은 운영 비용 ($1,400/월)<br>• 관리 복잡도 최고 | 5/10 |
|
||||
|
||||
**결정 이유**:
|
||||
1. **비용 효율성**: Standard tier $250/월 공유 (별도 계정 대비 50% 절감)
|
||||
2. **독립 최적화**: 각 기능별 최적 스키마 및 설정
|
||||
3. **운영 단순성**: 단일 플랫폼 통합 모니터링
|
||||
4. **확장성**: 각 인덱스 독립 스케일링
|
||||
1. **비용 효율성**: Phase 1-2에서 $250/월 절감 ($966 → $410)
|
||||
2. **기술적 타당성**: 용어집(정확 매칭) vs 관련회의록(의미 검색)의 요구사항 차이
|
||||
3. **운영 복잡도**: PostgreSQL 기존 활용으로 학습 곡선 최소화
|
||||
4. **확장성**: 명확한 마이그레이션 경로 보유
|
||||
|
||||
**공통 컴포넌트**:
|
||||
- **Embedding**: Azure OpenAI text-embedding-ada-002 (일관된 벡터 공간)
|
||||
@ -877,23 +899,42 @@ private RelatedMeeting createFallbackRelatedMeeting(SearchResult result) {
|
||||
- **L1 Cache**: Redis (통합 캐싱 플랫폼)
|
||||
|
||||
**차별화 전략**:
|
||||
- **용어집**: JSON 우선 + RAG fallback (하이브리드)
|
||||
- **관련회의록**: Hybrid Search + Semantic Ranking (순수 벡터)
|
||||
- **캐싱 L2**: CDN (정적) vs PostgreSQL (동적)
|
||||
- **용어집**: 키워드 우선 + Vector Fallback (정확성 중시)
|
||||
- **관련회의록**: Hybrid Search + Semantic Ranking (맥락 중시)
|
||||
- **캐싱 L2**: PostgreSQL (메타데이터 + 관계)
|
||||
|
||||
**비용 분석** (월간):
|
||||
```
|
||||
Azure AI Search Standard: $250
|
||||
Azure OpenAI Embedding: $55 (용어집 $25 + 관련자료 $30)
|
||||
Claude API: $366 (용어집 $150 + 관련자료 $216)
|
||||
Redis Enterprise: $50
|
||||
CDN: $10
|
||||
PostgreSQL Storage: $10
|
||||
─────────────────────────────
|
||||
통합 총계: $741/월
|
||||
|
||||
개별 계정 대비 절감: $250/월 (25% 절감)
|
||||
**Phase 3 (독립 운영)**:
|
||||
```
|
||||
PostgreSQL (용어집): $50
|
||||
Azure AI Search (회의록): $250
|
||||
Redis: $80 (통합)
|
||||
Azure OpenAI Embedding: $50
|
||||
Claude API: $516
|
||||
Storage: $20
|
||||
─────────────────────────────
|
||||
총계: $966/월
|
||||
```
|
||||
|
||||
**Phase 4 (통합시)**:
|
||||
```
|
||||
Azure AI Search (통합): $250
|
||||
PostgreSQL (메타만): $50
|
||||
Redis: $50
|
||||
Azure OpenAI Embedding: $55
|
||||
Claude API: $516
|
||||
Storage: $40
|
||||
─────────────────────────────
|
||||
총계: $881/월
|
||||
절감액: $85/월 (8.8%)
|
||||
```
|
||||
|
||||
**마이그레이션 비용**: $5,000 (일회성)
|
||||
|
||||
**참조 문서**:
|
||||
- **최종 결정**: `design/아키텍처_최적안_결정.md`
|
||||
- **용어집 상세**: `design/구현방안-용어집.md`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -698,23 +698,39 @@ Phase 3 (고도화 - 8주):
|
||||
|
||||
**컨텍스트**:
|
||||
- 초기에는 데이터량이 적어 pgvector로 충분
|
||||
- Qdrant는 전문 벡터 DB로 성능 우수하나 인프라 복잡도 증가
|
||||
- 관련회의록 기능은 Azure AI Search 사용 (별도 독립)
|
||||
- 용어집은 정확한 키워드 매칭이 중요하여 PostgreSQL 적합
|
||||
- 단계적 접근으로 리스크 분산
|
||||
|
||||
**대안 고려**:
|
||||
1. **Pinecone**: 관리형 서비스, 쉬운 시작 vs 높은 운영 비용 ($70/월~)
|
||||
2. **Weaviate**: 오픈소스, 풍부한 기능 vs 학습 곡선 높음
|
||||
3. **pgvector**: 간단한 설정, 기존 DB 활용 vs 성능 제한
|
||||
1. **PostgreSQL+pgvector** ✅:
|
||||
- 기존 DB 활용, 트랜잭션 보장, 학습 곡선 낮음
|
||||
- 소규모에 적합, 비용 $0 (기존 DB)
|
||||
|
||||
2. **Azure AI Search (초기 도입)**:
|
||||
- 고성능 검색, Semantic Ranking, 관리형 서비스
|
||||
- 소규모에 과도, 비용 $250/월
|
||||
|
||||
3. **Qdrant (self-hosted)**:
|
||||
- 전문 Vector DB, 고성능, 오픈소스
|
||||
- 운영 부담, 학습 곡선 높음, 비용 $500/월
|
||||
|
||||
4. **Pinecone (managed)**:
|
||||
- 관리형 서비스, 쉬운 사용, 고성능
|
||||
- 비용 높음 ($70-200/월), 한국어 지원 부족
|
||||
|
||||
**결정 근거**:
|
||||
- MVP 단계에서는 pgvector의 단순성 우선
|
||||
- 사용자 1000명 이상 시 Qdrant 전환 (명확한 마이그레이션 기준)
|
||||
- 비용 효율성: pgvector 무료 vs Qdrant 자체 호스팅 $500/월 vs Pinecone $1000/월
|
||||
- **Phase 1-2**: pgvector의 단순성 및 비용 효율성 우선
|
||||
- **Phase 3 조건**: 용어 500개 이상 OR 성능 이슈 OR 관리 복잡도 증가
|
||||
- **Phase 3 옵션 A**: Azure AI Search (terms-index) 마이그레이션 ($250/월 추가 비용 없음, 관련회의록과 공유)
|
||||
- **Phase 3 옵션 B**: 현상 유지 (독립 운영)
|
||||
- **비용 효율성**: pgvector 무료 vs Azure AI Search 통합시 $0 추가 vs Qdrant $500/월
|
||||
|
||||
**결과**:
|
||||
- 초기 인프라 비용 절감 (PostgreSQL 활용)
|
||||
- 검증된 기술 스택 사용으로 팀 학습 부담 감소
|
||||
- 명확한 확장 경로 확보
|
||||
- 관련회의록과 독립적으로 운영하여 장애 격리
|
||||
- Phase 4에서 조건 충족시 Azure AI Search 통합 옵션 보유
|
||||
|
||||
---
|
||||
|
||||
@ -1811,6 +1827,11 @@ class ClaudeAPIClient:
|
||||
---
|
||||
|
||||
**작성일**: 2025-10-28
|
||||
**최종 업데이트**: 2025-10-28 (아키텍처 최적안 반영)
|
||||
**작성자**: 회의록 개선 프로젝트 팀
|
||||
**버전**: 1.0
|
||||
**승인자**: 김민준 (Product Owner)
|
||||
**버전**: 1.1
|
||||
**승인자**: 김민준 (Product Owner), 홍길동 (Architect)
|
||||
|
||||
**관련 문서**:
|
||||
- **아키텍처 최적안 결정**: `design/아키텍처_최적안_결정.md`
|
||||
- **관련회의록 구현방안**: `design/구현방안-관련자료.md`
|
||||
1172
design/아키텍처_최적안_결정.md
Normal file
1172
design/아키텍처_최적안_결정.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -31,7 +31,7 @@ public class SecurityConfig {
|
||||
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
|
||||
@Value("${cors.allowed-origins:http://localhost:*}")
|
||||
@Value("${cors.allowed-origins:http://localhost:*,http://hgzero.20.249.184.228.nip.io/*}")
|
||||
private String allowedOrigins;
|
||||
|
||||
@Bean
|
||||
|
||||
@ -83,6 +83,6 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
path.startsWith("/swagger-ui") ||
|
||||
path.startsWith("/v3/api-docs") ||
|
||||
path.equals("/health") ||
|
||||
path.equals("/api/v1/auth/login");
|
||||
path.equals("/api/auth/login");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user