Compare commits

...

94 Commits

Author SHA1 Message Date
yabo0812
52b32cf978 발표자료 관련 2025-10-30 20:44:22 +09:00
yabo0812
b0fac155c6 서버 main 브랜치 내용으로 현행화 완료
- .gitignore 충돌 해결
- ai-java-back/, ai/ 디렉토리 제외 규칙 추가
- main 브랜치의 모든 변경사항 병합
2025-10-30 20:42:18 +09:00
ondal
72419c320a docs: README.md 최종 수정
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 20:28:39 +09:00
Minseo-Jo
74c9506249 fix: EventHubPublisher 주석 개선 및 재배포 트리거
- EventHub 환경변수 설정 및 이벤트 발행 프로세스 문서화
- AI Python 서비스로의 실시간 이벤트 전달 흐름 명시
- 재배포를 통해 실제 EventHub 연결 활성화

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 20:21:39 +09:00
ondal
a27f4dc95d docs: README.md 작성 완료
- README_sample.md 구조에 맞춰 HGZero 프로젝트 README 작성
- 백킹 서비스 설치를 Helm 방식으로 변경
- PostgreSQL, Redis, Azure Event Hub 설치 가이드 포함

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 20:11:43 +09:00
Minseo-Jo
b8942c9e04 fix: Ingress에 AI 회의록 통합 API 경로 추가
- /api/transcripts 경로를 ai-service:8087에 매핑
- Meeting 서비스가 AI 통합 API를 호출할 수 있도록 설정
2025-10-30 19:12:53 +09:00
hjmoons
d01d4d0b5d Jenkinsfile: Replace Kustomize with sed for manifest updates
- Remove curl dependency (not available in alpine/git)
- Use sed to directly update deployment.yaml files
- Change directory to hgzero-back/kustomize/base
- Update services list: user, meeting, stt, notification

Fix: curl not found error in manifest update stage
2025-10-30 19:08:57 +09:00
hjmoons
2d096265b5 Jenkinsfile: 빌드 서비스 목록에서 'ai' 제거
- services 목록: user, meeting, stt, notification (ai 제외)
- ai-python은 별도 파이프라인으로 관리
2025-10-30 18:57:36 +09:00
hjmoons
c00f1b03b9 Fix: PostgreSQL 예약어 'order' 컬럼명 이스케이프 처리
문제:
- PostgreSQL에서 order는 예약어
- INSERT 구문에서 'syntax error at or near "order"' 오류 발생

해결:
- @Column(name = "\"order\"") 로 수정
- SQL 생성 시 "order"로 이스케이프되어 예약어 충돌 방지

영향:
- MinutesSectionEntity INSERT/UPDATE 정상 동작
- 회의 메모 저장 기능 복구

File: meeting/src/main/java/com/unicorn/hgzero/meeting/infra/gateway/entity/MinutesSectionEntity.java:40
2025-10-30 18:54:40 +09:00
hjmoons
258bef0891 Jenkinsfile: Podman 기반 Kubernetes Pod 템플릿으로 전환
주요 변경사항:
- podTemplate 사용하여 Kubernetes Pod에서 실행
- 3개 컨테이너 사용: podman, gradle, git
- mgoltzsche/podman 이미지로 Podman 빌드
- gradle:jdk21 이미지로 Gradle 빌드
- alpine/git으로 manifest 저장소 업데이트

컨테이너별 역할:
- podman: Docker 이미지 빌드 및 ACR 푸시
- gradle: Gradle 빌드 및 JAR 생성
- git: Kustomize로 manifest 저장소 업데이트

리소스 최적화:
- Pod 자동 정리 (idleMinutes: 1, terminationGracePeriodSeconds: 3)
- 컨테이너별 리소스 제한 설정
- emptyDir 볼륨으로 Gradle 캐시 및 Podman 소켓 공유

Fix: Docker 대신 Podman 사용으로 Jenkins 환경 호환성 개선
2025-10-30 18:48:14 +09:00
Minseo-Jo
7e3f7b9471 fix: AI 회의록 통합 - decisions 필드 및 Todo assignee 필드 추가
- AgendaSummaryDTO에 decisions 필드 추가 (안건별 결정사항 배열)
- ExtractedTodoDTO에 assignee 필드 추가 (담당자 정보)
- EndMeetingService에서 AI 추출 담당자 정보 매핑
- Python AI 서비스 모델 및 프롬프트 업데이트
2025-10-30 18:44:58 +09:00
Daewoong Jeon
e406248572
Merge pull request #61 from hwanny1128/feat/dev-test
fix: user id 저장 추가 (회의시작 API)
2025-10-30 18:44:34 +09:00
djeon
e87f916657 fix: user id 저장 추가 (회의시작 API) 2025-10-30 18:43:54 +09:00
hjmoons
47385958d3 Jenkinsfile: JAVA_HOME 경로 수정 - /jdk-21 포함
- JAVA_HOME을 JDK21/jdk-21로 설정
- PATH도 JDK21/jdk-21/bin으로 수정
- jdkPath 변수로 경로 관리 통일
- 불필요한 ls 디버깅 명령 제거

Fix: Java 경로가 JDK21/jdk-21/bin/java인 구조에 맞춤
2025-10-30 18:40:32 +09:00
hjmoons
4929f8d80b Jenkinsfile: JDK 21 설치 경로 수정 및 디버깅 추가
- JDK 압축 해제 경로에 /jdk-21 서브디렉토리 추가
- 대기 중 ls 명령으로 디렉토리 상태 확인
- JDK 설치 진행 상황 디버깅 개선
2025-10-30 18:38:16 +09:00
hjmoons
991c1855e4 Jenkinsfile: JDK 21 설치 대기 및 명시적 사용 개선
- JDK 21 압축 해제 완료까지 대기 루프 추가
- Gradle 빌드 시 JAVA_HOME과 PATH 명시적 export
- java -version으로 사용 중인 Java 버전 확인
- JDK 경로를 직접 사용하여 Java 17 우선순위 문제 해결

Fix: JAVA_HOME is set to an invalid directory 오류 해결
2025-10-30 18:35:22 +09:00
hjmoons
718533cc88 Jenkinsfile: JDK 21 명시적 설정 추가
- Setup Java stage에서 JAVA_HOME 명시적 설정
- tool() 함수로 Jenkins에 등록된 JDK21 사용
- PATH에 JDK bin 디렉토리 추가
- java -version으로 설정 확인

Fix: Toolchain installation '/opt/bitnami/java' does not provide JAVA_COMPILER 오류 해결
2025-10-30 18:28:53 +09:00
hjmoons
2c59283d6c Jenkinsfile: Git credentials ID 수정
- git-credentials → github-credentials-dg0506로 변경
- Jenkins에 등록된 실제 credential ID와 일치시킴
2025-10-30 18:24:20 +09:00
hjmoons
d7742d60c3 Jenkinsfile: SonarQube 관련 코드 모두 제거
- SKIP_SONARQUBE 파라미터 제거
- SONAR_TOKEN credential 제거
- SonarQube Analysis stage 전체 제거
- 빌드 파이프라인 단순화
2025-10-30 18:21:36 +09:00
hjmoons
ec4a23cc33 Jenkinsfile 수정: workspace 자동 정리 제거
- post 블록에서 always의 cleanWs() 제거
- 빌드 후 workspace 유지하도록 변경
- 디버깅 및 아티팩트 확인 용이하게 함
2025-10-30 18:19:09 +09:00
hjmoons
3483c9c1b2 Jenkins 파이프라인 추가
- Jenkinsfile: GitHub Actions 대체 Jenkins Pipeline 구축
  - 5개 백엔드 서비스 빌드 (user, meeting, stt, ai, notification)
  - Gradle 빌드 및 SonarQube 분석 (선택사항)
  - Docker 이미지 빌드 및 ACR 푸시
  - Manifest 저장소 업데이트 (ArgoCD 연동)
  - 환경별 배포 지원 (dev/staging/prod)

- deployment/jenkins/JENKINS_SETUP.md: Jenkins 설정 가이드
  - Credentials 설정 방법
  - JDK 21 및 SonarQube 설정
  - Pipeline Job 생성 및 실행 가이드
  - 트러블슈팅 가이드

- 사용 이유: GitHub Actions 차단으로 인한 대체 CI/CD 구축
2025-10-30 18:16:56 +09:00
Minseo-Jo
0caa1ec3b6 Feat: AI 서비스 통합 및 회의록 기능 개선
- AI 서비스와 Meeting 서비스 통합 개선
  - AgendaSummaryDTO에 decisions 필드 추가 (안건별 결정사항 배열)
  - EndMeetingService에서 AI 서비스 타임아웃 처리 개선
  - AIServiceClient에 상세한 에러 로깅 추가

- 회의록 consolidate 프롬프트 개선
  - Todo 추출 로직 강화 (자연스러운 표현 인식)
  - 안건별 decisions 필드 추가 (대시보드 표시용)
  - 담당자 패턴 인식 개선

- Kubernetes 배포 설정 개선
  - meeting-service.yaml에 AI_SERVICE_URL 환경변수 추가
  - AI_SERVICE_TIMEOUT 설정 추가

- 데이터베이스 관리 SQL 스크립트 추가
  - check-agenda-sections.sql: 안건 섹션 확인
  - cleanup-test-data.sql: 테스트 데이터 정리
  - insert-test-data-final.sql: 최종 테스트 데이터

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 18:07:57 +09:00
Daewoong Jeon
4a87be88f0
Merge pull request #60 from hwanny1128/feat/rag-function
ddd
2025-10-30 16:49:05 +09:00
djeon
b47be6dd27 ddd 2025-10-30 16:48:00 +09:00
Daewoong Jeon
c4740c29d4
Merge pull request #59 from hwanny1128/feat/rag-function
dddd
2025-10-30 16:47:29 +09:00
djeon
aad04c63e6 dddd 2025-10-30 16:46:45 +09:00
Daewoong Jeon
814510d200
Merge pull request #58 from hwanny1128/feat/rag-function
upload artifacts 부활
2025-10-30 16:44:18 +09:00
djeon
18f1b2a844 upload artifacts 부활 2025-10-30 16:43:30 +09:00
Daewoong Jeon
43bc869ea1
Merge pull request #57 from hwanny1128/feat/rag-function
exclude upload github artifacts
2025-10-30 16:35:08 +09:00
djeon
390b3d520c exclude upload github artifacts 2025-10-30 16:34:01 +09:00
Daewoong Jeon
2985e3af08
Merge pull request #56 from hwanny1128/feat/rag-function
Feat/rag function
2025-10-30 16:31:01 +09:00
djeon
9f1afa4f1d feat: sessionId -> meetingId 2025-10-30 16:30:00 +09:00
djeon
eb8818494f Fix: EventHub 설정 조건 수정으로 실제 이벤트 발행 활성화
문제:
- @ConditionalOnExpression의 SpEL 표현식 오류로 EventHubConfig가 활성화되지 않음
- NoOpEventPublisher가 대신 사용되어 Event Hub로 메시지가 발행되지 않음

해결:
- @ConditionalOnProperty 사용으로 변경
- eventhub.connection-string 속성 존재 여부로 Bean 활성화 제어

영향:
- EventHub 설정이 있을 때 EventHubPublisher가 정상 활성화됨
- 회의 시작/종료, Todo 할당 등의 이벤트가 Event Hub로 발행됨

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 16:24:46 +09:00
Daewoong Jeon
6b2bad7c17
Merge pull request #55 from hwanny1128/feat/rag-function
보관기간 설정
2025-10-30 15:44:13 +09:00
djeon
b628013adf 보관기간 설정 2025-10-30 15:43:33 +09:00
Minseo-Jo
032842cf53 Feat: AI 서비스 및 STT 서비스 기능 개선
- AI 서비스: Redis 캐싱 및 EventHub 통합 개선
- STT 서비스: 오디오 버퍼링 및 변환 기능 추가
- 설정 파일 업데이트

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 15:24:13 +09:00
Daewoong Jeon
ad287de176
Merge pull request #54 from hwanny1128/feat/rag-function
Feat/rag function
2025-10-30 15:17:17 +09:00
djeon
c7a13a85d8 feat: add rag test UI 2025-10-30 15:16:38 +09:00
djeon
4a8a151bb2 fix cors error 2025-10-30 15:12:47 +09:00
hjmoons
7c89f2f2ac API Path 수정 2025-10-30 14:48:07 +09:00
hjmoons
5b9a6b327d python package 추가 2025-10-30 14:35:44 +09:00
hjmoons
8e0ff41bb7 AI 도커 파일 수정 2025-10-30 14:22:50 +09:00
Daewoong Jeon
cea800456c
Merge pull request #53 from hwanny1128/feat/rag-function
feat: add getting ralated document in realtime
2025-10-30 13:43:23 +09:00
djeon
9580de9c82 feat: add getting ralated document in realtime 2025-10-30 13:42:11 +09:00
Daewoong Jeon
f133faa509
Merge pull request #52 from hwanny1128/feat/rag-function
fix: build option
2025-10-30 12:25:53 +09:00
djeon
c1c50fa307 fix: build option 2025-10-30 12:25:23 +09:00
Daewoong Jeon
1690f79967
Merge pull request #51 from hwanny1128/feat/rag-function
fix: build option
2025-10-30 12:23:11 +09:00
djeon
d5c4bf8292 fix: build option 2025-10-30 12:22:40 +09:00
Daewoong Jeon
abd5af4308
Merge pull request #50 from hwanny1128/feat/rag-function
fix: build option
2025-10-30 12:17:58 +09:00
djeon
c332f7ef65 fix: build option 2025-10-30 12:17:16 +09:00
Daewoong Jeon
ee9ae0c4f3
Merge pull request #49 from hwanny1128/feat/rag-function
feat: rag md file
2025-10-30 11:27:07 +09:00
djeon
2481fa907b feat: rag md file 2025-10-30 11:26:23 +09:00
Daewoong Jeon
d17c4c8c9c
Merge pull request #48 from hwanny1128/feat/rag-function
Feat/rag function
2025-10-30 10:42:37 +09:00
djeon
155894c3ff feat: add ai-python ci/cd 2025-10-30 10:37:33 +09:00
djeon
663999a139 for merge 2025-10-30 10:25:40 +09:00
djeon
503078bf3f for merge 2025-10-30 10:24:09 +09:00
Daewoong Jeon
d7f90705d4
Update Dockerfile-rag 2025-10-30 10:15:39 +09:00
Minseo-Jo
e93f8d03f9 Fix: Gradle 빌드 에러 수정 - ai 모듈 제거
- settings.gradle: ai 모듈을 빌드에서 제외 (Python으로 구현됨)
- .gitignore: ai, ai-java-back 백업 디렉토리 추가

문제: GitHub Actions에서 빈 ai 모듈 빌드 시 메인 클래스 찾을 수 없어 실패
해결: AI 서비스는 ai-python(FastAPI)으로 구현되므로 Java 모듈에서 제외

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 10:08:01 +09:00
Minseo-Jo
e9e03e1ff8 Refactor: AI 서비스 Python 구현 및 디렉토리 구조 변경
- ai-python: FastAPI 기반 AI 서비스 구현
  - 실시간 회의 제안 기능 추가
  - Claude API 통합
  - EventHub 및 Redis 연동

- ai-java-back: 기존 Java AI 서비스 백업 디렉토리로 이동
  - Spring Boot 기반 구현 보존

- ai 디렉토리: Java 서비스 파일 삭제 처리

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 10:02:33 +09:00
Daewoong Jeon
5b4ca011c3
Merge pull request #47 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-30 09:14:40 +09:00
djeon
66101b2465 feat: add rag ci/cd 2025-10-30 09:13:53 +09:00
Minseo-Jo
ffb418ecb7 Merge branch 'main' of https://github.com/hwanny1128/HGZero 2025-10-30 09:12:08 +09:00
Minseo-Jo
42128e66f2 Fix: TranscriptionServiceImpl에 sessionId 파라미터 추가
- SegmentCreated.of() 메서드 호출 시 sessionId 파라미터 누락 수정
- sessionId에 meetingId 값 할당

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 09:11:28 +09:00
Daewoong Jeon
0aa0eba676
Merge pull request #46 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-30 09:09:10 +09:00
djeon
5c1285c3de feat: add rag ci/cd 2025-10-30 09:06:38 +09:00
Minseo-Jo
5c4f186290 Merge branch 'main' of https://github.com/hwanny1128/HGZero 2025-10-30 09:03:36 +09:00
Minseo-Jo
b1ef088795 STT 이벤트에 sessionId 추가 및 오디오 청크 처리 시간 15초로 변경
- TranscriptionEvent.SegmentCreated에 sessionId 필드 추가
- AudioBatchProcessor의 스케줄링 간격을 10초에서 15초로 변경
- AI 서비스의 TranscriptSegmentReadyEvent에도 sessionId 필드 추가
- 이벤트 발행 시 sessionId에 meetingId 값 할당

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 09:03:19 +09:00
Daewoong Jeon
d8036d2b17
Merge pull request #45 from hwanny1128/feat/rag-function
fix: add stt security config (header)
2025-10-30 08:44:43 +09:00
djeon
987f48c7ff fix: add stt security config (header) 2025-10-30 08:44:01 +09:00
Daewoong Jeon
8e99901786
Merge pull request #44 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 23:46:51 +09:00
djeon
7fd4cccd80 feat: add rag ci/cd 2025-10-29 23:46:19 +09:00
Daewoong Jeon
3195b7d9f7
Merge pull request #43 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 23:39:30 +09:00
djeon
5b744170e5 feat: add rag ci/cd 2025-10-29 23:39:01 +09:00
Daewoong Jeon
0a43bbfd0d
Merge pull request #42 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 23:22:59 +09:00
djeon
d3cbeff3ee feat: add rag ci/cd 2025-10-29 23:22:24 +09:00
Daewoong Jeon
13f31168ff
Merge pull request #41 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 22:58:57 +09:00
djeon
ea00cf4b03 feat: add rag ci/cd 2025-10-29 22:58:22 +09:00
Daewoong Jeon
98a14081c3
Merge pull request #40 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 22:56:25 +09:00
djeon
b49038e97e feat: add rag ci/cd 2025-10-29 22:55:48 +09:00
Daewoong Jeon
3c0da5c048
Merge pull request #39 from hwanny1128/feat/rag-function
feat: add rag ci/cd
2025-10-29 22:50:54 +09:00
djeon
e001312f07 feat: add rag ci/cd 2025-10-29 22:50:14 +09:00
Daewoong Jeon
8a25b24063
Merge pull request #38 from hwanny1128/feat/rag-function
Feat/rag function
2025-10-29 22:43:04 +09:00
djeon
81f9b02195 Merge branch 'main' of https://github.com/hwanny1128/HGZero into feat/rag-function 2025-10-29 22:42:12 +09:00
djeon
4e2182055b feat: add rag ci/cd 2025-10-29 22:42:07 +09:00
Daewoong Jeon
b80885593b
Merge pull request #37 from hwanny1128/feat/rag-function
Feat/rag function
2025-10-29 21:51:33 +09:00
djeon
1879c1e30a Merge branch 'main' of https://github.com/hwanny1128/HGZero into feat/rag-function 2025-10-29 21:50:56 +09:00
djeon
8bb91f646f feat: 실시간 용어설명 조회 기능 추가 2025-10-29 21:50:16 +09:00
Minseo Jo
2ba8503ad2
Merge pull request #35 from hwanny1128/feat/ai-create-summary
Feat: AI 요약 재생성 API 구현
2025-10-29 18:17:08 +09:00
Minseo-Jo
d48969c406 Merge: AI 요약 재생성 기능 및 포트 8087 통일
- AI 텍스트 요약 API 추가 (POST /api/v1/ai/summary/generate)
- 불릿 포인트 및 단락형 스타일 지원
- 포트 8087로 통일
- 압축률, 핵심 포인트 추출 기능 포함

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 18:12:15 +09:00
Minseo-Jo
0615538b1f Fix: AI 서비스 포트 8087로 변경
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-29 18:11:32 +09:00
Cho Yoon Jin
8f14b2d2dd
Merge pull request #36 from hwanny1128/feat/meeting
Chore: 회의록 수정 - AI 요약 정보 추가
2025-10-29 18:03:16 +09:00
cyjadela
78d72451fa Chore: 회의록 수정 - AI 요약 정보 추가 2025-10-29 17:58:26 +09:00
cyjadela
4944855210 Chore: ai-python 서비스 포트 변경 2025-10-29 17:45:37 +09:00
cyjadela
ed017129c7 Feat: AI 요약 재생성 API 구현 2025-10-29 17:35:01 +09:00
187 changed files with 5036 additions and 15221 deletions

View File

@ -0,0 +1,3 @@
# Development environment variables for ai-python service
resource_group=rg-digitalgarage-02
cluster_name=aks-digitalgarage-02

View File

@ -0,0 +1,7 @@
# Azure Resource Configuration
resource_group=rg-digitalgarage-02
cluster_name=aks-digitalgarage-02
# RAG Service Configuration
python_version=3.11
app_port=8088

View File

@ -0,0 +1,7 @@
# Azure Resource Configuration
resource_group=rg-digitalgarage-prod
cluster_name=aks-digitalgarage-prod
# RAG Service Configuration
python_version=3.11
app_port=8088

View File

@ -0,0 +1,7 @@
# Azure Resource Configuration
resource_group=rg-digitalgarage-staging
cluster_name=aks-digitalgarage-staging
# RAG Service Configuration
python_version=3.11
app_port=8088

View File

@ -32,6 +32,13 @@ spec:
name: stt
port:
number: 8080
- path: /api/transcripts
pathType: Prefix
backend:
service:
name: ai-service
port:
number: 8087
- path: /api/ai/suggestions
pathType: Prefix
backend:

View File

@ -0,0 +1,221 @@
name: AI-Python Service CI/CD
on:
push:
branches: [ main, develop ]
paths:
- 'ai-python/**'
- '.github/workflows/ai-python-cicd_ArgoCD.yaml'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- staging
- prod
SKIP_TESTS:
description: 'Skip Tests'
required: false
default: 'false'
type: choice
options:
- 'false'
- 'true'
env:
REGISTRY: acrdigitalgarage02.azurecr.io
IMAGE_ORG: hgzero
SERVICE_NAME: ai-python
RESOURCE_GROUP: rg-digitalgarage-02
AKS_CLUSTER: aks-digitalgarage-02
NAMESPACE: hgzero
jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.set_outputs.outputs.image_tag }}
environment: ${{ steps.set_outputs.outputs.environment }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python 3.13
uses: actions/setup-python@v4
with:
python-version: '3.13'
cache: 'pip'
cache-dependency-path: 'ai-python/requirements.txt'
- name: Determine environment
id: determine_env
run: |
ENVIRONMENT="${{ github.event.inputs.ENVIRONMENT || 'dev' }}"
echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT
- name: Load environment variables
id: env_vars
run: |
ENV=${{ steps.determine_env.outputs.environment }}
REGISTRY="acrdigitalgarage02.azurecr.io"
IMAGE_ORG="hgzero"
RESOURCE_GROUP="rg-digitalgarage-02"
AKS_CLUSTER="aks-digitalgarage-02"
NAMESPACE="hgzero"
if [[ -f ".github/config/deploy_env_vars_ai-python_${ENV}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
key=$(echo "$line" | cut -d '=' -f1)
value=$(echo "$line" | cut -d '=' -f2-)
case "$key" in
"resource_group") RESOURCE_GROUP="$value" ;;
"cluster_name") AKS_CLUSTER="$value" ;;
esac
done < ".github/config/deploy_env_vars_ai-python_${ENV}"
fi
echo "REGISTRY=$REGISTRY" >> $GITHUB_ENV
echo "IMAGE_ORG=$IMAGE_ORG" >> $GITHUB_ENV
echo "RESOURCE_GROUP=$RESOURCE_GROUP" >> $GITHUB_ENV
echo "AKS_CLUSTER=$AKS_CLUSTER" >> $GITHUB_ENV
- name: Install dependencies
run: |
cd ai-python
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Tests
env:
SKIP_TESTS: ${{ github.event.inputs.SKIP_TESTS || 'true' }}
run: |
if [[ "$SKIP_TESTS" == "true" ]]; then
echo "⏭️ Skipping Tests (SKIP_TESTS=$SKIP_TESTS)"
exit 0
fi
cd ai-python
# pytest가 requirements.txt에 있다면 실행
if pip list | grep -q "pytest"; then
if [ -d "tests" ]; then
pytest tests/ --cov=app --cov-report=xml --cov-report=html || echo "⚠️ Tests failed but continuing"
else
echo "⚠️ No tests directory found, skipping tests"
fi
else
echo "⚠️ pytest not installed, skipping tests"
fi
echo "✅ Tests completed successfully"
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
ai-python/htmlcov/
ai-python/coverage.xml
- name: Set outputs
id: set_outputs
run: |
IMAGE_TAG=$(date +%Y%m%d%H%M%S)
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "environment=${{ steps.determine_env.outputs.environment }}" >> $GITHUB_OUTPUT
release:
name: Build and Push Docker Image
needs: build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set environment variables from build job
run: |
echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV
echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $GITHUB_ENV
echo "SERVICE_NAME=${{ env.SERVICE_NAME }}" >> $GITHUB_ENV
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub (prevent rate limit)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Login to Azure Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
- name: Build and push Docker image
run: |
echo "Building and pushing AI-Python service..."
docker build \
-f deployment/container/Dockerfile-ai-python \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} \
ai-python/
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
echo "✅ Docker image pushed successfully"
update-manifest:
name: Update Manifest Repository
needs: [build, release]
runs-on: ubuntu-latest
steps:
- name: Set image tag environment variable
run: |
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
- name: Update Manifest Repository
run: |
# 매니페스트 레포지토리 클론
REPO_URL=$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||')
git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@${REPO_URL} manifest-repo
cd manifest-repo
# Kustomize 설치
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
# 매니페스트 업데이트
cd hgzero-back/kustomize/overlays/${{ env.ENVIRONMENT }}
# AI-Python 서비스 이미지 태그 업데이트
kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/ai-python:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
# Git 설정 및 푸시
cd ../../../..
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add .
git commit -m "🚀 Update AI-Python ${{ env.ENVIRONMENT }} image to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}"
git push origin main
echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."

View File

@ -2,7 +2,7 @@ name: Backend Services CI/CD
on:
push:
branches: [ main, develop ]
branches: [ main ]
paths:
- 'user/**'
- 'meeting/**'
@ -11,8 +11,8 @@ on:
- 'notification/**'
- 'common/**'
- '.github/**'
pull_request:
branches: [ main ]
# pull_request:
# branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
@ -143,6 +143,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: app-builds
retention-days: 1
path: |
user/build/libs/*.jar
meeting/build/libs/*.jar

214
.github/workflows/rag-cicd_ArgoCD.yaml vendored Normal file
View File

@ -0,0 +1,214 @@
name: RAG Service CI/CD
on:
push:
branches: [ main, develop ]
paths:
- 'rag/**'
- '.github/workflows/rag-cicd_ArgoCD.yaml'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- staging
- prod
SKIP_TESTS:
description: 'Skip Tests'
required: false
default: 'true'
type: choice
options:
- 'false'
- 'true'
env:
REGISTRY: acrdigitalgarage02.azurecr.io
IMAGE_ORG: hgzero
SERVICE_NAME: rag
RESOURCE_GROUP: rg-digitalgarage-02
AKS_CLUSTER: aks-digitalgarage-02
NAMESPACE: hgzero
jobs:
build:
name: Build and Test
runs-on: ubuntu-latest
outputs:
image_tag: ${{ steps.set_outputs.outputs.image_tag }}
environment: ${{ steps.set_outputs.outputs.environment }}
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up Python 3.11
uses: actions/setup-python@v4
with:
python-version: '3.11'
cache: 'pip'
cache-dependency-path: 'rag/requirements.txt'
- name: Determine environment
id: determine_env
run: |
ENVIRONMENT="${{ github.event.inputs.ENVIRONMENT || 'dev' }}"
echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT
- name: Load environment variables
id: env_vars
run: |
ENV=${{ steps.determine_env.outputs.environment }}
REGISTRY="acrdigitalgarage02.azurecr.io"
IMAGE_ORG="hgzero"
RESOURCE_GROUP="rg-digitalgarage-02"
AKS_CLUSTER="aks-digitalgarage-02"
NAMESPACE="hgzero"
if [[ -f ".github/config/deploy_env_vars_rag_${ENV}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
key=$(echo "$line" | cut -d '=' -f1)
value=$(echo "$line" | cut -d '=' -f2-)
case "$key" in
"resource_group") RESOURCE_GROUP="$value" ;;
"cluster_name") AKS_CLUSTER="$value" ;;
esac
done < ".github/config/deploy_env_vars_rag_${ENV}"
fi
echo "REGISTRY=$REGISTRY" >> $GITHUB_ENV
echo "IMAGE_ORG=$IMAGE_ORG" >> $GITHUB_ENV
echo "RESOURCE_GROUP=$RESOURCE_GROUP" >> $GITHUB_ENV
echo "AKS_CLUSTER=$AKS_CLUSTER" >> $GITHUB_ENV
- name: Install dependencies
run: |
cd rag
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Tests
env:
SKIP_TESTS: ${{ github.event.inputs.SKIP_TESTS || 'true' }}
run: |
if [[ "$SKIP_TESTS" == "true" ]]; then
echo "⏭️ Skipping Tests (SKIP_TESTS=$SKIP_TESTS)"
exit 0
fi
cd rag
# Run pytest with coverage
pytest tests/ --cov=src --cov-report=xml --cov-report=html
echo "✅ Tests completed successfully"
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results
path: |
rag/htmlcov/
rag/coverage.xml
- name: Set outputs
id: set_outputs
run: |
IMAGE_TAG=$(date +%Y%m%d%H%M%S)
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
echo "environment=${{ steps.determine_env.outputs.environment }}" >> $GITHUB_OUTPUT
release:
name: Build and Push Docker Image
needs: build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set environment variables from build job
run: |
echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV
echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $GITHUB_ENV
echo "SERVICE_NAME=${{ env.SERVICE_NAME }}" >> $GITHUB_ENV
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub (prevent rate limit)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Login to Azure Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
- name: Build and push Docker image
run: |
echo "Building and pushing RAG service..."
docker build \
--no-cache \
-f deployment/container/Dockerfile-rag \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} \
rag/
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/${{ env.SERVICE_NAME }}:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
echo "✅ Docker image pushed successfully"
update-manifest:
name: Update Manifest Repository
needs: [build, release]
runs-on: ubuntu-latest
steps:
- name: Set image tag environment variable
run: |
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
- name: Update Manifest Repository
run: |
# 매니페스트 레포지토리 클론
REPO_URL=$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||')
git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@${REPO_URL} manifest-repo
cd manifest-repo
# Kustomize 설치
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
# 매니페스트 업데이트
cd hgzero-back/kustomize/overlays/${{ env.ENVIRONMENT }}
# RAG 서비스 이미지 태그 업데이트
kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/rag:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
# Git 설정 및 푸시
cd ../../../..
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add .
git commit -m "🚀 Update RAG ${{ env.ENVIRONMENT }} image to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}"
git push origin main
echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."

4
.gitignore vendored
View File

@ -58,3 +58,7 @@ logs/
**/logs/
*.log
**/*.log
# Deprecated/Backup directories
ai-java-back/
ai/

215
Jenkinsfile vendored Normal file
View File

@ -0,0 +1,215 @@
def PIPELINE_ID = "${env.BUILD_NUMBER}"
def getImageTag() {
def dateFormat = new java.text.SimpleDateFormat('yyyyMMddHHmmss')
def currentDate = new Date()
return dateFormat.format(currentDate)
}
podTemplate(
label: "${PIPELINE_ID}",
serviceAccount: 'jenkins',
slaveConnectTimeout: 300,
idleMinutes: 1,
activeDeadlineSeconds: 3600,
podRetention: never(),
yaml: '''
spec:
terminationGracePeriodSeconds: 3
restartPolicy: Never
tolerations:
- effect: NoSchedule
key: dedicated
operator: Equal
value: cicd
''',
containers: [
containerTemplate(
name: 'podman',
image: "mgoltzsche/podman",
ttyEnabled: true,
command: 'cat',
privileged: true,
resourceRequestCpu: '500m',
resourceRequestMemory: '2Gi',
resourceLimitCpu: '2000m',
resourceLimitMemory: '4Gi'
),
containerTemplate(
name: 'gradle',
image: 'gradle:jdk21',
ttyEnabled: true,
command: 'cat',
resourceRequestCpu: '500m',
resourceRequestMemory: '1Gi',
resourceLimitCpu: '1000m',
resourceLimitMemory: '2Gi',
envVars: [
envVar(key: 'DOCKER_HOST', value: 'unix:///run/podman/podman.sock'),
envVar(key: 'TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE', value: '/run/podman/podman.sock'),
envVar(key: 'TESTCONTAINERS_RYUK_DISABLED', value: 'true')
]
),
containerTemplate(
name: 'git',
image: 'alpine/git:latest',
command: 'cat',
ttyEnabled: true,
resourceRequestCpu: '100m',
resourceRequestMemory: '256Mi',
resourceLimitCpu: '300m',
resourceLimitMemory: '512Mi'
)
],
volumes: [
emptyDirVolume(mountPath: '/home/gradle/.gradle', memory: false),
emptyDirVolume(mountPath: '/run/podman', memory: false)
]
) {
node(PIPELINE_ID) {
def imageTag = getImageTag()
def environment = params.ENVIRONMENT ?: 'dev'
def services = ['user', 'meeting', 'stt', 'notification']
def registry = 'acrdigitalgarage02.azurecr.io'
def imageOrg = 'hgzero'
try {
stage("Get Source") {
checkout scm
// 환경 변수 로드
def configFile = ".github/config/deploy_env_vars_${environment}"
if (fileExists(configFile)) {
echo "📋 Loading environment variables for ${environment}..."
def props = readProperties file: configFile
echo "Config loaded: ${props}"
}
}
stage('Build') {
container('gradle') {
echo "🔨 Building with Gradle..."
sh """
chmod +x gradlew
./gradlew build -x test
"""
}
}
stage('Archive Artifacts') {
echo "📦 Archiving build artifacts..."
archiveArtifacts artifacts: '**/build/libs/*.jar', fingerprint: true
}
stage('Build & Push Images') {
timeout(time: 30, unit: 'MINUTES') {
container('podman') {
withCredentials([
usernamePassword(
credentialsId: 'acr-credentials',
usernameVariable: 'ACR_USERNAME',
passwordVariable: 'ACR_PASSWORD'
),
usernamePassword(
credentialsId: 'dockerhub-credentials',
usernameVariable: 'DOCKERHUB_USERNAME',
passwordVariable: 'DOCKERHUB_PASSWORD'
)
]) {
echo "🐳 Building and pushing Docker images..."
// Login to Docker Hub (prevent rate limit)
sh "podman login docker.io --username \$DOCKERHUB_USERNAME --password \$DOCKERHUB_PASSWORD"
// Login to Azure Container Registry
sh "podman login ${registry} --username \$ACR_USERNAME --password \$ACR_PASSWORD"
// Build and push each service
services.each { service ->
echo "Building ${service}..."
def imageTagFull = "${registry}/${imageOrg}/${service}:${environment}-${imageTag}"
sh """
podman build \\
--build-arg BUILD_LIB_DIR="${service}/build/libs" \\
--build-arg ARTIFACTORY_FILE="${service}.jar" \\
-f deployment/container/Dockerfile-backend \\
-t ${imageTagFull} .
"""
echo "Pushing ${service}..."
sh "podman push ${imageTagFull}"
echo "✅ ${service} image pushed: ${imageTagFull}"
}
}
}
}
}
stage('Update Manifest Repository') {
container('git') {
withCredentials([usernamePassword(
credentialsId: 'github-credentials-dg0506',
usernameVariable: 'GIT_USERNAME',
passwordVariable: 'GIT_TOKEN'
)]) {
echo "📝 Updating manifest repository..."
sh """
# 매니페스트 레포지토리 클론
REPO_URL=\$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||')
git clone https://\${GIT_USERNAME}:\${GIT_TOKEN}@\${REPO_URL} manifest-repo
cd manifest-repo
# 각 서비스별 이미지 태그 업데이트 (sed 사용)
cd hgzero-back/kustomize/base
services="user meeting stt notification"
for service in \$services; do
echo "Updating \$service image tag..."
sed -i "s|image: ${registry}/${imageOrg}/\$service:.*|image: ${registry}/${imageOrg}/\$service:${environment}-${imageTag}|g" \\
\$service/deployment.yaml
# 변경 사항 확인
echo "Updated \$service deployment.yaml:"
grep "image: ${registry}/${imageOrg}/\$service" \$service/deployment.yaml
done
# Git 설정 및 푸시
cd ../../..
git config user.name "Jenkins"
git config user.email "jenkins@hgzero.com"
git add .
git commit -m "🚀 Update hgzero ${environment} images to ${environment}-${imageTag}"
git push origin main
echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."
"""
}
}
}
stage('Pipeline Complete') {
echo "🧹 Pipeline completed. Pod cleanup handled by Jenkins Kubernetes Plugin."
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
echo "✅ Pipeline completed successfully!"
echo "Environment: ${environment}"
echo "Image Tag: ${imageTag}"
} else {
echo "❌ Pipeline failed with result: ${currentBuild.result}"
}
}
} catch (Exception e) {
currentBuild.result = 'FAILURE'
echo "❌ Pipeline failed with exception: ${e.getMessage()}"
throw e
} finally {
echo "🧹 Cleaning up resources and preparing for pod termination..."
echo "Pod will be terminated in 3 seconds due to terminationGracePeriodSeconds: 3"
}
}
}

376
README.md
View File

@ -0,0 +1,376 @@
# HGZero - AI 기반 회의록 작성 및 이력 관리 개선 서비스
## 1. 소개
HGZero는 업무지식이 부족한 회의록 작성자도 누락 없이 정확하게 회의록을 작성하여 공유할 수 있는 AI 기반 서비스입니다.
사용자는 실시간 음성 변환(STT), AI 요약, 용어 설명, Todo 자동 추출 등의 기능을 통해 회의록 작성 업무를 효율적으로 수행할 수 있습니다.
### 1.1 핵심 기능
- **실시간 STT**: Azure Speech Services 기반 실시간 음성-텍스트 변환
- **AI 요약**: 안건별 2-3문장 자동 요약 (GPT-4o, 2-5초 처리)
- **맥락 기반 용어 설명**: 관련 회의록과 업무이력 기반 실용 정보 제공
- **Todo 자동 추출**: 회의록에서 액션 아이템 자동 추출 및 배정
- **지능형 회의 진행 지원**: 회의 패턴 분석, 안건 추천, 효율성 분석
- **실시간 협업**: WebSocket 기반 실시간 회의록 편집 및 동기화
### 1.2 MVP 산출물
- **발표자료**: {발표자료 링크}
- **설계결과**:
- [유저스토리](design/userstory.md)
- [논리 아키텍처](design/backend/logical/logical-architecture.md)
- [API 설계서](design/backend/api/API설계서.md)
- **Git Repo**:
- **메인**: https://gitea.cbiz.kubepia.net/shared-dg05-coffeeQuokka/hgzero.git
- **프론트엔드**: {프론트엔드 Repository 링크}
- **manifest**: {Manifest Repository 링크}
- **시연 동영상**: {시연 동영상 링크}
## 2. 시스템 아키텍처
### 2.1 전체 구조
마이크로서비스 아키텍처 기반 클라우드 네이티브 애플리케이션
```
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ React 18 + TypeScript │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ NGINX Ingress │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ User Service │ │Meeting Service│ │ STT Service │
│ (Java) │ │ (Java) │ │ (Java) │
│ :8081 │ │ :8081/:8082 │ │ :8083 │
└───────────────┘ └───────────────┘ └───────────────┘
│ │ │
│ │ │
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ AI Service │ │ RAG Service │ │Notification │
│ (Java) │ │ (Python) │ │ (Java) │
│ :8083 │ │ :8000 │ │ :8084 │
└───────────────┘ └───────────────┘ └───────────────┘
│ │
└───────────────────┤
┌───────────────────┐
│ Event Hub │
│ (Pub/Sub MQ) │
└───────────────────┘
┌─────────┼─────────┐
│ │ │
┌──────────┐ ┌────────┐ ┌─────────────┐
│PostgreSQL│ │ Redis │ │ OpenAI │
│ (6 DB) │ │ Cache │ │ │
└──────────┘ └────────┘ └─────────────┘
```
### 2.2 마이크로서비스 구성
- **User 서비스**: 사용자 인증 (LDAP, JWT) 및 프로필 관리
- **Meeting 서비스**: 회의/회의록/Todo 통합 관리, 실시간 동기화 (WebSocket)
- **STT 서비스**: 음성 스트리밍, 실시간 STT 변환 (Azure Speech Services)
- **AI 서비스**: 회의록 자동요약, Todo 추출, 안건별 AI 요약
- **RAG 서비스**: 용어집 검색, 관련자료 검색, 회의록 유사도 검색 (Python/FastAPI)
- **Notification 서비스**: 이메일 알림 (회의 시작, 회의록 확정, Todo 배정)
### 2.3 기술 스택
- **프론트엔드**: React 18, TypeScript, React Context API
- **백엔드**: Spring Boot 3.2.x, Java 17, FastAPI, Python 3.11+
- **인프라**: Azure Kubernetes Service (AKS), Azure Container Registry (ACR)
- **CI/CD**: GitHub Actions (CI), ArgoCD (CD - GitOps)
- **모니터링**: Prometheus, Grafana, Spring Boot Actuator
- **백킹 서비스**:
- **Database**: PostgreSQL 15 (Database per Service - 6개 독립 DB)
- **Message Queue**: Azure Event Hub (AMQP over TLS)
- **Cache**: Azure Redis Cache (Redis 7.x)
- **AI/ML**: Azure OpenAI (GPT-4o, text-embedding-3-large), Azure Speech Services, Azure AI Search
## 3. 백킹 서비스 설치
### 3.1 Database 설치
PostgreSQL 15 설치 (각 서비스별 독립 데이터베이스)
```bash
# Helm 저장소 추가
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# User 서비스용 DB
helm install hgzero-user bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=userdb \
--namespace hgzero
# Meeting 서비스용 DB
helm install hgzero-meeting bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=meetingdb \
--namespace hgzero
# STT 서비스용 DB
helm install hgzero-stt bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=sttdb \
--namespace hgzero
# AI 서비스용 DB
helm install hgzero-ai bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=aidb \
--namespace hgzero
# RAG 서비스용 DB
helm install hgzero-rag bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=ragdb \
--namespace hgzero
# Notification 서비스용 DB
helm install hgzero-notification bitnami/postgresql \
--set global.postgresql.auth.postgresPassword=Passw0rd \
--set global.postgresql.auth.username=hgzerouser \
--set global.postgresql.auth.password=Passw0rd \
--set global.postgresql.auth.database=notificationdb \
--namespace hgzero
```
**접속 정보 확인**:
```bash
# 각 서비스별 DB 접속 정보
# User DB: hgzero-user-postgresql.hgzero.svc.cluster.local:5432
# Meeting DB: hgzero-meeting-postgresql.hgzero.svc.cluster.local:5432
# STT DB: hgzero-stt-postgresql.hgzero.svc.cluster.local:5432
# AI DB: hgzero-ai-postgresql.hgzero.svc.cluster.local:5432
# RAG DB: hgzero-rag-postgresql.hgzero.svc.cluster.local:5432
# Notification DB: hgzero-notification-postgresql.hgzero.svc.cluster.local:5432
```
### 3.2 Cache 설치
Redis 설치
```bash
# Helm으로 Redis 설치
helm install hgzero-redis bitnami/redis \
--set auth.password=Passw0rd \
--set master.persistence.enabled=true \
--set master.persistence.size=8Gi \
--namespace hgzero
# 접속 정보 확인
export REDIS_PASSWORD=$(kubectl get secret --namespace hgzero hgzero-redis -o jsonpath="{.data.redis-password}" | base64 -d)
echo "Redis Password: $REDIS_PASSWORD"
echo "Redis Host: hgzero-redis-master.hgzero.svc.cluster.local"
echo "Redis Port: 6379"
```
**Azure Redis Cache 사용 (프로덕션)**:
```bash
# Azure Portal에서 Redis Cache 생성 후 연결 정보 사용
# 또는 Azure CLI 사용
az redis create \
--name hgzero-redis \
--resource-group your-resource-group \
--location koreacentral \
--sku Basic \
--vm-size c0
```
### 3.3 Message Queue 설치
Azure Event Hub 설정
```bash
# Azure CLI를 통한 Event Hub 생성
az eventhubs namespace create \
--name hgzero-eventhub-ns \
--resource-group your-resource-group \
--location koreacentral \
--sku Standard
az eventhubs eventhub create \
--name hgzero-events \
--namespace-name hgzero-eventhub-ns \
--resource-group your-resource-group \
--partition-count 4 \
--message-retention 7
# 연결 문자열 확인
az eventhubs namespace authorization-rule keys list \
--resource-group your-resource-group \
--namespace-name hgzero-eventhub-ns \
--name RootManageSharedAccessKey \
--query primaryConnectionString \
--output tsv
```
## 4. 빌드 및 배포
### 4.1 프론트엔드 빌드 및 배포
#### 1. 애플리케이션 빌드
```bash
cd frontend
npm install
npm run build
```
#### 2. 컨테이너 이미지 빌드
```bash
docker build \
--build-arg REACT_APP_API_URL="http://api.hgzero.com" \
--build-arg REACT_APP_WS_URL="ws://api.hgzero.com/ws" \
-f deployment/container/Dockerfile-frontend \
-t acrdigitalgarage02.azurecr.io/hgzero/frontend:latest .
```
#### 3. 이미지 푸시
```bash
docker push acrdigitalgarage02.azurecr.io/hgzero/frontend:latest
```
#### 4. Kubernetes 배포
```bash
kubectl apply -f deployment/k8s/frontend/frontend-deployment.yaml -n hgzero
```
### 4.2 백엔드 빌드 및 배포
#### 1. 애플리케이션 빌드
```bash
# 전체 프로젝트 빌드
./gradlew clean build -x test
# 또는 개별 서비스 빌드
./gradlew :user:clean :user:build -x test
./gradlew :meeting:clean :meeting:build -x test
./gradlew :stt:clean :stt:build -x test
./gradlew :ai:clean :ai:build -x test
./gradlew :notification:clean :notification:build -x test
```
#### 2. 컨테이너 이미지 빌드 (각 서비스별로 수행)
```bash
# User 서비스
docker build \
--build-arg BUILD_LIB_DIR="user/build/libs" \
--build-arg ARTIFACTORY_FILE="user.jar" \
-f deployment/container/Dockerfile-user \
-t acrdigitalgarage02.azurecr.io/hgzero/user-service:latest .
# Meeting 서비스
docker build \
--build-arg BUILD_LIB_DIR="meeting/build/libs" \
--build-arg ARTIFACTORY_FILE="meeting.jar" \
-f deployment/container/Dockerfile-meeting \
-t acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest .
# STT 서비스
docker build \
--build-arg BUILD_LIB_DIR="stt/build/libs" \
--build-arg ARTIFACTORY_FILE="stt.jar" \
-f deployment/container/Dockerfile-stt \
-t acrdigitalgarage02.azurecr.io/hgzero/stt-service:latest .
# AI 서비스
docker build \
--build-arg BUILD_LIB_DIR="ai/build/libs" \
--build-arg ARTIFACTORY_FILE="ai.jar" \
-f deployment/container/Dockerfile-ai \
-t acrdigitalgarage02.azurecr.io/hgzero/ai-service:latest .
# Notification 서비스
docker build \
--build-arg BUILD_LIB_DIR="notification/build/libs" \
--build-arg ARTIFACTORY_FILE="notification.jar" \
-f deployment/container/Dockerfile-notification \
-t acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest .
```
#### 3. RAG 서비스 빌드 (Python)
```bash
docker build \
-f deployment/container/Dockerfile-rag \
-t acrdigitalgarage02.azurecr.io/hgzero/rag-service:latest \
./rag
```
#### 4. 이미지 푸시
```bash
docker push acrdigitalgarage02.azurecr.io/hgzero/user-service:latest
docker push acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest
docker push acrdigitalgarage02.azurecr.io/hgzero/stt-service:latest
docker push acrdigitalgarage02.azurecr.io/hgzero/ai-service:latest
docker push acrdigitalgarage02.azurecr.io/hgzero/rag-service:latest
docker push acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest
```
#### 5. Kubernetes 배포
```bash
# Namespace 생성
kubectl create namespace hgzero
# Secret 생성 (환경 변수)
kubectl apply -f deployment/k8s/backend/secrets/ -n hgzero
# 서비스 배포
kubectl apply -f deployment/k8s/backend/user-service.yaml -n hgzero
kubectl apply -f deployment/k8s/backend/meeting-service.yaml -n hgzero
kubectl apply -f deployment/k8s/backend/stt-service.yaml -n hgzero
kubectl apply -f deployment/k8s/backend/ai-service.yaml -n hgzero
kubectl apply -f deployment/k8s/backend/rag-service.yaml -n hgzero
kubectl apply -f deployment/k8s/backend/notification-service.yaml -n hgzero
# Ingress 설정
kubectl apply -f deployment/k8s/ingress.yaml -n hgzero
```
### 4.3 테스트
#### 1) 프론트엔드 페이지 주소 구하기
```bash
# Namespace 설정
kubens hgzero
# Service 확인
kubectl get svc
# Ingress 확인
kubectl get ingress
```
#### 2) API 테스트
**Swagger UI 접근**:
- User Service: http://{INGRESS_URL}/user/swagger-ui.html
- Meeting Service: http://{INGRESS_URL}/meeting/swagger-ui.html
- STT Service: http://{INGRESS_URL}/stt/swagger-ui.html
- AI Service: http://{INGRESS_URL}/ai/swagger-ui.html
- RAG Service: http://{INGRESS_URL}/rag/docs
- Notification Service: http://{INGRESS_URL}/notification/swagger-ui.html
#### 3) 로그인 테스트
- ID: user-005, user2@example.com
- PW: 8자리
## 5. 팀
- 유동희 "야보" - Product Owner
- 조민서 "다람지" - AI Specialist
- 김주환 "블랙" - Architect
- 김종희 "페퍼" - Frontend Developer
- 문효종 "카누" - Frontend Developer / DevOps Engineer
- 전대웅 "맥심" - Backend Developer
- 조윤진 "쿼카" - Backend Developer

View File

@ -25,6 +25,11 @@ public class TranscriptSegmentReadyEvent {
*/
private String meetingId;
/**
* 세션 ID
*/
private String sessionId;
/**
* 변환 텍스트 세그먼트 ID
*/

View File

@ -248,3 +248,53 @@ A: 네, 각 클라이언트는 독립적으로 SSE 연결을 유지합니다.
**Q: 제안사항이 오지 않으면?**
A: Redis에 충분한 텍스트(10개 세그먼트)가 축적되어야 분석이 시작됩니다. 5초마다 체크합니다.
### 3. AI 텍스트 요약 생성
**엔드포인트**: `POST /api/v1/ai/summary/generate`
**설명**: 텍스트를 AI로 요약하여 핵심 내용과 포인트를 추출합니다.
**요청 본문**:
```json
{
"text": "요약할 텍스트 내용",
"language": "ko", // ko: 한국어, en: 영어 (기본값: ko)
"style": "bullet", // bullet: 불릿포인트, paragraph: 단락형 (기본값: bullet)
"max_length": 100 // 최대 요약 길이 (단어 수) - 선택사항
}
```
**응답 예시**:
```json
{
"summary": "• 프로젝트 총 개발 기간 3개월 확정 (디자인 2주, 개발 8주, 테스트 2주)\n• 총 예산 5천만원 배정 (인건비 3천만원, 인프라 1천만원, 기타 1천만원)\n• 주간 회의 일정: 매주 화요일 오전 10시",
"key_points": [
"프로젝트 전체 일정 3개월로 확정",
"개발 단계별 기간: 디자인 2주, 개발 8주, 테스트 2주",
"총 예산 5천만원 책정",
"예산 배분: 인건비 60%, 인프라 20%, 기타 20%",
"정기 회의: 매주 화요일 오전 10시"
],
"word_count": 32,
"original_word_count": 46,
"compression_ratio": 0.7,
"generated_at": "2025-10-29T17:23:49.429982"
}
```
**요청 예시 (curl)**:
```bash
curl -X POST "http://localhost:8087/api/v1/ai/summary/generate" \
-H "Content-Type: application/json" \
-d '{
"text": "오늘 회의에서는 프로젝트 일정과 예산에 대해 논의했습니다...",
"language": "ko",
"style": "bullet"
}'
```
**에러 응답**:
- `400 Bad Request`: 텍스트가 비어있거나 너무 짧은 경우 (최소 20자)
- `400 Bad Request`: 텍스트가 너무 긴 경우 (최대 10,000자)
- `500 Internal Server Error`: AI 처리 중 오류 발생

Some files were not shown because too many files have changed in this diff Show More