Merge branch 'main' of https://github.com/hwanny1128/HGZero into feat/meeting

This commit is contained in:
cyjadela 2025-10-28 09:40:18 +09:00
commit 280321fa94
144 changed files with 17692 additions and 18814 deletions

500
.github/actions-pipeline-guide.md vendored Normal file
View File

@ -0,0 +1,500 @@
# GitHub Actions CI/CD 파이프라인 구축 가이드
## 📋 목차
1. [개요](#개요)
2. [사전 준비사항](#사전-준비사항)
3. [GitHub 저장소 환경 구성](#github-저장소-환경-구성)
4. [디렉토리 구조](#디렉토리-구조)
5. [Kustomize 구조 설명](#kustomize-구조-설명)
6. [GitHub Actions 워크플로우](#github-actions-워크플로우)
7. [배포 방법](#배포-방법)
8. [롤백 방법](#롤백-방법)
9. [SonarQube 설정](#sonarqube-설정)
10. [트러블슈팅](#트러블슈팅)
---
## 개요
HGZero 프로젝트의 백엔드 서비스를 위한 GitHub Actions 기반 CI/CD 파이프라인입니다.
### 주요 기능
- ✅ Gradle 기반 빌드 및 테스트
- ✅ SonarQube 코드 품질 분석 (선택적)
- ✅ Azure Container Registry에 Docker 이미지 빌드 및 푸시
- ✅ Kustomize를 사용한 환경별(dev/staging/prod) 배포
- ✅ AKS 클러스터 자동 배포
### 지원 서비스
- **user**: 사용자 관리 서비스
- **meeting**: 회의 관리 서비스
- **stt**: 음성 인식 서비스
- **ai**: AI 처리 서비스
- **notification**: 알림 서비스
---
## 사전 준비사항
### 1. 프로젝트 정보
- **시스템명**: hgzero
- **ACR 이름**: acrdigitalgarage02
- **리소스 그룹**: rg-digitalgarage-02
- **AKS 클러스터**: aks-digitalgarage-02
- **네임스페이스**: hgzero
- **JDK 버전**: 21
### 2. 필수 도구
- Git
- kubectl
- Azure CLI
- Kustomize (자동 설치됨)
---
## GitHub 저장소 환경 구성
### 1. Repository Secrets 설정
`Repository Settings > Secrets and variables > Actions > Repository secrets`에 다음 항목을 등록하세요:
#### Azure 인증 정보
```json
AZURE_CREDENTIALS:
{
"clientId": "{클라이언트ID}",
"clientSecret": "{클라이언트시크릿}",
"subscriptionId": "{구독ID}",
"tenantId": "{테넌트ID}"
}
```
**예시:**
```json
{
"clientId": "5e4b5b41-7208-48b7-b821-d6d5acf50ecf",
"clientSecret": "ldu8Q~GQEzFYU.dJX7_QsahR7n7C2xqkIM6hqbV8",
"subscriptionId": "2513dd36-7978-48e3-9a7c-b221d4874f66",
"tenantId": "4f0a3bfd-1156-4cce-8dc2-a049a13dba23"
}
```
#### ACR Credentials
ACR Credential을 확인하려면:
```bash
az acr credential show --name acrdigitalgarage02
```
등록할 Secrets:
```
ACR_USERNAME: acrdigitalgarage02
ACR_PASSWORD: {ACR 패스워드}
```
#### SonarQube 설정
**SONAR_HOST_URL 확인:**
```bash
kubectl get svc -n sonarqube
```
출력된 External IP를 사용하여 `http://{External IP}` 형식으로 설정
**SONAR_TOKEN 생성:**
1. SonarQube에 로그인 (기본: admin/admin)
2. 우측 상단 'Administrator' > My Account 클릭
3. Security 탭 선택 후 토큰 생성
등록할 Secrets:
```
SONAR_TOKEN: {SonarQube 토큰}
SONAR_HOST_URL: http://{External IP}
```
#### Docker Hub (Rate Limit 해결용)
**패스워드 생성:**
1. [Docker Hub](https://hub.docker.com) 로그인
2. 우측 상단 프로필 아이콘 > Account Settings
3. 좌측 메뉴 'Personal Access Tokens' 클릭하여 생성
등록할 Secrets:
```
DOCKERHUB_USERNAME: {Docker Hub 사용자명}
DOCKERHUB_PASSWORD: {Docker Hub 패스워드 또는 토큰}
```
### 2. Repository Variables 설정
`Repository Settings > Secrets and variables > Actions > Variables > Repository variables`에 등록:
```
ENVIRONMENT: dev
SKIP_SONARQUBE: true
```
---
## 디렉토리 구조
```
.github/
├── workflows/
│ └── backend-cicd.yaml # GitHub Actions 워크플로우
├── kustomize/
│ ├── base/ # 기본 Kubernetes 매니페스트
│ │ ├── common/ # 공통 리소스
│ │ │ ├── cm-common.yaml
│ │ │ ├── secret-common.yaml
│ │ │ ├── secret-imagepull.yaml
│ │ │ └── ingress.yaml
│ │ ├── user/ # User 서비스
│ │ │ ├── deployment.yaml
│ │ │ ├── service.yaml
│ │ │ └── secret-user.yaml
│ │ ├── meeting/ # Meeting 서비스
│ │ ├── stt/ # STT 서비스
│ │ ├── ai/ # AI 서비스
│ │ ├── notification/ # Notification 서비스
│ │ └── kustomization.yaml
│ └── overlays/ # 환경별 오버레이
│ ├── dev/ # 개발 환경
│ │ ├── kustomization.yaml
│ │ ├── cm-common-patch.yaml
│ │ ├── secret-common-patch.yaml
│ │ ├── ingress-patch.yaml
│ │ ├── deployment-{service}-patch.yaml
│ │ └── secret-{service}-patch.yaml
│ ├── staging/ # 스테이징 환경
│ └── prod/ # 프로덕션 환경
├── config/ # 환경별 설정
│ ├── deploy_env_vars_dev
│ ├── deploy_env_vars_staging
│ └── deploy_env_vars_prod
└── scripts/
└── deploy-actions.sh # 수동 배포 스크립트
```
---
## Kustomize 구조 설명
### Base 구조
Base는 모든 환경에서 공통으로 사용되는 기본 매니페스트입니다.
**주요 리소스:**
- **ConfigMap (cm-common)**: 환경 변수, 프로파일 설정
- **Secret (secret-common)**: JWT 시크릿, Redis 패스워드
- **Ingress**: API 라우팅 규칙
- **Deployment**: 각 서비스별 배포 설정
- **Service**: 각 서비스별 ClusterIP 서비스
- **Secret**: 각 서비스별 데이터베이스 연결 정보
### Overlay 구조
각 환경(dev/staging/prod)별로 Base를 오버라이드합니다.
#### DEV 환경
- **Replicas**: 1
- **Resources**: CPU 256m-1024m, Memory 256Mi-1024Mi
- **Profile**: dev
- **DDL**: update
- **Log Level**: DEBUG
- **Image Tag**: dev-{timestamp}
#### STAGING 환경
- **Replicas**: 2
- **Resources**: CPU 512m-2048m, Memory 512Mi-2048Mi
- **Profile**: staging
- **DDL**: validate
- **Log Level**: INFO
- **Image Tag**: staging-{timestamp}
- **SSL**: Enabled
#### PROD 환경
- **Replicas**: 3
- **Resources**: CPU 1024m-4096m, Memory 1024Mi-4096Mi
- **Profile**: prod
- **DDL**: validate
- **Log Level**: WARN
- **JWT Expiration**: 짧게 설정 (보안 강화)
- **Image Tag**: prod-{timestamp}
- **SSL**: Enabled
---
## GitHub Actions 워크플로우
### 트리거 조건
1. **Push 이벤트**:
- 브랜치: `main`, `develop`
- 경로: 서비스 코드 변경 시 (`user/**`, `meeting/**` 등)
2. **Pull Request**:
- 대상 브랜치: `main`
3. **수동 실행 (workflow_dispatch)**:
- Environment 선택: dev/staging/prod
- SonarQube 분석 스킵 선택: true/false
### 워크플로우 단계
#### 1. Build Job
1. 소스코드 체크아웃
2. JDK 21 설정
3. 환경 결정 (input 또는 기본값 dev)
4. Gradle 빌드 (테스트 제외)
5. SonarQube 분석 (선택적)
6. 빌드 아티팩트 업로드
7. 이미지 태그 생성 (타임스탬프 기반)
#### 2. Release Job
1. 빌드 아티팩트 다운로드
2. Docker Buildx 설정
3. Docker Hub 로그인 (Rate Limit 방지)
4. ACR 로그인
5. 각 서비스별 Docker 이미지 빌드 및 푸시
#### 3. Deploy Job
1. Azure CLI 설치 및 로그인
2. kubectl 설정
3. AKS Credentials 가져오기
4. 네임스페이스 생성
5. Kustomize 설치
6. 이미지 태그 업데이트
7. 매니페스트 적용
8. Deployment Ready 대기
---
## 배포 방법
### 1. 자동 배포 (Push/PR)
코드를 `main` 또는 `develop` 브랜치에 push하면 자동으로 dev 환경에 배포됩니다.
```bash
git add .
git commit -m "feat: 새로운 기능 추가"
git push origin develop
```
### 2. 수동 배포 (GitHub Actions UI)
1. GitHub Repository > Actions 탭 이동
2. "Backend Services CI/CD" 워크플로우 선택
3. "Run workflow" 버튼 클릭
4. 환경 선택 (dev/staging/prod)
5. SonarQube 분석 스킵 여부 선택
6. "Run workflow" 실행
### 3. 로컬에서 수동 배포
```bash
# 스크립트 실행 권한 확인
chmod +x .github/scripts/deploy-actions.sh
# DEV 환경에 배포 (기본)
./.github/scripts/deploy-actions.sh dev latest
# STAGING 환경에 특정 이미지 태그로 배포
./.github/scripts/deploy-actions.sh staging 20250127120000
# PROD 환경에 배포
./.github/scripts/deploy-actions.sh prod 20250127120000
```
---
## 롤백 방법
### 1. GitHub Actions를 통한 롤백
1. GitHub > Actions > 성공한 이전 워크플로우 선택
2. "Re-run all jobs" 클릭
3. 이전 버전으로 재배포됨
### 2. kubectl을 이용한 롤백
```bash
# 특정 Revision으로 롤백
kubectl rollout undo deployment/user -n hgzero --to-revision=2
# 이전 버전으로 롤백
kubectl rollout undo deployment/user -n hgzero
# 롤백 상태 확인
kubectl rollout status deployment/user -n hgzero
# Rollout 히스토리 확인
kubectl rollout history deployment/user -n hgzero
```
### 3. 수동 스크립트를 이용한 롤백
```bash
# 이전 안정 버전의 이미지 태그로 배포
./.github/scripts/deploy-actions.sh dev 20250126110000
```
---
## SonarQube 설정
### 프로젝트 생성
각 서비스별로 SonarQube 프로젝트를 생성하세요:
- hgzero-user-dev
- hgzero-meeting-dev
- hgzero-stt-dev
- hgzero-ai-dev
- hgzero-notification-dev
### Quality Gate 설정
기본 Quality Gate 설정:
- **Coverage**: >= 80%
- **Duplicated Lines**: <= 3%
- **Maintainability Rating**: <= A
- **Reliability Rating**: <= A
- **Security Rating**: <= A
### Gradle 설정 (이미 구성됨)
```gradle
// build.gradle
plugins {
id 'org.sonarqube' version '4.0.0.2929'
id 'jacoco'
}
sonarqube {
properties {
property "sonar.projectKey", "hgzero-${project.name}"
property "sonar.projectName", "hgzero-${project.name}"
}
}
jacocoTestReport {
reports {
xml.enabled true
}
}
```
---
## 트러블슈팅
### 1. 이미지 Pull 실패
**증상**: `ImagePullBackOff` 또는 `ErrImagePull`
**해결 방법**:
```bash
# ACR 로그인 테스트
az acr login --name acrdigitalgarage02
# Image Pull Secret 재생성
kubectl delete secret acr-secret -n hgzero
kubectl create secret docker-registry acr-secret \
--docker-server=acrdigitalgarage02.azurecr.io \
--docker-username=acrdigitalgarage02 \
--docker-password={ACR_PASSWORD} \
-n hgzero
```
### 2. Deployment 타임아웃
**증상**: `deployment "user" exceeded its progress deadline`
**해결 방법**:
```bash
# Pod 상태 확인
kubectl get pods -n hgzero
# Pod 로그 확인
kubectl logs -n hgzero {pod-name}
# Events 확인
kubectl describe pod -n hgzero {pod-name}
```
### 3. Health Check 실패
**증상**: Deployment가 Ready 상태로 전환되지 않음
**해결 방법**:
```bash
# Actuator health 엔드포인트 확인
kubectl exec -n hgzero {pod-name} -- curl http://localhost:8080/actuator/health
# 애플리케이션 로그 확인
kubectl logs -n hgzero {pod-name} -f
```
### 4. Kustomize 빌드 오류
**증상**: `kustomize build` 실패
**해결 방법**:
```bash
# 로컬에서 Kustomize 검증
kubectl kustomize .github/kustomize/overlays/dev
# YAML 문법 검증
yamllint .github/kustomize/overlays/dev/*.yaml
```
### 5. SonarQube 연결 실패
**증상**: SonarQube Analysis 단계에서 연결 오류
**해결 방법**:
1. SONAR_HOST_URL이 올바른지 확인
2. SONAR_TOKEN이 유효한지 확인
3. SonarQube 서비스 상태 확인:
```bash
kubectl get pods -n sonarqube
kubectl logs -n sonarqube {sonarqube-pod}
```
### 6. 환경 변수 로드 실패
**증상**: 환경 설정 파일을 찾을 수 없음
**해결 방법**:
```bash
# 파일 존재 확인
ls -la .github/config/
# 파일 내용 확인
cat .github/config/deploy_env_vars_dev
```
---
## 참고 자료
- [Kustomize 공식 문서](https://kustomize.io/)
- [GitHub Actions 문서](https://docs.github.com/en/actions)
- [Azure Container Registry 문서](https://docs.microsoft.com/en-us/azure/container-registry/)
- [AKS 문서](https://docs.microsoft.com/en-us/azure/aks/)
- [SonarQube 문서](https://docs.sonarqube.org/)
---
## 문의 및 지원
문제가 발생하거나 질문이 있으시면:
1. GitHub Issues에 등록
2. DevOps 팀에 문의 (송주영)
3. Slack #devops 채널
---
**작성일**: 2025-01-27
**작성자**: DevOps Team (주영)
**버전**: 1.0.0

3
.github/config/deploy_env_vars_dev vendored Normal file
View File

@ -0,0 +1,3 @@
# dev Environment Configuration
resource_group=rg-digitalgarage-02
cluster_name=aks-digitalgarage-02

3
.github/config/deploy_env_vars_prod vendored Normal file
View File

@ -0,0 +1,3 @@
# prod Environment Configuration
resource_group=rg-digitalgarage-02
cluster_name=aks-digitalgarage-02

View File

@ -0,0 +1,3 @@
# staging Environment Configuration
resource_group=rg-digitalgarage-02
cluster_name=aks-digitalgarage-02

View File

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai
labels:
app: ai
spec:
replicas: 1
selector:
matchLabels:
app: ai
template:
metadata:
labels:
app: ai
spec:
containers:
- name: ai
image: acrdigitalgarage02.azurecr.io/hgzero/ai:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: cm-common
- secretRef:
name: secret-common
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: secret-ai
key: DB_URL
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-ai
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-ai
key: DB_PASSWORD
resources:
requests:
cpu: 256m
memory: 256Mi
limits:
cpu: 1024m
memory: 1024Mi
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-ai
labels:
app: ai
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service:5432/aidb"
DB_USERNAME: "aiuser"
DB_PASSWORD: "aipass123"

15
.github/kustomize/base/ai/service.yaml vendored Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: ai
labels:
app: ai
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
selector:
app: ai

View File

@ -0,0 +1,25 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-common
data:
# Spring Profiles
SPRING_PROFILES_ACTIVE: "dev"
# Database Configuration
DDL_AUTO: "update"
SHOW_SQL: "true"
# JWT Configuration
JWT_ACCESS_TOKEN_EXPIRATION: "3600000" # 1 hour
JWT_REFRESH_TOKEN_EXPIRATION: "86400000" # 24 hours
# Logging Configuration
LOG_LEVEL: "INFO"
# Application Configuration
SERVER_PORT: "8080"
# Redis Configuration
REDIS_HOST: "redis-service"
REDIS_PORT: "6379"

View File

@ -0,0 +1,48 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hgzero
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- host: hgzero-api.20.214.196.128.nip.io
http:
paths:
- path: /api/users
pathType: Prefix
backend:
service:
name: user
port:
number: 8080
- path: /api/meetings
pathType: Prefix
backend:
service:
name: meeting
port:
number: 8080
- path: /api/stt
pathType: Prefix
backend:
service:
name: stt
port:
number: 8080
- path: /api/ai
pathType: Prefix
backend:
service:
name: ai
port:
number: 8080
- path: /api/notifications
pathType: Prefix
backend:
service:
name: notification
port:
number: 8080

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-common
type: Opaque
stringData:
# JWT Secret Key (Base64 encoded in production)
JWT_SECRET_KEY: "hgzero-jwt-secret-key-change-in-production"
# Redis Password
REDIS_PASSWORD: "redis-password-change-in-production"

View File

@ -0,0 +1,7 @@
apiVersion: v1
kind: Secret
metadata:
name: acr-secret
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: e30K

View File

@ -0,0 +1,49 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: hgzero-base
resources:
# Common resources
- common/cm-common.yaml
- common/secret-common.yaml
- common/secret-imagepull.yaml
- common/ingress.yaml
# User service
- user/deployment.yaml
- user/service.yaml
- user/secret-user.yaml
# Meeting service
- meeting/deployment.yaml
- meeting/service.yaml
- meeting/secret-meeting.yaml
# STT service
- stt/deployment.yaml
- stt/service.yaml
- stt/secret-stt.yaml
# AI service
- ai/deployment.yaml
- ai/service.yaml
- ai/secret-ai.yaml
# Notification service
- notification/deployment.yaml
- notification/service.yaml
- notification/secret-notification.yaml
images:
- name: acrdigitalgarage02.azurecr.io/hgzero/user
newTag: latest
- name: acrdigitalgarage02.azurecr.io/hgzero/meeting
newTag: latest
- name: acrdigitalgarage02.azurecr.io/hgzero/stt
newTag: latest
- name: acrdigitalgarage02.azurecr.io/hgzero/ai
newTag: latest
- name: acrdigitalgarage02.azurecr.io/hgzero/notification
newTag: latest

View File

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: meeting
labels:
app: meeting
spec:
replicas: 1
selector:
matchLabels:
app: meeting
template:
metadata:
labels:
app: meeting
spec:
containers:
- name: meeting
image: acrdigitalgarage02.azurecr.io/hgzero/meeting:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: cm-common
- secretRef:
name: secret-common
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: secret-meeting
key: DB_URL
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-meeting
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-meeting
key: DB_PASSWORD
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-meeting
type: Opaque
stringData:
# Meeting Service Database Configuration (Development)
DB_URL: "jdbc:postgresql://postgres-meeting:5432/meeting"
DB_USERNAME: "meeting_user"
DB_PASSWORD: "meeting_password"

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: meeting
labels:
app: meeting
spec:
type: ClusterIP
selector:
app: meeting
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http

View File

@ -0,0 +1,68 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: notification
labels:
app: notification
system: hgzero
spec:
replicas: 1
selector:
matchLabels:
app: notification
template:
metadata:
labels:
app: notification
system: hgzero
spec:
containers:
- name: notification
image: acrdigitalgarage02.azurecr.io/hgzero/notification:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: cm-common
- secretRef:
name: secret-common
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: secret-notification
key: DB_URL
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-notification
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-notification
key: DB_PASSWORD
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-notification
labels:
app: notification
system: hgzero
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service:5432/notification_db"
DB_USERNAME: "notification_user"
DB_PASSWORD: "notification_pass"

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: notification
labels:
app: notification
system: hgzero
spec:
type: ClusterIP
selector:
app: notification
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http

View File

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: stt
labels:
app: stt
spec:
replicas: 1
selector:
matchLabels:
app: stt
template:
metadata:
labels:
app: stt
spec:
containers:
- name: stt
image: acrdigitalgarage02.azurecr.io/hgzero/stt:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: cm-common
- secretRef:
name: secret-common
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: secret-stt
key: DB_URL
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-stt
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-stt
key: DB_PASSWORD
resources:
requests:
cpu: 256m
memory: 256Mi
limits:
cpu: 1024m
memory: 1024Mi
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-stt
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service:5432/sttdb"
DB_USERNAME: "sttuser"
DB_PASSWORD: "sttpass"

15
.github/kustomize/base/stt/service.yaml vendored Normal file
View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: stt
labels:
app: stt
spec:
type: ClusterIP
selector:
app: stt
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http

View File

@ -0,0 +1,66 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: user
labels:
app: user
spec:
replicas: 1
selector:
matchLabels:
app: user
template:
metadata:
labels:
app: user
spec:
containers:
- name: user
image: acrdigitalgarage02.azurecr.io/hgzero/user:latest
ports:
- containerPort: 8080
protocol: TCP
envFrom:
- configMapRef:
name: cm-common
- secretRef:
name: secret-common
env:
- name: DB_URL
valueFrom:
secretKeyRef:
name: secret-user
key: DB_URL
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: secret-user
key: DB_USERNAME
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: secret-user
key: DB_PASSWORD
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-user
labels:
app: user
type: Opaque
stringData:
DB_URL: "jdbc:mysql://mysql-user:3306/userdb?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"
DB_USERNAME: "user"
DB_PASSWORD: "user1234"

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: user
labels:
app: user
spec:
type: ClusterIP
selector:
app: user
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http

View File

@ -0,0 +1,18 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: cm-common
data:
# Spring Profiles
SPRING_PROFILES_ACTIVE: "dev"
# Database Configuration
DDL_AUTO: "update"
SHOW_SQL: "true"
# JWT Configuration
JWT_ACCESS_TOKEN_EXPIRATION: "3600000" # 1 hour
JWT_REFRESH_TOKEN_EXPIRATION: "86400000" # 24 hours
# Logging Configuration
LOG_LEVEL: "DEBUG"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai
spec:
replicas: 1
template:
spec:
containers:
- name: ai
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: meeting
spec:
replicas: 1
template:
spec:
containers:
- name: meeting
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: notification
spec:
replicas: 1
template:
spec:
containers:
- name: notification
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: stt
spec:
replicas: 1
template:
spec:
containers:
- name: stt
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: user
spec:
replicas: 1
template:
spec:
containers:
- name: user
resources:
requests:
cpu: "256m"
memory: "256Mi"
limits:
cpu: "1024m"
memory: "1024Mi"

View File

@ -0,0 +1,48 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hgzero
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
ingressClassName: nginx
rules:
- host: hgzero-api.20.214.196.128.nip.io
http:
paths:
- path: /api/users
pathType: Prefix
backend:
service:
name: user
port:
number: 8080
- path: /api/meetings
pathType: Prefix
backend:
service:
name: meeting
port:
number: 8080
- path: /api/stt
pathType: Prefix
backend:
service:
name: stt
port:
number: 8080
- path: /api/ai
pathType: Prefix
backend:
service:
name: ai
port:
number: 8080
- path: /api/notifications
pathType: Prefix
backend:
service:
name: notification
port:
number: 8080

View File

@ -0,0 +1,84 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: hgzero
resources:
- ../../base
patches:
# Common patches
- path: cm-common-patch.yaml
target:
kind: ConfigMap
name: cm-common
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: ingress-patch.yaml
target:
kind: Ingress
name: hgzero
# User service patches
- path: deployment-user-patch.yaml
target:
kind: Deployment
name: user
- path: secret-user-patch.yaml
target:
kind: Secret
name: secret-user
# Meeting service patches
- path: deployment-meeting-patch.yaml
target:
kind: Deployment
name: meeting
- path: secret-meeting-patch.yaml
target:
kind: Secret
name: secret-meeting
# STT service patches
- path: deployment-stt-patch.yaml
target:
kind: Deployment
name: stt
- path: secret-stt-patch.yaml
target:
kind: Secret
name: secret-stt
# AI service patches
- path: deployment-ai-patch.yaml
target:
kind: Deployment
name: ai
- path: secret-ai-patch.yaml
target:
kind: Secret
name: secret-ai
# Notification service patches
- path: deployment-notification-patch.yaml
target:
kind: Deployment
name: notification
- path: secret-notification-patch.yaml
target:
kind: Secret
name: secret-notification
images:
- name: acrdigitalgarage02.azurecr.io/hgzero/user
newTag: dev-latest
- name: acrdigitalgarage02.azurecr.io/hgzero/meeting
newTag: dev-latest
- name: acrdigitalgarage02.azurecr.io/hgzero/stt
newTag: dev-latest
- name: acrdigitalgarage02.azurecr.io/hgzero/ai
newTag: dev-latest
- name: acrdigitalgarage02.azurecr.io/hgzero/notification
newTag: dev-latest

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-ai
labels:
app: ai
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service-dev:5432/aidb_dev"
DB_USERNAME: "aiuser_dev"
DB_PASSWORD: "aipass_dev123"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-common
type: Opaque
stringData:
# JWT Secret Key (개발용)
JWT_SECRET_KEY: "hgzero-jwt-secret-key-change-in-production"
# Redis Password (개발용)
REDIS_PASSWORD: "redis-password-change-in-production"

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-meeting
type: Opaque
stringData:
# Meeting Service Database Configuration (Development)
DB_URL: "jdbc:postgresql://postgres-meeting-dev:5432/meeting_dev"
DB_USERNAME: "meeting_dev_user"
DB_PASSWORD: "meeting_dev_password"

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-notification
labels:
app: notification
system: hgzero
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service-dev:5432/notification_db_dev"
DB_USERNAME: "notification_dev_user"
DB_PASSWORD: "notification_dev_pass"

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-stt
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-service-dev:5432/sttdb_dev"
DB_USERNAME: "sttuser_dev"
DB_PASSWORD: "sttpass_dev"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-user
labels:
app: user
type: Opaque
stringData:
DB_URL: "jdbc:mysql://mysql-user-dev:3306/userdb_dev?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"
DB_USERNAME: "user_dev"
DB_PASSWORD: "user_dev1234"

View File

@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: common-config
namespace: hgzero
data:
SPRING_PROFILES_ACTIVE: "prod"
DDL_AUTO: "validate"
LOG_LEVEL: "WARN"
JWT_ACCESS_TOKEN_EXPIRATION: "1800000"
JWT_REFRESH_TOKEN_EXPIRATION: "43200000"
REDIS_HOST: "redis-svc.hgzero.svc.cluster.local"
REDIS_PORT: "6379"
KAFKA_BOOTSTRAP_SERVERS: "kafka-svc.hgzero.svc.cluster.local:9092"

View File

@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-deploy
namespace: hgzero
spec:
replicas: 3
template:
spec:
containers:
- name: ai-container
resources:
requests:
cpu: "1024m"
memory: "1024Mi"
limits:
cpu: "4096m"
memory: "4096Mi"

View File

@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: meeting-deploy
namespace: hgzero
spec:
replicas: 3
template:
spec:
containers:
- name: meeting-container
resources:
requests:
cpu: "1024m"
memory: "1024Mi"
limits:
cpu: "4096m"
memory: "4096Mi"

View File

@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: notification-deploy
namespace: hgzero
spec:
replicas: 3
template:
spec:
containers:
- name: notification-container
resources:
requests:
cpu: "1024m"
memory: "1024Mi"
limits:
cpu: "4096m"
memory: "4096Mi"

View File

@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: stt-deploy
namespace: hgzero
spec:
replicas: 3
template:
spec:
containers:
- name: stt-container
resources:
requests:
cpu: "1024m"
memory: "1024Mi"
limits:
cpu: "4096m"
memory: "4096Mi"

View File

@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-deploy
namespace: hgzero
spec:
replicas: 3
template:
spec:
containers:
- name: user-container
resources:
requests:
cpu: "1024m"
memory: "1024Mi"
limits:
cpu: "4096m"
memory: "4096Mi"

View File

@ -0,0 +1,49 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hgzero-ingress
namespace: hgzero
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
rules:
- host: hgzero-api.example.com
http:
paths:
- path: /user(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: user-svc
port:
number: 8080
- path: /meeting(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: meeting-svc
port:
number: 8081
- path: /stt(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: stt-svc
port:
number: 8082
- path: /ai(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: ai-svc
port:
number: 8083
- path: /notification(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: notification-svc
port:
number: 8084

View File

@ -0,0 +1,84 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: hgzero
bases:
- ../../base
patches:
# Common patches
- path: cm-common-patch.yaml
target:
kind: ConfigMap
name: common-config
- path: secret-common-patch.yaml
target:
kind: Secret
name: common-secret
- path: ingress-patch.yaml
target:
kind: Ingress
name: hgzero-ingress
# User service patches
- path: deployment-user-patch.yaml
target:
kind: Deployment
name: user-deploy
- path: secret-user-patch.yaml
target:
kind: Secret
name: user-secret
# Meeting service patches
- path: deployment-meeting-patch.yaml
target:
kind: Deployment
name: meeting-deploy
- path: secret-meeting-patch.yaml
target:
kind: Secret
name: meeting-secret
# STT service patches
- path: deployment-stt-patch.yaml
target:
kind: Deployment
name: stt-deploy
- path: secret-stt-patch.yaml
target:
kind: Secret
name: stt-secret
# AI service patches
- path: deployment-ai-patch.yaml
target:
kind: Deployment
name: ai-deploy
- path: secret-ai-patch.yaml
target:
kind: Secret
name: ai-secret
# Notification service patches
- path: deployment-notification-patch.yaml
target:
kind: Deployment
name: notification-deploy
- path: secret-notification-patch.yaml
target:
kind: Secret
name: notification-secret
images:
- name: user-service
newTag: prod-latest
- name: meeting-service
newTag: prod-latest
- name: stt-service
newTag: prod-latest
- name: ai-service
newTag: prod-latest
- name: notification-service
newTag: prod-latest

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: ai-secret
namespace: hgzero
type: Opaque
stringData:
OPENAI_API_KEY: "your-openai-api-key"
LANGCHAIN_API_KEY: "your-langchain-api-key"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: common-secret
namespace: hgzero
type: Opaque
stringData:
JWT_SECRET_KEY: "your-prod-secret-key-change-this-in-production"
REDIS_PASSWORD: "your-prod-redis-password"
KAFKA_USERNAME: "admin"
KAFKA_PASSWORD: "admin-secret"

View File

@ -0,0 +1,13 @@
apiVersion: v1
kind: Secret
metadata:
name: meeting-secret
namespace: hgzero
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-prod:5432/meeting_prod"
DB_USERNAME: "meeting_admin"
DB_PASSWORD: "meeting_prod_password"
OPENAI_API_KEY: "your-openai-api-key"
S3_ACCESS_KEY: "your-s3-access-key"
S3_SECRET_KEY: "your-s3-secret-key"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: notification-secret
namespace: hgzero
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-prod:5432/notification_prod"
DB_USERNAME: "notification_admin"
DB_PASSWORD: "notification_prod_password"
OPENAI_API_KEY: "your-openai-api-key"

View File

@ -0,0 +1,10 @@
apiVersion: v1
kind: Secret
metadata:
name: stt-secret
namespace: hgzero
type: Opaque
stringData:
OPENAI_API_KEY: "your-openai-api-key"
S3_ACCESS_KEY: "your-s3-access-key"
S3_SECRET_KEY: "your-s3-secret-key"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: user-secret
namespace: hgzero
type: Opaque
stringData:
DB_URL: "jdbc:postgresql://postgres-prod:5432/user_prod"
DB_USERNAME: "user_admin"
DB_PASSWORD: "user_prod_password"
OPENAI_API_KEY: "your-openai-api-key"

View File

@ -0,0 +1,99 @@
# STAGING Environment Kustomize Overlay
## 개요
STAGING 환경을 위한 Kustomize overlay 설정입니다.
## 환경 설정
### 네임스페이스
- `hgzero`
### 공통 설정
- **프로파일**: staging
- **DDL 모드**: validate
- **로그 레벨**: INFO
- **Ingress 호스트**: hgzero-staging-api.example.com
- **SSL 리다이렉트**: 활성화
### 리소스 설정
- **Replicas**: 2
- **Resource Requests**:
- CPU: 512m
- Memory: 512Mi
- **Resource Limits**:
- CPU: 2048m
- Memory: 2048Mi
## 생성된 파일 목록 (총 14개)
### Common Patches (3개)
1. `cm-common-patch.yaml` - 공통 ConfigMap 패치
2. `secret-common-patch.yaml` - 공통 Secret 패치 (JWT, Redis)
3. `ingress-patch.yaml` - Ingress 패치 (호스트, SSL)
### Service-specific Patches (10개)
각 서비스(user, meeting, stt, ai, notification)별 2개 파일:
- `deployment-{서비스명}-patch.yaml` - Deployment 리소스 패치
- `secret-{서비스명}-patch.yaml` - DB 연결 정보 패치
4. `deployment-user-patch.yaml`
5. `secret-user-patch.yaml`
6. `deployment-meeting-patch.yaml`
7. `secret-meeting-patch.yaml`
8. `deployment-stt-patch.yaml`
9. `secret-stt-patch.yaml`
10. `deployment-ai-patch.yaml`
11. `secret-ai-patch.yaml`
12. `deployment-notification-patch.yaml`
13. `secret-notification-patch.yaml`
### Kustomization (1개)
14. `kustomization.yaml` - Kustomize 설정 파일
## 데이터베이스 설정
각 서비스별 STAGING 환경 DB 정보:
- **호스트**: {서비스명}-db-staging
- **포트**: 5432
- **데이터베이스명**: {서비스명}_db_staging
- **사용자명**: {서비스명}_service
- **비밀번호**: stringData로 정의 (실제 환경에서 변경 필요)
## 이미지 태그
모든 서비스: `staging-latest`
## 사용 방법
### 1. Kustomize 빌드 확인
```bash
kubectl kustomize .github/kustomize/overlays/staging
```
### 2. STAGING 환경 배포
```bash
kubectl apply -k .github/kustomize/overlays/staging
```
### 3. 배포 상태 확인
```bash
kubectl get all -n hgzero
```
### 4. Secret 업데이트 (실제 배포 시)
```bash
# Secret 파일들의 stringData를 실제 STAGING 환경 값으로 변경
vi .github/kustomize/overlays/staging/secret-common-patch.yaml
vi .github/kustomize/overlays/staging/secret-user-patch.yaml
# ... (각 서비스별 secret 파일 수정)
```
## 주의사항
1. Secret 파일들의 비밀번호는 반드시 실제 환경에 맞게 변경해야 합니다
2. Ingress 호스트명을 실제 STAGING 도메인으로 변경해야 합니다
3. DB 호스트명이 실제 STAGING 환경과 일치하는지 확인해야 합니다
4. 리소스 제한은 실제 부하 테스트 결과에 따라 조정이 필요할 수 있습니다
## 다음 단계
- PROD 환경 overlay 생성
- CI/CD 파이프라인과 통합
- Monitoring 및 Logging 설정 추가

View File

@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: hgzero-common-config
data:
SPRING_PROFILES_ACTIVE: "staging"
DDL_AUTO: "validate"
LOG_LEVEL: "INFO"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ai-service
spec:
replicas: 2
template:
spec:
containers:
- name: ai-service
resources:
requests:
memory: "512Mi"
cpu: "512m"
limits:
memory: "2048Mi"
cpu: "2048m"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: meeting-service
spec:
replicas: 2
template:
spec:
containers:
- name: meeting-service
resources:
requests:
memory: "512Mi"
cpu: "512m"
limits:
memory: "2048Mi"
cpu: "2048m"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: notification-service
spec:
replicas: 2
template:
spec:
containers:
- name: notification-service
resources:
requests:
memory: "512Mi"
cpu: "512m"
limits:
memory: "2048Mi"
cpu: "2048m"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: stt-service
spec:
replicas: 2
template:
spec:
containers:
- name: stt-service
resources:
requests:
memory: "512Mi"
cpu: "512m"
limits:
memory: "2048Mi"
cpu: "2048m"

View File

@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 2
template:
spec:
containers:
- name: user-service
resources:
requests:
memory: "512Mi"
cpu: "512m"
limits:
memory: "2048Mi"
cpu: "2048m"

View File

@ -0,0 +1,46 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hgzero-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
rules:
- host: hgzero-staging-api.example.com
http:
paths:
- path: /api/users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- path: /api/meetings
pathType: Prefix
backend:
service:
name: meeting-service
port:
number: 8080
- path: /api/stt
pathType: Prefix
backend:
service:
name: stt-service
port:
number: 8080
- path: /api/ai
pathType: Prefix
backend:
service:
name: ai-service
port:
number: 8080
- path: /api/notifications
pathType: Prefix
backend:
service:
name: notification-service
port:
number: 8080

View File

@ -0,0 +1,91 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: hgzero
resources:
- ../../base
patches:
# Common patches
- path: cm-common-patch.yaml
target:
kind: ConfigMap
name: hgzero-common-config
- path: secret-common-patch.yaml
target:
kind: Secret
name: hgzero-common-secret
- path: ingress-patch.yaml
target:
kind: Ingress
name: hgzero-ingress
# User service patches
- path: deployment-user-patch.yaml
target:
kind: Deployment
name: user-service
- path: secret-user-patch.yaml
target:
kind: Secret
name: user-service-secret
# Meeting service patches
- path: deployment-meeting-patch.yaml
target:
kind: Deployment
name: meeting-service
- path: secret-meeting-patch.yaml
target:
kind: Secret
name: meeting-service-secret
# STT service patches
- path: deployment-stt-patch.yaml
target:
kind: Deployment
name: stt-service
- path: secret-stt-patch.yaml
target:
kind: Secret
name: stt-service-secret
# AI service patches
- path: deployment-ai-patch.yaml
target:
kind: Deployment
name: ai-service
- path: secret-ai-patch.yaml
target:
kind: Secret
name: ai-service-secret
# Notification service patches
- path: deployment-notification-patch.yaml
target:
kind: Deployment
name: notification-service
- path: secret-notification-patch.yaml
target:
kind: Secret
name: notification-service-secret
images:
- name: user-service
newTag: staging-latest
- name: meeting-service
newTag: staging-latest
- name: stt-service
newTag: staging-latest
- name: ai-service
newTag: staging-latest
- name: notification-service
newTag: staging-latest

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: ai-service-secret
type: Opaque
stringData:
DB_HOST: "ai-db-staging"
DB_PORT: "5432"
DB_NAME: "ai_db_staging"
DB_USERNAME: "ai_service"
DB_PASSWORD: "your-staging-ai-db-password"

View File

@ -0,0 +1,9 @@
apiVersion: v1
kind: Secret
metadata:
name: hgzero-common-secret
type: Opaque
stringData:
JWT_SECRET: "your-staging-jwt-secret-key-here-change-in-production"
JWT_EXPIRATION: "3600000"
REDIS_PASSWORD: "your-staging-redis-password"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: meeting-service-secret
type: Opaque
stringData:
DB_HOST: "meeting-db-staging"
DB_PORT: "5432"
DB_NAME: "meeting_db_staging"
DB_USERNAME: "meeting_service"
DB_PASSWORD: "your-staging-meeting-db-password"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: notification-service-secret
type: Opaque
stringData:
DB_HOST: "notification-db-staging"
DB_PORT: "5432"
DB_NAME: "notification_db_staging"
DB_USERNAME: "notification_service"
DB_PASSWORD: "your-staging-notification-db-password"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: stt-service-secret
type: Opaque
stringData:
DB_HOST: "stt-db-staging"
DB_PORT: "5432"
DB_NAME: "stt_db_staging"
DB_USERNAME: "stt_service"
DB_PASSWORD: "your-staging-stt-db-password"

View File

@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: user-service-secret
type: Opaque
stringData:
DB_HOST: "user-db-staging"
DB_PORT: "5432"
DB_NAME: "user_db_staging"
DB_USERNAME: "user_service"
DB_PASSWORD: "your-staging-user-db-password"

69
.github/scripts/deploy-actions.sh vendored Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
set -e
ENVIRONMENT=${1:-dev}
IMAGE_TAG=${2:-latest}
echo "🚀 Manual deployment starting..."
echo "Environment: $ENVIRONMENT"
echo "Image Tag: $IMAGE_TAG"
# Check if kustomize is installed
if ! command -v kustomize &> /dev/null; then
echo "Installing Kustomize..."
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
fi
# Load environment variables from .github/config
if [[ -f ".github/config/deploy_env_vars_${ENVIRONMENT}" ]]; then
source ".github/config/deploy_env_vars_${ENVIRONMENT}"
echo "✅ Environment variables loaded for $ENVIRONMENT"
else
echo "❌ Environment configuration file not found: .github/config/deploy_env_vars_${ENVIRONMENT}"
exit 1
fi
# Create namespace
echo "📝 Creating namespace hgzero..."
kubectl create namespace hgzero --dry-run=client -o yaml | kubectl apply -f -
# 환경별 이미지 태그 업데이트 (.github/kustomize 사용)
cd .github/kustomize/overlays/${ENVIRONMENT}
echo "🔄 Updating image tags..."
# 서비스 배열 정의
services=(user meeting stt ai notification)
# 각 서비스별 이미지 태그 업데이트
for service in "${services[@]}"; do
kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/$service:${ENVIRONMENT}-${IMAGE_TAG}
done
echo "🚀 Deploying to Kubernetes..."
# 배포 실행
kubectl apply -k .
echo "⏳ Waiting for deployments to be ready..."
# 서비스별 배포 상태 확인
for service in "${services[@]}"; do
kubectl rollout status deployment/$service -n hgzero --timeout=300s || echo "⚠️ $service deployment timeout"
done
echo "🔍 Health check..."
# 각 서비스의 Health Check
for service in "${services[@]}"; do
POD=$(kubectl get pod -n hgzero -l app.kubernetes.io/name=$service -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
if [[ -n "$POD" ]]; then
kubectl -n hgzero exec $POD -- curl -f http://localhost:8080/actuator/health 2>/dev/null || echo "⚠️ $service health check failed"
else
echo "⚠️ $service pod not found"
fi
done
echo "📋 Service Information:"
kubectl get pods -n hgzero
kubectl get services -n hgzero
kubectl get ingress -n hgzero
echo "✅ GitHub Actions deployment completed successfully!"

276
.github/workflows/backend-cicd.yaml vendored Normal file
View File

@ -0,0 +1,276 @@
name: Backend Services CI/CD
on:
push:
branches: [ main, develop ]
paths:
- 'user/**'
- 'meeting/**'
- 'stt/**'
- 'ai/**'
- 'notification/**'
- 'common/**'
- '.github/**'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- staging
- prod
SKIP_SONARQUBE:
description: 'Skip SonarQube Analysis'
required: false
default: 'true'
type: choice
options:
- 'true'
- 'false'
env:
REGISTRY: acrdigitalgarage02.azurecr.io
IMAGE_ORG: hgzero
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 JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
cache: 'gradle'
- name: Determine environment
id: determine_env
run: |
# Use input parameter or default to 'dev'
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 }}
# Initialize variables with defaults
REGISTRY="acrdigitalgarage02.azurecr.io"
IMAGE_ORG="hgzero"
RESOURCE_GROUP="rg-digitalgarage-02"
AKS_CLUSTER="aks-digitalgarage-02"
NAMESPACE="hgzero"
# Read environment variables from .github/config file
if [[ -f ".github/config/deploy_env_vars_${ENV}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Extract key-value pairs
key=$(echo "$line" | cut -d '=' -f1)
value=$(echo "$line" | cut -d '=' -f2-)
# Override defaults if found in config
case "$key" in
"resource_group") RESOURCE_GROUP="$value" ;;
"cluster_name") AKS_CLUSTER="$value" ;;
esac
done < ".github/config/deploy_env_vars_${ENV}"
fi
# Export for other jobs
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: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: |
./gradlew build -x test
- name: SonarQube Analysis & Quality Gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
run: |
# Check if SonarQube should be skipped
SKIP_SONARQUBE="${{ github.event.inputs.SKIP_SONARQUBE || 'true' }}"
if [[ "$SKIP_SONARQUBE" == "true" ]]; then
echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=$SKIP_SONARQUBE)"
exit 0
fi
# Define services array
services=(user meeting stt ai notification)
# Run tests, coverage reports, and SonarQube analysis for each service
for service in "${services[@]}"; do
./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \
-Dsonar.projectKey=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.projectName=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.host.url=$SONAR_HOST_URL \
-Dsonar.token=$SONAR_TOKEN \
-Dsonar.java.binaries=build/classes/java/main \
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \
-Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/**
done
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: app-builds
path: |
user/build/libs/*.jar
meeting/build/libs/*.jar
stt/build/libs/*.jar
ai/build/libs/*.jar
notification/build/libs/*.jar
- name: Set outputs
id: set_outputs
run: |
# Generate timestamp for image tag
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 Images
needs: build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: app-builds
- name: Set environment variables from build job
run: |
echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV
echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $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 images for all services
run: |
# Define services array
services=(user meeting stt ai notification)
# Build and push each service image
for service in "${services[@]}"; do
echo "Building and pushing $service..."
docker build \
--build-arg BUILD_LIB_DIR="$service/build/libs" \
--build-arg ARTIFACTORY_FILE="$service.jar" \
-f deployment/container/Dockerfile-backend \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} .
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
done
deploy:
name: Deploy to Kubernetes
needs: [build, release]
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- 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: Install Azure CLI
run: |
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Setup kubectl
uses: azure/setup-kubectl@v3
- name: Get AKS Credentials
run: |
az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP }} --name ${{ env.AKS_CLUSTER }} --overwrite-existing
- name: Create namespace
run: |
kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | kubectl apply -f -
- name: Install Kustomize
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
- name: Update Kustomize images and deploy
run: |
# 환경별 디렉토리로 이동
cd .github/kustomize/overlays/${{ env.ENVIRONMENT }}
# 각 서비스별 이미지 태그 업데이트
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/user:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/meeting:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/stt:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/ai:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/notification:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
# 매니페스트 적용
kubectl apply -k .
- name: Wait for deployments to be ready
run: |
echo "Waiting for deployments to be ready..."
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/user --timeout=300s || true
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/meeting --timeout=300s || true
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/stt --timeout=300s || true
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/ai --timeout=300s || true
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/notification --timeout=300s || true

View File

@ -0,0 +1,254 @@
name: Backend Services CI/CD
on:
push:
branches: [ main, develop ]
paths:
- 'user/**'
- 'meeting/**'
- 'stt/**'
- 'ai/**'
- 'notification/**'
- 'common/**'
- '.github/**'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- staging
- prod
SKIP_SONARQUBE:
description: 'Skip SonarQube Analysis'
required: false
default: 'true'
type: choice
options:
- 'true'
- 'false'
env:
REGISTRY: acrdigitalgarage02.azurecr.io
IMAGE_ORG: hgzero
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 JDK 21
uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
cache: 'gradle'
- name: Determine environment
id: determine_env
run: |
# Use input parameter or default to 'dev'
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 }}
# Initialize variables with defaults
REGISTRY="acrdigitalgarage02.azurecr.io"
IMAGE_ORG="hgzero"
RESOURCE_GROUP="rg-digitalgarage-02"
AKS_CLUSTER="aks-digitalgarage-02"
NAMESPACE="hgzero"
# Read environment variables from .github/config file
if [[ -f ".github/config/deploy_env_vars_${ENV}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Extract key-value pairs
key=$(echo "$line" | cut -d '=' -f1)
value=$(echo "$line" | cut -d '=' -f2-)
# Override defaults if found in config
case "$key" in
"resource_group") RESOURCE_GROUP="$value" ;;
"cluster_name") AKS_CLUSTER="$value" ;;
esac
done < ".github/config/deploy_env_vars_${ENV}"
fi
# Export for other jobs
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: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: |
./gradlew build -x test
- name: SonarQube Analysis & Quality Gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
run: |
# Check if SonarQube should be skipped
SKIP_SONARQUBE="${{ github.event.inputs.SKIP_SONARQUBE || 'true' }}"
if [[ "$SKIP_SONARQUBE" == "true" ]]; then
echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=$SKIP_SONARQUBE)"
exit 0
fi
# Define services array
services=(user meeting stt ai notification)
# Run tests, coverage reports, and SonarQube analysis for each service
for service in "${services[@]}"; do
./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \
-Dsonar.projectKey=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.projectName=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.host.url=$SONAR_HOST_URL \
-Dsonar.token=$SONAR_TOKEN \
-Dsonar.java.binaries=build/classes/java/main \
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \
-Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/**
done
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: app-builds
path: |
user/build/libs/*.jar
meeting/build/libs/*.jar
stt/build/libs/*.jar
ai/build/libs/*.jar
notification/build/libs/*.jar
- name: Set outputs
id: set_outputs
run: |
# Generate timestamp for image tag
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 Images
needs: build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: app-builds
- name: Set environment variables from build job
run: |
echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV
echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $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 images for all services
run: |
# Define services array
services=(user meeting stt ai notification)
# Build and push each service image
for service in "${services[@]}"; do
echo "Building and pushing $service..."
docker build \
--build-arg BUILD_LIB_DIR="$service/build/libs" \
--build-arg ARTIFACTORY_FILE="$service.jar" \
-f deployment/container/Dockerfile-backend \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} .
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
done
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 }}
# 각 서비스별 이미지 태그 업데이트
services="user meeting stt ai notification"
for service in $services; do
kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/$service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
done
# Git 설정 및 푸시
cd ../../../..
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git add .
git commit -m "🚀 Update hgzero ${{ env.ENVIRONMENT }} images to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}"
git push origin main
echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."

View File

@ -284,3 +284,729 @@ This generated password is for development use only. Your security configuration
2025-10-24 09:46:36 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@35883f25] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@139da216] 2025-10-24 09:46:36 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@35883f25] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@139da216]
2025-10-24 09:46:36 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated... 2025-10-24 09:46:36 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-24 09:46:36 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed. 2025-10-24 09:46:36 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-27 15:56:01 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 21.0.8 with PID 79883 (/Users/adela/home/workspace/recent/HGZero/ai/build/classes/java/main started by adela in /Users/adela/home/workspace/recent/HGZero/ai)
2025-10-27 15:56:01 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.5, Spring v6.1.14
2025-10-27 15:56:01 [main] INFO com.unicorn.hgzero.ai.AiApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-27 15:56:01 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:56:01 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-27 15:56:02 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 75 ms. Found 1 JPA repository interface.
2025-10-27 15:56:02 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:56:02 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-27 15:56:02 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.ai.infra.gateway.repository.ProcessedTranscriptJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-27 15:56:02 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
2025-10-27 15:56:02 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8083 (http)
2025-10-27 15:56:02 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-27 15:56:02 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.31]
2025-10-27 15:56:02 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-27 15:56:02 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1140 ms
2025-10-27 15:56:02 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-27 15:56:02 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.3.Final
2025-10-27 15:56:02 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@7c03f9d0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@7c03f9d0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@7c03f9d0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@6ad3fbe4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@6ad3fbe4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@17189618
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@17189618
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@983050b
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@983050b
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@6aadb092
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@6aadb092
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@6aadb092
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@1f547af8
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@1f547af8
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@1f547af8
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@4caf875c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@4caf875c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@5d15789f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@5abb7a8f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@5abb7a8f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@6684589a
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@5621a671
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@4cf5d999
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@4cf5d999
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@4bdef487
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@4bdef487
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@3e595da3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@5c0272e0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@5c0272e0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@60c4cf2b
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@6614ecca
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@43e7f104
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@7294a684
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@2762253e
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@6651efa4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@1ac25dbb
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@1ac25dbb
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@4db568e1
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@4db568e1
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@7bc8ffbc
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@7bc8ffbc
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@120d13ae
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@120d13ae
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@1aaaabd1
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@1aaaabd1
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@7cbe3a05
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@40b70f31
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@3adde4ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@3adde4ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@75663443
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@780546f8
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@b3004e
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@559c4e06
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@559c4e06
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@111cbcda
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@437c1a87
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@5b55c3d6
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@5b55c3d6
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@6c8e5ac4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@6c8e5ac4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@1800c1e3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@1800c1e3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@1800c1e3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@3b8b4846
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@3b8b4846
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@3b8b4846
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@4e357792
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@50734cea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@4e6280de
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@4e6280de
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@2fca282c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@2fca282c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@2fca282c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@4a2653a0
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@784212
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@5ac646b3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@5ac646b3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@24b38e8f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@24b38e8f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@24b38e8f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@5cf072ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@5cf072ea
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@1edac3b4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@1edac3b4
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@7641ed02
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@7641ed02
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@4ebed2b3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@4ebed2b3
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@11069eac
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@11069eac
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@5909285b
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@2059f785
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@52a75c12
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@52a75c12
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@7f894a6f
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@3d05435c
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@1b732dd
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@3458dab6
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@23d060c2
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@59278072
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@61be6051
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@13c18bba
2025-10-27 15:56:02 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@33373f70
2025-10-27 15:56:02 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-27 15:56:02 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-27 15:56:03 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@5300694d
2025-10-27 15:56:03 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2025-10-27 15:56:03 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(2003, org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@483fe83a) replaced previous registration(org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@16120270)
2025-10-27 15:56:03 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(6, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@74babce8) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@1fab0394)
2025-10-27 15:56:03 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2004, BlobTypeDescriptor(BLOB_BINDING)) replaced previous registration(BlobTypeDescriptor(DEFAULT))
2025-10-27 15:56:03 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2005, ClobTypeDescriptor(CLOB_BINDING)) replaced previous registration(ClobTypeDescriptor(DEFAULT))
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration JAVA_OBJECT -> org.hibernate.type.JavaObjectType@5cc152f9
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@5cc152f9
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Type registration key [java.lang.Object] overrode previous entry : `org.hibernate.type.JavaObjectType@52a75c12`
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.DurationType -> basicType@1(java.time.Duration,3015)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetDateTimeType -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.ZonedDateTimeType -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetTimeType -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:56:03 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:56:03 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@5adc71e7] to MetadataBuildingContext [org.hibernate.boot.internal.MetadataBuildingContextRootImpl@7fc5a558]
2025-10-27 15:56:03 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-10-27 15:56:03 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@5adc71e7] to SessionFactoryImplementor [org.hibernate.internal.SessionFactoryImpl@2438a038]
2025-10-27 15:56:03 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column decisions set data type TEXT
2025-10-27 15:56:03 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column discussions set data type TEXT
2025-10-27 15:56:03 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column pending_items set data type TEXT
2025-10-27 15:56:03 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column summary set data type TEXT
2025-10-27 15:56:03 [main] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@2438a038] for TypeConfiguration
2025-10-27 15:56:03 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:56:04 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-10-27 15:56:04 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: abe7cc82-6f4c-4133-9ef1-00a2d943f75c
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-27 15:56:04 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-10-27 15:56:04 [main] ERROR i.n.r.d.DnsServerAddressStreamProviders - Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'. Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError: failed to load the required native library
2025-10-27 15:56:04 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 3 endpoints beneath base path '/actuator'
2025-10-27 15:56:04 [main] DEBUG o.s.s.web.DefaultSecurityFilterChain - Will secure any request with filters: DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, CorsFilter, LogoutFilter, JwtAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter
2025-10-27 15:56:05 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 8083 (http) with context path '/'
2025-10-27 15:56:05 [main] INFO com.unicorn.hgzero.ai.AiApplication - Started AiApplication in 3.968 seconds (process running for 4.195)
2025-10-27 15:56:12 [http-nio-8083-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-27 15:56:12 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-27 15:56:12 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms
2025-10-27 15:56:12 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.html
2025-10-27 15:56:12 [http-nio-8083-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.html
2025-10-27 15:56:12 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui.css
2025-10-27 15:56:12 [http-nio-8083-exec-2] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui.css
2025-10-27 15:56:12 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.css
2025-10-27 15:56:12 [http-nio-8083-exec-3] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:56:12 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.css
2025-10-27 15:56:12 [http-nio-8083-exec-4] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:56:12 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-initializer.js
2025-10-27 15:56:12 [http-nio-8083-exec-6] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-initializer.js
2025-10-27 15:56:12 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:56:12 [http-nio-8083-exec-5] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:56:12 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs/swagger-config
2025-10-27 15:56:12 [http-nio-8083-exec-7] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs/swagger-config
2025-10-27 15:56:12 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@3c5248f7]]
2025-10-27 15:56:12 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 완료 - 실행시간: 0ms
2025-10-27 15:56:12 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs
2025-10-27 15:56:12 [http-nio-8083-exec-8] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:56:12 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs
2025-10-27 15:56:12 [http-nio-8083-exec-8] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@2f1c3c44], /v3/api-docs, ko_KR]
2025-10-27 15:56:12 [http-nio-8083-exec-8] INFO o.s.api.AbstractOpenApiResource - Init duration for springdoc-openapi is: 241 ms
2025-10-27 15:56:12 [http-nio-8083-exec-8] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 완료 - 실행시간: 251ms
2025-10-27 15:58:44 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:58:44 [SpringApplicationShutdownHook] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryClosed from [org.hibernate.internal.SessionFactoryImpl@2438a038] for TypeConfiguration
2025-10-27 15:58:44 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@33940bc6] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@2438a038]
2025-10-27 15:58:44 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-27 15:58:44 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-27 15:58:47 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 21.0.8 with PID 80239 (/Users/adela/home/workspace/recent/HGZero/ai/build/classes/java/main started by adela in /Users/adela/home/workspace/recent/HGZero/ai)
2025-10-27 15:58:47 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.5, Spring v6.1.14
2025-10-27 15:58:47 [main] INFO com.unicorn.hgzero.ai.AiApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 80 ms. Found 1 JPA repository interface.
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.ai.infra.gateway.repository.ProcessedTranscriptJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-27 15:58:47 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
2025-10-27 15:58:48 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8083 (http)
2025-10-27 15:58:48 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-27 15:58:48 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.31]
2025-10-27 15:58:48 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-27 15:58:48 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1087 ms
2025-10-27 15:58:48 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-27 15:58:48 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.3.Final
2025-10-27 15:58:48 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@5621a671
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@5621a671
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@5621a671
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@4cf5d999
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@4cf5d999
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@4bdef487
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@3e595da3
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@5c0272e0
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@60c4cf2b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@60c4cf2b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@60c4cf2b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@6614ecca
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@43e7f104
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@43e7f104
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@7294a684
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@2762253e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@2762253e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@2762253e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@6651efa4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@1ac25dbb
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@4db568e1
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@7bc8ffbc
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@7bc8ffbc
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@120d13ae
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@120d13ae
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@1aaaabd1
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@7cbe3a05
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@40b70f31
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@3adde4ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@75663443
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@780546f8
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@b3004e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@b3004e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@559c4e06
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@559c4e06
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@111cbcda
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@111cbcda
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@437c1a87
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@437c1a87
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@5b55c3d6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@5b55c3d6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@6c8e5ac4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@1800c1e3
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@3b8b4846
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@3b8b4846
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@4e357792
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@50734cea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@4e6280de
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@2fca282c
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@2fca282c
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@4a2653a0
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@784212
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@5ac646b3
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@5ac646b3
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@24b38e8f
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@24b38e8f
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@5cf072ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@5cf072ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@5cf072ea
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@1edac3b4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@1edac3b4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@1edac3b4
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@7641ed02
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@4ebed2b3
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@11069eac
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@11069eac
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@5909285b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@5909285b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@5909285b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@2059f785
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@18ca9277
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@3d9c8c3c
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@3d9c8c3c
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@2dc73024
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@2dc73024
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@2dc73024
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@42cd0fc6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@42cd0fc6
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@e5864c2
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@e5864c2
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@577cf459
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@577cf459
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@432eb882
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@432eb882
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@69372c1e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@69372c1e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@24842b8e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@146add7b
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@72b1df49
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@72b1df49
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@56f61d74
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@44d84313
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@511de4dd
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@37e64e37
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@31204303
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@369fb99a
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@81a8898
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@d08f85a
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@3e839aa3
2025-10-27 15:58:48 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-27 15:58:48 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-27 15:58:48 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@6dfebd2a
2025-10-27 15:58:48 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2025-10-27 15:58:48 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(2003, org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@361c4981) replaced previous registration(org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@35fac3ba)
2025-10-27 15:58:48 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(6, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@50a095cb) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@3f2afa8b)
2025-10-27 15:58:48 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2004, BlobTypeDescriptor(BLOB_BINDING)) replaced previous registration(BlobTypeDescriptor(DEFAULT))
2025-10-27 15:58:48 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2005, ClobTypeDescriptor(CLOB_BINDING)) replaced previous registration(ClobTypeDescriptor(DEFAULT))
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration JAVA_OBJECT -> org.hibernate.type.JavaObjectType@5002be8e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@5002be8e
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Type registration key [java.lang.Object] overrode previous entry : `org.hibernate.type.JavaObjectType@72b1df49`
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.DurationType -> basicType@1(java.time.Duration,3015)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetDateTimeType -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.ZonedDateTimeType -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetTimeType -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:58:48 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:58:48 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@2fe38b73] to MetadataBuildingContext [org.hibernate.boot.internal.MetadataBuildingContextRootImpl@511a307e]
2025-10-27 15:58:49 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-10-27 15:58:49 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@2fe38b73] to SessionFactoryImplementor [org.hibernate.internal.SessionFactoryImpl@77d7d2d0]
2025-10-27 15:58:49 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column decisions set data type TEXT
2025-10-27 15:58:49 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column discussions set data type TEXT
2025-10-27 15:58:49 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column pending_items set data type TEXT
2025-10-27 15:58:49 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column summary set data type TEXT
2025-10-27 15:58:49 [main] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@77d7d2d0] for TypeConfiguration
2025-10-27 15:58:49 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:58:49 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-10-27 15:58:49 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: 77c151a9-73b9-46a6-8526-20c751151a64
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-27 15:58:49 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-10-27 15:58:50 [main] ERROR i.n.r.d.DnsServerAddressStreamProviders - Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'. Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError: failed to load the required native library
2025-10-27 15:58:50 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 3 endpoints beneath base path '/actuator'
2025-10-27 15:58:50 [main] DEBUG o.s.s.web.DefaultSecurityFilterChain - Will secure any request with filters: DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, CorsFilter, LogoutFilter, JwtAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter
2025-10-27 15:58:50 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 8083 (http) with context path '/'
2025-10-27 15:58:50 [main] INFO com.unicorn.hgzero.ai.AiApplication - Started AiApplication in 3.766 seconds (process running for 3.93)
2025-10-27 15:58:51 [http-nio-8083-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-27 15:58:51 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-27 15:58:51 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms
2025-10-27 15:58:51 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.html
2025-10-27 15:58:51 [http-nio-8083-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.html
2025-10-27 15:58:51 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui.css
2025-10-27 15:58:51 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.css
2025-10-27 15:58:51 [http-nio-8083-exec-2] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-3] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui.css
2025-10-27 15:58:51 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.css
2025-10-27 15:58:51 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:58:51 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:58:51 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-initializer.js
2025-10-27 15:58:51 [http-nio-8083-exec-4] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-6] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-5] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:58:51 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:58:51 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-initializer.js
2025-10-27 15:58:51 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/favicon-32x32.png
2025-10-27 15:58:51 [http-nio-8083-exec-8] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs/swagger-config
2025-10-27 15:58:51 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/favicon-32x32.png
2025-10-27 15:58:51 [http-nio-8083-exec-7] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs/swagger-config
2025-10-27 15:58:51 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@52d9a152]]
2025-10-27 15:58:51 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 완료 - 실행시간: 1ms
2025-10-27 15:58:51 [http-nio-8083-exec-9] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs
2025-10-27 15:58:51 [http-nio-8083-exec-9] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:58:51 [http-nio-8083-exec-9] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs
2025-10-27 15:58:51 [http-nio-8083-exec-9] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@17c260bc], /v3/api-docs, ko_KR]
2025-10-27 15:58:51 [http-nio-8083-exec-9] INFO o.s.api.AbstractOpenApiResource - Init duration for springdoc-openapi is: 223 ms
2025-10-27 15:58:51 [http-nio-8083-exec-9] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 완료 - 실행시간: 235ms
2025-10-27 15:59:04 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:59:04 [SpringApplicationShutdownHook] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryClosed from [org.hibernate.internal.SessionFactoryImpl@77d7d2d0] for TypeConfiguration
2025-10-27 15:59:04 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@5ffe7aa8] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@77d7d2d0]
2025-10-27 15:59:04 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-27 15:59:04 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-27 15:59:07 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 21.0.8 with PID 80306 (/Users/adela/home/workspace/recent/HGZero/ai/build/classes/java/main started by adela in /Users/adela/home/workspace/recent/HGZero/ai)
2025-10-27 15:59:07 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.5, Spring v6.1.14
2025-10-27 15:59:07 [main] INFO com.unicorn.hgzero.ai.AiApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 119 ms. Found 1 JPA repository interface.
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.ai.infra.gateway.repository.ProcessedTranscriptJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-27 15:59:08 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
2025-10-27 15:59:09 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8083 (http)
2025-10-27 15:59:09 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-27 15:59:09 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.31]
2025-10-27 15:59:09 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-27 15:59:09 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1430 ms
2025-10-27 15:59:09 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-27 15:59:09 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.3.Final
2025-10-27 15:59:09 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@c1f0c7b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@c1f0c7b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@c1f0c7b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@642c5bb3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@642c5bb3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@4e79c25
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@4e79c25
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@2ace1cd3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@2ace1cd3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@5e46a125
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@5e46a125
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@5e46a125
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@5831989d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@5831989d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@5831989d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@608f310a
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@608f310a
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@3a7d914c
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@515940af
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@515940af
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@5f8df69
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@1ce6a9bd
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@4a47bc9c
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@4a47bc9c
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@4a47bc9c
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@5100c143
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@5100c143
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@5100c143
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@12404f9d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@12404f9d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@12404f9d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@3b42b729
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@3b42b729
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@3b42b729
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@4c164f81
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@4c164f81
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@4c164f81
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@1bcb8599
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@1bcb8599
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@b671dda
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@b671dda
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@25b20860
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@25b20860
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@25b20860
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@5ba63110
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@1c0680b0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@1c0680b0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@2f3cd727
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@1af82ba8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@1af82ba8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@1af82ba8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@703cb756
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@5897aae1
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@11dbcb3b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@4aa517c3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@4aa517c3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@5f369fc6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@5f369fc6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@3a13f663
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@75de7009
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@17a77a7e
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@7c840fe3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@59014efe
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@5f5923ef
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@7381d6f0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@7381d6f0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@2f262474
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@2f262474
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@7c03f9d0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@7c03f9d0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@6ad3fbe4
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@6ad3fbe4
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@17189618
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@17189618
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@983050b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@6aadb092
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@1f547af8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@1f547af8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@4caf875c
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@5d15789f
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@5abb7a8f
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@6684589a
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@6684589a
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@5621a671
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@2006fdaa
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@21688427
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@656c5818
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@3e2578ea
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@29592929
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@4cf5d999
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@4bdef487
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@5ea9373e
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@3e595da3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@3e595da3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@3e595da3
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@5c0272e0
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@60c4cf2b
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@774304ca
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@303fbc4
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@4cd90c36
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@aa23f11
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@65a80fdb
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@79e90571
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@7d551ec6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@6614ecca
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@43e7f104
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@3a116ca6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@3a116ca6
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@6b899971
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@453a30f8
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@73a116d
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@205f52ea
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@34f60be9
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@29ccab93
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@7e2a76be
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@24b8a393
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@20155dae
2025-10-27 15:59:09 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-27 15:59:09 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-27 15:59:09 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@7a85dc58
2025-10-27 15:59:09 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2025-10-27 15:59:09 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(2003, org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@1859b996) replaced previous registration(org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@71098fb3)
2025-10-27 15:59:09 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(6, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@75e92bb7) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@2ebcbf9d)
2025-10-27 15:59:09 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2004, BlobTypeDescriptor(BLOB_BINDING)) replaced previous registration(BlobTypeDescriptor(DEFAULT))
2025-10-27 15:59:09 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2005, ClobTypeDescriptor(CLOB_BINDING)) replaced previous registration(ClobTypeDescriptor(DEFAULT))
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration JAVA_OBJECT -> org.hibernate.type.JavaObjectType@1b3a95d9
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@1b3a95d9
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Type registration key [java.lang.Object] overrode previous entry : `org.hibernate.type.JavaObjectType@3a116ca6`
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.DurationType -> basicType@1(java.time.Duration,3015)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> basicType@1(java.time.Duration,3015)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetDateTimeType -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.ZonedDateTimeType -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetTimeType -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:59:09 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-27 15:59:09 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@73818435] to MetadataBuildingContext [org.hibernate.boot.internal.MetadataBuildingContextRootImpl@2fce8243]
2025-10-27 15:59:10 [main] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-10-27 15:59:10 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@73818435] to SessionFactoryImplementor [org.hibernate.internal.SessionFactoryImpl@650d5a3d]
2025-10-27 15:59:10 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column decisions set data type TEXT
2025-10-27 15:59:10 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column discussions set data type TEXT
2025-10-27 15:59:10 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column pending_items set data type TEXT
2025-10-27 15:59:10 [main] DEBUG org.hibernate.SQL -
alter table if exists processed_transcripts
alter column summary set data type TEXT
2025-10-27 15:59:10 [main] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@650d5a3d] for TypeConfiguration
2025-10-27 15:59:10 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:59:10 [main] WARN o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-10-27 15:59:10 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: b4f1d9f6-2d90-4677-93fa-48b602f76673
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-27 15:59:10 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-10-27 15:59:11 [main] ERROR i.n.r.d.DnsServerAddressStreamProviders - Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos'. Use DEBUG level to see the full stack: java.lang.UnsatisfiedLinkError: failed to load the required native library
2025-10-27 15:59:11 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 3 endpoints beneath base path '/actuator'
2025-10-27 15:59:11 [main] DEBUG o.s.s.web.DefaultSecurityFilterChain - Will secure any request with filters: DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, CorsFilter, LogoutFilter, JwtAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter
2025-10-27 15:59:11 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 8083 (http) with context path '/'
2025-10-27 15:59:11 [main] INFO com.unicorn.hgzero.ai.AiApplication - Started AiApplication in 4.209 seconds (process running for 4.381)
2025-10-27 15:59:12 [http-nio-8083-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-27 15:59:12 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-27 15:59:12 [http-nio-8083-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms
2025-10-27 15:59:12 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.html
2025-10-27 15:59:12 [http-nio-8083-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-1] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.html
2025-10-27 15:59:12 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/index.css
2025-10-27 15:59:12 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-initializer.js
2025-10-27 15:59:12 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:59:12 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui.css
2025-10-27 15:59:12 [http-nio-8083-exec-6] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-3] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:59:12 [http-nio-8083-exec-3] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/index.css
2025-10-27 15:59:12 [http-nio-8083-exec-5] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-4] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-6] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-initializer.js
2025-10-27 15:59:12 [http-nio-8083-exec-2] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-4] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-bundle.js
2025-10-27 15:59:12 [http-nio-8083-exec-5] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui-standalone-preset.js
2025-10-27 15:59:12 [http-nio-8083-exec-2] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/swagger-ui.css
2025-10-27 15:59:12 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui/favicon-32x32.png
2025-10-27 15:59:12 [http-nio-8083-exec-8] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs/swagger-config
2025-10-27 15:59:12 [http-nio-8083-exec-8] DEBUG o.s.security.web.FilterChainProxy - Secured GET /swagger-ui/favicon-32x32.png
2025-10-27 15:59:12 [http-nio-8083-exec-7] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-7] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs/swagger-config
2025-10-27 15:59:12 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@25a06564]]
2025-10-27 15:59:12 [http-nio-8083-exec-7] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.ui.SwaggerConfigResource.openapiJson 완료 - 실행시간: 0ms
2025-10-27 15:59:12 [http-nio-8083-exec-9] DEBUG o.s.security.web.FilterChainProxy - Securing GET /v3/api-docs
2025-10-27 15:59:12 [http-nio-8083-exec-9] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-27 15:59:12 [http-nio-8083-exec-9] DEBUG o.s.security.web.FilterChainProxy - Secured GET /v3/api-docs
2025-10-27 15:59:12 [http-nio-8083-exec-9] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 호출 - 파라미터: [SecurityContextHolderAwareRequestWrapper[ org.springframework.security.web.header.HeaderWriterFilter$HeaderWriterRequest@3dc0cf9a], /v3/api-docs, ko_KR]
2025-10-27 15:59:12 [http-nio-8083-exec-9] INFO o.s.api.AbstractOpenApiResource - Init duration for springdoc-openapi is: 254 ms
2025-10-27 15:59:12 [http-nio-8083-exec-9] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson 완료 - 실행시간: 264ms
2025-10-27 15:59:37 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-27 15:59:37 [SpringApplicationShutdownHook] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryClosed from [org.hibernate.internal.SessionFactoryImpl@650d5a3d] for TypeConfiguration
2025-10-27 15:59:37 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@f81fe76] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@650d5a3d]
2025-10-27 15:59:37 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-27 15:59:37 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

View File

@ -18,7 +18,7 @@ import java.util.stream.Collectors;
* GET /api/terms/{term}/explain * GET /api/terms/{term}/explain
*/ */
@RestController @RestController
@RequestMapping("/api/terms") @RequestMapping("/api/ai/terms")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Term", description = "전문용어 감지 및 설명 API") @Tag(name = "Term", description = "전문용어 감지 및 설명 API")

View File

@ -20,7 +20,7 @@ import java.util.stream.Collectors;
* GET /api/transcripts/{meetingId}/related * GET /api/transcripts/{meetingId}/related
*/ */
@RestController @RestController
@RequestMapping("/api/transcripts") @RequestMapping("/api/ai/transcripts")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Relation", description = "관련 회의록 조회 API") @Tag(name = "Relation", description = "관련 회의록 조회 API")

View File

@ -19,7 +19,7 @@ import java.time.LocalDateTime;
* POST /api/sections/{sectionId}/regenerate-summary * POST /api/sections/{sectionId}/regenerate-summary
*/ */
@RestController @RestController
@RequestMapping("/api/sections") @RequestMapping("/api/ai/sections")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Section", description = "섹션 AI 요약 재생성 API") @Tag(name = "Section", description = "섹션 AI 요약 재생성 API")

View File

@ -27,7 +27,7 @@ import java.util.stream.Collectors;
* POST /api/suggestions/decision * POST /api/suggestions/decision
*/ */
@RestController @RestController
@RequestMapping("/api/suggestions") @RequestMapping("/api/ai/suggestions")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Suggestion", description = "논의사항/결정사항 제안 API") @Tag(name = "Suggestion", description = "논의사항/결정사항 제안 API")

View File

@ -24,7 +24,7 @@ import java.util.stream.Collectors;
* POST /api/terms/detect * POST /api/terms/detect
*/ */
@RestController @RestController
@RequestMapping("/api/terms") @RequestMapping("/api/ai/terms")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Term", description = "전문용어 감지 및 설명 API") @Tag(name = "Term", description = "전문용어 감지 및 설명 API")

View File

@ -23,7 +23,7 @@ import java.util.stream.Collectors;
* POST /api/todos/extract * POST /api/todos/extract
*/ */
@RestController @RestController
@RequestMapping("/api/todos") @RequestMapping("/api/ai/todos")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Todo", description = "Todo 자동 추출 API") @Tag(name = "Todo", description = "Todo 자동 추출 API")

View File

@ -21,7 +21,7 @@ import java.util.stream.Collectors;
* POST /api/transcripts/process * POST /api/transcripts/process
*/ */
@RestController @RestController
@RequestMapping("/api/transcripts") @RequestMapping("/api/ai/transcripts")
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j @Slf4j
@Tag(name = "Transcript", description = "회의록 자동 작성 API") @Tag(name = "Transcript", description = "회의록 자동 작성 API")

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,82 @@
# 백엔드 컨테이너이미지 작성가이드
[요청사항]
- 백엔드 각 서비스를의 컨테이너 이미지 생성
- 실제 빌드 수행 및 검증까지 완료
- '[결과파일]'에 수행한 명령어를 포함하여 컨테이너 이미지 작성 과정 생성
[작업순서]
- 서비스명 확인
서비스명은 settings.gradle에서 확인
예시) include 'common'하위의 4개가 서비스명임.
```
rootProject.name = 'tripgen'
include 'common'
include 'user-service'
include 'location-service'
include 'ai-service'
include 'trip-service'
```
- 실행Jar 파일 설정
실행Jar 파일명을 서비스명과 일치하도록 build.gradle에 설정 합니다.
```
bootJar {
archiveFileName = '{서비스명}.jar'
}
```
- Dockerfile 생성
아래 내용으로 deployment/container/Dockerfile-backend 생성
```
# Build stage
FROM openjdk:23-oraclelinux8 AS builder
ARG BUILD_LIB_DIR
ARG ARTIFACTORY_FILE
COPY ${BUILD_LIB_DIR}/${ARTIFACTORY_FILE} app.jar
# Run stage
FROM openjdk:23-slim
ENV USERNAME=k8s
ENV ARTIFACTORY_HOME=/home/${USERNAME}
ENV JAVA_OPTS=""
# Add a non-root user
RUN adduser --system --group ${USERNAME} && \
mkdir -p ${ARTIFACTORY_HOME} && \
chown ${USERNAME}:${USERNAME} ${ARTIFACTORY_HOME}
WORKDIR ${ARTIFACTORY_HOME}
COPY --from=builder app.jar app.jar
RUN chown ${USERNAME}:${USERNAME} app.jar
USER ${USERNAME}
ENTRYPOINT [ "sh", "-c" ]
CMD ["java ${JAVA_OPTS} -jar app.jar"]
```
- 컨테이너 이미지 생성
아래 명령으로 각 서비스 빌드. shell 파일을 생성하지 말고 command로 수행.
서브에이젼트를 생성하여 병렬로 수행.
```
DOCKER_FILE=deployment/container/Dockerfile-backend
service={서비스명}
docker build \
--platform linux/amd64 \
--build-arg BUILD_LIB_DIR="${서비스명}/build/libs" \
--build-arg ARTIFACTORY_FILE="${서비스명}.jar" \
-f ${DOCKER_FILE} \
-t ${서비스명}:latest .
```
- 생성된 이미지 확인
아래 명령으로 모든 서비스의 이미지가 빌드되었는지 확인
```
docker images | grep {서비스명}
```
[결과파일]
deployment/container/build-image.md

View File

@ -0,0 +1,770 @@
# 백엔드 GitHub Actions 파이프라인 작성 가이드
[요청사항]
- GitHub Actions 기반 CI/CD 파이프라인 구축 가이드 작성
- 환경별(dev/staging/prod) Kustomize 매니페스트 관리 및 자동 배포 구현
- SonarQube 코드 품질 분석과 Quality Gate 포함
- Kustomize 매니페스트 생성부터 배포까지 전체 과정 안내
- '[결과파일]'에 구축 방법 및 파이프라인 작성 가이드 생성
- 아래 작업은 실제 수행하여 파일 생성
- Kustomize 디렉토리 구조 생성
- Base Kustomization 작성
- 환경별 Overlay 작성
- 환경별 Patch 파일 생성
- GitHub Actions 워크플로우 파일 작성
- 환경별 배포 변수 파일 작성
- 수동 배포 스크립트 작성
[작업순서]
- 사전 준비사항 확인
프롬프트의 '[실행정보]'섹션에서 아래정보를 확인
- {ACR_NAME}: Azure Container Registry 이름
- {RESOURCE_GROUP}: Azure 리소스 그룹명
- {AKS_CLUSTER}: AKS 클러스터명
- {NAMESPACE}: Namespace명
예시)
```
[실행정보]
- ACR_NAME: acrdigitalgarage01
- RESOURCE_GROUP: rg-digitalgarage-01
- AKS_CLUSTER: aks-digitalgarage-01
- NAMESPACE: phonebill-dg0500
```
- 시스템명과 서비스명 확인
settings.gradle에서 확인.
- {SYSTEM_NAME}: rootProject.name
- {SERVICE_NAMES}: include 'common'하위의 include문 뒤의 값임
예시) include 'common'하위의 서비스명들.
```
rootProject.name = 'phonebill'
include 'common'
include 'api-gateway'
include 'user-service'
include 'order-service'
include 'payment-service'
```
- JDK버전 확인
루트 build.gradle에서 JDK 버전 확인.
{JDK_VERSION}: 'java' 섹션에서 JDK 버전 확인. 아래 예에서는 21임.
```
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
```
- GitHub 저장소 환경 구성 안내
- GitHub Repository Secrets 설정
- Azure 접근 인증정보 설정
```
# Azure Service Principal
Repository Settings > Secrets and variables > Actions > Repository secrets에 등록
AZURE_CREDENTIALS:
{
"clientId": "{클라이언트ID}",
"clientSecret": "{클라이언트시크릿}",
"subscriptionId": "{구독ID}",
"tenantId": "{테넌트ID}"
}
예시)
{
"clientId": "5e4b5b41-7208-48b7-b821-d6d5acf50ecf",
"clientSecret": "ldu8Q~GQEzFYU.dJX7_QsahR7n7C2xqkIM6hqbV8",
"subscriptionId": "2513dd36-7978-48e3-9a7c-b221d4874f66",
"tenantId": "4f0a3bfd-1156-4cce-8dc2-a049a13dba23",
}
```
- ACR Credentials
Credential 구하는 방법 안내
az acr credential show --name {acr 이름}
예) az acr credential show --name acrdigitalgarage01
```
ACR_USERNAME: {ACR_NAME}
ACR_PASSWORD: {ACR패스워드}
```
- SonarQube URL과 인증 토큰
SONAR_HOST_URL 구하는 방법과 SONAR_TOKEN 작성법 안내
SONAR_HOST_URL: 아래 명령 수행 후 http://{External IP}를 지정
k get svc -n sonarqube
예) http://20.249.187.69
SONAR_TOKEN 값은 아래와 같이 작성
- SonarQube 로그인 후 우측 상단 'Administrator' > My Account 클릭
- Security 탭 선택 후 토큰 생성
```
SONAR_TOKEN: {SonarQube토큰}
SONAR_HOST_URL: {SonarQube서버URL}
```
- Docker Hub (Rate Limit 해결용)
Docker Hub 패스워드 작성 방법 안내
- DockerHub(https://hub.docker.com)에 로그인
- 우측 상단 프로필 아이콘 클릭 후 Account Settings를 선택
- 좌측메뉴에서 'Personal Access Tokens' 클릭하여 생성
```
DOCKERHUB_USERNAME: {Docker Hub 사용자명}
DOCKERHUB_PASSWORD: {Docker Hub 패스워드}
```
- GitHub Repository Variables 설정
```
# Workflow 제어 변수
Repository Settings > Secrets and variables > Actions > Variables > Repository variables에 등록
ENVIRONMENT: dev (기본값, 수동실행시 선택 가능: dev/staging/prod)
SKIP_SONARQUBE: true (기본값, 수동실행시 선택 가능: true/false)
```
**사용 방법:**
- **자동 실행**: Push/PR 시 기본값 사용 (ENVIRONMENT=dev, SKIP_SONARQUBE=true)
- **수동 실행**: Actions 탭 > "Backend Services CI/CD" > "Run workflow" 버튼 클릭
- Environment: dev/staging/prod 선택
- Skip SonarQube Analysis: true/false 선택
- Kustomize 디렉토리 구조 생성
- GitHub Actions 전용 Kustomize 디렉토리 생성
```bash
mkdir -p .github/kustomize/{base,overlays/{dev,staging,prod}}
mkdir -p .github/kustomize/base/{common,{서비스명1},{서비스명2},...}
mkdir -p .github/{config,scripts}
```
- 기존 k8s 매니페스트를 base로 복사
```bash
# 기존 deployment/k8s/* 파일들을 base로 복사
cp deployment/k8s/common/* .github/kustomize/base/common/
cp deployment/k8s/{서비스명}/* .github/kustomize/base/{서비스명}/
# 네임스페이스 하드코딩 제거
find .github/kustomize/base -name "*.yaml" -exec sed -i 's/namespace: .*//' {} \;
```
- Base Kustomization 작성
`.github/kustomize/base/kustomization.yaml` 파일 생성
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
metadata:
name: {SYSTEM_NAME}-base
resources:
# Common resources
- common/configmap-common.yaml
- common/secret-common.yaml
- common/secret-imagepull.yaml
- common/ingress.yaml
# 각 서비스별 리소스
- {SERVICE_NAME}/deployment.yaml
- {SERVICE_NAME}/service.yaml
- {SERVICE_NAME}/configmap.yaml
- {SERVICE_NAME}/secret.yaml
images:
- name: {ACR_NAME}.azurecr.io/{SYSTEM_NAME}/{SERVICE_NAME}
newTag: latest
```
- 환경별 Patch 파일 생성
각 환경별로 필요한 patch 파일들을 생성합니다.
**중요원칙**:
- **base 매니페스트에 없는 항목은 추가 안함**
- **base 매니페스트와 항목이 일치해야 함**
- Secret 매니페스트에 'data'가 아닌 'stringData'사용
**1. ConfigMap Common Patch 파일 생성**
`.github/kustomize/overlays/{ENVIRONMENT}/cm-common-patch.yaml`
- base 매니페스트를 환경별로 복사
```
cp .github/kustomize/base/common/cm-common.yaml .github/kustomize/overlays/{ENVIRONMENT}/cm-common-patch.yaml
```
- SPRING_PROFILES_ACTIVE를 환경에 맞게 설정 (dev/staging/prod)
- DDL_AUTO 설정: dev는 "update", staging/prod는 "validate"
- JWT 토큰 유효시간은 prod에서 보안을 위해 짧게 설정
**2. Secret Common Patch 파일 생성**
`.github/kustomize/overlays/{ENVIRONMENT}/secret-common-patch.yaml`
- base 매니페스트를 환경별로 복사
```
cp .github/kustomize/base/common/secret-common.yaml .github/kustomize/overlays/{ENVIRONMENT}/secret-common-patch.yaml
```
**3. Ingress Patch 파일 생성**
`.github/kustomize/overlays/{ENVIRONMENT}/ingress-patch.yaml`
- base의 ingress.yaml을 환경별로 오버라이드
- **⚠️ 중요**: 개발환경 Ingress Host의 기본값은 base의 ingress.yaml과 **정확히 동일하게**
- base에서 `host: {SYSTEM_NAME}-api.20.214.196.128.nip.io` 이면
- dev에서도 `host: {SYSTEM_NAME}-api.20.214.196.128.nip.io` 로 동일하게 설정
- **절대** `{SYSTEM_NAME}-dev-api.xxx` 처럼 변경하지 말 것
- Staging/Prod 환경별 도메인 설정: {SYSTEM_NAME}.도메인 형식
- service name을 '{서비스명}'으로 함.
- Staging/prod 환경은 HTTPS 강제 적용 및 SSL 인증서 설정
- staging/prod는 nginx.ingress.kubernetes.io/ssl-redirect: "true"
- dev는 nginx.ingress.kubernetes.io/ssl-redirect: "false"
**4. deployment Patch 파일 생성** ⚠️ **중요**
각 서비스별로 별도 파일 생성
`.github/kustomize/overlays/{ENVIRONMENT}/deployment-{SERVICE_NAME}-patch.yaml`
**필수 포함 사항:**
- ✅ **replicas 설정**: 각 서비스별 Deployment의 replica 수를 환경별로 설정
- dev: 모든 서비스 1 replica (리소스 절약)
- staging: 모든 서비스 2 replicas
- prod: 모든 서비스 3 replicas
- ✅ **resources 설정**: 각 서비스별 Deployment의 resources를 환경별로 설정
- dev: requests(256m CPU, 256Mi Memory), limits(1024m CPU, 1024Mi Memory)
- staging: requests(512m CPU, 512Mi Memory), limits(2048m CPU, 2048Mi Memory)
- prod: requests(1024m CPU, 1024Mi Memory), limits(4096m CPU, 4096Mi Memory)
**5. Secret Service Patch 파일 생성**
각 서비스별로 별도 파일 생성
`.github/kustomize/overlays/{ENVIRONMENT}/secret-{SERVICE_NAME}-patch.yaml`
- base 매니페스트를 환경별로 복사
```
cp .github/kustomize/base/{SERVICE_NAME}/secret-{SERVICE_NAME}.yaml .github/kustomize/overlays/{ENVIRONMENT}/secret-{SERVICE_NAME}-patch.yaml
```
- 환경별 데이터베이스 연결 정보로 수정
- **⚠️ 중요**: 패스워드 등 민감정보는 실제 환경 구축 시 별도 설정
- 환경별 Overlay 작성
각 환경별로 `overlays/{환경}/kustomization.yaml` 생성
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: {NAMESPACE}
resources:
- ../../base
patches:
- path: cm-common-patch.yaml
target:
kind: ConfigMap
name: cm-common
- path: deployment-{SERVICE_NAME}-patch.yaml
target:
kind: Deployment
name: {SERVICE_NAME}
- path: ingress-patch.yaml
target:
kind: Ingress
name: {SYSTEM_NAME}
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: secret-{SERVICE_NAME}-patch.yaml
target:
kind: Secret
name: secret-{SERVICE_NAME}
images:
- name: {ACR_NAME}.azurecr.io/{SYSTEM_NAME}/{SERVICE_NAME}
newTag: {ENVIRONMENT}-latest
```
- GitHub Actions 워크플로우 작성
`.github/workflows/backend-cicd.yaml` 파일 생성 방법을 안내합니다.
주요 구성 요소:
- **Build & Test**: Gradle 기반 빌드 및 단위 테스트
- **SonarQube Analysis**: 코드 품질 분석 및 Quality Gate
- **Container Build & Push**: 환경별 이미지 태그로 빌드 및 푸시
- **Kustomize Deploy**: 환경별 매니페스트 적용
```yaml
name: Backend Services CI/CD
on:
push:
branches: [ main, develop ]
paths:
- '{서비스명1}/**'
- '{서비스명2}/**'
- '{서비스명3}/**'
- '{서비스명N}/**'
- 'common/**'
- '.github/**'
pull_request:
branches: [ main ]
workflow_dispatch:
inputs:
ENVIRONMENT:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options:
- dev
- staging
- prod
SKIP_SONARQUBE:
description: 'Skip SonarQube Analysis'
required: false
default: 'true'
type: choice
options:
- 'true'
- 'false'
env:
REGISTRY: ${{ secrets.REGISTRY }}
IMAGE_ORG: ${{ secrets.IMAGE_ORG }}
RESOURCE_GROUP: ${{ secrets.RESOURCE_GROUP }}
AKS_CLUSTER: ${{ secrets.AKS_CLUSTER }}
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 JDK {버전}
uses: actions/setup-java@v3
with:
java-version: '{JDK버전}'
distribution: 'temurin'
cache: 'gradle'
- name: Determine environment
id: determine_env
run: |
# Use input parameter or default to 'dev'
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 }}
# Initialize variables with defaults
REGISTRY="{ACR_NAME}.azurecr.io"
IMAGE_ORG="{SYSTEM_NAME}"
RESOURCE_GROUP="{RESOURCE_GROUP}"
AKS_CLUSTER="{AKS_CLUSTER}"
NAMESPACE="{NAMESPACE}"
# Read environment variables from .github/config file
if [[ -f ".github/config/deploy_env_vars_${ENV}" ]]; then
while IFS= read -r line || [[ -n "$line" ]]; do
# Skip comments and empty lines
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
# Extract key-value pairs
key=$(echo "$line" | cut -d '=' -f1)
value=$(echo "$line" | cut -d '=' -f2-)
# Override defaults if found in config
case "$key" in
"resource_group") RESOURCE_GROUP="$value" ;;
"cluster_name") AKS_CLUSTER="$value" ;;
esac
done < ".github/config/deploy_env_vars_${ENV}"
fi
# Export for other jobs
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: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: |
./gradlew build -x test
- name: SonarQube Analysis & Quality Gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
run: |
# Check if SonarQube should be skipped
SKIP_SONARQUBE="${{ github.event.inputs.SKIP_SONARQUBE || 'true' }}"
if [[ "$SKIP_SONARQUBE" == "true" ]]; then
echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=$SKIP_SONARQUBE)"
exit 0
fi
# Define services array
services=({SERVICE_NAME1} {SERVICE_NAME2} {SERVICE_NAME3} {SERVICE_NAMEN})
# Run tests, coverage reports, and SonarQube analysis for each service
for service in "${services[@]}"; do
./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \
-Dsonar.projectKey={SYSTEM_NAME}-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.projectName={SYSTEM_NAME}-$service-${{ steps.determine_env.outputs.environment }} \
-Dsonar.host.url=$SONAR_HOST_URL \
-Dsonar.token=$SONAR_TOKEN \
-Dsonar.java.binaries=build/classes/java/main \
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \
-Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/**
done
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: app-builds
path: |
{SERVICE_NAME1}/build/libs/*.jar
{SERVICE_NAME2}/build/libs/*.jar
{SERVICE_NAME3}/build/libs/*.jar
{SERVICE_NAMEN}/build/libs/*.jar
- name: Set outputs
id: set_outputs
run: |
# Generate timestamp for image tag
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 Images
needs: build
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: app-builds
- name: Set environment variables from build job
run: |
echo "REGISTRY=${{ needs.build.outputs.registry }}" >> $GITHUB_ENV
echo "IMAGE_ORG=${{ needs.build.outputs.image_org }}" >> $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 images for all services
run: |
# Define services array
services=({SERVICE_NAME1} {SERVICE_NAME2} {SERVICE_NAME3} {SERVICE_NAMEN})
# Build and push each service image
for service in "${services[@]}"; do
echo "Building and pushing $service..."
docker build \
--build-arg BUILD_LIB_DIR="$service/build/libs" \
--build-arg ARTIFACTORY_FILE="$service.jar" \
-f deployment/container/Dockerfile-backend \
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} .
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
done
deploy:
name: Deploy to Kubernetes
needs: [build, release]
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- 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: Install Azure CLI
run: |
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Setup kubectl
uses: azure/setup-kubectl@v3
- name: Get AKS Credentials
run: |
az aks get-credentials --resource-group ${{ env.RESOURCE_GROUP }} --name ${{ env.AKS_CLUSTER }} --overwrite-existing
- name: Create namespace
run: |
kubectl create namespace ${{ env.NAMESPACE }} --dry-run=client -o yaml | kubectl apply -f -
- name: Install Kustomize
run: |
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
- name: Update Kustomize images and deploy
run: |
# 환경별 디렉토리로 이동
cd deployment/cicd/kustomize/overlays/${{ env.ENVIRONMENT }}
# 각 서비스별 이미지 태그 업데이트
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/api-gateway:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/user-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/bill-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/product-service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
kustomize edit set image ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/kos-mock:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
# 매니페스트 적용
kubectl apply -k .
- name: Wait for deployments to be ready
run: |
echo "Waiting for deployments to be ready..."
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-api-gateway --timeout=300s
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-user-service --timeout=300s
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-bill-service --timeout=300s
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-product-service --timeout=300s
kubectl -n ${{ env.NAMESPACE }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-kos-mock --timeout=300s
```
- GitHub Actions 전용 환경별 설정 파일 작성
`.github/config/deploy_env_vars_{환경}` 파일 생성 방법
**.github/config/deploy_env_vars_dev**
```bash
# dev Environment Configuration
resource_group={RESOURCE_GROUP}
cluster_name={AKS_CLUSTER}
```
**.github/config/deploy_env_vars_staging**
```bash
# staging Environment Configuration
resource_group={RESOURCE_GROUP}
cluster_name={AKS_CLUSTER}
```
**.github/config/deploy_env_vars_prod**
```bash
# prod Environment Configuration
resource_group={RESOURCE_GROUP}
cluster_name={AKS_CLUSTER}
```
**참고**: Kustomize 방식에서는 namespace, replicas, resources 등은 kustomization.yaml과 patch 파일에서 관리됩니다.
- GitHub Actions 전용 수동 배포 스크립트 작성
`.github/scripts/deploy-actions.sh` 파일 생성:
```bash
#!/bin/bash
set -e
ENVIRONMENT=${1:-dev}
IMAGE_TAG=${2:-latest}
echo "🚀 Manual deployment starting..."
echo "Environment: $ENVIRONMENT"
echo "Image Tag: $IMAGE_TAG"
# Check if kustomize is installed
if ! command -v kustomize &> /dev/null; then
echo "Installing Kustomize..."
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
sudo mv kustomize /usr/local/bin/
fi
# Load environment variables from .github/config
if [[ -f ".github/config/deploy_env_vars_${ENVIRONMENT}" ]]; then
source ".github/config/deploy_env_vars_${ENVIRONMENT}"
echo "✅ Environment variables loaded for $ENVIRONMENT"
else
echo "❌ Environment configuration file not found: .github/config/deploy_env_vars_${ENVIRONMENT}"
exit 1
fi
# Create namespace
echo "📝 Creating namespace {NAMESPACE}..."
kubectl create namespace {NAMESPACE} --dry-run=client -o yaml | kubectl apply -f -
# 환경별 이미지 태그 업데이트 (.github/kustomize 사용)
cd .github/kustomize/overlays/${ENVIRONMENT}
echo "🔄 Updating image tags..."
# 서비스 배열 정의
services=({SERVICE_NAME1} {SERVICE_NAME2} {SERVICE_NAME3} {SERVICE_NAMEN})
# 각 서비스별 이미지 태그 업데이트
for service in "${services[@]}"; do
kustomize edit set image {ACR_NAME}.azurecr.io/{SYSTEM_NAME}/$service:${ENVIRONMENT}-${IMAGE_TAG}
done
echo "🚀 Deploying to Kubernetes..."
# 배포 실행
kubectl apply -k .
echo "⏳ Waiting for deployments to be ready..."
# 서비스별 배포 상태 확인
for service in "${services[@]}"; do
kubectl rollout status deployment/${ENVIRONMENT}-$service -n {NAMESPACE} --timeout=300s
done
echo "🔍 Health check..."
# API Gateway Health Check (첫 번째 서비스가 API Gateway라고 가정)
GATEWAY_SERVICE=${services[0]}
GATEWAY_POD=$(kubectl get pod -n {NAMESPACE} -l app.kubernetes.io/name=${ENVIRONMENT}-$GATEWAY_SERVICE -o jsonpath='{.items[0].metadata.name}')
kubectl -n {NAMESPACE} exec $GATEWAY_POD -- curl -f http://localhost:8080/actuator/health || echo "Health check failed, but deployment completed"
echo "📋 Service Information:"
kubectl get pods -n {NAMESPACE}
kubectl get services -n {NAMESPACE}
kubectl get ingress -n {NAMESPACE}
echo "✅ GitHub Actions deployment completed successfully!"
```
- SonarQube 프로젝트 설정 방법 작성
- SonarQube에서 각 서비스별 프로젝트 생성
- Quality Gate 설정:
```
Coverage: >= 80%
Duplicated Lines: <= 3%
Maintainability Rating: <= A
Reliability Rating: <= A
Security Rating: <= A
```
- 롤백 방법 작성
- GitHub Actions에서 이전 버전으로 롤백:
```bash
# 이전 워크플로우 실행으로 롤백
1. GitHub > Actions > 성공한 이전 워크플로우 선택
2. Re-run all jobs 클릭
```
- kubectl을 이용한 롤백:
```bash
# 특정 버전으로 롤백
kubectl rollout undo deployment/{환경}-{서비스명} -n {NAMESPACE} --to-revision=2
# 롤백 상태 확인
kubectl rollout status deployment/{환경}-{서비스명} -n {NAMESPACE}
```
- 수동 스크립트를 이용한 롤백:
```bash
# 이전 안정 버전 이미지 태그로 배포
./deployment/cicd/scripts/deploy-actions.sh {환경} {이전태그}
```
[체크리스트]
GitHub Actions CI/CD 파이프라인 구축 작업을 누락 없이 진행하기 위한 체크리스트입니다.
## 📋 사전 준비 체크리스트
- [ ] settings.gradle에서 시스템명과 서비스명 확인 완료
- [ ] 실행정보 섹션에서 ACR명, 리소스 그룹, AKS 클러스터명 확인 완료
## 📂 GitHub Actions 전용 Kustomize 구조 생성 체크리스트
- [ ] 디렉토리 구조 생성: `.github/kustomize/{base,overlays/{dev,staging,prod}}`
- [ ] 서비스별 base 디렉토리 생성: `.github/kustomize/base/{common,{서비스명들}}`
- [ ] 기존 k8s 매니페스트를 base로 복사 완료
- [ ] **리소스 누락 방지 검증 완료**:
- [ ] `ls .github/kustomize/base/*/` 명령으로 모든 서비스 디렉토리의 파일 확인
- [ ] 각 서비스별 필수 파일 존재 확인 (deployment.yaml, service.yaml 필수)
- [ ] ConfigMap 파일 존재 시 `cm-{서비스명}.yaml` 명명 규칙 준수 확인
- [ ] Secret 파일 존재 시 `secret-{서비스명}.yaml` 명명 규칙 준수 확인
- [ ] Base kustomization.yaml 파일 생성 완료
- [ ] 모든 서비스의 deployment.yaml, service.yaml 포함 확인
- [ ] 존재하는 모든 ConfigMap 파일 포함 확인 (`cm-{서비스명}.yaml`)
- [ ] 존재하는 모든 Secret 파일 포함 확인 (`secret-{서비스명}.yaml`)
- [ ] **검증 명령어 실행 완료**:
- [ ] `kubectl kustomize .github/kustomize/base/` 정상 실행 확인
- [ ] 에러 메시지 없이 모든 리소스 출력 확인
## 🔧 GitHub Actions 전용 환경별 Overlay 구성 체크리스트
### 중요 체크 사항
- Base Kustomization에서 존재하지 않는 Secret 파일들 제거
### 공통 체크 사항
- **base 매니페스트에 없는 항목을 추가하지 않았는지 체크**
- **base 매니페스트와 항목이 일치 하는지 체크**
- Secret 매니페스트에 'data'가 아닌 'stringData'사용했는지 체크
- **⚠️ Kustomize patch 방법 변경**: `patchesStrategicMerge``patches` (target 명시)
### DEV 환경
- [ ] `.github/kustomize/overlays/dev/kustomization.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/dev/cm-common-patch.yaml` 생성 완료 (dev 프로파일, update DDL)
- [ ] `.github/kustomize/overlays/dev/secret-common-patch.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/dev/ingress-patch.yaml` 생성 완료 (**Host 기본값은 base의 ingress.yaml과 동일**)
- [ ] `.github/kustomize/overlays/dev/deployment-{서비스명}-patch.yaml` 생성 완료 (replicas, resources 지정)
- [ ] 각 서비스별 `.github/kustomize/overlays/dev/secret-{서비스명}-patch.yaml` 생성 완료
### STAGING 환경
- [ ] `.github/kustomize/overlays/staging/kustomization.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/staging/cm-common-patch.yaml` 생성 완료 (staging 프로파일, validate DDL)
- [ ] `.github/kustomize/overlays/staging/secret-common-patch.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/staging/ingress-patch.yaml` 생성 완료 (prod 도메인, HTTPS, SSL 인증서)
- [ ] `.github/kustomize/overlays/staging/deployment-{서비스명}-patch.yaml` 생성 완료 (replicas, resources 지정)
- [ ] 각 서비스별 `.github/kustomize/overlays/staging/secret-{서비스명}-patch.yaml` 생성 완료
### PROD 환경
- [ ] `.github/kustomize/overlays/prod/kustomization.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/prod/cm-common-patch.yaml` 생성 완료 (prod 프로파일, validate DDL, 짧은 JWT)
- [ ] `.github/kustomize/overlays/prod/secret-common-patch.yaml` 생성 완료
- [ ] `.github/kustomize/overlays/prod/ingress-patch.yaml` 생성 완료 (prod 도메인, HTTPS, SSL 인증서)
- [ ] `.github/kustomize/overlays/prod/deployment-{서비스명}-patch.yaml` 생성 완료 (replicas, resources 지정)
- [ ] 각 서비스별 `.github/kustomize/overlays/prod/secret-{서비스명}-patch.yaml` 생성 완료
## ⚙️ GitHub Actions 설정 및 스크립트 체크리스트
- [ ] 환경별 설정 파일 생성: `.github/config/deploy_env_vars_{dev,staging,prod}`
- [ ] GitHub Actions 워크플로우 파일 `.github/workflows/backend-cicd.yaml` 생성 완료
- [ ] 워크플로우 주요 내용 확인
- Build, SonarQube, Docker Build & Push, Deploy 단계 포함
- JDK 버전 확인: `java-version: '{JDK버전}'`
- 변수 참조 문법 확인: `${{ needs.build.outputs.* }}` 사용
- 모든 서비스명이 실제 프로젝트 서비스명으로 치환되었는지 확인
- **환경 변수 SKIP_SONARQUBE 처리 확인**: 기본값 'true', 조건부 실행
- **플레이스홀더 사용 확인**: {ACR_NAME}, {SYSTEM_NAME}, {SERVICE_NAME} 등
- [ ] 수동 배포 스크립트 `.github/scripts/deploy-actions.sh` 생성 완료
- [ ] 스크립트 실행 권한 설정 완료 (`chmod +x .github/scripts/*.sh`)
[결과파일]
- 가이드: .github/actions-pipeline-guide.md
- GitHub Actions 워크플로우: .github/workflows/backend-cicd.yaml
- GitHub Actions 전용 Kustomize 매니페스트: .github/kustomize/*
- GitHub Actions 전용 환경별 설정 파일: .github/config/*
- GitHub Actions 전용 수동배포 스크립트: .github/scripts/deploy-actions.sh

View File

@ -1,454 +0,0 @@
# 유저스토리 v2.2.0 → v2.3.0 변경사항 보고서
**작성일**: 2025-10-25
**작성자**: 지수 (Product Designer), 민준 (Product Owner)
**문서 버전**: 1.0
---
## 📋 개요
본 보고서는 AI기반 회의록 작성 및 이력 관리 개선 서비스의 유저스토리 문서가 v2.2.0에서 v2.3.0으로 업데이트되면서 변경된 내용과 그 의미를 분석합니다.
### 요약 통계
| 항목 | v2.2.0 | v2.3.0 | 변화 |
|------|--------|--------|------|
| **유저스토리 수** | 25개 | 27개 | +2개 (+8%) |
| **신규 추가** | - | 5개 | UFR-USER-010, UFR-USER-020, UFR-MEET-015, UFR-AI-030, UFR-NOTI-010 |
| **삭제/전환** | - | 2개 | AFR-USER-010, AFR-USER-020 → UFR로 전환 |
| **AFR 코드** | 2개 | 0개 | -2개 (100% 제거) |
| **UFR 코드** | 23개 | 27개 | +4개 (+17%) |
| **평균 상세도** | 20-30줄 | 60-100줄 | **약 3배 증가** |
| **프로토타입 연계** | 부분적 | 100% (10개 화면) | - |
| **표준 형식 적용** | 0% | 100% (27개) | - |
---
## 📊 한눈에 보는 변경사항
```
v2.2.0 (25개) v2.3.0 (27개)
┌─────────────────┐ ┌─────────────────┐
│ AFR-USER-010 │ ──────────────────>│ UFR-USER-010 ✨ │ (로그인 상세화)
│ AFR-USER-020 │ ──────────────────>│ UFR-USER-020 ✨ │ (대시보드 재설계)
├─────────────────┤ ├─────────────────┤
│ UFR-MEET-010 │ ──────────────────>│ UFR-MEET-010 ✨ │ (회의예약 개선)
│ │ │ UFR-MEET-015 🆕 │ (참석자 실시간 초대)
│ UFR-MEET-020 │ ──────────────────>│ UFR-MEET-020 ✨ │ (템플릿선택 상세화)
│ UFR-MEET-030 │ ──────────────────>│ UFR-MEET-030 ✨ │ (회의시작 4개 탭)
│ UFR-MEET-040 │ ──────────────────>│ UFR-MEET-040 ✨ │ (회의종료 3가지 액션)
│ UFR-MEET-050 │ ──────────────────>│ UFR-MEET-050 ✨ │ (최종확정 2가지 시나리오)
│ UFR-MEET-046 │ ──────────────────>│ UFR-MEET-046 ✨ │ (목록조회 샘플 30개)
│ UFR-MEET-047 │ ──────────────────>│ UFR-MEET-047 ✨ │ (상세조회 관련회의록)
│ UFR-MEET-055 │ ──────────────────>│ UFR-MEET-055 ✨ │ (회의록수정 3가지 시나리오)
├─────────────────┤ ├─────────────────┤
│ UFR-AI-010 │ ──────────────────>│ UFR-AI-010 │
│ UFR-AI-020 │ ──────────────────>│ UFR-AI-020 │
│ │ │ UFR-AI-030 🆕🎯 │ (실시간 AI 제안 - 차별화!)
│ UFR-AI-035 │ ──────────────────>│ UFR-AI-035 │
│ UFR-AI-036 │ ──────────────────>│ UFR-AI-036 │
│ UFR-AI-040 │ ──────────────────>│ UFR-AI-040 │
├─────────────────┤ ├─────────────────┤
│ UFR-STT-010 │ ──────────────────>│ UFR-STT-010 │
│ UFR-STT-020 │ ──────────────────>│ UFR-STT-020 │
├─────────────────┤ ├─────────────────┤
│ UFR-RAG-010 │ ──────────────────>│ UFR-RAG-010 │
│ UFR-RAG-020 │ ──────────────────>│ UFR-RAG-020 │
├─────────────────┤ ├─────────────────┤
│ UFR-COLLAB-010 │ ──────────────────>│ UFR-COLLAB-010 │
│ UFR-COLLAB-020 │ ──────────────────>│ UFR-COLLAB-020 │
│ UFR-COLLAB-030 │ ──────────────────>│ UFR-COLLAB-030 │
├─────────────────┤ ├─────────────────┤
│ UFR-TODO-010 │ ──────────────────>│ UFR-TODO-010 │
│ UFR-TODO-030 │ ──────────────────>│ UFR-TODO-030 │
│ UFR-TODO-040 │ ──────────────────>│ UFR-TODO-040 │
└─────────────────┘ ├─────────────────┤
│ UFR-NOTI-010 🆕 │ (알림발송 - 폴링 방식)
└─────────────────┘
범례:
🆕 = 완전 신규 추가
🎯 = 차별화 핵심 기능
✨ = 대폭 개선 (프로토타입 기반 재작성)
```
---
## 🎯 핵심 변경사항
### 1. 신규 추가된 유저스토리 (5개)
#### 1.1 UFR-USER-010: 로그인 🆕
- **이전**: AFR-USER-010 (간략한 인증 설명)
- **변경**: UFR-USER-010으로 전환 및 상세화
- **의미**:
- 로그인 프로세스 단계별 명시 (Enter 키 동작, 로딩 상태 등)
- 예외처리 시나리오 구체화 (사번 미입력, 비밀번호 8자 미만 등)
- 프로토타입 `01-로그인.html`과 1:1 매핑
#### 1.2 UFR-USER-020: 대시보드 🆕
- **이전**: AFR-USER-020 (간략한 대시보드 설명)
- **변경**: UFR-USER-020으로 전환 및 대폭 확장
- **의미**:
- 통계 블록, 최근 회의, 나의 Todo, 나의 회의록 위젯 상세 명세
- FAB 버튼 2가지 액션 (회의예약/바로 시작) 명확화
- 프로토타입 `02-대시보드.html`과 1:1 매핑
#### 1.3 UFR-MEET-015: 참석자 실시간 초대 🆕
- **이전**: 없음
- **변경**: 완전 신규 추가
- **의미**:
- 회의 진행 중 "참석자" 탭에서 실시간으로 참석자 추가 기능
- 검색 모달 → 추가 → WebSocket 동기화 → 알림 발송 흐름 명시
- **효과**: 회의 진행 중 동적 참석자 관리로 유연성 향상
- 프로토타입 `05-회의진행.html`의 "참석자" 탭과 연계
#### 1.4 UFR-AI-030: 실시간 AI 제안 🆕🎯
- **이전**: 없음
- **변경**: 완전 신규 추가
- **의미**:
- **차별화 전략 "지능형 회의 진행 지원" 실현**
- STT 텍스트 실시간 분석 → 주요 내용 감지 → AI 제안 카드 생성
- 제안 카드에서 메모 탭으로 드래그 앤 드롭으로 추가
- **효과**: 회의 중 놓치는 내용 최소화, 차별화 핵심 기능
- 프로토타입 `05-회의진행.html`의 "AI 제안" 탭과 연계
#### 1.5 UFR-NOTI-010: 알림 발송 🆕
- **이전**: 없음 (암묵적으로 Meeting Service에서 직접 발송)
- **변경**: Notification 서비스의 독립적인 유저스토리로 추가
- **의미**:
- **알림 아키텍처를 폴링 방식으로 통일**
- 1분 간격 폴링 → 이메일 발송 → 최대 3회 재시도
- 6가지 알림 유형 명시 (Todo 할당, Todo 완료, 회의 시작, 회의록 확정, 참석자 초대, 회의록 수정)
- **효과**: Notification 서비스 독립성 확보, 시스템 안정성 향상
---
### 2. 대폭 개선된 유저스토리 (주요 8개)
#### 2.1 UFR-MEET-010: 회의예약
- **변경사항**:
- 수행절차 10단계 명시 (FAB 버튼 → 입력 → 저장/완료)
- 입력 필드별 상세 명세 (타입, 필수 여부, 최대/최소값, UI 요소)
- 임시저장/예약 완료 2가지 시나리오 구분
- 예외처리 7가지 추가 (제목 미입력, 과거 날짜, 참석자 미선택 등)
- **의미**: 프로토타입 `03-회의예약.html` 기반 전면 재작성
#### 2.2 UFR-MEET-030: 회의시작
- **변경사항**:
- 회의 진행 화면 4개 탭 상세 명세 (녹음/메모, 참석자, AI 제안, 안건)
- 녹음 시작/일시정지/재시작 플로우 명시
- 참석자 상태 표시 (온라인/오프라인/참석중)
- 탭별 UI 요소와 인터랙션 상세화
- **의미**: 프로토타입 `05-회의진행.html` 4개 탭 구조 반영
#### 2.3 UFR-MEET-040: 회의종료
- **변경사항**:
- 회의 종료 후 3가지 액션 명시 (바로 확정, 나중에 확정, 검토 후 확정)
- 각 액션별 이동 화면 명확화
- 안건 요약 및 검증 상태 표시 추가
- **의미**: 프로토타입 `07-회의종료.html` 반영, 사용자 선택권 강화
#### 2.4 UFR-MEET-050: 최종확정
- **변경사항**:
- 2가지 시나리오 분리 (검토 후 확정, 회의 종료 화면에서 바로 확정)
- 안건별 검증 완료 여부 체크 로직 추가
- 미검증 안건 있을 시 확정 불가 정책 명시
- **의미**: 회의록 품질 보증 메커니즘 강화
#### 2.5 UFR-MEET-046: 회의록목록조회
- **변경사항**:
- 샘플 데이터 30개 명시 (제목, 날짜, 상태, 검증 현황 등)
- 필터/정렬 기능 상세화 (기간, 상태, 폴더별)
- 상태 배지 5종 추가 (진행중, 검토중, 확정완료 등)
- **의미**: 프로토타입 `12-회의록목록조회.html` 반영
#### 2.6 UFR-MEET-047: 회의록상세조회
- **변경사항**:
- 관련 회의록 섹션 추가 (AI가 자동 연결한 회의록 3개 표시)
- 안건별 검증 상태 표시 추가
- 용어 팝업 연계 (UFR-RAG-010) 명시
- **의미**: 프로토타입 `10-회의록상세조회.html` 반영, RAG 기능 연계
#### 2.7 UFR-MEET-055: 회의록수정
- **변경사항**:
- 3가지 진입 시나리오 명시 (회의종료 화면, 목록 화면, 상세조회 화면)
- 실시간 협업 플로우 상세화 (UFR-COLLAB-010, UFR-COLLAB-020 연계)
- 수정 저장/임시저장/취소 3가지 액션 구분
- **의미**: 프로토타입 `11-회의록수정.html` 반영, 협업 기능 강화
#### 2.8 UFR-COLLAB-020: 충돌해결
- **변경사항**:
- 안건 기반 충돌 방지 메커니즘 상세화
- 동일 안건 동시 수정 시 경고 표시 및 잠금 정책 명시
- 충돌 해결 시나리오 3가지 (대기, 새 안건 작성, 취소)
- **의미**: 실시간 협업 안정성 강화
---
### 3. 유지된 유저스토리 (14개)
다음 유저스토리들은 v2.2.0과 v2.3.0에서 ID와 핵심 내용이 유지되었습니다:
- UFR-AI-010 (회의록 자동 작성)
- UFR-AI-020 (Todo 자동 추출)
- UFR-AI-035 (섹션 AI 요약)
- UFR-AI-036 (AI 한줄 요약)
- UFR-AI-040 (관련 회의록 연결)
- UFR-STT-010 (음성 녹음 인식)
- UFR-STT-020 (텍스트 변환)
- UFR-RAG-010 (전문용어 감지)
- UFR-RAG-020 (맥락 기반 용어 설명)
- UFR-COLLAB-010 (회의록 수정 동기화)
- UFR-COLLAB-030 (검증 완료)
- UFR-TODO-010 (Todo 할당)
- UFR-TODO-030 (Todo 완료 처리)
- UFR-TODO-040 (Todo 관리)
---
## 📈 문서 품질 개선
### 3.1 유저스토리 형식 표준화
#### Before (v2.2.0) - 자유 형식
```
UFR-MEET-010: [회의예약] 회의 생성자로서 | 나는, ...
- 시나리오: 회의 예약 및 참석자 초대
회의 예약 화면에 접근한 상황에서 | ...
[입력 요구사항]
- 회의 제목: 최대 100자 (필수)
...
[처리 결과]
- 회의가 예약됨
...
- M/13
```
#### After (v2.3.0) - 표준 5단계 형식
```
### UFR-MEET-010: [회의예약] 회의 생성자로서 | 나는, ...
**수행절차:**
1. 대시보드에서 "회의예약" FAB 버튼 클릭
2. 회의 제목 입력 (최대 100자)
3. 날짜 선택 (오늘 이후 날짜, 달력 UI)
...
10. "임시저장" 버튼 또는 "예약 완료" 버튼 클릭
**입력:**
- 회의 제목: 텍스트 입력, 필수, 최대 100자, 문자 카운터 표시
- 날짜: date 타입, 필수, 오늘 이후 날짜만 선택 가능
...
**출력/결과:**
- 예약 완료: "회의가 예약되었습니다" 토스트 메시지, 대시보드로 이동
- 임시저장: "임시 저장되었습니다" 토스트 메시지
...
**예외처리:**
- 제목 미입력: "회의 제목을 입력해주세요" 토스트, 제목 필드 포커스
- 과거 날짜 선택: "과거 날짜는 선택할 수 없습니다" 토스트
...
**관련 유저스토리:**
- UFR-USER-020: 대시보드 조회
- UFR-MEET-020: 템플릿선택
```
### 3.2 개선 효과
| 섹션 | 개선 효과 |
|------|-----------|
| **수행절차** | 단계별 명확한 작업 흐름, 개발자가 UI 플로우 이해 가능 |
| **입력** | 필드 타입, 검증 규칙, UI 요소 상세 명세, API 명세서 작성 기준 제공 |
| **출력/결과** | 성공/실패 시나리오별 응답 명시, 테스트 케이스 작성 기준 제공 |
| **예외처리** | 에러 상황별 처리 방법 구체화, QA 시나리오 명확화 |
| **관련 유저스토리** | 기능 간 연계성 추적, 통합 테스트 범위 파악 용이 |
---
## 🏗️ 프로토타입 연계 강화
v2.3.0에서는 모든 유저스토리가 프로토타입 화면과 명확하게 연계되었습니다.
| 프로토타입 화면 | 연계 유저스토리 | 상태 |
|----------------|----------------|------|
| 01-로그인.html | UFR-USER-010 | ✅ 1:1 매핑 |
| 02-대시보드.html | UFR-USER-020 | ✅ 1:1 매핑 |
| 03-회의예약.html | UFR-MEET-010 | ✅ 1:1 매핑 |
| 04-템플릿선택.html | UFR-MEET-020 | ✅ 1:1 매핑 |
| 05-회의진행.html | UFR-MEET-030, UFR-MEET-015 (신규), UFR-AI-030 (신규) | ✅ 1:N 매핑 |
| 07-회의종료.html | UFR-MEET-040 | ✅ 1:1 매핑 |
| 10-회의록상세조회.html | UFR-MEET-047 | ✅ 1:1 매핑 |
| 11-회의록수정.html | UFR-MEET-055 | ✅ 1:1 매핑 |
| 12-회의록목록조회.html | UFR-MEET-046 | ✅ 1:1 매핑 |
| 08-최종확정.html | UFR-MEET-050 | ✅ 1:1 매핑 |
**결과**: 10개 프로토타입 화면 100% 유저스토리 연계 완료
---
## 🔑 핵심 아키텍처 변경
### 알림 아키텍처: 실시간 → 폴링 방식
#### Before (v2.2.0)
```
[Meeting Service] ──(실시간 발송)──> [Notification Service] ──> [Email]
Todo 할당 발생 → 즉시 이메일 발송
```
**문제점**:
- Meeting Service와 Notification Service 간 강한 결합
- 이메일 발송 실패 시 Meeting Service에 영향
#### After (v2.3.0)
```
[Meeting Service] ──(DB 레코드 생성)──> [Notification 테이블]
(1분 간격 폴링)
[Notification Service] ──> [Email]
(발송 상태 업데이트)
```
**개선 효과**:
- ✅ **Notification 서비스 독립성 강화**: 마이크로서비스 간 느슨한 결합
- ✅ **시스템 안정성 향상**: 이메일 발송 실패 시 자동 재시도 (최대 3회)
- ✅ **확장성 확보**: 폴링 주기 조정으로 트래픽 제어 가능
- ✅ **모니터링 용이**: 발송 대기/성공/실패 상태 DB에서 추적
---
## 💡 변경의 의미와 개선 효과
### 1. 사용자 경험 (UX) 개선
| 영역 | 개선 내용 | 효과 |
|------|----------|------|
| **회의 진행 중 유연성** | UFR-MEET-015 (참석자 실시간 초대) | 회의 중 동적 참석자 관리 가능 |
| **회의 중 놓침 방지** | UFR-AI-030 (실시간 AI 제안) 🎯 | 차별화 핵심 기능, 회의 중 주요 내용 실시간 감지 |
| **회의 종료 후 선택권** | UFR-MEET-040 (3가지 액션) | 바로 확정/나중에 확정/검토 후 확정 |
| **회의록 품질 보증** | UFR-MEET-050 (검증 후 확정) | 미검증 안건 있을 시 확정 불가 정책 |
| **실시간 협업 안정성** | UFR-COLLAB-020 (안건 기반 충돌 방지) | 동일 안건 동시 수정 시 경고 및 잠금 |
### 2. 기능적 개선
| 영역 | 개선 내용 | 효과 |
|------|----------|------|
| **알림 시스템 안정성** | UFR-NOTI-010 (폴링 방식) | Notification 서비스 독립성 확보, 재시도 메커니즘 |
| **차별화 전략 실현** | UFR-AI-030 (실시간 AI 제안) 🎯 | "지능형 회의 진행 지원" 구체화 |
| **프로토타입 정합성** | 10개 화면 100% 매핑 | 기획-디자인-개발 간 일관성 확보 |
| **유저스토리 표준화** | 5단계 표준 형식 | 개발 가이드 역할 강화, API 명세서 작성 기준 제공 |
### 3. 문서화 개선
| 영역 | 개선 내용 | 효과 |
|------|----------|------|
| **상세도 3배 증가** | 20-30줄 → 60-100줄 | 개발자가 구현에 필요한 모든 정보 확보 |
| **AFR 코드 폐지** | AFR → UFR 통일 | 유저스토리 체계 단순화 |
| **예외처리 명시** | 각 유저스토리별 5-7개 예외 시나리오 | QA 테스트 케이스 작성 기준 제공 |
| **관련 유저스토리 연계** | 기능 간 의존성 추적 | 통합 테스트 범위 명확화 |
---
## 📋 권장 후속 조치
### 🔴 긴급 (1주 내)
- [ ] **신규 유저스토리 3개 기반 API 설계**
- UFR-MEET-015: 참석자 실시간 초대 API
- UFR-AI-030: 실시간 AI 제안 API (SSE 또는 WebSocket)
- UFR-NOTI-010: 알림 폴링 및 발송 API
- [ ] **알림 아키텍처 폴링 방식 반영**
- 물리 아키텍처 다이어그램 업데이트
- Notification 테이블 스키마 정의
- 폴링 스케줄러 설계
- [ ] **프로토타입 ↔ 유저스토리 1:1 매핑 검증**
- 10개 화면별 유저스토리 매핑 검증
- 누락된 화면 또는 유저스토리 확인
### 🟡 중요 (2주 내)
- [ ] **API 설계서 v2.3.0 기반 전면 업데이트**
- 입력/출력 명세 반영 (타입, 필수 여부, 검증 규칙)
- 예외처리 시나리오 → HTTP 상태 코드 및 에러 메시지 매핑
- 관련 유저스토리 기반 API 그룹핑
- [ ] **예외처리 시나리오 → 테스트 케이스 전환**
- 각 유저스토리의 예외처리 섹션을 테스트 케이스로 변환
- 입력 검증 테스트 케이스 작성
- [ ] **관련 유저스토리 기반 통합 테스트 시나리오 작성**
- 예: UFR-MEET-010 → UFR-MEET-020 → UFR-MEET-030 전체 플로우 테스트
### 🟢 일반 (3주 내)
- [ ] **유저스토리별 개발 우선순위 재평가**
- 신규 유저스토리 3개 우선순위 결정
- 차별화 핵심 기능 (UFR-AI-030) 우선 개발 검토
- [ ] **신규 기능 3개 개발 일정 수립**
- UFR-MEET-015: 참석자 실시간 초대
- UFR-AI-030: 실시간 AI 제안 (Sprint 목표로 권장)
- UFR-NOTI-010: 알림 발송
- [ ] **프로토타입 기반 개발 가이드 작성**
- 프로토타입 → 유저스토리 → API → 컴포넌트 매핑 가이드
- 프론트엔드 개발자를 위한 프로토타입 활용 가이드
---
## 🔍 핵심 시사점 (Key Takeaways)
1. **v2.3.0은 프로토타입 분석을 통해 유저스토리를 전면 재정비한 버전**
- 10개 프로토타입 화면과 100% 매핑
- 실제 UI/UX 플로우를 유저스토리에 반영
2. **신규 기능 3개 추가로 차별화 강화**
- 특히 UFR-AI-030 (실시간 AI 제안)은 차별화 핵심 기능
3. **알림 아키텍처 폴링 방식으로 통일하여 시스템 안정성 확보**
- Notification 서비스 독립성 강화
- 재시도 메커니즘으로 안정성 향상
4. **유저스토리 형식 표준화로 개발 가이드 역할 강화**
- 5단계 표준 형식 (수행절차, 입력, 출력/결과, 예외처리, 관련 유저스토리)
- API 명세서 및 테스트 케이스 작성 기준 제공
5. **평균 유저스토리 상세도 약 3배 증가로 품질 대폭 향상**
- 개발자가 구현에 필요한 모든 정보 포함
- 예외처리, 검증 규칙, UI 요소까지 상세 명시
6. **기존 24개 유저스토리 ID 승계하여 연속성 유지**
- AFR-USER-010 → UFR-USER-010 전환
- 기존 설계 문서와의 연계성 유지
7. **프로토타입-유저스토리 1:1 매핑으로 개발 명확성 확보**
- 기획-디자인-개발 간 일관성 확보
- 개발 우선순위 및 Sprint 계획 수립 용이
---
## 📎 참고 자료
- **상세 분석 (JSON)**: `claude/userstory-comparison-v2.2.0-to-v2.3.0.json` (19KB)
- **상세 분석 (Markdown)**: `claude/userstory-comparison-v2.2.0-to-v2.3.0.md` (16KB)
- **요약 분석**: `claude/userstory-comparison-summary.md` (11KB)
- **유저스토리 v2.2.0 백업**: `design/userstory_v2.2.0_backup.md`
- **유저스토리 v2.3.0 현재**: `design/userstory.md`
---
**보고서 작성**: 지수 (Product Designer), 민준 (Product Owner)
**분석 일시**: 2025-10-25
**문서 버전**: 1.0

View File

@ -0,0 +1,420 @@
# HGZero 백엔드 서비스 Kubernetes 배포 가이드
## 개요
이 가이드는 HGZero 백엔드 서비스(User, Meeting, Notification)를 Azure Kubernetes Service(AKS)에 배포하는 방법을 설명합니다.
## 배포 환경
- **ACR(Azure Container Registry)**: acrdigitalgarage02
- **AKS(Azure Kubernetes Service)**: aks-digitalgarage-02
- **네임스페이스**: hgzero
- **리소스 그룹**: rg-digitalgarage-02
## 서비스 구성
### 1. User Service
- **포트**: 8080
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/user-service:latest
- **기능**: 사용자 인증 및 관리, LDAP 연동
### 2. Meeting Service
- **포트**: 8081 (HTTP), 8082 (WebSocket)
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest
- **기능**: 회의 관리, WebSocket 통신
### 3. Notification Service
- **포트**: 8082
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest
- **기능**: 알림 전송, 이메일 발송
## 리소스 할당
각 서비스는 다음과 같은 리소스를 사용합니다:
- **Requests**:
- CPU: 256m
- Memory: 256Mi
- **Limits**:
- CPU: 1024m
- Memory: 1024Mi
- **Replicas**: 1 (각 서비스)
## 사전 요구사항
1. **Azure CLI 설치**
```bash
# macOS
brew install azure-cli
# Windows
# Download from https://aka.ms/installazurecliwindows
# Linux
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
```
2. **kubectl 설치**
```bash
# macOS
brew install kubectl
# Windows
# Download from https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/
# Linux
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
```
3. **Azure 로그인**
```bash
az login
```
4. **ACR 로그인**
```bash
az acr login --name acrdigitalgarage02
```
## 배포 파일 구조
```
deploy/k8s/backend/
├── namespace.yaml # 네임스페이스 정의
├── configmap.yaml # ConfigMap (Redis, Mail 설정)
├── secret-template.yaml # Secret 템플릿 (민감 정보)
├── user-service.yaml # User Service 배포 매니페스트
├── meeting-service.yaml # Meeting Service 배포 매니페스트
├── notification-service.yaml # Notification Service 배포 매니페스트
├── deploy.sh # 배포 스크립트
├── undeploy.sh # 배포 해제 스크립트
├── create-secrets.sh # Secret 생성 스크립트
└── README.md # 이 문서
```
## 배포 절차
### 1단계: AKS 클러스터 접근 설정
```bash
# AKS credentials 가져오기
az aks get-credentials \
--resource-group rg-digitalgarage-02 \
--name aks-digitalgarage-02 \
--overwrite-existing
# 클러스터 연결 확인
kubectl cluster-info
```
### 2단계: 네임스페이스 생성
```bash
kubectl apply -f namespace.yaml
```
### 3단계: ConfigMap 생성
```bash
kubectl apply -f configmap.yaml
```
### 4단계: Secret 생성
옵션 A: 대화형 스크립트 사용 (권장)
```bash
./create-secrets.sh
```
옵션 B: 직접 생성
```bash
# Database Secret
kubectl create secret generic db-secret \
--from-literal=host=<DB_HOST> \
--from-literal=username=<DB_USERNAME> \
--from-literal=password=<DB_PASSWORD> \
--namespace=hgzero
# Azure Secret
kubectl create secret generic azure-secret \
--from-literal=eventhub-connection-string=<EVENTHUB_CONN> \
--from-literal=blob-connection-string=<BLOB_CONN> \
--namespace=hgzero
# Mail Secret
kubectl create secret generic mail-secret \
--from-literal=username=<MAIL_USERNAME> \
--from-literal=password=<MAIL_PASSWORD> \
--namespace=hgzero
```
### 5단계: 서비스 배포
옵션 A: 자동 배포 스크립트 사용 (권장)
```bash
./deploy.sh
```
옵션 B: 수동 배포
```bash
# ACR 연동 설정
az aks update \
-n aks-digitalgarage-02 \
-g rg-digitalgarage-02 \
--attach-acr acrdigitalgarage02
# 서비스 배포
kubectl apply -f user-service.yaml
kubectl apply -f notification-service.yaml
kubectl apply -f meeting-service.yaml
```
### 6단계: 배포 상태 확인
```bash
# Deployment 상태 확인
kubectl get deployments -n hgzero
# Pod 상태 확인
kubectl get pods -n hgzero
# Service 확인
kubectl get services -n hgzero
# 상세 정보 확인
kubectl describe deployment user-service -n hgzero
```
## 배포 확인 및 테스트
### Pod 로그 확인
```bash
# User Service 로그
kubectl logs -f deployment/user-service -n hgzero
# Meeting Service 로그
kubectl logs -f deployment/meeting-service -n hgzero
# Notification Service 로그
kubectl logs -f deployment/notification-service -n hgzero
```
### Health Check
```bash
# User Service health check
kubectl port-forward svc/user-service 8080:8080 -n hgzero
curl http://localhost:8080/actuator/health
# Meeting Service health check
kubectl port-forward svc/meeting-service 8081:8081 -n hgzero
curl http://localhost:8081/actuator/health
# Notification Service health check
kubectl port-forward svc/notification-service 8082:8082 -n hgzero
curl http://localhost:8082/actuator/health
```
### Pod 내부 접속
```bash
# Pod 내부로 접속하여 디버깅
kubectl exec -it deployment/user-service -n hgzero -- /bin/sh
```
## 배포 해제
### 전체 서비스 삭제
```bash
./undeploy.sh
```
### 개별 서비스 삭제
```bash
kubectl delete -f user-service.yaml
kubectl delete -f meeting-service.yaml
kubectl delete -f notification-service.yaml
```
### Secret 및 ConfigMap 삭제
```bash
kubectl delete configmap redis-config mail-config -n hgzero
kubectl delete secret db-secret azure-secret mail-secret -n hgzero
```
### 네임스페이스 삭제
```bash
kubectl delete namespace hgzero
```
## 트러블슈팅
### Pod가 시작되지 않는 경우
```bash
# Pod 상태 확인
kubectl get pods -n hgzero
# Pod 상세 정보 확인
kubectl describe pod <pod-name> -n hgzero
# Pod 로그 확인
kubectl logs <pod-name> -n hgzero
# 이전 컨테이너 로그 확인 (재시작된 경우)
kubectl logs <pod-name> -n hgzero --previous
```
### 이미지 Pull 오류
```bash
# ACR 연동 상태 확인
az aks show -n aks-digitalgarage-02 -g rg-digitalgarage-02 --query "servicePrincipalProfile"
# ACR 재연동
az aks update -n aks-digitalgarage-02 -g rg-digitalgarage-02 --attach-acr acrdigitalgarage02
# ImagePullSecret 확인
kubectl get serviceaccount default -n hgzero -o yaml
```
### Secret 관련 오류
```bash
# Secret 존재 확인
kubectl get secrets -n hgzero
# Secret 내용 확인
kubectl get secret db-secret -n hgzero -o yaml
# Secret 재생성
kubectl delete secret db-secret -n hgzero
./create-secrets.sh
```
### 네트워크 연결 문제
```bash
# Service Endpoint 확인
kubectl get endpoints -n hgzero
# DNS 확인
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup user-service.hgzero.svc.cluster.local
# 네트워크 정책 확인
kubectl get networkpolicies -n hgzero
```
### 리소스 부족 문제
```bash
# 노드 리소스 사용량 확인
kubectl top nodes
# Pod 리소스 사용량 확인
kubectl top pods -n hgzero
# 리소스 제한 조정 (필요 시)
kubectl edit deployment user-service -n hgzero
```
## 업데이트 및 롤링 배포
### 이미지 업데이트
```bash
# 새 이미지 태그로 업데이트
kubectl set image deployment/user-service \
user-service=acrdigitalgarage02.azurecr.io/hgzero/user-service:v2.0.0 \
-n hgzero
# 롤아웃 상태 확인
kubectl rollout status deployment/user-service -n hgzero
# 롤아웃 히스토리 확인
kubectl rollout history deployment/user-service -n hgzero
```
### 롤백
```bash
# 이전 버전으로 롤백
kubectl rollout undo deployment/user-service -n hgzero
# 특정 revision으로 롤백
kubectl rollout undo deployment/user-service --to-revision=2 -n hgzero
```
## 모니터링
### Kubernetes Dashboard
```bash
# Dashboard 접근
az aks browse -n aks-digitalgarage-02 -g rg-digitalgarage-02
```
### 리소스 모니터링
```bash
# 실시간 리소스 사용량 모니터링
watch kubectl top pods -n hgzero
# 이벤트 모니터링
kubectl get events -n hgzero --sort-by='.lastTimestamp'
```
## 보안 권장사항
1. **Secret 관리**
- Secret은 절대 Git에 커밋하지 마세요
- Azure Key Vault 통합을 고려하세요
- Secret rotation 정책을 수립하세요
2. **네트워크 보안**
- Network Policy를 활용하여 Pod 간 통신을 제한하세요
- Service Mesh 도입을 고려하세요
3. **이미지 보안**
- 정기적으로 이미지 스캔을 수행하세요
- 최소 권한 원칙을 적용하세요
## 성능 최적화
1. **Auto Scaling 설정**
```bash
kubectl autoscale deployment user-service \
--cpu-percent=70 \
--min=1 \
--max=5 \
-n hgzero
```
2. **리소스 조정**
- 실제 사용량에 따라 requests/limits를 조정하세요
- HPA(Horizontal Pod Autoscaler) 설정을 고려하세요
## 참고 자료
- [Azure Kubernetes Service 문서](https://docs.microsoft.com/azure/aks/)
- [Kubernetes 공식 문서](https://kubernetes.io/docs/)
- [kubectl 치트시트](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
## 지원 및 문의
문제 발생 시 다음 정보를 수집하여 보고해주세요:
```bash
# 진단 정보 수집
kubectl get all -n hgzero > hgzero-resources.txt
kubectl describe pods -n hgzero > hgzero-pods-detail.txt
kubectl logs deployment/user-service -n hgzero > user-service.log
kubectl logs deployment/meeting-service -n hgzero > meeting-service.log
kubectl logs deployment/notification-service -n hgzero > notification-service.log
```

View File

@ -0,0 +1,20 @@
---
# Redis Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: hgzero
data:
host: "redis-service.hgzero.svc.cluster.local"
port: "6379"
---
# Mail Configuration
apiVersion: v1
kind: ConfigMap
metadata:
name: mail-config
namespace: hgzero
data:
host: "smtp.gmail.com"
port: "587"

View File

@ -0,0 +1,103 @@
#!/bin/bash
# HGZero Backend Services Secrets Creation Script
# This script helps create Kubernetes secrets for the backend services
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
NAMESPACE="hgzero"
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}HGZero Secrets Creation${NC}"
echo -e "${GREEN}======================================${NC}"
# Check if kubectl is installed
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed${NC}"
exit 1
fi
# Verify connection to cluster
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
exit 1
fi
# Check if namespace exists
if ! kubectl get namespace ${NAMESPACE} &> /dev/null; then
echo -e "${RED}Error: Namespace '${NAMESPACE}' does not exist${NC}"
echo -e "${YELLOW}Please run deploy.sh first to create the namespace${NC}"
exit 1
fi
# Function to prompt for secret value
prompt_secret() {
local prompt_text=$1
local secret_value
echo -n -e "${YELLOW}${prompt_text}: ${NC}"
read -s secret_value
echo ""
echo -n "$secret_value"
}
# Create Database Secret
echo -e "${GREEN}Creating Database Secret...${NC}"
DB_HOST=$(prompt_secret "Enter Database Host")
DB_USERNAME=$(prompt_secret "Enter Database Username")
DB_PASSWORD=$(prompt_secret "Enter Database Password")
kubectl create secret generic db-secret \
--from-literal=host="${DB_HOST}" \
--from-literal=username="${DB_USERNAME}" \
--from-literal=password="${DB_PASSWORD}" \
--namespace=${NAMESPACE} \
--dry-run=client -o yaml | kubectl apply -f -
echo -e "${GREEN}✓ Database secret created${NC}"
echo ""
# Create Azure Secret
echo -e "${GREEN}Creating Azure Secret...${NC}"
EVENTHUB_CONN=$(prompt_secret "Enter EventHub Connection String")
BLOB_CONN=$(prompt_secret "Enter Blob Storage Connection String")
kubectl create secret generic azure-secret \
--from-literal=eventhub-connection-string="${EVENTHUB_CONN}" \
--from-literal=blob-connection-string="${BLOB_CONN}" \
--namespace=${NAMESPACE} \
--dry-run=client -o yaml | kubectl apply -f -
echo -e "${GREEN}✓ Azure secret created${NC}"
echo ""
# Create Mail Secret
echo -e "${GREEN}Creating Mail Secret...${NC}"
MAIL_USERNAME=$(prompt_secret "Enter Mail Username")
MAIL_PASSWORD=$(prompt_secret "Enter Mail Password")
kubectl create secret generic mail-secret \
--from-literal=username="${MAIL_USERNAME}" \
--from-literal=password="${MAIL_PASSWORD}" \
--namespace=${NAMESPACE} \
--dry-run=client -o yaml | kubectl apply -f -
echo -e "${GREEN}✓ Mail secret created${NC}"
echo ""
# Verify secrets
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}Secrets Created Successfully${NC}"
echo -e "${GREEN}======================================${NC}"
kubectl get secrets -n ${NAMESPACE}
echo ""
echo -e "${YELLOW}Note: Secrets are stored in Kubernetes and can be viewed with:${NC}"
echo -e " kubectl get secret <secret-name> -n ${NAMESPACE} -o yaml"

133
deploy/k8s/backend/deploy.sh Executable file
View File

@ -0,0 +1,133 @@
#!/bin/bash
# HGZero Backend Services Kubernetes Deployment Script
# Azure Container Registry: acrdigitalgarage02
# Azure Kubernetes Service: aks-digitalgarage-02
# Namespace: hgzero
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
ACR_NAME="acrdigitalgarage02"
AKS_NAME="aks-digitalgarage-02"
RESOURCE_GROUP="rg-digitalgarage-02"
NAMESPACE="hgzero"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}HGZero Backend Services Deployment${NC}"
echo -e "${GREEN}======================================${NC}"
# Check if kubectl is installed
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed${NC}"
exit 1
fi
# Check if Azure CLI is installed
if ! command -v az &> /dev/null; then
echo -e "${RED}Error: Azure CLI is not installed${NC}"
exit 1
fi
# Login to Azure (if not already logged in)
echo -e "${YELLOW}Checking Azure login status...${NC}"
if ! az account show &> /dev/null; then
echo -e "${YELLOW}Please login to Azure...${NC}"
az login
fi
# Get AKS credentials
echo -e "${YELLOW}Getting AKS credentials...${NC}"
az aks get-credentials --resource-group ${RESOURCE_GROUP} --name ${AKS_NAME} --overwrite-existing
# Verify connection to cluster
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
exit 1
fi
echo -e "${GREEN}✓ Successfully connected to ${AKS_NAME}${NC}"
# Create namespace if it doesn't exist
echo -e "${YELLOW}Creating namespace '${NAMESPACE}'...${NC}"
kubectl apply -f ${SCRIPT_DIR}/namespace.yaml
echo -e "${GREEN}✓ Namespace created/verified${NC}"
# Apply ConfigMaps
echo -e "${YELLOW}Applying ConfigMaps...${NC}"
kubectl apply -f ${SCRIPT_DIR}/configmap.yaml
echo -e "${GREEN}✓ ConfigMaps applied${NC}"
# Check if secrets exist
echo -e "${YELLOW}Checking for secrets...${NC}"
if ! kubectl get secret db-secret -n ${NAMESPACE} &> /dev/null || \
! kubectl get secret azure-secret -n ${NAMESPACE} &> /dev/null || \
! kubectl get secret mail-secret -n ${NAMESPACE} &> /dev/null; then
echo -e "${RED}Warning: One or more secrets are missing!${NC}"
echo -e "${YELLOW}Please create secrets using secret-template.yaml as reference${NC}"
echo -e "${YELLOW}Example:${NC}"
echo -e " kubectl create secret generic db-secret -n ${NAMESPACE} \\"
echo -e " --from-literal=host=<DB_HOST> \\"
echo -e " --from-literal=username=<DB_USERNAME> \\"
echo -e " --from-literal=password=<DB_PASSWORD>"
echo ""
read -p "Do you want to continue without secrets? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}Deployment cancelled${NC}"
exit 1
fi
fi
# Configure ACR integration
echo -e "${YELLOW}Configuring ACR integration...${NC}"
az aks update -n ${AKS_NAME} -g ${RESOURCE_GROUP} --attach-acr ${ACR_NAME}
echo -e "${GREEN}✓ ACR integration configured${NC}"
# Deploy services
echo -e "${YELLOW}Deploying User Service...${NC}"
kubectl apply -f ${SCRIPT_DIR}/user-service.yaml
echo -e "${GREEN}✓ User Service deployed${NC}"
echo -e "${YELLOW}Deploying Notification Service...${NC}"
kubectl apply -f ${SCRIPT_DIR}/notification-service.yaml
echo -e "${GREEN}✓ Notification Service deployed${NC}"
echo -e "${YELLOW}Deploying Meeting Service...${NC}"
kubectl apply -f ${SCRIPT_DIR}/meeting-service.yaml
echo -e "${GREEN}✓ Meeting Service deployed${NC}"
# Wait for deployments to be ready
echo -e "${YELLOW}Waiting for deployments to be ready...${NC}"
kubectl wait --for=condition=available --timeout=300s \
deployment/user-service \
deployment/notification-service \
deployment/meeting-service \
-n ${NAMESPACE}
# Show deployment status
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}Deployment Status${NC}"
echo -e "${GREEN}======================================${NC}"
kubectl get deployments -n ${NAMESPACE}
echo ""
kubectl get pods -n ${NAMESPACE}
echo ""
kubectl get services -n ${NAMESPACE}
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}Deployment Completed Successfully!${NC}"
echo -e "${GREEN}======================================${NC}"
echo ""
echo -e "${YELLOW}Useful commands:${NC}"
echo -e " View logs: kubectl logs -f deployment/<service-name> -n ${NAMESPACE}"
echo -e " View pods: kubectl get pods -n ${NAMESPACE}"
echo -e " Describe pod: kubectl describe pod <pod-name> -n ${NAMESPACE}"
echo -e " Port forward: kubectl port-forward svc/<service-name> <local-port>:<service-port> -n ${NAMESPACE}"

View File

@ -0,0 +1,112 @@
---
# Meeting Service Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: meeting-service
namespace: hgzero
labels:
app: meeting-service
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: meeting-service
template:
metadata:
labels:
app: meeting-service
tier: backend
spec:
containers:
- name: meeting-service
image: acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest
imagePullPolicy: Always
ports:
- containerPort: 8081
name: http
- containerPort: 8082
name: websocket
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: SERVER_PORT
value: "8081"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: redis-config
key: host
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: port
- name: AZURE_EVENTHUB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: azure-secret
key: eventhub-connection-string
- name: NOTIFICATION_SERVICE_URL
value: "http://notification-service:8082"
resources:
requests:
cpu: 256m
memory: 256Mi
limits:
cpu: 1024m
memory: 1024Mi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8081
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8081
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
---
# Meeting Service Service
apiVersion: v1
kind: Service
metadata:
name: meeting-service
namespace: hgzero
labels:
app: meeting-service
spec:
type: ClusterIP
ports:
- port: 8081
targetPort: 8081
protocol: TCP
name: http
- port: 8082
targetPort: 8082
protocol: TCP
name: websocket
selector:
app: meeting-service

View File

@ -0,0 +1,9 @@
---
# Namespace for HGZero application
apiVersion: v1
kind: Namespace
metadata:
name: hgzero
labels:
name: hgzero
environment: production

View File

@ -0,0 +1,129 @@
---
# Notification Service Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: notification-service
namespace: hgzero
labels:
app: notification-service
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: notification-service
template:
metadata:
labels:
app: notification-service
tier: backend
spec:
containers:
- name: notification-service
image: acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest
imagePullPolicy: Always
ports:
- containerPort: 8082
name: http
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: SERVER_PORT
value: "8082"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: redis-config
key: host
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: port
- name: AZURE_EVENTHUB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: azure-secret
key: eventhub-connection-string
- name: AZURE_BLOB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: azure-secret
key: blob-connection-string
- name: MAIL_HOST
valueFrom:
configMapKeyRef:
name: mail-config
key: host
- name: MAIL_PORT
valueFrom:
configMapKeyRef:
name: mail-config
key: port
- name: MAIL_USERNAME
valueFrom:
secretKeyRef:
name: mail-secret
key: username
- name: MAIL_PASSWORD
valueFrom:
secretKeyRef:
name: mail-secret
key: password
resources:
requests:
cpu: 256m
memory: 256Mi
limits:
cpu: 1024m
memory: 1024Mi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8082
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8082
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
---
# Notification Service Service
apiVersion: v1
kind: Service
metadata:
name: notification-service
namespace: hgzero
labels:
app: notification-service
spec:
type: ClusterIP
ports:
- port: 8082
targetPort: 8082
protocol: TCP
name: http
selector:
app: notification-service

View File

@ -0,0 +1,36 @@
---
# Database Secret Template
# Note: Replace base64 encoded values with your actual credentials
# To encode: echo -n 'your-value' | base64
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: hgzero
type: Opaque
data:
host: <BASE64_ENCODED_DB_HOST>
username: <BASE64_ENCODED_DB_USERNAME>
password: <BASE64_ENCODED_DB_PASSWORD>
---
# Azure Secret Template
apiVersion: v1
kind: Secret
metadata:
name: azure-secret
namespace: hgzero
type: Opaque
data:
eventhub-connection-string: <BASE64_ENCODED_EVENTHUB_CONNECTION_STRING>
blob-connection-string: <BASE64_ENCODED_BLOB_CONNECTION_STRING>
---
# Mail Secret Template
apiVersion: v1
kind: Secret
metadata:
name: mail-secret
namespace: hgzero
type: Opaque
data:
username: <BASE64_ENCODED_MAIL_USERNAME>
password: <BASE64_ENCODED_MAIL_PASSWORD>

89
deploy/k8s/backend/undeploy.sh Executable file
View File

@ -0,0 +1,89 @@
#!/bin/bash
# HGZero Backend Services Kubernetes Undeployment Script
set -e
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
NAMESPACE="hgzero"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
echo -e "${YELLOW}======================================${NC}"
echo -e "${YELLOW}HGZero Backend Services Undeployment${NC}"
echo -e "${YELLOW}======================================${NC}"
# Check if kubectl is installed
if ! command -v kubectl &> /dev/null; then
echo -e "${RED}Error: kubectl is not installed${NC}"
exit 1
fi
# Verify connection to cluster
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
exit 1
fi
# Check if namespace exists
if ! kubectl get namespace ${NAMESPACE} &> /dev/null; then
echo -e "${YELLOW}Namespace '${NAMESPACE}' does not exist. Nothing to undeploy.${NC}"
exit 0
fi
echo -e "${YELLOW}This will delete all services in namespace '${NAMESPACE}'${NC}"
read -p "Are you sure you want to continue? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}Undeployment cancelled${NC}"
exit 0
fi
# Delete services
echo -e "${YELLOW}Deleting Meeting Service...${NC}"
kubectl delete -f ${SCRIPT_DIR}/meeting-service.yaml --ignore-not-found=true
echo -e "${GREEN}✓ Meeting Service deleted${NC}"
echo -e "${YELLOW}Deleting Notification Service...${NC}"
kubectl delete -f ${SCRIPT_DIR}/notification-service.yaml --ignore-not-found=true
echo -e "${GREEN}✓ Notification Service deleted${NC}"
echo -e "${YELLOW}Deleting User Service...${NC}"
kubectl delete -f ${SCRIPT_DIR}/user-service.yaml --ignore-not-found=true
echo -e "${GREEN}✓ User Service deleted${NC}"
# Delete ConfigMaps
echo -e "${YELLOW}Deleting ConfigMaps...${NC}"
kubectl delete -f ${SCRIPT_DIR}/configmap.yaml --ignore-not-found=true
echo -e "${GREEN}✓ ConfigMaps deleted${NC}"
# Ask about secrets deletion
echo ""
echo -e "${YELLOW}Do you want to delete secrets as well?${NC}"
echo -e "${RED}Warning: This will delete all database and Azure credentials${NC}"
read -p "Delete secrets? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
kubectl delete secret db-secret azure-secret mail-secret -n ${NAMESPACE} --ignore-not-found=true
echo -e "${GREEN}✓ Secrets deleted${NC}"
fi
# Ask about namespace deletion
echo ""
echo -e "${YELLOW}Do you want to delete the namespace '${NAMESPACE}'?${NC}"
read -p "Delete namespace? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
kubectl delete namespace ${NAMESPACE}
echo -e "${GREEN}✓ Namespace deleted${NC}"
fi
echo -e "${GREEN}======================================${NC}"
echo -e "${GREEN}Undeployment Completed${NC}"
echo -e "${GREEN}======================================${NC}"

View File

@ -0,0 +1,102 @@
---
# User Service Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: hgzero
labels:
app: user-service
tier: backend
spec:
replicas: 1
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
tier: backend
spec:
containers:
- name: user-service
image: acrdigitalgarage02.azurecr.io/hgzero/user-service:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
name: http
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: host
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: redis-config
key: host
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: redis-config
key: port
- name: AZURE_EVENTHUB_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: azure-secret
key: eventhub-connection-string
resources:
requests:
cpu: 256m
memory: 256Mi
limits:
cpu: 1024m
memory: 1024Mi
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
---
# User Service Service
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: hgzero
labels:
app: user-service
spec:
type: ClusterIP
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
selector:
app: user-service

View File

@ -0,0 +1,25 @@
# Build stage
FROM openjdk:23-oraclelinux8 AS builder
ARG BUILD_LIB_DIR
ARG ARTIFACTORY_FILE
COPY ${BUILD_LIB_DIR}/${ARTIFACTORY_FILE} app.jar
# Run stage
FROM openjdk:23-slim
ENV USERNAME=k8s
ENV ARTIFACTORY_HOME=/home/${USERNAME}
ENV JAVA_OPTS=""
# Add a non-root user
RUN adduser --system --group ${USERNAME} && \
mkdir -p ${ARTIFACTORY_HOME} && \
chown ${USERNAME}:${USERNAME} ${ARTIFACTORY_HOME}
WORKDIR ${ARTIFACTORY_HOME}
COPY --from=builder app.jar app.jar
RUN chown ${USERNAME}:${USERNAME} app.jar
USER ${USERNAME}
ENTRYPOINT [ "sh", "-c" ]
CMD ["java ${JAVA_OPTS} -jar app.jar"]

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