feat: add 회의시작 API

This commit is contained in:
djeon 2025-10-24 15:44:55 +09:00
parent 48b760d850
commit 4f80189d57
12 changed files with 870 additions and 26 deletions

View File

@ -9954,3 +9954,426 @@ Caused by: io.lettuce.core.RedisReadOnlyException: READONLY You can't write agai
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2025-10-24 15:16:51 [http-nio-8082-exec-4] INFO c.u.h.m.i.c.MeetingController - 회의 예약 완료 - userId: user-005, meetingId: 4b340eed-31d9-4b7b-a95f-65180d9f663e 2025-10-24 15:16:51 [http-nio-8082-exec-4] INFO c.u.h.m.i.c.MeetingController - 회의 예약 완료 - userId: user-005, meetingId: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:16:51 [http-nio-8082-exec-4] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] com.unicorn.hgzero.meeting.infra.controller.MeetingController.createMeeting 완료 - 실행시간: 1831ms 2025-10-24 15:16:51 [http-nio-8082-exec-4] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] com.unicorn.hgzero.meeting.infra.controller.MeetingController.createMeeting 완료 - 실행시간: 1831ms
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO c.a.m.e.i.EventHubConnectionProcessor - {"az.sdk.message":"Upstream connection publisher was completed. Terminating processor.","entityPath":"hgzero-eventhub-name"}
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO c.a.c.a.i.ReactorConnection - {"az.sdk.message":"Disposing of ReactorConnection.","connectionId":"MF_281659_1761286483128","isTransient":false,"isInitiatedByClient":true,"shutdownMessage":"Disposed by client."}
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO c.a.m.e.i.EventHubConnectionProcessor - {"az.sdk.message":"Channel is disposed.","entityPath":"hgzero-eventhub-name"}
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
2025-10-24 15:19:59 [SpringApplicationShutdownHook] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryClosed from [org.hibernate.internal.SessionFactoryImpl@c42ee90] for TypeConfiguration
2025-10-24 15:19:59 [SpringApplicationShutdownHook] DEBUG o.h.type.spi.TypeConfiguration$Scope - Un-scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@626c0d] from SessionFactory [org.hibernate.internal.SessionFactoryImpl@c42ee90]
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2025-10-24 15:19:59 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2025-10-24 15:37:09 [main] INFO c.u.h.meeting.MeetingApplication - Starting MeetingApplication using Java 21.0.8 with PID 96456 (/Users/daewoong/home/workspace/HGZero/meeting/build/classes/java/main started by daewoong in /Users/daewoong/home/workspace/HGZero/meeting)
2025-10-24 15:37:09 [main] DEBUG c.u.h.meeting.MeetingApplication - Running with Spring Boot v3.3.5, Spring v6.1.14
2025-10-24 15:37:09 [main] INFO c.u.h.meeting.MeetingApplication - The following 1 profile is active: "dev"
2025-10-24 15:37:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-24 15:37:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-10-24 15:37:09 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 59 ms. Found 6 JPA repository interfaces.
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Multiple Spring Data modules found, entering strict repository configuration mode
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.MeetingJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.MinutesJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.MinutesSectionJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.SessionJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.TemplateJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationExtensionSupport - Spring Data Redis - Could not safely identify store assignment for repository candidate interface com.unicorn.hgzero.meeting.infra.gateway.repository.TodoJpaRepository; If you want this repository to be a Redis repository, consider annotating your entities with one of these annotations: org.springframework.data.redis.core.RedisHash (preferred), or consider extending one of the following types with your repository: org.springframework.data.keyvalue.repository.KeyValueRepository
2025-10-24 15:37:10 [main] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces.
2025-10-24 15:37:10 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port 8082 (http)
2025-10-24 15:37:10 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2025-10-24 15:37:10 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/10.1.31]
2025-10-24 15:37:10 [main] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2025-10-24 15:37:10 [main] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 999 ms
2025-10-24 15:37:10 [main] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
2025-10-24 15:37:10 [main] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 6.5.3.Final
2025-10-24 15:37:10 [main] INFO o.h.c.i.RegionFactoryInitiator - HHH000026: Second-level cache disabled
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@7509226c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration boolean -> org.hibernate.type.BasicTypeReference@7509226c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Boolean -> org.hibernate.type.BasicTypeReference@7509226c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration numeric_boolean -> org.hibernate.type.BasicTypeReference@4c9cce17
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.NumericBooleanConverter -> org.hibernate.type.BasicTypeReference@4c9cce17
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration true_false -> org.hibernate.type.BasicTypeReference@73316a0a
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.TrueFalseConverter -> org.hibernate.type.BasicTypeReference@73316a0a
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration yes_no -> org.hibernate.type.BasicTypeReference@63a7af06
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.YesNoConverter -> org.hibernate.type.BasicTypeReference@63a7af06
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@5f01fb5c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte -> org.hibernate.type.BasicTypeReference@5f01fb5c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Byte -> org.hibernate.type.BasicTypeReference@5f01fb5c
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary -> org.hibernate.type.BasicTypeReference@75c77add
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration byte[] -> org.hibernate.type.BasicTypeReference@75c77add
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [B -> org.hibernate.type.BasicTypeReference@75c77add
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration binary_wrapper -> org.hibernate.type.BasicTypeReference@d5e3f55
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-binary -> org.hibernate.type.BasicTypeReference@d5e3f55
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration image -> org.hibernate.type.BasicTypeReference@53df7e67
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration blob -> org.hibernate.type.BasicTypeReference@3d4b45b
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Blob -> org.hibernate.type.BasicTypeReference@3d4b45b
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob -> org.hibernate.type.BasicTypeReference@4d0b276e
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_blob_wrapper -> org.hibernate.type.BasicTypeReference@31531d0d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@19d76106
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration short -> org.hibernate.type.BasicTypeReference@19d76106
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Short -> org.hibernate.type.BasicTypeReference@19d76106
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration integer -> org.hibernate.type.BasicTypeReference@3f87780b
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration int -> org.hibernate.type.BasicTypeReference@3f87780b
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Integer -> org.hibernate.type.BasicTypeReference@3f87780b
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@2ba318c2
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration long -> org.hibernate.type.BasicTypeReference@2ba318c2
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Long -> org.hibernate.type.BasicTypeReference@2ba318c2
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@231d3ce
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration float -> org.hibernate.type.BasicTypeReference@231d3ce
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Float -> org.hibernate.type.BasicTypeReference@231d3ce
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@204c5ddf
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration double -> org.hibernate.type.BasicTypeReference@204c5ddf
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Double -> org.hibernate.type.BasicTypeReference@204c5ddf
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_integer -> org.hibernate.type.BasicTypeReference@240f2efd
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigInteger -> org.hibernate.type.BasicTypeReference@240f2efd
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration big_decimal -> org.hibernate.type.BasicTypeReference@175957b6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.math.BigDecimal -> org.hibernate.type.BasicTypeReference@175957b6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character -> org.hibernate.type.BasicTypeReference@1b7a4930
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char -> org.hibernate.type.BasicTypeReference@1b7a4930
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Character -> org.hibernate.type.BasicTypeReference@1b7a4930
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration character_nchar -> org.hibernate.type.BasicTypeReference@591a4d25
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration string -> org.hibernate.type.BasicTypeReference@4bfe83d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.String -> org.hibernate.type.BasicTypeReference@4bfe83d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nstring -> org.hibernate.type.BasicTypeReference@5906ebfb
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration characters -> org.hibernate.type.BasicTypeReference@10fc1a22
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration char[] -> org.hibernate.type.BasicTypeReference@10fc1a22
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration [C -> org.hibernate.type.BasicTypeReference@10fc1a22
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration wrapper-characters -> org.hibernate.type.BasicTypeReference@1b841e7d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration text -> org.hibernate.type.BasicTypeReference@6081f330
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ntext -> org.hibernate.type.BasicTypeReference@eb695e8
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration clob -> org.hibernate.type.BasicTypeReference@7eebb316
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Clob -> org.hibernate.type.BasicTypeReference@7eebb316
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration nclob -> org.hibernate.type.BasicTypeReference@45273d40
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.NClob -> org.hibernate.type.BasicTypeReference@45273d40
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob -> org.hibernate.type.BasicTypeReference@2a504ea7
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_char_array -> org.hibernate.type.BasicTypeReference@10f397d0
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_clob_character_array -> org.hibernate.type.BasicTypeReference@33a3e5db
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob -> org.hibernate.type.BasicTypeReference@4f9213d2
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_character_array -> org.hibernate.type.BasicTypeReference@679f59f1
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration materialized_nclob_char_array -> org.hibernate.type.BasicTypeReference@6b5e1fc5
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> org.hibernate.type.BasicTypeReference@47ffa248
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> org.hibernate.type.BasicTypeReference@47ffa248
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDateTime -> org.hibernate.type.BasicTypeReference@18ac25e6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDateTime -> org.hibernate.type.BasicTypeReference@18ac25e6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalDate -> org.hibernate.type.BasicTypeReference@5e1a7d3
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalDate -> org.hibernate.type.BasicTypeReference@5e1a7d3
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration LocalTime -> org.hibernate.type.BasicTypeReference@1eda309d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.LocalTime -> org.hibernate.type.BasicTypeReference@1eda309d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> org.hibernate.type.BasicTypeReference@248d2cec
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> org.hibernate.type.BasicTypeReference@248d2cec
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@5d77be8e
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@55a055cc
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> org.hibernate.type.BasicTypeReference@1ab1d93d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> org.hibernate.type.BasicTypeReference@1ab1d93d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeUtc -> org.hibernate.type.BasicTypeReference@57167ccb
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithTimezone -> org.hibernate.type.BasicTypeReference@37753b69
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@602c167e
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> org.hibernate.type.BasicTypeReference@74c04377
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> org.hibernate.type.BasicTypeReference@74c04377
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithTimezone -> org.hibernate.type.BasicTypeReference@10d49900
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTimeWithoutTimezone -> org.hibernate.type.BasicTypeReference@e645600
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration date -> org.hibernate.type.BasicTypeReference@e7b3e54
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Date -> org.hibernate.type.BasicTypeReference@e7b3e54
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration time -> org.hibernate.type.BasicTypeReference@78d61f17
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Time -> org.hibernate.type.BasicTypeReference@78d61f17
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timestamp -> org.hibernate.type.BasicTypeReference@4cfe9594
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.sql.Timestamp -> org.hibernate.type.BasicTypeReference@4cfe9594
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Date -> org.hibernate.type.BasicTypeReference@4cfe9594
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar -> org.hibernate.type.BasicTypeReference@60861e5d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Calendar -> org.hibernate.type.BasicTypeReference@60861e5d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.GregorianCalendar -> org.hibernate.type.BasicTypeReference@60861e5d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_date -> org.hibernate.type.BasicTypeReference@37d81587
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration calendar_time -> org.hibernate.type.BasicTypeReference@7f3e9acc
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration instant -> org.hibernate.type.BasicTypeReference@47d4e28a
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Instant -> org.hibernate.type.BasicTypeReference@47d4e28a
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid -> org.hibernate.type.BasicTypeReference@177068db
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.UUID -> org.hibernate.type.BasicTypeReference@177068db
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration pg-uuid -> org.hibernate.type.BasicTypeReference@177068db
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-binary -> org.hibernate.type.BasicTypeReference@60f3239f
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration uuid-char -> org.hibernate.type.BasicTypeReference@6b103db7
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration class -> org.hibernate.type.BasicTypeReference@b3042ed
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Class -> org.hibernate.type.BasicTypeReference@b3042ed
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration currency -> org.hibernate.type.BasicTypeReference@1f12d5e0
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Currency -> org.hibernate.type.BasicTypeReference@1f12d5e0
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Currency -> org.hibernate.type.BasicTypeReference@1f12d5e0
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration locale -> org.hibernate.type.BasicTypeReference@6604f246
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.Locale -> org.hibernate.type.BasicTypeReference@6604f246
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration serializable -> org.hibernate.type.BasicTypeReference@c1386b4
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.io.Serializable -> org.hibernate.type.BasicTypeReference@c1386b4
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration timezone -> org.hibernate.type.BasicTypeReference@53d9af1
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.util.TimeZone -> org.hibernate.type.BasicTypeReference@53d9af1
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZoneOffset -> org.hibernate.type.BasicTypeReference@c89e263
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZoneOffset -> org.hibernate.type.BasicTypeReference@c89e263
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration url -> org.hibernate.type.BasicTypeReference@4d5ea776
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.net.URL -> org.hibernate.type.BasicTypeReference@4d5ea776
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration vector -> org.hibernate.type.BasicTypeReference@5d68be4f
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration row_version -> org.hibernate.type.BasicTypeReference@34eb5d01
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration object -> org.hibernate.type.JavaObjectType@5521407f
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@5521407f
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration null -> org.hibernate.type.NullType@7305cfb1
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_date -> org.hibernate.type.BasicTypeReference@582c1f8d
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_time -> org.hibernate.type.BasicTypeReference@443253a6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_timestamp -> org.hibernate.type.BasicTypeReference@191774d6
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar -> org.hibernate.type.BasicTypeReference@21ffc00e
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_date -> org.hibernate.type.BasicTypeReference@134955bb
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_calendar_time -> org.hibernate.type.BasicTypeReference@45b08b17
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_binary -> org.hibernate.type.BasicTypeReference@6723e6b3
2025-10-24 15:37:10 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration imm_serializable -> org.hibernate.type.BasicTypeReference@3883b5e9
2025-10-24 15:37:10 [main] INFO o.s.o.j.p.SpringPersistenceUnitInfo - No LoadTimeWeaver setup: ignoring JPA class transformer
2025-10-24 15:37:10 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2025-10-24 15:37:11 [main] INFO com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection org.postgresql.jdbc.PgConnection@162e29a1
2025-10-24 15:37:11 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2025-10-24 15:37:11 [main] WARN org.hibernate.orm.deprecation - HHH90000025: PostgreSQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-10-24 15:37:11 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(2003, org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@d641499) replaced previous registration(org.hibernate.type.descriptor.sql.internal.ArrayDdlTypeImpl@634d3439)
2025-10-24 15:37:11 [main] DEBUG o.h.t.d.sql.spi.DdlTypeRegistry - addDescriptor(6, org.hibernate.type.descriptor.sql.internal.CapacityDependentDdlType@44e0c3d) replaced previous registration(org.hibernate.type.descriptor.sql.internal.DdlTypeImpl@71891d6b)
2025-10-24 15:37:11 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2004, BlobTypeDescriptor(BLOB_BINDING)) replaced previous registration(BlobTypeDescriptor(DEFAULT))
2025-10-24 15:37:11 [main] DEBUG o.h.t.d.jdbc.spi.JdbcTypeRegistry - addDescriptor(2005, ClobTypeDescriptor(CLOB_BINDING)) replaced previous registration(ClobTypeDescriptor(DEFAULT))
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration JAVA_OBJECT -> org.hibernate.type.JavaObjectType@63896cf7
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.lang.Object -> org.hibernate.type.JavaObjectType@63896cf7
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Type registration key [java.lang.Object] overrode previous entry : `org.hibernate.type.JavaObjectType@5521407f`
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.DurationType -> basicType@1(java.time.Duration,3015)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration Duration -> basicType@1(java.time.Duration,3015)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.Duration -> basicType@1(java.time.Duration,3015)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetDateTimeType -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetDateTime -> basicType@2(java.time.OffsetDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.ZonedDateTimeType -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.ZonedDateTime -> basicType@3(java.time.ZonedDateTime,3003)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration org.hibernate.type.OffsetTimeType -> basicType@4(java.time.OffsetTime,3007)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-24 15:37:11 [main] DEBUG o.hibernate.type.BasicTypeRegistry - Adding type registration java.time.OffsetTime -> basicType@4(java.time.OffsetTime,3007)
2025-10-24 15:37:11 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@6fe337a5] to MetadataBuildingContext [org.hibernate.boot.internal.MetadataBuildingContextRootImpl@7d60bd5a]
2025-10-24 15:37:11 [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-24 15:37:11 [main] DEBUG o.h.type.spi.TypeConfiguration$Scope - Scoping TypeConfiguration [org.hibernate.type.spi.TypeConfiguration@6fe337a5] to SessionFactoryImplementor [org.hibernate.internal.SessionFactoryImpl@188500e9]
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists meetings
alter column description set data type TEXT
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists meetings
alter column participants set data type TEXT
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists minutes_sections
alter column content set data type TEXT
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
create table sessions (
session_id varchar(50) not null,
created_at timestamp(6) not null,
updated_at timestamp(6) not null,
ended_at timestamp(6),
meeting_id varchar(50) not null,
minutes_id varchar(50),
started_at timestamp(6) not null,
started_by varchar(50) not null,
status varchar(20) not null,
primary key (session_id)
)
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists templates
alter column description set data type TEXT
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists templates
alter column sections set data type TEXT
2025-10-24 15:37:12 [main] DEBUG org.hibernate.SQL -
alter table if exists todos
alter column description set data type TEXT
2025-10-24 15:37:12 [main] TRACE o.h.type.spi.TypeConfiguration$Scope - Handling #sessionFactoryCreated from [org.hibernate.internal.SessionFactoryImpl@188500e9] for TypeConfiguration
2025-10-24 15:37:12 [main] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-10-24 15:37:12 [main] INFO o.s.d.j.r.query.QueryEnhancerFactory - Hibernate is in classpath; If applicable, HQL parser will be used.
2025-10-24 15:37:13 [main] INFO c.u.h.m.infra.cache.CacheConfig - Redis 연결 설정 - host: 20.249.177.114, port: 6379, database: 1, password: ****
2025-10-24 15:37:13 [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-24 15:37:13 [main] INFO c.u.h.m.infra.cache.CacheConfig - Redis 템플릿 설정 완료
2025-10-24 15:37:13 [main] INFO c.u.h.m.infra.cache.CacheConfig - ObjectMapper 설정 완료
2025-10-24 15:37:13 [main] INFO c.u.h.m.infra.config.EventHubConfig - Initializing Azure EventHub configuration with hub name: hgzero-eventhub-name
2025-10-24 15:37:13 [main] INFO c.u.h.m.infra.config.EventHubConfig - Creating EventHub producer for hub: hgzero-eventhub-name
2025-10-24 15:37:13 [main] INFO c.a.m.e.EventHubClientBuilder - {"az.sdk.message":"Emitting a single connection.","connectionId":"MF_e4b94c_1761287833470"}
2025-10-24 15:37:13 [main] INFO c.a.m.e.i.EventHubConnectionProcessor - {"az.sdk.message":"Setting next AMQP channel.","entityPath":"hgzero-eventhub-name"}
2025-10-24 15:37:13 [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-24 15:37:13 [main] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration -
Using generated security password: fc24964d-2039-440d-8e58-2eb38fcd3eb8
This generated password is for development use only. Your security configuration must be updated before running your application in production.
2025-10-24 15:37:13 [main] INFO o.s.s.c.a.a.c.InitializeUserDetailsBeanManagerConfigurer$InitializeUserDetailsManagerConfigurer - Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
2025-10-24 15:37:13 [main] INFO c.u.h.m.infra.config.WebSocketConfig - WebSocket 핸들러 등록 완료 - endpoint: /ws/minutes/{minutesId}
2025-10-24 15:37:13 [main] INFO o.s.b.a.e.web.EndpointLinksResolver - Exposing 3 endpoints beneath base path '/actuator'
2025-10-24 15:37:13 [main] DEBUG o.s.s.web.DefaultSecurityFilterChain - Will secure any request with filters: DisableEncodeUrlFilter, WebAsyncManagerIntegrationFilter, SecurityContextHolderFilter, HeaderWriterFilter, CorsFilter, LogoutFilter, JwtAuthenticationFilter, RequestCacheAwareFilter, SecurityContextHolderAwareRequestFilter, AnonymousAuthenticationFilter, SessionManagementFilter, ExceptionTranslationFilter, AuthorizationFilter
2025-10-24 15:37:14 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port 8082 (http) with context path '/'
2025-10-24 15:37:14 [main] INFO c.u.h.meeting.MeetingApplication - Started MeetingApplication in 4.937 seconds (process running for 5.094)
2025-10-24 15:38:21 [http-nio-8082-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-10-24 15:38:21 [http-nio-8082-exec-1] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet'
2025-10-24 15:38:21 [http-nio-8082-exec-1] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 3 ms
2025-10-24 15:38:21 [http-nio-8082-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing POST /api/meetings/4b340eed-31d9-4b7b-a95f-65180d9f663e/start
2025-10-24 15:38:21 [http-nio-8082-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-24 15:38:21 [http-nio-8082-exec-1] DEBUG o.s.security.web.FilterChainProxy - Secured POST /api/meetings/4b340eed-31d9-4b7b-a95f-65180d9f663e/start
2025-10-24 15:38:21 [http-nio-8082-exec-1] WARN o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.bind.MissingRequestHeaderException: Required request header 'X-User-Id' for method parameter type String is not present]
2025-10-24 15:38:21 [http-nio-8082-exec-1] DEBUG o.s.security.web.FilterChainProxy - Securing POST /error
2025-10-24 15:38:21 [http-nio-8082-exec-1] DEBUG o.s.security.web.FilterChainProxy - Secured POST /error
2025-10-24 15:38:22 [http-nio-8082-exec-1] DEBUG o.s.s.w.a.AnonymousAuthenticationFilter - Set SecurityContextHolder to anonymous SecurityContext
2025-10-24 15:39:50 [http-nio-8082-exec-4] DEBUG o.s.security.web.FilterChainProxy - Securing POST /api/meetings/4b340eed-31d9-4b7b-a95f-65180d9f663e/start
2025-10-24 15:39:50 [http-nio-8082-exec-4] DEBUG c.u.h.m.i.c.j.JwtAuthenticationFilter - 헤더 기반 인증된 사용자: dohyunjung (user-005)
2025-10-24 15:39:50 [http-nio-8082-exec-4] DEBUG o.s.security.web.FilterChainProxy - Secured POST /api/meetings/4b340eed-31d9-4b7b-a95f-65180d9f663e/start
2025-10-24 15:39:50 [http-nio-8082-exec-4] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] com.unicorn.hgzero.meeting.infra.controller.MeetingController.startMeeting 호출 - 파라미터: [4b340eed-31d9-4b7b-a95f-65180d9f663e, user-005, dohyunjung, dohyun.jung@example.com]
2025-10-24 15:39:50 [http-nio-8082-exec-4] INFO c.u.h.m.i.c.MeetingController - 회의 시작 요청 - meetingId: 4b340eed-31d9-4b7b-a95f-65180d9f663e, userId: user-005
2025-10-24 15:39:51 [http-nio-8082-exec-4] INFO c.u.h.m.biz.service.MeetingService - Starting meeting: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - Cache miss for meeting: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
select
me1_0.meeting_id,
me1_0.created_at,
me1_0.description,
me1_0.end_time,
me1_0.ended_at,
me1_0.location,
me1_0.organizer_id,
me1_0.participants,
me1_0.purpose,
me1_0.scheduled_at,
me1_0.started_at,
me1_0.status,
me1_0.template_id,
me1_0.title,
me1_0.updated_at
from
meetings me1_0
where
me1_0.meeting_id=?
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.infra.cache.CacheService - 회의 정보 캐시 저장 - meetingId: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
select
se1_0.session_id,
se1_0.created_at,
se1_0.ended_at,
se1_0.meeting_id,
se1_0.minutes_id,
se1_0.started_at,
se1_0.started_by,
se1_0.status,
se1_0.updated_at
from
sessions se1_0
where
se1_0.session_id=?
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - Session created: sessionId=90de549f-ff4f-4098-a0c0-8f2cd28b1176, meetingId=4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - Meeting status updated to IN_PROGRESS: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.infra.cache.CacheService - 캐시 삭제 - key: meeting:4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - Meeting cache evicted: 4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
select
me1_0.minutes_id,
me1_0.created_at,
me1_0.created_by,
me1_0.finalized_at,
me1_0.finalized_by,
me1_0.meeting_id,
me1_0.status,
me1_0.title,
me1_0.updated_at,
me1_0.version,
s1_0.minutes_id,
s1_0.section_id,
s1_0.content,
s1_0.created_at,
s1_0.locked,
s1_0.locked_by,
s1_0."order",
s1_0.title,
s1_0.type,
s1_0.updated_at,
s1_0.verified
from
minutes me1_0
left join
minutes_sections s1_0
on me1_0.minutes_id=s1_0.minutes_id
where
me1_0.minutes_id=?
2025-10-24 15:39:51 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - Minutes draft created: minutesId=30e642a9-fa4d-4cbe-a838-33214aaa2170, meetingId=4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:51 [http-nio-8082-exec-4] INFO c.a.c.a.i.ReactorConnection - {"az.sdk.message":"Creating and starting connection.","connectionId":"MF_e4b94c_1761287833470","hostName":"hgzero-eventhub-ns.servicebus.windows.net","port":5671}
2025-10-24 15:39:51 [http-nio-8082-exec-4] INFO c.a.c.a.i.ReactorExecutor - {"az.sdk.message":"Starting reactor.","connectionId":"MF_e4b94c_1761287833470"}
2025-10-24 15:39:51 [reactor-executor-1] INFO c.a.c.a.i.handler.ConnectionHandler - {"az.sdk.message":"onConnectionInit","connectionId":"MF_e4b94c_1761287833470","hostName":"hgzero-eventhub-ns.servicebus.windows.net","namespace":"hgzero-eventhub-ns.servicebus.windows.net"}
2025-10-24 15:39:51 [reactor-executor-1] INFO c.a.c.a.i.handler.ReactorHandler - {"az.sdk.message":"reactor.onReactorInit","connectionId":"MF_e4b94c_1761287833470"}
2025-10-24 15:39:51 [reactor-executor-1] INFO c.a.c.a.i.handler.ConnectionHandler - {"az.sdk.message":"onConnectionLocalOpen","connectionId":"MF_e4b94c_1761287833470","errorCondition":null,"errorDescription":null,"hostName":"hgzero-eventhub-ns.servicebus.windows.net"}
2025-10-24 15:39:51 [reactor-executor-1] INFO c.a.c.a.i.handler.ConnectionHandler - {"az.sdk.message":"onConnectionBound","connectionId":"MF_e4b94c_1761287833470","hostName":"hgzero-eventhub-ns.servicebus.windows.net","peerDetails":"hgzero-eventhub-ns.servicebus.windows.net:5671"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.ConnectionHandler - {"az.sdk.message":"onConnectionRemoteOpen","connectionId":"MF_e4b94c_1761287833470","hostName":"hgzero-eventhub-ns.servicebus.windows.net","remoteContainer":"f95a8629f37b4a79bf39489e5eb57624_G17"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.m.e.i.EventHubConnectionProcessor - {"az.sdk.message":"Channel is now active.","entityPath":"hgzero-eventhub-name"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.SessionHandler - {"az.sdk.message":"onSessionRemoteOpen","connectionId":"MF_e4b94c_1761287833470","sessionName":"hgzero-eventhub-name","sessionIncCapacity":0,"sessionOutgoingWindow":2147483647}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.ReactorConnection - {"az.sdk.message":"Setting CBS channel.","connectionId":"MF_e4b94c_1761287833470"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.SessionHandler - {"az.sdk.message":"onSessionRemoteOpen","connectionId":"MF_e4b94c_1761287833470","sessionName":"cbs-session","sessionIncCapacity":0,"sessionOutgoingWindow":2147483647}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.ReactorConnection - {"az.sdk.message":"Emitting new response channel.","connectionId":"MF_e4b94c_1761287833470","entityPath":"$cbs","linkName":"cbs"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.AmqpChannelProcessor - {"az.sdk.message":"Setting next AMQP channel.","connectionId":"MF_e4b94c_1761287833470","entityPath":"$cbs"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.AmqpChannelProcessor - {"az.sdk.message":"Next AMQP channel received.","connectionId":"MF_e4b94c_1761287833470","entityPath":"$cbs","subscriberId":"un_93ac20_1761287992168"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.SendLinkHandler - {"az.sdk.message":"onLinkRemoteOpen","connectionId":"MF_e4b94c_1761287833470","linkName":"cbs:sender","entityPath":"$cbs","remoteTarget":"Target{address='$cbs', durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null}"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.AmqpChannelProcessor - {"az.sdk.message":"Channel is now active.","connectionId":"MF_e4b94c_1761287833470","entityPath":"$cbs"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.ReceiveLinkHandler - {"az.sdk.message":"onLinkRemoteOpen","connectionId":"MF_e4b94c_1761287833470","entityPath":"$cbs","linkName":"cbs:receiver","remoteSource":"Source{address='$cbs', durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false, dynamicNodeProperties=null, distributionMode=null, filter=null, defaultOutcome=null, outcomes=null, capabilities=null}"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.ActiveClientTokenManager - {"az.sdk.message":"Scheduling refresh token task.","scopes":"amqp://hgzero-eventhub-ns.servicebus.windows.net/hgzero-eventhub-name"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.ReactorSession - {"az.sdk.message":"Creating a new send link.","connectionId":"MF_e4b94c_1761287833470","linkName":"hgzero-eventhub-name","sessionName":"hgzero-eventhub-name"}
2025-10-24 15:39:52 [reactor-executor-1] INFO c.a.c.a.i.handler.SendLinkHandler - {"az.sdk.message":"onLinkRemoteOpen","connectionId":"MF_e4b94c_1761287833470","linkName":"hgzero-eventhub-name","entityPath":"hgzero-eventhub-name","remoteTarget":"Target{address='hgzero-eventhub-name', durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false, dynamicNodeProperties=null, capabilities=null}"}
2025-10-24 15:39:52 [http-nio-8082-exec-4] INFO c.u.h.m.i.e.p.EventHubPublisher - 이벤트 발행 완료: topic=meeting, type=MEETING_STARTED, partitionKey=4b340eed-31d9-4b7b-a95f-65180d9f663e
2025-10-24 15:39:52 [http-nio-8082-exec-4] DEBUG c.u.h.m.biz.service.MeetingService - MeetingStarted event published: meetingId=4b340eed-31d9-4b7b-a95f-65180d9f663e, sessionId=90de549f-ff4f-4098-a0c0-8f2cd28b1176
2025-10-24 15:39:52 [http-nio-8082-exec-4] INFO c.u.h.m.biz.service.MeetingService - Meeting started successfully: meetingId=4b340eed-31d9-4b7b-a95f-65180d9f663e, sessionId=90de549f-ff4f-4098-a0c0-8f2cd28b1176, minutesId=30e642a9-fa4d-4cbe-a838-33214aaa2170
2025-10-24 15:39:52 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
/* insert for
com.unicorn.hgzero.meeting.infra.gateway.entity.SessionEntity */insert
into
sessions (created_at, ended_at, meeting_id, minutes_id, started_at, started_by, status, updated_at, session_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?)
2025-10-24 15:39:52 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
/* insert for
com.unicorn.hgzero.meeting.infra.gateway.entity.MinutesEntity */insert
into
minutes (created_at, created_by, finalized_at, finalized_by, meeting_id, status, title, updated_at, version, minutes_id)
values
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2025-10-24 15:39:52 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
/* update
for com.unicorn.hgzero.meeting.infra.gateway.entity.MeetingEntity */update meetings
set
description=?,
end_time=?,
ended_at=?,
location=?,
organizer_id=?,
participants=?,
purpose=?,
scheduled_at=?,
started_at=?,
status=?,
template_id=?,
title=?,
updated_at=?
where
meeting_id=?
2025-10-24 15:39:52 [http-nio-8082-exec-4] DEBUG org.hibernate.SQL -
/* update
for com.unicorn.hgzero.meeting.infra.gateway.entity.SessionEntity */update sessions
set
ended_at=?,
meeting_id=?,
minutes_id=?,
started_at=?,
started_by=?,
status=?,
updated_at=?
where
session_id=?
2025-10-24 15:39:52 [http-nio-8082-exec-4] INFO c.u.h.m.i.c.MeetingController - 회의 시작 완료 - meetingId: 4b340eed-31d9-4b7b-a95f-65180d9f663e, sessionId: 90de549f-ff4f-4098-a0c0-8f2cd28b1176
2025-10-24 15:39:52 [http-nio-8082-exec-4] INFO c.u.hgzero.common.aop.LoggingAspect - [Controller] com.unicorn.hgzero.meeting.infra.controller.MeetingController.startMeeting 완료 - 실행시간: 1797ms
2025-10-24 15:44:09 [lettuce-nioEventLoop-6-1] INFO i.l.core.protocol.CommandHandler - null Unexpected exception during request: java.net.SocketException: Connection reset
java.net.SocketException: Connection reset
at java.base/sun.nio.ch.SocketChannelImpl.throwConnectionReset(SocketChannelImpl.java:401)
at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:434)
at io.netty.buffer.PooledByteBuf.setBytes(PooledByteBuf.java:255)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:1132)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:356)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:151)
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:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
2025-10-24 15:44:09 [lettuce-eventExecutorLoop-1-2] INFO i.l.core.protocol.ConnectionWatchdog - Reconnecting, last destination was /20.249.177.114:6379
2025-10-24 15:44:09 [lettuce-nioEventLoop-6-2] INFO i.l.c.protocol.ReconnectionHandler - Reconnected to 20.249.177.114/<unresolved>:6379

View File

@ -0,0 +1,70 @@
package com.unicorn.hgzero.meeting.biz.domain;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 회의 세션 도메인 모델
* 회의가 시작되면 생성되고 회의 종료 종료됨
*/
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Session {
/**
* 세션 ID (UUID)
*/
private String sessionId;
/**
* 회의 ID
*/
private String meetingId;
/**
* 회의록 ID
*/
private String minutesId;
/**
* 세션 시작자 (사용자 ID)
*/
private String startedBy;
/**
* 세션 시작 시간
*/
private LocalDateTime startedAt;
/**
* 세션 종료 시간
*/
private LocalDateTime endedAt;
/**
* 세션 상태 (ACTIVE, CLOSED)
*/
@Builder.Default
private String status = "ACTIVE";
/**
* 세션 종료
*/
public void close() {
this.status = "CLOSED";
this.endedAt = LocalDateTime.now();
}
/**
* 세션이 활성 상태인지 확인
*/
public boolean isActive() {
return "ACTIVE".equals(this.status);
}
}

View File

@ -3,10 +3,16 @@ package com.unicorn.hgzero.meeting.biz.service;
import com.unicorn.hgzero.common.exception.BusinessException; import com.unicorn.hgzero.common.exception.BusinessException;
import com.unicorn.hgzero.common.exception.ErrorCode; import com.unicorn.hgzero.common.exception.ErrorCode;
import com.unicorn.hgzero.meeting.biz.domain.Meeting; import com.unicorn.hgzero.meeting.biz.domain.Meeting;
import com.unicorn.hgzero.meeting.biz.domain.Minutes;
import com.unicorn.hgzero.meeting.biz.domain.Session;
import com.unicorn.hgzero.meeting.biz.usecase.in.meeting.*; import com.unicorn.hgzero.meeting.biz.usecase.in.meeting.*;
import com.unicorn.hgzero.meeting.biz.usecase.out.MeetingReader; import com.unicorn.hgzero.meeting.biz.usecase.out.MeetingReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.MeetingWriter; import com.unicorn.hgzero.meeting.biz.usecase.out.MeetingWriter;
import com.unicorn.hgzero.meeting.biz.usecase.out.MinutesWriter;
import com.unicorn.hgzero.meeting.biz.usecase.out.SessionReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.SessionWriter;
import com.unicorn.hgzero.meeting.infra.cache.CacheService; import com.unicorn.hgzero.meeting.infra.cache.CacheService;
import com.unicorn.hgzero.meeting.infra.event.dto.MeetingStartedEvent;
import com.unicorn.hgzero.meeting.infra.event.publisher.EventPublisher; import com.unicorn.hgzero.meeting.infra.event.publisher.EventPublisher;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -34,6 +40,9 @@ public class MeetingService implements
private final MeetingReader meetingReader; private final MeetingReader meetingReader;
private final MeetingWriter meetingWriter; private final MeetingWriter meetingWriter;
private final SessionReader sessionReader;
private final SessionWriter sessionWriter;
private final MinutesWriter minutesWriter;
private final CacheService cacheService; private final CacheService cacheService;
private final EventPublisher eventPublisher; private final EventPublisher eventPublisher;
@ -123,36 +132,126 @@ public class MeetingService implements
*/ */
@Override @Override
@Transactional @Transactional
public Meeting startMeeting(String meetingId) { public Session startMeeting(String meetingId) {
log.info("Starting meeting: {}", meetingId); log.info("Starting meeting: {}", meetingId);
// Redis 캐시 조회 기능 필요 // 1. Redis 캐시 조회
Meeting meeting = cacheService.getCachedMeeting(meetingId, Meeting.class);
// 회의 조회 // 2. 캐시 미스시 DB 조회 캐싱
Meeting meeting = meetingReader.findById(meetingId) if (meeting == null) {
.orElseThrow(() -> new BusinessException(ErrorCode.ENTITY_NOT_FOUND)); log.debug("Cache miss for meeting: {}", meetingId);
meeting = meetingReader.findById(meetingId)
.orElseThrow(() -> {
log.error("Meeting not found: {}", meetingId);
return new BusinessException(ErrorCode.ENTITY_NOT_FOUND);
});
// 권한 검증 (생성자 or 참석자) // 캐시 저장 (TTL: 10분)
try {
// 회의 상태 검증 cacheService.cacheMeeting(meetingId, meeting, 600);
if (!"SCHEDULED".equals(meeting.getStatus())) { } catch (Exception e) {
throw new BusinessException(ErrorCode.INVALID_INPUT_VALUE); log.warn("Failed to cache meeting: {}", meetingId, e);
}
} else {
log.debug("Cache hit for meeting: {}", meetingId);
} }
// 세션 생성 기능 필요 // 3. 비즈니스 규칙 검증
// TODO: 권한 검증 (생성자 또는 참석자) - userId 파라미터 필요
// 회의 시작 // 4. 회의 상태 확인 (SCHEDULED만 시작 가능)
if (!"SCHEDULED".equals(meeting.getStatus())) {
log.warn("Meeting is not in SCHEDULED status: meetingId={}, status={}",
meetingId, meeting.getStatus());
if ("IN_PROGRESS".equals(meeting.getStatus())) {
throw new BusinessException(ErrorCode.INVALID_INPUT_VALUE,
"이미 진행 중인 회의입니다");
}
throw new BusinessException(ErrorCode.INVALID_INPUT_VALUE,
"회의 상태가 올바르지 않습니다");
}
// 5. 회의 세션 생성
String sessionId = UUID.randomUUID().toString();
Session session = Session.builder()
.sessionId(sessionId)
.meetingId(meetingId)
.startedBy(meeting.getOrganizerId()) // TODO: 실제 사용자 ID 사용
.startedAt(LocalDateTime.now())
.status("ACTIVE")
.build();
// 6. 세션 저장
Session savedSession = sessionWriter.save(session);
log.debug("Session created: sessionId={}, meetingId={}", sessionId, meetingId);
// 7. 회의 상태를 IN_PROGRESS로 업데이트
meeting.start(); meeting.start();
// 저장
Meeting updatedMeeting = meetingWriter.save(meeting); Meeting updatedMeeting = meetingWriter.save(meeting);
log.debug("Meeting status updated to IN_PROGRESS: {}", meetingId);
// 회의록 초안 생성 필요 // 8. 캐시 무효화
try {
cacheService.evictCache("meeting:", meetingId);
log.debug("Meeting cache evicted: {}", meetingId);
} catch (Exception e) {
log.warn("Failed to evict meeting cache: {}", meetingId, e);
}
// 이벤트 발행 필요 // 9. 회의록 초안 생성 ( 회의록)
String minutesId = UUID.randomUUID().toString();
Minutes minutesDraft = Minutes.builder()
.minutesId(minutesId)
.meetingId(meetingId)
.title(meeting.getTitle() + " - 회의록")
.sections(List.of())
.status("DRAFT")
.version(1)
.createdBy(meeting.getOrganizerId()) // TODO: 실제 사용자 ID 사용
.createdAt(LocalDateTime.now())
.build();
log.info("Meeting started successfully: {}", meetingId); Minutes savedMinutes = minutesWriter.save(minutesDraft);
return updatedMeeting; log.debug("Minutes draft created: minutesId={}, meetingId={}", minutesId, meetingId);
// 세션에 회의록 ID 연결
Session updatedSession = Session.builder()
.sessionId(savedSession.getSessionId())
.meetingId(savedSession.getMeetingId())
.minutesId(minutesId)
.startedBy(savedSession.getStartedBy())
.startedAt(savedSession.getStartedAt())
.status(savedSession.getStatus())
.build();
sessionWriter.save(updatedSession);
// 10. 비동기 이벤트 발행
try {
MeetingStartedEvent event = MeetingStartedEvent.builder()
.meetingId(meetingId)
.sessionId(sessionId)
.title(meeting.getTitle())
.startTime(meeting.getStartedAt())
.organizer(meeting.getOrganizerId())
.participants(meeting.getParticipants())
.minutesId(minutesId)
.eventTime(LocalDateTime.now())
.build();
eventPublisher.publishMeetingStarted(event);
log.debug("MeetingStarted event published: meetingId={}, sessionId={}",
meetingId, sessionId);
} catch (Exception e) {
log.error("Failed to publish MeetingStarted event: meetingId={}", meetingId, e);
// 이벤트 발행 실패는 비즈니스 로직에 영향을 주지 않으므로 계속 진행
}
log.info("Meeting started successfully: meetingId={}, sessionId={}, minutesId={}",
meetingId, sessionId, minutesId);
return updatedSession;
} }
/** /**

View File

@ -1,6 +1,6 @@
package com.unicorn.hgzero.meeting.biz.usecase.in.meeting; package com.unicorn.hgzero.meeting.biz.usecase.in.meeting;
import com.unicorn.hgzero.meeting.biz.domain.Meeting; import com.unicorn.hgzero.meeting.biz.domain.Session;
/** /**
* 회의 시작 UseCase * 회의 시작 UseCase
@ -9,6 +9,8 @@ public interface StartMeetingUseCase {
/** /**
* 회의 시작 * 회의 시작
* @param meetingId 회의 ID
* @return 생성된 세션 정보
*/ */
Meeting startMeeting(String meetingId); Session startMeeting(String meetingId);
} }

View File

@ -0,0 +1,32 @@
package com.unicorn.hgzero.meeting.biz.usecase.out;
import com.unicorn.hgzero.meeting.biz.domain.Session;
import java.util.List;
import java.util.Optional;
/**
* Session Reader Port
*/
public interface SessionReader {
/**
* ID로 세션 조회
*/
Optional<Session> findById(String sessionId);
/**
* 회의 ID로 세션 목록 조회
*/
List<Session> findByMeetingId(String meetingId);
/**
* 회의 ID로 활성 세션 조회
*/
Optional<Session> findActiveSesionByMeetingId(String meetingId);
/**
* 시작자 ID로 세션 목록 조회
*/
List<Session> findByStartedBy(String startedBy);
}

View File

@ -0,0 +1,19 @@
package com.unicorn.hgzero.meeting.biz.usecase.out;
import com.unicorn.hgzero.meeting.biz.domain.Session;
/**
* Session Writer Port
*/
public interface SessionWriter {
/**
* 세션 저장
*/
Session save(Session session);
/**
* 세션 삭제
*/
void delete(String sessionId);
}

View File

@ -149,12 +149,12 @@ public class MeetingController {
// meeting id 유효성 검증 필요 // meeting id 유효성 검증 필요
var sessionData = startMeetingUseCase.startMeeting(meetingId); var session = startMeetingUseCase.startMeeting(meetingId);
var response = SessionResponse.from(sessionData); var response = SessionResponse.from(session, "ws://localhost:8080/ws/collaboration");
log.info("회의 시작 완료 - meetingId: {}", meetingId); log.info("회의 시작 완료 - meetingId: {}, sessionId: {}", meetingId, session.getSessionId());
return ResponseEntity.ok(ApiResponse.success(response)); return ResponseEntity.status(HttpStatus.CREATED).body(ApiResponse.success(response));
} }
/** /**

View File

@ -21,6 +21,12 @@ public class SessionResponse {
@Schema(description = "회의 ID", example = "550e8400-e29b-41d4-a716-446655440000") @Schema(description = "회의 ID", example = "550e8400-e29b-41d4-a716-446655440000")
private final String meetingId; private final String meetingId;
@Schema(description = "회의록 ID", example = "minutes-001")
private final String minutesId;
@Schema(description = "세션 상태", example = "IN_PROGRESS")
private final String status;
@Schema(description = "WebSocket URL", example = "ws://localhost:8080/ws/collaboration") @Schema(description = "WebSocket URL", example = "ws://localhost:8080/ws/collaboration")
private final String websocketUrl; private final String websocketUrl;
@ -40,10 +46,28 @@ public class SessionResponse {
return SessionResponse.builder() return SessionResponse.builder()
.sessionId("session-" + meeting.getMeetingId()) .sessionId("session-" + meeting.getMeetingId())
.meetingId(meeting.getMeetingId()) .meetingId(meeting.getMeetingId())
.minutesId(null) // 실제로는 세션에서 가져와야
.status(meeting.getStatus())
.websocketUrl("ws://localhost:8080/ws/collaboration") .websocketUrl("ws://localhost:8080/ws/collaboration")
.sessionToken("session-token-" + System.currentTimeMillis()) .sessionToken("session-token-" + System.currentTimeMillis())
.startedAt(meeting.getStartedAt() != null ? meeting.getStartedAt() : LocalDateTime.now()) .startedAt(meeting.getStartedAt() != null ? meeting.getStartedAt() : LocalDateTime.now())
.expiresAt(LocalDateTime.now().plusHours(4)) .expiresAt(LocalDateTime.now().plusHours(4))
.build(); .build();
} }
/**
* Session 객체로부터 SessionResponse 생성
*/
public static SessionResponse from(com.unicorn.hgzero.meeting.biz.domain.Session session, String websocketUrl) {
return SessionResponse.builder()
.sessionId(session.getSessionId())
.meetingId(session.getMeetingId())
.minutesId(session.getMinutesId())
.status(session.getStatus())
.websocketUrl(websocketUrl != null ? websocketUrl : "ws://localhost:8080/ws/collaboration")
.sessionToken("session-token-" + System.currentTimeMillis())
.startedAt(session.getStartedAt())
.expiresAt(session.getStartedAt().plusHours(4))
.build();
}
} }

View File

@ -18,6 +18,11 @@ public class MeetingStartedEvent {
*/ */
private final String meetingId; private final String meetingId;
/**
* 세션 ID
*/
private final String sessionId;
/** /**
* 회의 제목 * 회의 제목
*/ */

View File

@ -0,0 +1,64 @@
package com.unicorn.hgzero.meeting.infra.gateway;
import com.unicorn.hgzero.meeting.biz.domain.Session;
import com.unicorn.hgzero.meeting.biz.usecase.out.SessionReader;
import com.unicorn.hgzero.meeting.biz.usecase.out.SessionWriter;
import com.unicorn.hgzero.meeting.infra.gateway.entity.SessionEntity;
import com.unicorn.hgzero.meeting.infra.gateway.repository.SessionJpaRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 세션 Gateway 구현체
* SessionReader, SessionWriter 인터페이스 구현
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class SessionGateway implements SessionReader, SessionWriter {
private final SessionJpaRepository sessionJpaRepository;
@Override
public Optional<Session> findById(String sessionId) {
return sessionJpaRepository.findById(sessionId)
.map(SessionEntity::toDomain);
}
@Override
public List<Session> findByMeetingId(String meetingId) {
return sessionJpaRepository.findByMeetingId(meetingId).stream()
.map(SessionEntity::toDomain)
.collect(Collectors.toList());
}
@Override
public Optional<Session> findActiveSesionByMeetingId(String meetingId) {
return sessionJpaRepository.findActiveSessionByMeetingId(meetingId)
.map(SessionEntity::toDomain);
}
@Override
public List<Session> findByStartedBy(String startedBy) {
return sessionJpaRepository.findByStartedBy(startedBy).stream()
.map(SessionEntity::toDomain)
.collect(Collectors.toList());
}
@Override
public Session save(Session session) {
SessionEntity entity = SessionEntity.fromDomain(session);
SessionEntity savedEntity = sessionJpaRepository.save(entity);
return savedEntity.toDomain();
}
@Override
public void delete(String sessionId) {
sessionJpaRepository.deleteById(sessionId);
}
}

View File

@ -0,0 +1,75 @@
package com.unicorn.hgzero.meeting.infra.gateway.entity;
import com.unicorn.hgzero.common.entity.BaseTimeEntity;
import com.unicorn.hgzero.meeting.biz.domain.Session;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 회의 세션 Entity
*/
@Entity
@Table(name = "sessions")
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SessionEntity extends BaseTimeEntity {
@Id
@Column(name = "session_id", length = 50)
private String sessionId;
@Column(name = "meeting_id", length = 50, nullable = false)
private String meetingId;
@Column(name = "minutes_id", length = 50)
private String minutesId;
@Column(name = "started_by", length = 50, nullable = false)
private String startedBy;
@Column(name = "started_at", nullable = false)
private LocalDateTime startedAt;
@Column(name = "ended_at")
private LocalDateTime endedAt;
@Column(name = "status", length = 20, nullable = false)
@Builder.Default
private String status = "ACTIVE";
public Session toDomain() {
return Session.builder()
.sessionId(this.sessionId)
.meetingId(this.meetingId)
.minutesId(this.minutesId)
.startedBy(this.startedBy)
.startedAt(this.startedAt)
.endedAt(this.endedAt)
.status(this.status)
.build();
}
public static SessionEntity fromDomain(Session session) {
return SessionEntity.builder()
.sessionId(session.getSessionId())
.meetingId(session.getMeetingId())
.minutesId(session.getMinutesId())
.startedBy(session.getStartedBy())
.startedAt(session.getStartedAt())
.endedAt(session.getEndedAt())
.status(session.getStatus())
.build();
}
public void close() {
this.status = "CLOSED";
this.endedAt = LocalDateTime.now();
}
}

View File

@ -0,0 +1,31 @@
package com.unicorn.hgzero.meeting.infra.gateway.repository;
import com.unicorn.hgzero.meeting.infra.gateway.entity.SessionEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
/**
* 세션 JPA Repository
*/
public interface SessionJpaRepository extends JpaRepository<SessionEntity, String> {
/**
* 회의 ID로 세션 목록 조회
*/
List<SessionEntity> findByMeetingId(String meetingId);
/**
* 회의 ID로 활성 세션 조회
*/
@Query("SELECT s FROM SessionEntity s WHERE s.meetingId = :meetingId AND s.status = 'ACTIVE'")
Optional<SessionEntity> findActiveSessionByMeetingId(@Param("meetingId") String meetingId);
/**
* 시작자 ID로 세션 목록 조회
*/
List<SessionEntity> findByStartedBy(String startedBy);
}