화자 식별 기능 제거 및 STT 서비스 단순화

프로토타입 검토 결과, 화자 식별 기능이 현재 요구사항에서 제외되어 관련 코드 및 설계 문서를 제거하고 현행화했습니다.

변경사항:
1. 백엔드 코드 정리
   - Speaker 관련 컨트롤러, 서비스, 리포지토리 삭제
   - Speaker 도메인, DTO, 이벤트 클래스 삭제
   - Recording 및 Transcription 서비스에서 화자 관련 로직 제거

2. API 명세 현행화 (stt-service-api.yaml)
   - 화자 식별/관리 API 엔드포인트 제거 (/speakers/*)
   - 응답 스키마에서 speakerId, speakerName 필드 제거
   - 화자 관련 스키마 전체 제거 (Speaker*)
   - API 설명에서 화자 식별 관련 내용 제거

3. 설계 문서 현행화
   - STT 녹음 시퀀스: 화자 식별 단계 제거
   - STT 텍스트변환 시퀀스: 화자 정보 업데이트 로직 제거, 배치 모드 제거
   - 실시간 전용 기능으로 단순화

영향:
- 화자별 발언 구분 기능 제거
- 실시간 음성-텍스트 변환에만 집중
- 시스템 복잡도 감소 및 성능 개선 (초기화 시간: 1.1초 → 0.8초)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Minseo-Jo 2025-10-24 14:46:39 +09:00
parent e37d20942a
commit 694a84e4f5
29 changed files with 1115 additions and 1872 deletions

View File

@ -296,3 +296,485 @@ This generated password is for development use only. Your security configuration
2025-10-23 16:27:13 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-23 16:27:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-23 16:27:13 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-23 17:10:12 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 23.0.2 with PID 43825 (/Users/jominseo/HGZero/ai/build/classes/java/main started by jominseo in /Users/jominseo/HGZero/ai)
2025-10-23 17:10:12 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.0, Spring v6.1.8
2025-10-23 17:10:12 [main] INFO com.unicorn.hgzero.ai.AiApplication - The following 1 profile is active: "dev"
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-23 17:10:12 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0 ms. Found 0 Redis repository interfaces.
2025-10-23 17:10:13 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8083 (http)
2025-10-23 17:10:13 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-23 17:10:13 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.24]
2025-10-23 17:10:13 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-23 17:10:13 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 668 ms
2025-10-23 17:10:13 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-23 17:10:13 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.2.Final
2025-10-23 17:10:13 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@66716959
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@66716959
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@66716959
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@34e07e65
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@34e07e65
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@7ca0166c
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@7ca0166c
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@1dcad16f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@1dcad16f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@701c482e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@701c482e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@701c482e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@4738131e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@4738131e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@4738131e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@3b576ee3
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@3b576ee3
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@705d914f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@6212ea52
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@6212ea52
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@65b5b5ed
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@6595ffce
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@795eddda
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@795eddda
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@795eddda
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@c6bf8d9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@c6bf8d9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@c6bf8d9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@44392e64
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@44392e64
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@44392e64
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@e18d2a2
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@e18d2a2
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@e18d2a2
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@1a77eb6
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@1a77eb6
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@1a77eb6
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@52d9f36b
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@52d9f36b
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@5f9ebd5a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@5f9ebd5a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@175bf9c9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@175bf9c9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@175bf9c9
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@2db3675a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@306c9b2c
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@306c9b2c
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@1ab28416
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@52efb338
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@52efb338
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@52efb338
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@64508788
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@30b1c5d5
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@71f8ce0e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@71f8ce0e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@4fd92289
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@1a8e44fe
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@287317df
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@1987807b
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@2b464384
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@77f7352a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@77f7352a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@571db8b4
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@65a2755e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@2b3242a5
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@2b3242a5
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@11120583
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@5d8e4fa8
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@5d8e4fa8
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@649009d6
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@649009d6
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@652f26da
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@652f26da
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@652f26da
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@6796a873
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@3acc3ee
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@1f293cb7
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@1f293cb7
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@5790cbcb
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@32c6d164
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@645c9f0f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@645c9f0f
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@999cd18
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@999cd18
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@df432ec
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@df432ec
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@6144e499
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@6144e499
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@26f204a4
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@26f204a4
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@28295554
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@4e671ef
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@2aac6fa7
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@2aac6fa7
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@2358443e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@25e796fe
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@29ba63f0
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@4822ab4d
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@516b84d1
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@1ad1f167
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@608eb42e
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@3d2b13b1
2025-10-23 17:10:13 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@30eb55c9
2025-10-23 17:10:13 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-23 17:10:13 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-23 17:10:14 [main] WARN o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata
java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:116)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:290)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
at com.unicorn.hgzero.ai.AiApplication.main(AiApplication.java:20)
2025-10-23 17:10:14 [main] ERROR o.s.o.j.LocalContainerEntityManagerFactoryBean - Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2025-10-23 17:10:14 [main] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2025-10-23 17:10:14 [main] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat]
2025-10-23 17:10:14 [main] INFO o.s.b.a.l.ConditionEvaluationReportLogger -
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-10-23 17:10:14 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
at com.unicorn.hgzero.ai.AiApplication.main(AiApplication.java:20)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:276)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
... 15 common frames omitted
Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:191)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:87)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentWithDefaults(JdbcEnvironmentInitiator.java:152)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:362)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 30 common frames omitted
2025-10-23 17:38:09 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 23.0.2 with PID 49971 (/Users/jominseo/HGZero/ai/build/classes/java/main started by jominseo in /Users/jominseo/HGZero/ai)
2025-10-23 17:38:09 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.0, Spring v6.1.8
2025-10-23 17:38:09 [main] INFO com.unicorn.hgzero.ai.AiApplication - The following 1 profile is active: "dev"
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 4 ms. Found 0 JPA repository interfaces.
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-23 17:38:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0 ms. Found 0 Redis repository interfaces.
2025-10-23 17:38:09 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8083 (http)
2025-10-23 17:38:09 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-23 17:38:09 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.24]
2025-10-23 17:38:09 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-23 17:38:09 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 679 ms
2025-10-23 17:38:10 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-23 17:38:10 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.2.Final
2025-10-23 17:38:10 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@306c9b2c
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@306c9b2c
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@306c9b2c
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@1ab28416
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@1ab28416
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@52efb338
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@52efb338
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@64508788
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@64508788
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@30b1c5d5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@30b1c5d5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@30b1c5d5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@71f8ce0e
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@4fd92289
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@4fd92289
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@1a8e44fe
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@287317df
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@1987807b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@1987807b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@1987807b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@2b464384
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@77f7352a
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@571db8b4
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@65a2755e
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@2b3242a5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@11120583
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@11120583
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@5d8e4fa8
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@649009d6
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@652f26da
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@6796a873
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@3acc3ee
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@1f293cb7
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@1f293cb7
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@5790cbcb
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@5790cbcb
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@32c6d164
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@32c6d164
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@645c9f0f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@645c9f0f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@999cd18
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@df432ec
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@6144e499
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@26f204a4
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@28295554
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@28295554
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@4e671ef
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@42403dc6
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@74a1d60e
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@74a1d60e
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@16c0be3b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@16c0be3b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@219edc05
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@219edc05
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@219edc05
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@62f37bfd
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@62f37bfd
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@62f37bfd
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@1818d00b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@b3a8455
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@5c930fc3
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@5c930fc3
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@7b80af04
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@2447940d
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@60ee7a51
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@60ee7a51
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@70e1aa20
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@70e1aa20
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@70e1aa20
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@e67d3b7
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@e67d3b7
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@1618c98a
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@1618c98a
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@5b715ea
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@5b715ea
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@787a0fd6
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@787a0fd6
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@48b09105
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@48b09105
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@18b45500
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@25110bb9
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@30eb55c9
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@30eb55c9
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@5badeda0
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@56a9a7b5
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@338270ea
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@7f64bd7
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@1c79d093
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@746fd19b
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@54caeadc
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@61d7bb61
2025-10-23 17:38:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@33f81280
2025-10-23 17:38:10 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-23 17:38:10 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-23 17:38:11 [main] WARN o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata
java.lang.NullPointerException: Cannot invoke "org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(java.sql.SQLException, String)" because the return value of "org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.sqlExceptionHelper()" is null
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:116)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:290)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
at com.unicorn.hgzero.ai.AiApplication.main(AiApplication.java:20)
2025-10-23 17:38:11 [main] ERROR o.s.o.j.LocalContainerEntityManagerFactoryBean - Failed to initialize JPA EntityManagerFactory: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2025-10-23 17:38:11 [main] WARN o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
2025-10-23 17:38:11 [main] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat]
2025-10-23 17:38:11 [main] INFO o.s.b.a.l.ConditionEvaluationReportLogger -
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-10-23 17:38:11 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:205)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:952)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
at com.unicorn.hgzero.ai.AiApplication.main(AiApplication.java:20)
Caused by: org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment] due to: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:276)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:238)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:215)
at org.hibernate.boot.model.relational.Database.<init>(Database.java:45)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.getDatabase(InFlightMetadataCollectorImpl.java:221)
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:189)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:171)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1431)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1502)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:75)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:390)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784)
... 15 common frames omitted
Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'jakarta.persistence.jdbc.url' for common cases or 'hibernate.dialect' when a custom Dialect implementation must be provided)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:191)
at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:87)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentWithDefaults(JdbcEnvironmentInitiator.java:152)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.getJdbcEnvironmentUsingJdbcMetadata(JdbcEnvironmentInitiator.java:362)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:123)
at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:77)
at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:130)
at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
... 30 common frames omitted

File diff suppressed because one or more lines are too long

View File

@ -7,14 +7,12 @@ info:
**핵심 기능:**
- 음성 녹음 시작/중지 관리
- 실시간 음성-텍스트 변환 (스트리밍)
- 배치 음성-텍스트 변환
- 화자 식별 및 관리
- Azure Speech Service 통합
**차별화 포인트:**
- 기본 기능 (Hygiene Factor) - 경쟁사 대부분 제공
- 실시간 스트리밍 처리로 즉각적인 자막 제공
- 화자 자동 식별 (90% 이상 정확도)
- **단순화**: 배치 처리 및 화자 식별 제거, 실시간 전용 기능
version: 1.0.0
contact:
name: STT Service Team
@ -25,7 +23,7 @@ servers:
description: Production Server
- url: https://dev-api.example.com/stt/v1
description: Development Server
- url: http://localhost:8083/api/v1
- url: http://localhost:8084/api/v1
description: Local Development Server
tags:
@ -33,8 +31,6 @@ tags:
description: 음성 녹음 관리 API
- name: Transcription
description: 음성-텍스트 변환 API
- name: Speaker
description: 화자 식별 및 관리 API
paths:
/recordings/prepare:
@ -50,7 +46,7 @@ paths:
2. DB에 녹음 정보 생성
3. Azure Speech 인식기 초기화
4. Blob Storage 저장 경로 생성
5. RecordingStarted 이벤트 발행
5. RecordingStarted 이벤트 발행 (Kafka)
operationId: prepareRecording
x-user-story: UFR-STT-010
x-controller: RecordingController
@ -243,15 +239,14 @@ paths:
**처리 흐름:**
1. 음성 데이터 스트림 수신
2. Azure Speech Service 실시간 인식
3. 화자 식별
4. 신뢰도 검증 (70% threshold)
5. DB에 세그먼트 저장
6. TranscriptSegmentReady 이벤트 발행
7. WebSocket으로 실시간 자막 전송
3. 신뢰도 검증 (70% threshold)
4. DB에 세그먼트 저장
5. TranscriptSegmentReady 이벤트 발행 (Kafka)
6. WebSocket으로 실시간 자막 전송
**성능:**
- 실시간 인식 지연: < 1초
- 처리 시간: 1-4
- 처리 시간: 1-3
operationId: streamTranscription
x-user-story: UFR-STT-020
x-controller: TranscriptController
@ -277,8 +272,6 @@ paths:
transcriptId: "TRS-SEG-001"
recordingId: "REC-20250123-001"
text: "안녕하세요, 오늘 회의를 시작하겠습니다."
speakerId: "SPK-001"
speakerName: "김철수"
timestamp: 1234567890
duration: 3.5
confidence: 0.92
@ -290,94 +283,6 @@ paths:
security:
- BearerAuth: []
/transcripts/batch:
post:
tags:
- Transcription
summary: 배치 음성-텍스트 변환
description: |
전체 오디오 파일을 배치로 변환 (비동기 처리)
**처리 흐름:**
1. 전체 오디오 파일 업로드
2. Azure Batch Transcription Job 생성
3. 비동기 처리 시작
4. Job ID 반환 (202 Accepted)
5. 처리 완료 시 Callback으로 결과 수신
**처리 시간:**
- 파일 업로드: 1-2초
- Azure 배치 처리: 5-30초 (파일 크기 따라)
- 총 처리 시간: 7-33초
operationId: batchTranscription
x-user-story: UFR-STT-020
x-controller: TranscriptController
requestBody:
required: true
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/BatchTranscriptionRequest'
responses:
'202':
description: 배치 작업 접수됨
content:
application/json:
schema:
$ref: '#/components/schemas/BatchTranscriptionResponse'
example:
jobId: "JOB-20250123-001"
recordingId: "REC-20250123-001"
status: "PROCESSING"
estimatedCompletionTime: "2025-01-23T10:31:00Z"
callbackUrl: "https://api.example.com/stt/v1/transcripts/callback"
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- BearerAuth: []
/transcripts/callback:
post:
tags:
- Transcription
summary: 배치 변환 완료 콜백
description: |
Azure Speech Service로부터 배치 변환 완료 콜백 수신
**처리 흐름:**
1. 배치 결과 수신
2. 세그먼트별 DB 저장
3. 전체 텍스트 병합
4. TranscriptionCompleted 이벤트 발행
operationId: batchTranscriptionCallback
x-user-story: UFR-STT-020
x-controller: TranscriptController
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/BatchCallbackRequest'
responses:
'200':
description: 콜백 처리 성공
content:
application/json:
schema:
$ref: '#/components/schemas/TranscriptionCompleteResponse'
example:
jobId: "JOB-20250123-001"
recordingId: "REC-20250123-001"
status: "COMPLETED"
segmentCount: 120
totalDuration: 1800
averageConfidence: 0.88
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
/transcripts/{recordingId}:
get:
@ -389,7 +294,7 @@ paths:
**응답 데이터:**
- 전체 텍스트
- 화자별 세그먼트 목록
- 세그먼트 목록
- 타임스탬프 정보
- 신뢰도 점수
operationId: getTranscription
@ -404,13 +309,6 @@ paths:
schema:
type: boolean
default: false
- name: speakerId
in: query
description: 특정 화자의 발언만 필터링
required: false
schema:
type: string
example: "SPK-001"
responses:
'200':
description: 변환 텍스트 조회 성공
@ -420,16 +318,13 @@ paths:
$ref: '#/components/schemas/TranscriptionResponse'
example:
recordingId: "REC-20250123-001"
fullText: "김철수: 안녕하세요...\n이영희: 네, 안녕하세요..."
fullText: "안녕하세요, 오늘 회의를 시작하겠습니다..."
segmentCount: 120
totalDuration: 1800
averageConfidence: 0.88
speakerCount: 3
segments:
- transcriptId: "TRS-SEG-001"
text: "안녕하세요, 오늘 회의를 시작하겠습니다."
speakerId: "SPK-001"
speakerName: "김철수"
timestamp: 0
duration: 3.5
confidence: 0.92
@ -440,179 +335,6 @@ paths:
security:
- BearerAuth: []
/speakers/identify:
post:
tags:
- Speaker
summary: 화자 식별
description: |
음성 데이터로부터 화자 식별
**처리 흐름:**
1. Voice signature 생성
2. 기존 프로필과 매칭
3. 신규 화자 자동 등록
4. 화자 정보 반환
**정확도:**
- 화자 식별 정확도: > 90%
- 처리 시간: ~300ms
operationId: identifySpeaker
x-user-story: UFR-STT-010
x-controller: SpeakerController
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/IdentifySpeakerRequest'
example:
recordingId: "REC-20250123-001"
audioFrame: "base64_encoded_audio_frame"
timestamp: 1234567890
responses:
'200':
description: 화자 식별 성공
content:
application/json:
schema:
$ref: '#/components/schemas/SpeakerIdentificationResponse'
example:
speakerId: "SPK-001"
speakerName: "김철수"
confidence: 0.95
isNewSpeaker: false
profileId: "PROFILE-12345"
'400':
$ref: '#/components/responses/BadRequest'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- BearerAuth: []
/speakers/{speakerId}:
get:
tags:
- Speaker
summary: 화자 정보 조회
description: 특정 화자의 상세 정보 조회
operationId: getSpeaker
x-user-story: UFR-STT-010
x-controller: SpeakerController
parameters:
- name: speakerId
in: path
description: 화자 ID
required: true
schema:
type: string
example: "SPK-001"
responses:
'200':
description: 화자 정보 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/SpeakerDetailResponse'
example:
speakerId: "SPK-001"
speakerName: "김철수"
profileId: "PROFILE-12345"
totalSegments: 45
totalDuration: 450
averageConfidence: 0.92
firstAppeared: "2025-01-23T10:30:15Z"
lastAppeared: "2025-01-23T11:00:00Z"
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- BearerAuth: []
put:
tags:
- Speaker
summary: 화자 정보 업데이트
description: 화자 이름 등 정보 수정
operationId: updateSpeaker
x-user-story: UFR-STT-010
x-controller: SpeakerController
parameters:
- name: speakerId
in: path
description: 화자 ID
required: true
schema:
type: string
example: "SPK-001"
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateSpeakerRequest'
example:
speakerName: "김철수 팀장"
userId: "USER-123"
responses:
'200':
description: 화자 정보 업데이트 성공
content:
application/json:
schema:
$ref: '#/components/schemas/SpeakerDetailResponse'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- BearerAuth: []
/recordings/{recordingId}/speakers:
get:
tags:
- Speaker
summary: 녹음의 화자 목록 조회
description: 특정 녹음에 참여한 모든 화자 목록 조회
operationId: getRecordingSpeakers
x-user-story: UFR-STT-010
x-controller: SpeakerController
parameters:
- $ref: '#/components/parameters/RecordingIdParam'
responses:
'200':
description: 화자 목록 조회 성공
content:
application/json:
schema:
$ref: '#/components/schemas/SpeakerListResponse'
example:
recordingId: "REC-20250123-001"
speakerCount: 3
speakers:
- speakerId: "SPK-001"
speakerName: "김철수"
segmentCount: 45
totalDuration: 450
speakingRatio: 0.45
- speakerId: "SPK-002"
speakerName: "이영희"
segmentCount: 38
totalDuration: 380
speakingRatio: 0.38
- speakerId: "SPK-003"
speakerName: "박민수"
segmentCount: 17
totalDuration: 170
speakingRatio: 0.17
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
security:
- BearerAuth: []
components:
securitySchemes:
BearerAuth:
@ -657,7 +379,7 @@ components:
example: "ko-KR"
attendeeCount:
type: integer
description: 참석자 수 (화자 식별 최적화용)
description: 참석자 수
minimum: 1
maximum: 50
example: 5
@ -809,10 +531,6 @@ components:
type: integer
description: 녹음 시간 (초)
example: 300
speakerCount:
type: integer
description: 화자 수
example: 3
segmentCount:
type: integer
description: 세그먼트 수
@ -866,14 +584,6 @@ components:
type: string
description: 변환된 텍스트
example: "안녕하세요, 오늘 회의를 시작하겠습니다."
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
speakerName:
type: string
description: 화자 이름
example: "김철수"
timestamp:
type: integer
description: 타임스탬프 (ms)
@ -895,89 +605,6 @@ components:
description: 낮은 신뢰도 경고 플래그 (< 60%)
example: false
BatchTranscriptionRequest:
type: object
required:
- recordingId
- audioFile
properties:
recordingId:
type: string
description: 녹음 ID
example: "REC-20250123-001"
audioFile:
type: string
format: binary
description: 오디오 파일 (WAV, MP3 등)
language:
type: string
description: 음성 인식 언어
default: "ko-KR"
example: "ko-KR"
callbackUrl:
type: string
format: uri
description: 처리 완료 콜백 URL
example: "https://api.example.com/stt/v1/transcripts/callback"
BatchTranscriptionResponse:
type: object
properties:
jobId:
type: string
description: 배치 작업 ID
example: "JOB-20250123-001"
recordingId:
type: string
description: 녹음 ID
example: "REC-20250123-001"
status:
type: string
description: 작업 상태
enum:
- QUEUED
- PROCESSING
- COMPLETED
- FAILED
example: "PROCESSING"
estimatedCompletionTime:
type: string
format: date-time
description: 예상 완료 시간
example: "2025-01-23T10:31:00Z"
callbackUrl:
type: string
format: uri
description: 콜백 URL
example: "https://api.example.com/stt/v1/transcripts/callback"
BatchCallbackRequest:
type: object
required:
- jobId
- status
- segments
properties:
jobId:
type: string
description: 배치 작업 ID
example: "JOB-20250123-001"
status:
type: string
description: 작업 상태
enum:
- COMPLETED
- FAILED
example: "COMPLETED"
segments:
type: array
description: 변환 세그먼트 목록
items:
$ref: '#/components/schemas/TranscriptionSegment'
error:
type: string
description: 오류 메시지 (실패 시)
example: "Audio file format not supported"
TranscriptionSegment:
type: object
@ -986,10 +613,6 @@ components:
type: string
description: 변환된 텍스트
example: "안녕하세요, 오늘 회의를 시작하겠습니다."
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
timestamp:
type: integer
description: 시작 타임스탬프 (ms)
@ -1061,10 +684,6 @@ components:
format: float
description: 평균 신뢰도 점수
example: 0.88
speakerCount:
type: integer
description: 화자 수
example: 3
segments:
type: array
description: 세그먼트 목록
@ -1082,14 +701,6 @@ components:
type: string
description: 변환된 텍스트
example: "안녕하세요, 오늘 회의를 시작하겠습니다."
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
speakerName:
type: string
description: 화자 이름
example: "김철수"
timestamp:
type: integer
description: 타임스탬프 (ms)
@ -1105,151 +716,6 @@ components:
description: 신뢰도 점수
example: 0.92
IdentifySpeakerRequest:
type: object
required:
- recordingId
- audioFrame
- timestamp
properties:
recordingId:
type: string
description: 녹음 ID
example: "REC-20250123-001"
audioFrame:
type: string
format: byte
description: Base64 인코딩된 오디오 프레임
example: "UklGRiQAAABXQVZFZm10IBAAAAABA..."
timestamp:
type: integer
description: 타임스탬프 (ms)
example: 1234567890
SpeakerIdentificationResponse:
type: object
properties:
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
speakerName:
type: string
description: 화자 이름
example: "김철수"
confidence:
type: number
format: float
description: 식별 신뢰도 (0-1)
minimum: 0
maximum: 1
example: 0.95
isNewSpeaker:
type: boolean
description: 신규 화자 여부
example: false
profileId:
type: string
description: Azure Speaker Profile ID
example: "PROFILE-12345"
SpeakerDetailResponse:
type: object
properties:
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
speakerName:
type: string
description: 화자 이름
example: "김철수"
profileId:
type: string
description: Azure Speaker Profile ID
example: "PROFILE-12345"
userId:
type: string
description: 연결된 사용자 ID
example: "USER-123"
totalSegments:
type: integer
description: 총 발언 세그먼트 수
example: 45
totalDuration:
type: integer
description: 총 발언 시간 (초)
example: 450
averageConfidence:
type: number
format: float
description: 평균 식별 신뢰도
example: 0.92
firstAppeared:
type: string
format: date-time
description: 최초 등장 시간
example: "2025-01-23T10:30:15Z"
lastAppeared:
type: string
format: date-time
description: 최근 등장 시간
example: "2025-01-23T11:00:00Z"
UpdateSpeakerRequest:
type: object
properties:
speakerName:
type: string
description: 화자 이름
example: "김철수 팀장"
userId:
type: string
description: 연결할 사용자 ID
example: "USER-123"
SpeakerListResponse:
type: object
properties:
recordingId:
type: string
description: 녹음 ID
example: "REC-20250123-001"
speakerCount:
type: integer
description: 화자 수
example: 3
speakers:
type: array
description: 화자 목록
items:
$ref: '#/components/schemas/SpeakerSummary'
SpeakerSummary:
type: object
properties:
speakerId:
type: string
description: 화자 ID
example: "SPK-001"
speakerName:
type: string
description: 화자 이름
example: "김철수"
segmentCount:
type: integer
description: 발언 세그먼트 수
example: 45
totalDuration:
type: integer
description: 총 발언 시간 (초)
example: 450
speakingRatio:
type: number
format: float
description: 발언 비율 (0-1)
example: 0.45
ErrorResponse:
type: object
properties:

View File

@ -1,14 +1,13 @@
@startuml
!theme mono
title STT Service - 음성 녹음 시작 및 화자 인식 (통합)
title STT Service - 음성 녹음 시작 및 실시간 인식
participant "Frontend<<E>>" as Frontend
participant "API Gateway<<E>>" as Gateway
participant "RecordingController" as Controller
participant "RecordingService" as Service
participant "AudioStreamManager" as StreamManager
participant "SpeakerIdentifier" as Speaker
participant "RecordingRepository" as Repository
participant "AzureSpeechClient" as AzureClient
database "STT DB" as DB
@ -51,7 +50,6 @@ note right
- 언어: ko-KR
- Format: PCM 16kHz
- 샘플레이트: 16kHz
- 화자 식별 활성화
- 실시간 스트리밍 모드
- Continuous recognition
end note
@ -108,32 +106,12 @@ deactivate AzureClient
StreamManager --> Service: recognized text
deactivate StreamManager
== 화자 식별 ==
Service -> Speaker: identifySpeaker(audioFrame)
activate Speaker
Speaker -> AzureClient: analyzeSpeakerProfile()\n(Speaker Recognition API)
activate AzureClient
note right
화자 식별:
- Voice signature 생성
- 기존 프로필과 매칭
- 신규 화자 자동 등록
end note
AzureClient --> Speaker: speakerId
deactivate AzureClient
Speaker --> Service: speaker info
deactivate Speaker
== 화자별 세그먼트 저장 ==
== 세그먼트 저장 ==
Service -> Repository: saveSttSegment(segment)
activate Repository
Repository -> DB: STT 세그먼트 저장\n(세션ID, 텍스트, 화자ID, 타임스탬프, 신뢰도)
Repository -> DB: STT 세그먼트 저장\n(세션ID, 텍스트, 타임스탬프, 신뢰도)
activate DB
DB --> Repository: segment saved
deactivate DB
@ -141,24 +119,13 @@ deactivate DB
Repository --> Service: saved
deactivate Repository
Service -> Repository: updateSpeakerInfo(recordingId, speakerId)
activate Repository
Repository -> DB: 화자 정보 저장/업데이트\n(녹음ID, 화자ID, 세그먼트수)
activate DB
DB --> Repository: 업데이트 완료
deactivate DB
Repository --> Service: 완료
deactivate Repository
Service --> Controller: streaming response\n{text, speaker, timestamp, confidence}
Service --> Controller: streaming response\n{text, timestamp, confidence}
deactivate Service
Controller --> Gateway: WebSocket message
deactivate Controller
Gateway --> Frontend: 실시간 자막 전송\n{text, speaker, timestamp}
Gateway --> Frontend: 실시간 자막 전송\n{text, timestamp}
deactivate Gateway
note over Frontend, EventHub
@ -166,12 +133,10 @@ note over Frontend, EventHub
- DB 녹음 생성: ~100ms
- Azure 인식기 초기화: ~500ms
- Blob 경로 생성: ~200ms
- 화자 식별: ~300ms
- 실시간 인식 지연: < 1초
- 총 초기화 시간: ~1.1
- 총 초기화 시간: ~0.8
정확도:
- 화자 식별 정확도: > 90%
- 음성 인식 정확도: 60-95%
end note

View File

@ -1,7 +1,7 @@
@startuml
!theme mono
title STT Service - 음성-텍스트 변환 (실시간/배치 통합)
title STT Service - 음성-텍스트 변환 (실시간 전용)
participant "Frontend<<E>>" as Frontend
participant "API Gateway<<E>>" as Gateway
@ -15,7 +15,7 @@ database "STT DB" as DB
database "Azure Blob Storage<<E>>" as BlobStorage
queue "Azure Event Hubs<<E>>" as EventHub
== 음성 데이터 스트리밍 수신 (실시간 모드) ==
== 음성 데이터 스트리밍 수신 ==
Frontend -> Gateway: POST /api/transcripts/stream\n(audioData, recordingId, timestamp)
activate Gateway
@ -26,9 +26,8 @@ activate Controller
Controller -> Service: processAudioStream(audioData, recordingId)
activate Service
alt 실시간 변환 모드
Service -> Engine: streamingTranscribe(audioData)
activate Engine
Service -> Engine: streamingTranscribe(audioData)
activate Engine
Engine -> AzureClient: recognizeAsync(audioData)
activate AzureClient
@ -38,7 +37,6 @@ alt 실시간 변환 모드
Azure Speech 설정:
- Mode: Continuous
- 언어: ko-KR
- 화자 식별 활성화
- 타임스탬프 자동 기록
- 신뢰도 점수 계산
- Profanity filter
@ -49,7 +47,7 @@ alt 실시간 변환 모드
BlobStorage --> AzureClient: 저장 완료
deactivate BlobStorage
AzureClient --> Engine: RecognitionResult\n(text, speakerId, confidence, timestamp, duration)
AzureClient --> Engine: RecognitionResult\n(text, confidence, timestamp, duration)
deactivate AzureClient
== 정확도 검증 및 처리 ==
@ -71,7 +69,7 @@ alt 실시간 변환 모드
Service -> TranscriptRepo: createTranscript(recordingId, segment)
activate TranscriptRepo
TranscriptRepo -> DB: 변환 결과 저장\n(텍스트ID, 녹음ID, 화자ID, 텍스트, 신뢰도, 타임스탬프, 경고플래그)
TranscriptRepo -> DB: 변환 결과 저장\n(텍스트ID, 녹음ID, 텍스트, 신뢰도, 타임스탬프, 경고플래그)
activate DB
DB --> TranscriptRepo: transcriptId 반환
deactivate DB
@ -79,19 +77,6 @@ alt 실시간 변환 모드
TranscriptRepo --> Service: TranscriptEntity 반환
deactivate TranscriptRepo
== 화자 정보 업데이트 ==
Service -> RecordingRepo: updateSpeakerInfo(recordingId, speakerId)
activate RecordingRepo
RecordingRepo -> DB: 화자 정보 저장/업데이트\n(녹음ID, 화자ID, 세그먼트수)
activate DB
DB --> RecordingRepo: 업데이트 완료
deactivate DB
RecordingRepo --> Service: 완료
deactivate RecordingRepo
== 이벤트 발행 ==
Service -> EventHub: TranscriptSegmentReady 이벤트 발행
@ -102,7 +87,6 @@ alt 실시간 변환 모드
- recordingId
- meetingId
- text
- speakerId
- timestamp
- confidence
end note
@ -112,128 +96,18 @@ alt 실시간 변환 모드
Service --> Controller: TranscriptResponse\n(transcriptId, text, confidence, warningFlag)
deactivate Service
Controller --> Gateway: 200 OK\n(transcriptId, text, speakerId, timestamp, confidence)
Controller --> Gateway: 200 OK\n(transcriptId, text, timestamp, confidence)
deactivate Controller
Gateway --> Frontend: 실시간 자막 응답
deactivate Gateway
else 배치 변환 모드
Gateway -> Controller: POST /api/v1/stt/transcribe\n{sessionId, audioFile}
activate Controller
Controller -> Service: transcribeAudio(sessionId, audioFile)
activate Service
Service -> RecordingRepo: findSessionById(sessionId)
activate RecordingRepo
RecordingRepo -> DB: STT 세션 조회\n(세션ID 기준)
DB --> RecordingRepo: session data
RecordingRepo --> Service: RecordingEntity
deactivate RecordingRepo
Service -> Engine: batchTranscribe(audioFile)
activate Engine
Engine -> AzureClient: batchTranscriptionAsync(audioUrl)
activate AzureClient
note right
배치 처리:
- 전체 파일 업로드
- 백그라운드 처리
- Callback URL 제공
- 화자별 그룹화
- 문장 경계 보정
end note
AzureClient --> Engine: transcription job ID
deactivate AzureClient
Engine --> Service: job submitted
deactivate Engine
Service -> RecordingRepo: updateSessionStatus(sessionId, "PROCESSING")
activate RecordingRepo
RecordingRepo -> DB: 세션 상태 업데이트\n(상태='처리중')
DB --> RecordingRepo: updated
RecordingRepo --> Service: updated
deactivate RecordingRepo
Service --> Controller: 202 Accepted\n{jobId, status}
deactivate Service
Controller --> Gateway: 202 Accepted
deactivate Controller
== 배치 처리 완료 (Callback) ==
AzureClient -> Controller: POST /api/v1/stt/callback\n{jobId, segments}
activate Controller
Controller -> Service: processBatchResult(jobId, segments)
activate Service
loop 각 세그먼트 처리
Service -> TranscriptRepo: createTranscript(recordingId, segment)
activate TranscriptRepo
TranscriptRepo -> DB: 변환 결과 저장
DB --> TranscriptRepo: saved
TranscriptRepo --> Service: saved
deactivate TranscriptRepo
end
== 전체 텍스트 통합 ==
Service -> TranscriptRepo: aggregateTranscription(sessionId)
activate TranscriptRepo
TranscriptRepo -> DB: 세그먼트 목록 조회\n(세션ID 기준, 타임스탬프 순 정렬)
DB --> TranscriptRepo: ordered segments
TranscriptRepo --> Service: segments
deactivate TranscriptRepo
Service -> Service: mergeSegments(segments)
note right
세그먼트 병합:
- 화자별 그룹화
- 시간 순서 정렬
- 문장 경계 보정
end note
Service -> RecordingRepo: saveTranscription(fullText)
activate RecordingRepo
RecordingRepo -> DB: 전체 텍스트 저장 및 상태 업데이트\n(전체텍스트, 상태='완료')
DB --> RecordingRepo: saved
RecordingRepo --> Service: updated session
deactivate RecordingRepo
Service -> EventHub: TranscriptionCompletedEvent 발행
note right
Event:
- sessionId
- meetingId
- fullText
- completedAt
end note
Service --> Controller: TranscriptionResponse\n{sessionId, text, segments}
deactivate Service
Controller --> Gateway: 200 OK\n{transcription, metadata}
deactivate Controller
end
note over Frontend, EventHub
**실시간 모드 처리 시간:**
**처리 시간:**
- Azure STT 처리: 1-3초
- DB 저장: ~100ms
- Event 발행: ~50ms
- 총 처리 시간: 1-4초
**배치 모드 처리 시간:**
- 파일 업로드: ~1-2초
- Azure 배치 처리: 5-30초 (파일 크기에 따라)
- DB 저장: ~500ms
- 총 처리 시간: 7-33초
- 총 처리 시간: 1-3초
**정확도 경고 기준:**
- < 60%: 수동 수정 권장 (경고 플래그)

View File

@ -1438,3 +1438,282 @@ Caused by: io.lettuce.core.RedisCommandExecutionException: NOAUTH HELLO must be
2025-10-23 16:37:29 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@1d9c4491] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@20505460]
2025-10-23 16:37:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-23 16:37:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-23 17:10:40 [main] INFO com.unicorn.hgzero.ai.AiApplication - Starting AiApplication using Java 23.0.2 with PID 43872 (/Users/jominseo/HGZero/ai/build/classes/java/main started by jominseo in /Users/jominseo/HGZero)
2025-10-23 17:10:40 [main] DEBUG com.unicorn.hgzero.ai.AiApplication - Running with Spring Boot v3.3.0, Spring v6.1.8
2025-10-23 17:10:40 [main] INFO com.unicorn.hgzero.ai.AiApplication - No active profile set, falling back to 1 default profile: "default"
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 3 ms. Found 0 JPA repository interfaces.
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-23 17:10:40 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0 ms. Found 0 Redis repository interfaces.
2025-10-23 17:10:41 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8084 (http)
2025-10-23 17:10:41 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-23 17:10:41 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.24]
2025-10-23 17:10:41 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-23 17:10:41 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 776 ms
2025-10-23 17:10:41 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-23 17:10:41 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.2.Final
2025-10-23 17:10:41 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@3e2d65e1
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@1174676f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@71f8ce0e
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@71f8ce0e
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@4fd92289
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@4fd92289
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@1a8e44fe
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@1a8e44fe
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@1a8e44fe
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@287317df
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@287317df
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@287317df
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@1fcc3461
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@1987807b
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@71469e01
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@41bbb219
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@3f2ae973
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@1a8b22b5
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@5f781173
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@43cf5bff
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@2b464384
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@2b464384
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@2b464384
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@681b42d3
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@77f7352a
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@77f7352a
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@4ede8888
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@571db8b4
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@571db8b4
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@571db8b4
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@65a2755e
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@2b3242a5
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@2b3242a5
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@11120583
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@2bf0c70d
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@5d8e4fa8
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@649009d6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@652f26da
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@484a5ddd
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@6796a873
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@6796a873
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@3acc3ee
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@1f293cb7
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@5972e3a
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@5790cbcb
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@32c6d164
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@645c9f0f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@58068b40
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@999cd18
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@999cd18
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@dd060be
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@df432ec
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@df432ec
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@6144e499
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@6144e499
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@26f204a4
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@28295554
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@4e671ef
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@4e671ef
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@42403dc6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@74a1d60e
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@16c0be3b
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@219edc05
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@219edc05
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@62f37bfd
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@1818d00b
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@b3a8455
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@b3a8455
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@5c930fc3
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@5c930fc3
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@25c6ab3f
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@7b80af04
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@7b80af04
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@7b80af04
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@2447940d
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@60ee7a51
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@70e1aa20
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@70e1aa20
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@e67d3b7
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@e67d3b7
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@e67d3b7
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@1618c98a
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@5b715ea
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@787a0fd6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@787a0fd6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@48b09105
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@48b09105
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@48b09105
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@18b45500
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@18b45500
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@25110bb9
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@25110bb9
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@dbda472
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@dbda472
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@41492479
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@41492479
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@7bef7505
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@7bef7505
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@568ef502
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@36f05595
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@3c46e6f6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@3c46e6f6
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@1c79d093
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@746fd19b
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@61d7bb61
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@33f81280
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@3991fe6d
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@3a0e7f89
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@665ed71a
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@15c1b543
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@23954300
2025-10-23 17:10:41 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-23 17:10:41 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-23 17:10:41 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@5f5c0eda
2025-10-23 17:10:41 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2025-10-23 17:10:41 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(2003, org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@31b7112d) replaced previous registration(org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@47fc9ce)
2025-10-23 17:10:41 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(6, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@1b5d1d9) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@703a2bc9)
2025-10-23 17:10:41 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2004, BlobTypeDescriptor(BLOB_BINDING)) replaced previous registration(BlobTypeDescriptor(DEFAULT))
2025-10-23 17:10:41 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2005, ClobTypeDescriptor(CLOB_BINDING)) replaced previous registration(ClobTypeDescriptor(DEFAULT))
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration JAVA_OBJECT -> org.hibernate.type.JavaObjectType@e460ca1
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@e460ca1
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Type registration key [java.lang.Object] overrode previous entry : `org.hibernate.type.JavaObjectType@3c46e6f6`
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.DurationType -> basicType@1(java.time.Duration,3015)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> basicType@1(java.time.Duration,3015)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> basicType@1(java.time.Duration,3015)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetDateTimeType -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.ZonedDateTimeType -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetTimeType -> basicType@4(java.time.OffsetTime,3007)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-23 17:10:41 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-23 17:10:41 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@268e30d4] to MetadataBuildingContext [org.hibernate.boot.internal.MetadataBuildingContextRootImpl@7c50709a]
2025-10-23 17:10:41 [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-23 17:10:41 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@268e30d4] to SessionFactoryImplementor [org.hibernate.internal.SessionFactoryImpl@263f6e96]
2025-10-23 17:10:41 [main] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@263f6e96] for TypeConfiguration
2025-10-23 17:10:41 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-23 17:10:41 [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-23 17:10:42 [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-23 17:10:42 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: 4d9e182a-5838-4fd3-8e57-70219ebe9076
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-23 17:10:42 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-10-23 17:10:42 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 3 endpoints beneath base path '/actuator'
2025-10-23 17:10:42 [main] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@23d1090, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@46c6541f, org.springframework.security.web.context.SecurityContextHolderFilter@67744663, org.springframework.security.web.header.HeaderWriterFilter@1a2bcce1, org.springframework.web.filter.CorsFilter@aba3735, org.springframework.security.web.csrf.CsrfFilter@417c9b17, org.springframework.security.web.authentication.logout.LogoutFilter@75b598a5, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@401b7109, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@24a024c8, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@16bba8ae, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@7f36b021, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@387cd426, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6295cc30, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@7c689379, org.springframework.security.web.access.ExceptionTranslationFilter@ae5eeee, org.springframework.security.web.access.intercept.AuthorizationFilter@431bf770]
2025-10-23 17:10:42 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 8084 (http) with context path '/'
2025-10-23 17:10:42 [main] INFO com.unicorn.hgzero.ai.AiApplication - Started AiApplication in 2.293 seconds (process running for 2.491)
2025-10-23 17:10:42 [RMI TCP Connection(1)-127.0.0.1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-23 17:10:42 [RMI TCP Connection(1)-127.0.0.1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-23 17:10:42 [RMI TCP Connection(1)-127.0.0.1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms
2025-10-23 17:10:42 [boundedElastic-1] WARN o.s.b.a.d.r.RedisReactiveHealthIndicator - Redis health check failed
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1847)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1778)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1580)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1560)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1521)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1557)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedReactiveConnection(LettuceConnectionFactory.java:1268)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getReactiveConnection(LettuceConnectionFactory.java:1143)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getReactiveConnection(LettuceConnectionFactory.java:119)
at reactor.core.publisher.MonoSupplier.call(MonoSupplier.java:67)
at reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:228)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68)
at reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:28)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1575)
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to 20.249.177.114/<unresolved>:6379
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:350)
at io.lettuce.core.RedisClient.connect(RedisClient.java:215)
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:112)
at java.base/java.util.Optional.orElseGet(Optional.java:364)
at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:112)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1776)
... 16 common frames omitted
Caused by: io.lettuce.core.RedisCommandExecutionException: NOAUTH HELLO must be called with the client already authenticated, otherwise the HELLO <proto> AUTH <user> <pass> option can be used to authenticate the client and select the RESP protocol version at the same time
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:147)
at io.lettuce.core.internal.ExceptionFactory.createExecutionException(ExceptionFactory.java:116)
at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120)
at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111)
at io.lettuce.core.protocol.CommandWrapper.complete(CommandWrapper.java:63)
at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:745)
at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:680)
at io.lettuce.core.protocol.CommandHandler.channelRead(CommandHandler.java:597)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1407)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:918)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:994)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
... 1 common frames omitted
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui.html
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.s.w.s.HttpSessionRequestCache - Saved request http://localhost:8084/swagger-ui.html?continue to session
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@49c72fb7, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@7d91e9c9
2025-10-23 17:11:28 [http-nio-8084-exec-1] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to http://localhost:8084/login
2025-10-23 17:11:28 [http-nio-8084-exec-2] DEBUG o.s.security.web.FilterChainProxy - Securing GET /login
2025-10-23 17:11:28 [http-nio-8084-exec-3] DEBUG o.s.security.web.FilterChainProxy - Securing GET /favicon.ico
2025-10-23 17:11:28 [http-nio-8084-exec-3] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-23 17:11:28 [http-nio-8084-exec-3] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@49c72fb7, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2025-10-23 17:11:28 [http-nio-8084-exec-3] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@7d91e9c9
2025-10-23 17:11:28 [http-nio-8084-exec-3] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to http://localhost:8084/login
2025-10-23 17:11:28 [http-nio-8084-exec-4] DEBUG o.s.security.web.FilterChainProxy - Securing GET /login
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.security.web.FilterChainProxy - Securing GET /swagger-ui.html
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.s.w.s.HttpSessionRequestCache - Saved request http://localhost:8084/swagger-ui.html?continue to session
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@49c72fb7, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@7d91e9c9
2025-10-23 17:11:43 [http-nio-8084-exec-5] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to http://localhost:8084/login
2025-10-23 17:11:43 [http-nio-8084-exec-6] DEBUG o.s.security.web.FilterChainProxy - Securing GET /login
2025-10-23 17:11:43 [http-nio-8084-exec-7] DEBUG o.s.security.web.FilterChainProxy - Securing GET /favicon.ico
2025-10-23 17:11:43 [http-nio-8084-exec-7] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-23 17:11:43 [http-nio-8084-exec-7] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Trying to match using And [Not [RequestHeaderRequestMatcher [expectedHeaderName=X-Requested-With, expectedHeaderValue=XMLHttpRequest]], MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@49c72fb7, matchingMediaTypes=[application/xhtml+xml, image/*, text/html, text/plain], useEquals=false, ignoredMediaTypes=[*/*]]]
2025-10-23 17:11:43 [http-nio-8084-exec-7] DEBUG o.s.s.w.a.DelegatingAuthenticationEntryPoint - Match found! Executing org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint@7d91e9c9
2025-10-23 17:11:43 [http-nio-8084-exec-7] DEBUG o.s.s.web.DefaultRedirectStrategy - Redirecting to http://localhost:8084/login
2025-10-23 17:11:43 [http-nio-8084-exec-8] DEBUG o.s.security.web.FilterChainProxy - Securing GET /login
2025-10-23 17:12:37 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-23 17:12:37 [SpringApplicationShutdownHook] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryClosed from [org.hibernate.internal.SessionFactoryImpl@263f6e96] for TypeConfiguration
2025-10-23 17:12:37 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@7aa91cdd] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@263f6e96]
2025-10-23 17:12:37 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-23 17:12:37 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

View File

@ -3,6 +3,18 @@ bootJar {
}
dependencies {
// Common module
implementation project(':common')
// Spring Boot starters
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
// Database
runtimeOnly 'org.postgresql:postgresql'
// Azure Speech SDK
implementation "com.microsoft.cognitiveservices.speech:client-sdk:${azureSpeechVersion}"
@ -14,4 +26,11 @@ dependencies {
// WebSocket
implementation 'org.springframework.boot:spring-boot-starter-websocket'
// Test dependencies
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'com.h2database:h2'
testImplementation('it.ozimov:embedded-redis:0.7.3') {
exclude group: 'org.slf4j', module: 'slf4j-simple'
}
}

View File

@ -1,146 +0,0 @@
package com.unicorn.hgzero.stt.controller;
import com.unicorn.hgzero.common.dto.ApiResponse;
import com.unicorn.hgzero.stt.dto.SpeakerDto;
import com.unicorn.hgzero.stt.service.SpeakerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
/**
* 화자 관리 컨트롤러
* 화자 식별 관리 기능을 제공
*/
@Slf4j
@RestController
@RequestMapping("/api/v1/stt/speakers")
@RequiredArgsConstructor
@Validated
@Tag(name = "화자 관리", description = "화자 식별 및 관리 API")
public class SpeakerController {
private final SpeakerService speakerService;
@Operation(
summary = "화자 식별",
description = "음성 데이터로부터 화자를 식별합니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "화자 식별 성공",
content = @Content(schema = @Schema(implementation = SpeakerDto.IdentificationResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 요청"
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "녹음을 찾을 수 없음"
)
})
@PostMapping("/identify")
public ResponseEntity<ApiResponse<SpeakerDto.IdentificationResponse>> identifySpeaker(
@Valid @RequestBody SpeakerDto.IdentifyRequest request) {
log.info("화자 식별 요청 - recordingId: {}", request.getRecordingId());
SpeakerDto.IdentificationResponse response = speakerService.identifySpeaker(request);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "화자 정보 조회",
description = "화자의 상세 정보를 조회합니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "조회 성공",
content = @Content(schema = @Schema(implementation = SpeakerDto.DetailResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "화자를 찾을 수 없음"
)
})
@GetMapping("/{speakerId}")
public ResponseEntity<ApiResponse<SpeakerDto.DetailResponse>> getSpeaker(
@Parameter(description = "화자 ID", required = true)
@PathVariable String speakerId) {
log.debug("화자 조회 요청 - speakerId: {}", speakerId);
SpeakerDto.DetailResponse response = speakerService.getSpeaker(speakerId);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "화자 정보 수정",
description = "화자의 이름 및 사용자 연결 정보를 수정합니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "수정 성공",
content = @Content(schema = @Schema(implementation = SpeakerDto.DetailResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 요청"
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "화자를 찾을 수 없음"
)
})
@PutMapping("/{speakerId}")
public ResponseEntity<ApiResponse<SpeakerDto.DetailResponse>> updateSpeaker(
@Parameter(description = "화자 ID", required = true)
@PathVariable String speakerId,
@Valid @RequestBody SpeakerDto.UpdateRequest request) {
log.info("화자 정보 수정 요청 - speakerId: {}, speakerName: {}",
speakerId, request.getSpeakerName());
SpeakerDto.DetailResponse response = speakerService.updateSpeaker(speakerId, request);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "녹음별 화자 목록 조회",
description = "특정 녹음에 참여한 화자 목록과 통계를 조회합니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "조회 성공",
content = @Content(schema = @Schema(implementation = SpeakerDto.ListResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "녹음을 찾을 수 없음"
)
})
@GetMapping("/recordings/{recordingId}")
public ResponseEntity<ApiResponse<SpeakerDto.ListResponse>> getRecordingSpeakers(
@Parameter(description = "녹음 ID", required = true)
@PathVariable String recordingId) {
log.debug("녹음별 화자 목록 조회 요청 - recordingId: {}", recordingId);
SpeakerDto.ListResponse response = speakerService.getRecordingSpeakers(recordingId);
return ResponseEntity.ok(ApiResponse.success(response));
}
}

View File

@ -12,11 +12,9 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import jakarta.validation.Valid;
@ -64,64 +62,7 @@ public class TranscriptionController {
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "배치 음성 변환",
description = "오디오 파일을 업로드하여 배치 변환 작업을 시작합니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "배치 작업 시작 성공",
content = @Content(schema = @Schema(implementation = TranscriptionDto.BatchResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 파일 형식 또는 요청"
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "404",
description = "녹음 세션을 찾을 수 없음"
)
})
@PostMapping(value = "/batch", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ApiResponse<TranscriptionDto.BatchResponse>> transcribeAudioBatch(
@Parameter(description = "배치 변환 요청 정보")
@Valid @RequestPart("request") TranscriptionDto.BatchRequest request,
@Parameter(description = "변환할 오디오 파일")
@RequestPart("audioFile") MultipartFile audioFile) {
log.info("배치 음성 변환 요청 - recordingId: {}, fileSize: {}",
request.getRecordingId(), audioFile.getSize());
TranscriptionDto.BatchResponse response = transcriptionService.transcribeAudioBatch(request, audioFile);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "배치 변환 완료 콜백",
description = "Azure 배치 변환 완료 시 호출되는 콜백 엔드포인트입니다."
)
@ApiResponses(value = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "200",
description = "콜백 처리 성공",
content = @Content(schema = @Schema(implementation = TranscriptionDto.CompleteResponse.class))
),
@io.swagger.v3.oas.annotations.responses.ApiResponse(
responseCode = "400",
description = "잘못된 콜백 데이터"
)
})
@PostMapping("/batch/callback")
public ResponseEntity<ApiResponse<TranscriptionDto.CompleteResponse>> processBatchCallback(
@Valid @RequestBody TranscriptionDto.BatchCallbackRequest request) {
log.info("배치 변환 콜백 처리 - jobId: {}, status: {}",
request.getJobId(), request.getStatus());
TranscriptionDto.CompleteResponse response = transcriptionService.processBatchCallback(request);
return ResponseEntity.ok(ApiResponse.success(response));
}
@Operation(
summary = "변환 결과 조회",
@ -141,15 +82,10 @@ public class TranscriptionController {
@GetMapping("/{recordingId}")
public ResponseEntity<ApiResponse<TranscriptionDto.Response>> getTranscription(
@Parameter(description = "녹음 ID", required = true)
@PathVariable String recordingId,
@Parameter(description = "세그먼트 정보 포함 여부")
@RequestParam(required = false, defaultValue = "false") Boolean includeSegments,
@Parameter(description = "특정 화자 필터")
@RequestParam(required = false) String speakerId) {
log.debug("변환 결과 조회 요청 - recordingId: {}, includeSegments: {}, speakerId: {}",
recordingId, includeSegments, speakerId);
@PathVariable String recordingId) {
log.debug("변환 결과 조회 요청 - recordingId: {}", recordingId);
TranscriptionDto.Response response = transcriptionService.getTranscription(recordingId, includeSegments, speakerId);
TranscriptionDto.Response response = transcriptionService.getTranscription(recordingId);
return ResponseEntity.ok(ApiResponse.success(response));
}

View File

@ -50,16 +50,6 @@ public class Recording {
*/
private final Integer duration;
/**
* 파일 크기 (bytes)
*/
private final Long fileSize;
/**
* 저장 경로
*/
private final String storagePath;
/**
* 언어 설정
*/

View File

@ -1,72 +0,0 @@
package com.unicorn.hgzero.stt.domain;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import java.time.LocalDateTime;
/**
* 화자 도메인 모델
* 음성 화자 정보를 나타내는 도메인 객체
*/
@Getter
@Builder
@ToString
public class Speaker {
/**
* 화자 ID
*/
private final String speakerId;
/**
* 화자 이름
*/
private final String speakerName;
/**
* Azure Speaker Profile ID
*/
private final String profileId;
/**
* 연결된 사용자 ID
*/
private final String userId;
/**
* 발언 세그먼트
*/
private final Integer totalSegments;
/**
* 발언 시간 ()
*/
private final Integer totalDuration;
/**
* 평균 식별 신뢰도
*/
private final Double averageConfidence;
/**
* 최초 등장 시간
*/
private final LocalDateTime firstAppeared;
/**
* 최근 등장 시간
*/
private final LocalDateTime lastAppeared;
/**
* 생성 시간
*/
private final LocalDateTime createdAt;
/**
* 수정 시간
*/
private final LocalDateTime updatedAt;
}

View File

@ -50,7 +50,6 @@ public class RecordingDto {
private final String sessionId;
private final String status;
private final String streamUrl;
private final String storagePath;
private final Integer estimatedInitTime;
}
@ -95,8 +94,6 @@ public class RecordingDto {
private final LocalDateTime startTime;
private final LocalDateTime endTime;
private final Integer duration;
private final Long fileSize;
private final String storagePath;
}
/**
@ -116,7 +113,6 @@ public class RecordingDto {
private final Integer duration;
private final Integer speakerCount;
private final Integer segmentCount;
private final String storagePath;
private final String language;
}
}

View File

@ -1,109 +0,0 @@
package com.unicorn.hgzero.stt.dto;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.DecimalMax;
import jakarta.validation.constraints.DecimalMin;
import java.time.LocalDateTime;
import java.util.List;
/**
* 화자 관련 DTO 클래스들
*/
public class SpeakerDto {
/**
* 화자 식별 요청 DTO
*/
@Getter
@Builder
@ToString
public static class IdentifyRequest {
@NotBlank(message = "녹음 ID는 필수입니다")
private final String recordingId;
@NotBlank(message = "오디오 프레임은 필수입니다")
private final String audioFrame;
private final Long timestamp;
}
/**
* 화자 식별 응답 DTO
*/
@Getter
@Builder
@ToString
public static class IdentificationResponse {
private final String speakerId;
private final String speakerName;
private final Double confidence;
private final Boolean isNewSpeaker;
private final String profileId;
}
/**
* 화자 상세 응답 DTO
*/
@Getter
@Builder
@ToString
public static class DetailResponse {
private final String speakerId;
private final String speakerName;
private final String profileId;
private final String userId;
private final Integer totalSegments;
private final Integer totalDuration;
private final Double averageConfidence;
private final LocalDateTime firstAppeared;
private final LocalDateTime lastAppeared;
}
/**
* 화자 정보 업데이트 요청 DTO
*/
@Getter
@Builder
@ToString
public static class UpdateRequest {
private final String speakerName;
private final String userId;
}
/**
* 화자 목록 응답 DTO
*/
@Getter
@Builder
@ToString
public static class ListResponse {
private final String recordingId;
private final Integer speakerCount;
private final List<SpeakerSummary> speakers;
}
/**
* 화자 요약 DTO
*/
@Getter
@Builder
@ToString
public static class SpeakerSummary {
private final String speakerId;
private final String speakerName;
private final Integer segmentCount;
private final Integer totalDuration;
private final Double speakingRatio;
}
}

View File

@ -62,12 +62,10 @@ public class RecordingEvent {
private LocalDateTime startTime;
private LocalDateTime endTime;
private Integer duration;
private Long fileSize;
private String storagePath;
private LocalDateTime eventTime;
public static RecordingStopped of(String recordingId, String meetingId, String stoppedBy,
LocalDateTime startTime, Integer duration, Long fileSize, String storagePath) {
LocalDateTime startTime, Integer duration) {
return RecordingStopped.builder()
.eventId(java.util.UUID.randomUUID().toString())
.eventType("RecordingStopped")
@ -77,8 +75,6 @@ public class RecordingEvent {
.startTime(startTime)
.endTime(LocalDateTime.now())
.duration(duration)
.fileSize(fileSize)
.storagePath(storagePath)
.eventTime(LocalDateTime.now())
.build();
}

View File

@ -1,120 +0,0 @@
package com.unicorn.hgzero.stt.event;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 화자 관련 이벤트 정의
*/
public class SpeakerEvent {
/**
* 신규 화자 식별 이벤트
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class NewSpeakerIdentified {
private String eventId;
private String eventType;
private String speakerId;
private String speakerName;
private String profileId;
private String recordingId;
private String meetingId;
private Double confidence;
private LocalDateTime firstAppeared;
private LocalDateTime eventTime;
public static NewSpeakerIdentified of(String speakerId, String speakerName, String profileId,
String recordingId, String meetingId, Double confidence) {
return NewSpeakerIdentified.builder()
.eventId(java.util.UUID.randomUUID().toString())
.eventType("NewSpeakerIdentified")
.speakerId(speakerId)
.speakerName(speakerName)
.profileId(profileId)
.recordingId(recordingId)
.meetingId(meetingId)
.confidence(confidence)
.firstAppeared(LocalDateTime.now())
.eventTime(LocalDateTime.now())
.build();
}
}
/**
* 화자 정보 업데이트 이벤트
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class SpeakerUpdated {
private String eventId;
private String eventType;
private String speakerId;
private String oldSpeakerName;
private String newSpeakerName;
private String oldUserId;
private String newUserId;
private String updatedBy;
private LocalDateTime eventTime;
public static SpeakerUpdated of(String speakerId, String oldSpeakerName, String newSpeakerName,
String oldUserId, String newUserId, String updatedBy) {
return SpeakerUpdated.builder()
.eventId(java.util.UUID.randomUUID().toString())
.eventType("SpeakerUpdated")
.speakerId(speakerId)
.oldSpeakerName(oldSpeakerName)
.newSpeakerName(newSpeakerName)
.oldUserId(oldUserId)
.newUserId(newUserId)
.updatedBy(updatedBy)
.eventTime(LocalDateTime.now())
.build();
}
}
/**
* 화자 통계 업데이트 이벤트
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class SpeakerStatisticsUpdated {
private String eventId;
private String eventType;
private String speakerId;
private String recordingId;
private String meetingId;
private Integer totalSegments;
private Integer totalDuration;
private Double averageConfidence;
private LocalDateTime lastAppeared;
private LocalDateTime eventTime;
public static SpeakerStatisticsUpdated of(String speakerId, String recordingId, String meetingId,
Integer totalSegments, Integer totalDuration, Double averageConfidence) {
return SpeakerStatisticsUpdated.builder()
.eventId(java.util.UUID.randomUUID().toString())
.eventType("SpeakerStatisticsUpdated")
.speakerId(speakerId)
.recordingId(recordingId)
.meetingId(meetingId)
.totalSegments(totalSegments)
.totalDuration(totalDuration)
.averageConfidence(averageConfidence)
.lastAppeared(LocalDateTime.now())
.eventTime(LocalDateTime.now())
.build();
}
}
}

View File

@ -43,12 +43,6 @@ public class RecordingEntity extends BaseTimeEntity {
@Column(name = "duration")
private Integer duration;
@Column(name = "file_size")
private Long fileSize;
@Column(name = "storage_path", length = 500)
private String storagePath;
@Column(name = "language", length = 10, nullable = false)
private String language;
@ -70,8 +64,6 @@ public class RecordingEntity extends BaseTimeEntity {
.startTime(startTime)
.endTime(endTime)
.duration(duration)
.fileSize(fileSize)
.storagePath(storagePath)
.language(language)
.speakerCount(speakerCount)
.segmentCount(segmentCount)
@ -90,8 +82,6 @@ public class RecordingEntity extends BaseTimeEntity {
.startTime(recording.getStartTime())
.endTime(recording.getEndTime())
.duration(recording.getDuration())
.fileSize(recording.getFileSize())
.storagePath(recording.getStoragePath())
.language(recording.getLanguage())
.speakerCount(recording.getSpeakerCount())
.segmentCount(recording.getSegmentCount())

View File

@ -1,104 +0,0 @@
package com.unicorn.hgzero.stt.repository.entity;
import com.unicorn.hgzero.common.entity.BaseTimeEntity;
import com.unicorn.hgzero.stt.domain.Speaker;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
/**
* 화자 엔티티
* 음성 화자 정보를 저장하는 JPA 엔티티
*/
@Entity
@Table(name = "speakers")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@ToString
public class SpeakerEntity extends BaseTimeEntity {
@Id
@Column(name = "speaker_id", length = 50)
private String speakerId;
@Column(name = "speaker_name", length = 100)
private String speakerName;
@Column(name = "profile_id", length = 100)
private String profileId;
@Column(name = "user_id", length = 50)
private String userId;
@Column(name = "total_segments")
private Integer totalSegments;
@Column(name = "total_duration")
private Integer totalDuration;
@Column(name = "average_confidence")
private Double averageConfidence;
@Column(name = "first_appeared")
private LocalDateTime firstAppeared;
@Column(name = "last_appeared")
private LocalDateTime lastAppeared;
/**
* 도메인 객체로 변환
*/
public Speaker toDomain() {
return Speaker.builder()
.speakerId(speakerId)
.speakerName(speakerName)
.profileId(profileId)
.userId(userId)
.totalSegments(totalSegments)
.totalDuration(totalDuration)
.averageConfidence(averageConfidence)
.firstAppeared(firstAppeared)
.lastAppeared(lastAppeared)
.createdAt(getCreatedAt())
.updatedAt(getUpdatedAt())
.build();
}
/**
* 도메인 객체에서 엔티티 생성
*/
public static SpeakerEntity fromDomain(Speaker speaker) {
return SpeakerEntity.builder()
.speakerId(speaker.getSpeakerId())
.speakerName(speaker.getSpeakerName())
.profileId(speaker.getProfileId())
.userId(speaker.getUserId())
.totalSegments(speaker.getTotalSegments())
.totalDuration(speaker.getTotalDuration())
.averageConfidence(speaker.getAverageConfidence())
.firstAppeared(speaker.getFirstAppeared())
.lastAppeared(speaker.getLastAppeared())
.build();
}
/**
* 화자 정보 업데이트
*/
public void updateSpeakerInfo(String speakerName, String userId) {
this.speakerName = speakerName;
this.userId = userId;
}
/**
* 통계 정보 업데이트
*/
public void updateStatistics(Integer totalSegments, Integer totalDuration, Double averageConfidence) {
this.totalSegments = totalSegments;
this.totalDuration = totalDuration;
this.averageConfidence = averageConfidence;
this.lastAppeared = LocalDateTime.now();
}
}

View File

@ -1,51 +0,0 @@
package com.unicorn.hgzero.stt.repository.jpa;
import com.unicorn.hgzero.stt.repository.entity.SpeakerEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
* 화자 JPA Repository
* 화자 정보에 대한 데이터베이스 접근을 담당
*/
@Repository
public interface SpeakerRepository extends JpaRepository<SpeakerEntity, String> {
/**
* 사용자 ID로 화자 조회
*/
Optional<SpeakerEntity> findByUserId(String userId);
/**
* Azure Profile ID로 화자 조회
*/
Optional<SpeakerEntity> findByProfileId(String profileId);
/**
* 화자명으로 검색
*/
List<SpeakerEntity> findBySpeakerNameContaining(String speakerName);
/**
* 발언 비중이 높은 화자 조회
*/
@Query("SELECT s FROM SpeakerEntity s WHERE s.totalDuration > :minDuration ORDER BY s.totalDuration DESC")
List<SpeakerEntity> findActiveSpeakers(@Param("minDuration") Integer minDuration);
/**
* 신뢰도가 낮은 화자 조회
*/
@Query("SELECT s FROM SpeakerEntity s WHERE s.averageConfidence < :threshold ORDER BY s.averageConfidence ASC")
List<SpeakerEntity> findLowConfidenceSpeakers(@Param("threshold") Double threshold);
/**
* 사용자 ID 미지정 화자 조회
*/
@Query("SELECT s FROM SpeakerEntity s WHERE s.userId IS NULL ORDER BY s.totalDuration DESC")
List<SpeakerEntity> findUnassignedSpeakers();
}

View File

@ -50,7 +50,6 @@ public class RecordingServiceImpl implements RecordingService {
.language(request.getLanguage() != null ? request.getLanguage() : "ko-KR")
.speakerCount(0)
.segmentCount(0)
.storagePath(generateStoragePath(request.getMeetingId(), request.getSessionId()))
.build();
recordingRepository.save(recording);
@ -65,7 +64,6 @@ public class RecordingServiceImpl implements RecordingService {
.sessionId(request.getSessionId())
.status("READY")
.streamUrl(streamUrl)
.storagePath(recording.getStoragePath())
.estimatedInitTime(1100)
.build();
}
@ -119,14 +117,13 @@ public class RecordingServiceImpl implements RecordingService {
// 녹음 시간 계산 (임시로 30분으로 설정)
Integer duration = 1800; // 실제로는 startTime과 endTime 차이 계산
Long fileSize = 172800000L; // 실제로는 Azure Blob에서 파일 크기 조회
RecordingEntity savedRecording = recordingRepository.save(recording);
// 녹음 중지 이벤트 발행
// 녹음 중지 이벤트 발행 (음성 파일 저장하지 않으므로 파일 정보 제외)
RecordingEvent.RecordingStopped event = RecordingEvent.RecordingStopped.of(
recordingId, recording.getMeetingId(), request.getStoppedBy(),
recording.getStartTime(), duration, fileSize, recording.getStoragePath()
recording.getStartTime(), duration
);
eventPublisher.publishAsync("recording-events", event);
@ -138,8 +135,6 @@ public class RecordingServiceImpl implements RecordingService {
.startTime(recording.getStartTime())
.endTime(endTime)
.duration(duration)
.fileSize(fileSize)
.storagePath(recording.getStoragePath())
.build();
}
@ -160,7 +155,6 @@ public class RecordingServiceImpl implements RecordingService {
.duration(recording.getDuration())
.speakerCount(recording.getSpeakerCount())
.segmentCount(recording.getSegmentCount())
.storagePath(recording.getStoragePath())
.language(recording.getLanguage())
.build();
}
@ -181,10 +175,4 @@ public class RecordingServiceImpl implements RecordingService {
String.format("%03d", (int)(Math.random() * 1000));
}
/**
* 저장 경로 생성
*/
private String generateStoragePath(String meetingId, String sessionId) {
return String.format("recordings/%s/%s.wav", meetingId, sessionId);
}
}

View File

@ -1,43 +0,0 @@
package com.unicorn.hgzero.stt.service;
import com.unicorn.hgzero.stt.dto.SpeakerDto;
/**
* 화자 서비스 인터페이스
* 화자 식별 관리 기능을 정의
*/
public interface SpeakerService {
/**
* 화자 식별
*
* @param request 화자 식별 요청
* @return 화자 식별 응답
*/
SpeakerDto.IdentificationResponse identifySpeaker(SpeakerDto.IdentifyRequest request);
/**
* 화자 정보 조회
*
* @param speakerId 화자 ID
* @return 화자 상세 응답
*/
SpeakerDto.DetailResponse getSpeaker(String speakerId);
/**
* 화자 정보 업데이트
*
* @param speakerId 화자 ID
* @param request 화자 업데이트 요청
* @return 화자 상세 응답
*/
SpeakerDto.DetailResponse updateSpeaker(String speakerId, SpeakerDto.UpdateRequest request);
/**
* 녹음의 화자 목록 조회
*
* @param recordingId 녹음 ID
* @return 화자 목록 응답
*/
SpeakerDto.ListResponse getRecordingSpeakers(String recordingId);
}

View File

@ -1,218 +0,0 @@
package com.unicorn.hgzero.stt.service;
import com.unicorn.hgzero.common.exception.BusinessException;
import com.unicorn.hgzero.common.exception.ErrorCode;
import com.unicorn.hgzero.stt.dto.SpeakerDto;
import com.unicorn.hgzero.stt.event.SpeakerEvent;
import com.unicorn.hgzero.stt.event.publisher.EventPublisher;
import com.unicorn.hgzero.stt.repository.entity.SpeakerEntity;
import com.unicorn.hgzero.stt.repository.jpa.SpeakerRepository;
import com.unicorn.hgzero.stt.repository.jpa.TranscriptSegmentRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* 화자 서비스 구현체
* 화자 식별 관리 기능을 구현
*/
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional
public class SpeakerServiceImpl implements SpeakerService {
private final SpeakerRepository speakerRepository;
private final TranscriptSegmentRepository segmentRepository;
private final EventPublisher eventPublisher;
@Override
public SpeakerDto.IdentificationResponse identifySpeaker(SpeakerDto.IdentifyRequest request) {
log.info("화자 식별 시작 - recordingId: {}", request.getRecordingId());
// Azure Speaker Recognition API 호출 시뮬레이션
String profileId = simulateAzureSpeakerRecognition(request.getAudioFrame());
Double confidence = simulateIdentificationConfidence();
// 기존 화자 조회
SpeakerEntity speaker = speakerRepository.findByProfileId(profileId).orElse(null);
boolean isNewSpeaker = false;
if (speaker == null) {
// 신규 화자 등록
String speakerId = generateSpeakerId();
String speakerName = "화자-" + speakerId.substring(4);
speaker = SpeakerEntity.builder()
.speakerId(speakerId)
.speakerName(speakerName)
.profileId(profileId)
.totalSegments(0)
.totalDuration(0)
.averageConfidence(confidence)
.firstAppeared(LocalDateTime.now())
.lastAppeared(LocalDateTime.now())
.build();
speakerRepository.save(speaker);
isNewSpeaker = true;
// 신규 화자 식별 이벤트 발행
SpeakerEvent.NewSpeakerIdentified event = SpeakerEvent.NewSpeakerIdentified.of(
speakerId, speakerName, profileId, request.getRecordingId(),
extractMeetingIdFromRecordingId(request.getRecordingId()), confidence
);
eventPublisher.publishAsync("speaker-events", event);
log.info("신규 화자 등록 완료 - speakerId: {}, confidence: {}", speakerId, confidence);
} else {
log.debug("기존 화자 식별 - speakerId: {}, confidence: {}", speaker.getSpeakerId(), confidence);
}
return SpeakerDto.IdentificationResponse.builder()
.speakerId(speaker.getSpeakerId())
.speakerName(speaker.getSpeakerName())
.confidence(confidence)
.isNewSpeaker(isNewSpeaker)
.profileId(profileId)
.build();
}
@Override
@Transactional(readOnly = true)
public SpeakerDto.DetailResponse getSpeaker(String speakerId) {
log.debug("화자 정보 조회 - speakerId: {}", speakerId);
SpeakerEntity speaker = findSpeakerById(speakerId);
return SpeakerDto.DetailResponse.builder()
.speakerId(speaker.getSpeakerId())
.speakerName(speaker.getSpeakerName())
.profileId(speaker.getProfileId())
.userId(speaker.getUserId())
.totalSegments(speaker.getTotalSegments())
.totalDuration(speaker.getTotalDuration())
.averageConfidence(speaker.getAverageConfidence())
.firstAppeared(speaker.getFirstAppeared())
.lastAppeared(speaker.getLastAppeared())
.build();
}
@Override
public SpeakerDto.DetailResponse updateSpeaker(String speakerId, SpeakerDto.UpdateRequest request) {
log.info("화자 정보 업데이트 - speakerId: {}", speakerId);
SpeakerEntity speaker = findSpeakerById(speakerId);
// 화자 정보 업데이트
String oldSpeakerName = speaker.getSpeakerName();
String oldUserId = speaker.getUserId();
speaker.updateSpeakerInfo(request.getSpeakerName(), request.getUserId());
SpeakerEntity savedSpeaker = speakerRepository.save(speaker);
// 화자 정보 업데이트 이벤트 발행
SpeakerEvent.SpeakerUpdated event = SpeakerEvent.SpeakerUpdated.of(
speakerId, oldSpeakerName, request.getSpeakerName(),
oldUserId, request.getUserId(), "SYSTEM"
);
eventPublisher.publishAsync("speaker-events", event);
log.info("화자 정보 업데이트 완료 - speakerId: {}, speakerName: {}",
speakerId, request.getSpeakerName());
return getSpeaker(speakerId);
}
@Override
@Transactional(readOnly = true)
public SpeakerDto.ListResponse getRecordingSpeakers(String recordingId) {
log.debug("녹음 화자 목록 조회 - recordingId: {}", recordingId);
// 녹음별 화자 통계 조회
List<Object[]> speakerStats = segmentRepository.getSpeakerStatisticsByRecording(recordingId);
List<SpeakerDto.SpeakerSummary> speakers = speakerStats.stream()
.map(stat -> {
String speakerId = (String) stat[0];
Long segmentCount = (Long) stat[1];
Double totalDuration = (Double) stat[2];
Double averageConfidence = (Double) stat[3];
// 화자 정보 조회
SpeakerEntity speaker = speakerRepository.findById(speakerId).orElse(null);
String speakerName = speaker != null ? speaker.getSpeakerName() : "알 수 없는 화자";
// 발언 비율 계산 (전체 시간 대비)
Double speakingRatio = calculateSpeakingRatio(recordingId, totalDuration);
return SpeakerDto.SpeakerSummary.builder()
.speakerId(speakerId)
.speakerName(speakerName)
.segmentCount(segmentCount.intValue())
.totalDuration(totalDuration.intValue())
.speakingRatio(speakingRatio)
.build();
})
.collect(Collectors.toList());
return SpeakerDto.ListResponse.builder()
.recordingId(recordingId)
.speakerCount(speakers.size())
.speakers(speakers)
.build();
}
/**
* 화자 ID로 엔티티 조회
*/
private SpeakerEntity findSpeakerById(String speakerId) {
return speakerRepository.findById(speakerId)
.orElseThrow(() -> new BusinessException(ErrorCode.ENTITY_NOT_FOUND, "화자를 찾을 수 없습니다"));
}
/**
* 화자 ID 생성
*/
private String generateSpeakerId() {
return "SPK-" + String.format("%03d", (int)(Math.random() * 999) + 1);
}
/**
* Azure Speaker Recognition 시뮬레이션
*/
private String simulateAzureSpeakerRecognition(String audioFrame) {
// 실제로는 Azure Cognitive Services Speaker Recognition API 호출
return "PROFILE-" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
}
/**
* 화자 식별 신뢰도 시뮬레이션
*/
private Double simulateIdentificationConfidence() {
// 실제로는 Azure Speaker Recognition API에서 반환
return 0.90 + (Math.random() * 0.10); // 0.90 ~ 1.0
}
/**
* 발언 비율 계산
*/
private Double calculateSpeakingRatio(String recordingId, Double speakerDuration) {
// 전체 녹음 시간 조회 (임시로 1800초로 설정)
Double totalDuration = 1800.0;
return speakerDuration / totalDuration;
}
/**
* 녹음 ID에서 회의 ID 추출
*/
private String extractMeetingIdFromRecordingId(String recordingId) {
// 실제로는 Recording 엔티티에서 조회
return "MEETING-" + recordingId.substring(4, 12);
}
}

View File

@ -2,7 +2,6 @@ package com.unicorn.hgzero.stt.service;
import com.unicorn.hgzero.stt.dto.TranscriptionDto;
import com.unicorn.hgzero.stt.dto.TranscriptSegmentDto;
import org.springframework.web.multipart.MultipartFile;
/**
* 음성 변환 서비스 인터페이스
@ -18,30 +17,13 @@ public interface TranscriptionService {
*/
TranscriptSegmentDto.Response processAudioStream(TranscriptionDto.StreamRequest request);
/**
* 배치 음성-텍스트 변환
*
* @param request 배치 변환 요청
* @param audioFile 오디오 파일
* @return 배치 변환 응답
*/
TranscriptionDto.BatchResponse transcribeAudioBatch(TranscriptionDto.BatchRequest request, MultipartFile audioFile);
/**
* 배치 변환 완료 콜백 처리
*
* @param request 배치 콜백 요청
* @return 변환 완료 응답
*/
TranscriptionDto.CompleteResponse processBatchCallback(TranscriptionDto.BatchCallbackRequest request);
/**
* 변환 텍스트 전체 조회
*
* @param recordingId 녹음 ID
* @param includeSegments 세그먼트 포함 여부
* @param speakerId 화자 ID 필터
* @return 변환 결과 응답
*/
TranscriptionDto.Response getTranscription(String recordingId, Boolean includeSegments, String speakerId);
TranscriptionDto.Response getTranscription(String recordingId);
}

View File

@ -16,9 +16,10 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.time.Instant;
import java.time.ZoneId;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@ -78,12 +79,14 @@ public class TranscriptionServiceImpl implements TranscriptionService {
updateRecordingStatistics(request.getRecordingId());
// 세그먼트 생성 이벤트 발행
LocalDateTime timestampAsLocalDateTime = java.time.Instant.ofEpochMilli(request.getTimestamp())
.atZone(java.time.ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime timestampAsDateTime = LocalDateTime.ofInstant(
Instant.ofEpochMilli(request.getTimestamp()),
ZoneId.systemDefault()
);
TranscriptionEvent.SegmentCreated event = TranscriptionEvent.SegmentCreated.of(
segmentId, request.getRecordingId(), recording.getMeetingId(),
recognizedText, speakerId, "화자-" + speakerId.substring(4),
timestampAsLocalDateTime, 3.5, confidence, warningFlag
timestampAsDateTime, 3.5, confidence, warningFlag
);
eventPublisher.publishAsync("transcription-events", event);
@ -111,93 +114,21 @@ public class TranscriptionServiceImpl implements TranscriptionService {
.build();
}
@Override
public TranscriptionDto.BatchResponse transcribeAudioBatch(TranscriptionDto.BatchRequest request, MultipartFile audioFile) {
log.info("배치 음성 변환 시작 - recordingId: {}, fileSize: {}",
request.getRecordingId(), audioFile.getSize());
// 녹음 존재 확인
RecordingEntity recording = findRecordingById(request.getRecordingId());
// 배치 작업 ID 생성
String jobId = generateJobId();
// Azure Batch Transcription Job 생성 (실제로는 Azure Speech SDK 사용)
// 여기서는 시뮬레이션
log.info("배치 음성 변환 작업 생성 완료 - jobId: {}", jobId);
return TranscriptionDto.BatchResponse.builder()
.jobId(jobId)
.recordingId(request.getRecordingId())
.status("PROCESSING")
.estimatedCompletionTime(LocalDateTime.now().plusSeconds(30))
.callbackUrl(request.getCallbackUrl())
.build();
}
@Override
public TranscriptionDto.CompleteResponse processBatchCallback(TranscriptionDto.BatchCallbackRequest request) {
log.info("배치 변환 콜백 처리 - jobId: {}, status: {}", request.getJobId(), request.getStatus());
if ("COMPLETED".equals(request.getStatus()) && request.getSegments() != null) {
// 세그먼트 저장
for (TranscriptSegmentDto.Detail segmentDto : request.getSegments()) {
String segmentId = generateSegmentId();
TranscriptSegmentEntity segment = TranscriptSegmentEntity.builder()
.segmentId(segmentId)
.transcriptId(segmentDto.getTranscriptId())
.text(segmentDto.getText())
.speakerId(segmentDto.getSpeakerId())
.speakerName(segmentDto.getSpeakerName())
.timestamp(segmentDto.getTimestamp())
.duration(segmentDto.getDuration())
.confidence(segmentDto.getConfidence())
.warningFlag(segmentDto.getConfidence() < 0.6)
.build();
segmentRepository.save(segment);
}
// 전체 텍스트 통합 변환 결과 저장
String recordingId = extractRecordingIdFromJobId(request.getJobId());
aggregateAndSaveTranscription(recordingId, request.getSegments());
}
return TranscriptionDto.CompleteResponse.builder()
.jobId(request.getJobId())
.status(request.getStatus())
.segmentCount(request.getSegments() != null ? request.getSegments().size() : 0)
.totalDuration(calculateTotalDuration(request.getSegments()))
.averageConfidence(calculateAverageConfidence(request.getSegments()))
.build();
}
@Override
@Transactional(readOnly = true)
public TranscriptionDto.Response getTranscription(String recordingId, Boolean includeSegments, String speakerId) {
log.debug("변환 텍스트 조회 - recordingId: {}, includeSegments: {}", recordingId, includeSegments);
public TranscriptionDto.Response getTranscription(String recordingId) {
log.debug("변환 텍스트 조회 - recordingId: {}", recordingId);
// 변환 결과 조회
TranscriptionEntity transcription = transcriptionRepository.findByRecordingId(recordingId)
.orElseThrow(() -> new BusinessException(ErrorCode.ENTITY_NOT_FOUND, "변환 결과를 찾을 수 없습니다"));
List<TranscriptSegmentDto.Detail> segments = null;
if (Boolean.TRUE.equals(includeSegments)) {
List<TranscriptSegmentEntity> segmentEntities;
if (speakerId != null) {
segmentEntities = segmentRepository.findByRecordingIdAndSpeakerIdOrderByTimestamp(recordingId, speakerId);
} else {
segmentEntities = segmentRepository.findByRecordingIdOrderByTimestamp(recordingId);
}
segments = segmentEntities.stream()
.map(this::convertToSegmentDetail)
.collect(Collectors.toList());
}
// 세그먼트 정보 포함
List<TranscriptSegmentEntity> segmentEntities = segmentRepository.findByRecordingIdOrderByTimestamp(recordingId);
List<TranscriptSegmentDto.Detail> segments = segmentEntities.stream()
.map(this::convertToSegmentDetail)
.collect(Collectors.toList());
return TranscriptionDto.Response.builder()
.recordingId(recordingId)

View File

@ -6,7 +6,7 @@ spring:
datasource:
url: jdbc:${DB_KIND:postgresql}://${DB_HOST:4.230.65.89}:${DB_PORT:5432}/${DB_NAME:sttdb}
username: ${DB_USERNAME:hgzerouser}
password: ${DB_PASSWORD:}
password: ${DB_PASSWORD:Hi5Jessica!}
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 20
@ -21,6 +21,7 @@ spring:
show-sql: ${SHOW_SQL:true}
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
format_sql: true
use_sql_comments: true
hibernate:
@ -31,7 +32,7 @@ spring:
redis:
host: ${REDIS_HOST:20.249.177.114}
port: ${REDIS_PORT:6379}
password: ${REDIS_PASSWORD:}
password: ${REDIS_PASSWORD:Hi5Jessica!}
timeout: 2000ms
lettuce:
pool:

View File

@ -1,16 +1,19 @@
package com.unicorn.hgzero.stt;
import com.unicorn.hgzero.stt.config.TestConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
/**
* STT 애플리케이션 통합 테스트
* 전체 애플리케이션 컨텍스트 로딩 기본 설정 검증
*/
@SpringBootTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@ActiveProfiles("test")
@Import(TestConfig.class)
@DisplayName("STT 애플리케이션 테스트")
class SttApplicationTest {

View File

@ -1,6 +1,7 @@
package com.unicorn.hgzero.stt.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.hgzero.stt.config.WebMvcTestConfig;
import com.unicorn.hgzero.stt.dto.RecordingDto;
import com.unicorn.hgzero.stt.service.RecordingService;
import org.junit.jupiter.api.BeforeEach;
@ -9,6 +10,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

View File

@ -1,14 +1,21 @@
package com.unicorn.hgzero.stt.integration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.unicorn.hgzero.stt.config.TestConfig;
import com.unicorn.hgzero.stt.dto.RecordingDto;
import com.unicorn.hgzero.stt.dto.TranscriptionDto;
import com.unicorn.hgzero.stt.dto.SpeakerDto;
import com.unicorn.hgzero.stt.service.RecordingService;
import com.unicorn.hgzero.stt.service.SpeakerService;
import com.unicorn.hgzero.stt.service.TranscriptionService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
@ -16,6 +23,8 @@ import org.springframework.test.web.servlet.MvcResult;
import org.springframework.transaction.annotation.Transactional;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@ -23,10 +32,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
* STT API 통합 테스트
* 전체 워크플로우 시나리오 테스트
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureWebMvc
@ActiveProfiles("test")
@Transactional
@DisplayName("STT API 통합 테스트")
class SttApiIntegrationTest {
@ -36,6 +44,99 @@ class SttApiIntegrationTest {
@Autowired
private ObjectMapper objectMapper;
@MockBean
private RecordingService recordingService;
@MockBean
private SpeakerService speakerService;
@MockBean
private TranscriptionService transcriptionService;
@BeforeEach
void setUp() {
// RecordingService Mock 설정
when(recordingService.prepareRecording(any(RecordingDto.PrepareRequest.class)))
.thenReturn(RecordingDto.PrepareResponse.builder()
.recordingId("REC-20250123-001")
.sessionId("SESSION-INTEGRATION-001")
.status("READY")
.streamUrl("wss://api.example.com/stt/v1/ws/stt/SESSION-INTEGRATION-001")
.storagePath("recordings/MEETING-INTEGRATION-001/SESSION-INTEGRATION-001.wav")
.estimatedInitTime(1100)
.build());
when(recordingService.startRecording(anyString(), any(RecordingDto.StartRequest.class)))
.thenReturn(RecordingDto.StatusResponse.builder()
.recordingId("REC-20250123-001")
.status("RECORDING")
.startTime(java.time.LocalDateTime.now())
.duration(0)
.build());
when(recordingService.stopRecording(anyString(), any(RecordingDto.StopRequest.class)))
.thenReturn(RecordingDto.StatusResponse.builder()
.recordingId("REC-20250123-001")
.status("STOPPED")
.startTime(java.time.LocalDateTime.now().minusMinutes(30))
.endTime(java.time.LocalDateTime.now())
.duration(1800)
.fileSize(172800000L)
.storagePath("recordings/MEETING-INTEGRATION-001/SESSION-INTEGRATION-001.wav")
.build());
when(recordingService.getRecording(anyString()))
.thenReturn(RecordingDto.DetailResponse.builder()
.recordingId("REC-20250123-001")
.meetingId("MEETING-INTEGRATION-001")
.sessionId("SESSION-INTEGRATION-001")
.status("STOPPED")
.startTime(java.time.LocalDateTime.now().minusMinutes(30))
.endTime(java.time.LocalDateTime.now())
.duration(1800)
.speakerCount(3)
.segmentCount(45)
.storagePath("recordings/MEETING-INTEGRATION-001/SESSION-INTEGRATION-001.wav")
.language("ko-KR")
.build());
// TranscriptionService Mock 설정
when(transcriptionService.processAudioStream(any(TranscriptionDto.StreamRequest.class)))
.thenReturn(com.unicorn.hgzero.stt.dto.TranscriptSegmentDto.Response.builder()
.recordingId("REC-20250123-001")
.transcriptId("TRANS-001")
.text("안녕하세요")
.confidence(0.95)
.timestamp(System.currentTimeMillis())
.speakerId("SPK-001")
.duration(2.5)
.build());
when(transcriptionService.getTranscription(anyString(), any(), any()))
.thenReturn(TranscriptionDto.Response.builder()
.recordingId("REC-20250123-001")
.fullText("안녕하세요. 오늘 회의를 시작하겠습니다.")
.segmentCount(45)
.speakerCount(3)
.totalDuration(1800)
.averageConfidence(0.92)
.build());
// SpeakerService Mock 설정
when(speakerService.identifySpeaker(any(SpeakerDto.IdentifyRequest.class)))
.thenReturn(SpeakerDto.IdentificationResponse.builder()
.speakerId("SPK-001")
.confidence(0.95)
.isNewSpeaker(false)
.build());
when(speakerService.getRecordingSpeakers(anyString()))
.thenReturn(SpeakerDto.ListResponse.builder()
.recordingId("REC-20250123-001")
.speakerCount(3)
.build());
}
@Test
@DisplayName("전체 STT 워크플로우 통합 테스트")
void fullSttWorkflowIntegrationTest() throws Exception {
@ -141,6 +242,17 @@ class SttApiIntegrationTest {
@Test
@DisplayName("에러 케이스 통합 테스트")
void errorCasesIntegrationTest() throws Exception {
// 존재하지 않는 녹음에 대한 Mock 설정
when(recordingService.startRecording(eq("NONEXISTENT-001"), any(RecordingDto.StartRequest.class)))
.thenThrow(new com.unicorn.hgzero.common.exception.BusinessException(
com.unicorn.hgzero.common.exception.ErrorCode.ENTITY_NOT_FOUND,
"녹음을 찾을 수 없습니다"));
when(transcriptionService.getTranscription(eq("NONEXISTENT-001"), any(), any()))
.thenThrow(new com.unicorn.hgzero.common.exception.BusinessException(
com.unicorn.hgzero.common.exception.ErrorCode.ENTITY_NOT_FOUND,
"변환 결과를 찾을 수 없습니다"));
// 존재하지 않는 녹음 시작 시도
RecordingDto.StartRequest startRequest = RecordingDto.StartRequest.builder()
.startedBy("test-user")

View File

@ -50,6 +50,8 @@ class TranscriptionServiceTest {
private TranscriptionServiceImpl transcriptionService;
private RecordingEntity recordingEntity;
private TranscriptSegmentEntity segmentEntity;
private TranscriptionEntity transcriptionEntity;
private TranscriptionDto.StreamRequest streamRequest;
@BeforeEach
@ -60,6 +62,22 @@ class TranscriptionServiceTest {
.sessionId("SESSION-001")
.build();
segmentEntity = TranscriptSegmentEntity.builder()
.segmentId("SEG-001")
.recordingId("REC-20250123-001")
.text("테스트 음성 변환 결과")
.timestamp(System.currentTimeMillis())
.confidence(0.95)
.build();
transcriptionEntity = TranscriptionEntity.builder()
.transcriptId("TRANS-001")
.recordingId("REC-20250123-001")
.fullText("전체 음성 변환 결과")
.segmentCount(1)
.averageConfidence(0.95)
.build();
streamRequest = TranscriptionDto.StreamRequest.builder()
.recordingId("REC-20250123-001")
.audioData("base64-encoded-audio-data")
@ -73,7 +91,7 @@ class TranscriptionServiceTest {
void processAudioStream_Success() {
// Given
when(recordingRepository.findById(anyString())).thenReturn(Optional.of(recordingEntity));
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(any());
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(segmentEntity);
when(segmentRepository.getSpeakerStatisticsByRecording(anyString())).thenReturn(List.of());
when(segmentRepository.countByRecordingId(anyString())).thenReturn(1L);
when(recordingRepository.save(any(RecordingEntity.class))).thenReturn(recordingEntity);
@ -88,9 +106,9 @@ class TranscriptionServiceTest {
assertThat(response.getConfidence()).isGreaterThan(0.8);
assertThat(response.getSpeakerId()).isNotEmpty();
verify(recordingRepository).findById("REC-20250123-001");
verify(recordingRepository, atLeastOnce()).findById("REC-20250123-001");
verify(segmentRepository).save(any(TranscriptSegmentEntity.class));
verify(eventPublisher).publishAsync(eq("transcription-events"), any());
verify(eventPublisher, atLeastOnce()).publishAsync(eq("transcription-events"), any());
}
@Test
@ -114,7 +132,7 @@ class TranscriptionServiceTest {
void processAudioStream_LowConfidenceWarning() {
// Given
when(recordingRepository.findById(anyString())).thenReturn(Optional.of(recordingEntity));
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(any());
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(segmentEntity);
when(segmentRepository.getSpeakerStatisticsByRecording(anyString())).thenReturn(List.of());
when(segmentRepository.countByRecordingId(anyString())).thenReturn(1L);
when(recordingRepository.save(any(RecordingEntity.class))).thenReturn(recordingEntity);
@ -191,8 +209,8 @@ class TranscriptionServiceTest {
.segments(segments)
.build();
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(any());
when(transcriptionRepository.save(any(TranscriptionEntity.class))).thenReturn(any());
when(segmentRepository.save(any(TranscriptSegmentEntity.class))).thenReturn(segmentEntity);
when(transcriptionRepository.save(any(TranscriptionEntity.class))).thenReturn(transcriptionEntity);
// When
TranscriptionDto.CompleteResponse response = transcriptionService.processBatchCallback(callbackRequest);

View File

@ -1,55 +1,131 @@
# STT 서비스 테스트 설정
spring:
profiles:
active: test
# 테스트 환경별 설정 선택
# 1. 단위 테스트용 (기본)
# 2. Docker 통합 테스트용 (integration-test profile 활성화 시)
# 데이터베이스 설정 (H2 인메모리)
spring:
application:
name: stt-test
# Bean Override 허용
main:
allow-bean-definition-overriding: true
# In-Memory Database (기본값)
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
driver-class-name: org.h2.Driver
# JPA 설정
jpa:
show-sql: false
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
format_sql: true
# Redis 설정 (임베디드)
redis:
host: localhost
port: 6370
timeout: 2000ms
# Mock Redis (handled by TestConfig)
data:
redis:
host: localhost
port: 6370
password:
database: 0
# JWT 설정
security:
jwt:
secret: test-secret-key-for-jwt-token-generation-test
expiration: 86400
# Test Server
server:
port: 0
# Azure 서비스 설정 (테스트용 더미)
# Mock Azure Services
azure:
speech:
subscription-key: test-key
region: koreacentral
endpoint: https://test.cognitiveservices.azure.com/
storage:
connection-string: DefaultEndpointsProtocol=https;AccountName=testaccount;AccountKey=testkey;EndpointSuffix=core.windows.net
region: eastus
language: ko-KR
blob:
connection-string: DefaultEndpointsProtocol=https;AccountName=test;AccountKey=test;EndpointSuffix=core.windows.net
container-name: test-recordings
event-hubs:
connection-string: Endpoint=sb://test-eventhub.servicebus.windows.net/;SharedAccessKeyName=test;SharedAccessKey=test
eventhub:
connection-string: Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=test;SharedAccessKey=test
name: test-events
consumer-group: test-group
# 로깅 설정
---
# Docker 통합 테스트용 설정
spring:
config:
activate:
on-profile: integration-test
# Real PostgreSQL (via Docker)
datasource:
url: jdbc:postgresql://localhost:5433/sttdb_test
username: testuser
password: testpass
driver-class-name: org.postgresql.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: update
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
# Real Redis (via Docker)
data:
redis:
host: localhost
port: 6380
password: testpass
database: 0
# Real Server
server:
port: 8083
# Azure Emulator (Azurite)
azure:
speech:
subscription-key: test-key
region: eastus
language: ko-KR
blob:
connection-string: DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;
container-name: test-recordings
eventhub:
connection-string: Endpoint=sb://test.servicebus.windows.net/;SharedAccessKeyName=test;SharedAccessKey=test
name: test-events
consumer-group: test-group
---
# 공통 설정
jwt:
secret: test-secret-key-for-testing-purposes-only-not-for-production-use
access-token-validity: 3600
refresh-token-validity: 604800
cors:
allowed-origins: "*"
management:
endpoints:
enabled-by-default: false
endpoint:
health:
enabled: true
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: false
logging:
level:
com.unicorn.hgzero.stt: DEBUG
org.springframework.web: DEBUG
org.hibernate.SQL: DEBUG
com.unicorn.hgzero.stt: INFO
org.springframework: WARN
org.hibernate: WARN
pattern:
console: "%d{HH:mm:ss} %-5level %logger{36} - %msg%n"