From f89e4b3ee4644b07589d6c29dc8862b482560d6c Mon Sep 17 00:00:00 2001 From: 19013na <19013@naver.com> Date: Thu, 31 Jul 2025 17:37:59 +0900 Subject: [PATCH 001/149] develop init --- src/main/resources/application.properties | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 479a627..0362d09 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,16 @@ spring.application.name=booking + +# 기본 true +spring.devtools.restart.enabled=true + +# 애플리케이션 포트 설정, 기본은 8080 +server.port=8080 + +# 모든 IP 주소에서 접근 허용 +server.address=0.0.0.0 + +# 현재 활성화된 환경 - 개발 환경에 따라 수정하세요 +spring.profiles.active=test + +# log file +logging.file.path=logs \ No newline at end of file From 6f2c4152c9213951d71f639ca829c9b9689eef7a Mon Sep 17 00:00:00 2001 From: 19013na <19013@naver.com> Date: Fri, 1 Aug 2025 16:11:24 +0900 Subject: [PATCH 002/149] =?UTF-8?q?MNMS-143=20feat:=20=EB=8C=80=EA=B8=B0?= =?UTF-8?q?=EC=97=B4=201=EC=B0=A8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit redis 사용해서 대기열큐 zset redis + websocket 사용해서 대기 번호 set --- build.gradle | 26 +- logs/spring.log | 1771 +++++++++++++++++ .../com/mnms/booking/config/RedisConfig.java | 65 + .../mnms/booking/config/WebSocketConfig.java | 28 + .../booking/controller/BookingController.java | 69 + .../dto/response/WaitingNumberDto.java | 16 + .../booking/exception/BusinessException.java | 18 + .../com/mnms/booking/exception/ErrorCode.java | 22 + .../exception/global/ErrorResponse.java | 20 + .../global/GlobalExceptionHandler.java | 54 + .../exception/global/SuccessResponse.java | 18 + .../service/RedisMessageSubscriber.java | 43 + .../mnms/booking/service/WaitingService.java | 199 ++ .../resources/application-test.properties | 26 + src/main/resources/static/index.html | 129 ++ src/main/resources/static/test-websocket.html | 44 + 16 files changed, 2545 insertions(+), 3 deletions(-) create mode 100644 logs/spring.log create mode 100644 src/main/java/com/mnms/booking/config/RedisConfig.java create mode 100644 src/main/java/com/mnms/booking/config/WebSocketConfig.java create mode 100644 src/main/java/com/mnms/booking/controller/BookingController.java create mode 100644 src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java create mode 100644 src/main/java/com/mnms/booking/exception/BusinessException.java create mode 100644 src/main/java/com/mnms/booking/exception/ErrorCode.java create mode 100644 src/main/java/com/mnms/booking/exception/global/ErrorResponse.java create mode 100644 src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java create mode 100644 src/main/java/com/mnms/booking/exception/global/SuccessResponse.java create mode 100644 src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java create mode 100644 src/main/java/com/mnms/booking/service/WaitingService.java create mode 100644 src/main/resources/application-test.properties create mode 100644 src/main/resources/static/index.html create mode 100644 src/main/resources/static/test-websocket.html diff --git a/build.gradle b/build.gradle index c1d5d4f..7161842 100644 --- a/build.gradle +++ b/build.gradle @@ -28,12 +28,32 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.kafka:spring-kafka' - compileOnly 'org.projectlombok:lombok' - runtimeOnly 'com.h2database:h2' - annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.kafka:spring-kafka-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + + // security + //implementation 'org.springframework.boot:spring-boot-starter-security' + + // h2 + runtimeOnly 'com.h2database:h2' + + // websocket + implementation 'org.springframework.boot:spring-boot-starter-websocket' + + // redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + implementation 'redis.clients:jedis' // 삭제 가능 + + // mariadb + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' + + // mongodb + //implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' } tasks.named('test') { diff --git a/logs/spring.log b/logs/spring.log new file mode 100644 index 0000000..befd357 --- /dev/null +++ b/logs/spring.log @@ -0,0 +1,1771 @@ +2025-08-01T13:12:53.183+09:00 INFO 19824 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 19824 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T13:12:53.186+09:00 INFO 19824 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T13:12:54.689+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:12:54.692+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T13:12:54.723+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces. +2025-08-01T13:12:54.761+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:12:54.761+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T13:12:54.766+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T13:12:54.779+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:12:54.781+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T13:12:54.796+09:00 INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T13:12:55.931+09:00 INFO 19824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T13:12:55.955+09:00 INFO 19824 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T13:12:55.956+09:00 INFO 19824 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T13:12:56.085+09:00 INFO 19824 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T13:12:56.086+09:00 INFO 19824 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2832 ms +2025-08-01T13:12:56.469+09:00 INFO 19824 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T13:12:56.549+09:00 INFO 19824 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T13:12:56.586+09:00 INFO 19824 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T13:12:56.934+09:00 INFO 19824 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T13:12:56.967+09:00 INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T13:12:57.177+09:00 INFO 19824 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T13:12:57.181+09:00 INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T13:12:57.211+09:00 WARN 19824 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T13:12:57.241+09:00 INFO 19824 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T13:12:57.726+09:00 INFO 19824 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T13:12:57.732+09:00 INFO 19824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:12:59.065+09:00 WARN 19824 --- [booking] [main] 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-08-01T13:12:59.272+09:00 INFO 19824 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T13:12:59.885+09:00 INFO 19824 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@24e31f06, com.mongodb.Jep395RecordCodecProvider@5d260494, com.mongodb.KotlinCodecProvider@d43f205]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T13:12:59.886+09:00 INFO 19824 --- [booking] [cluster-ClusterId{value='688c3ecb0a3db11f80b7808c', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T13:13:00.472+09:00 INFO 19824 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T13:13:00.664+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T13:13:00.665+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3ede428e]] +2025-08-01T13:13:00.666+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T13:13:00.690+09:00 INFO 19824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T13:13:01.210+09:00 INFO 19824 --- [booking] [main] o.s.b.w.e.tomcat.GracefulShutdown : Commencing graceful shutdown. Waiting for active requests to complete +2025-08-01T13:13:01.356+09:00 INFO 19824 --- [booking] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown : Graceful shutdown complete +2025-08-01T13:13:01.359+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping... +2025-08-01T13:13:01.359+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3ede428e]] +2025-08-01T13:13:01.360+09:00 INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped. +2025-08-01T13:13:01.371+09:00 WARN 19824 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer' +2025-08-01T13:13:01.381+09:00 INFO 19824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:13:01.386+09:00 INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2025-08-01T13:13:01.389+09:00 INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +2025-08-01T13:13:01.405+09:00 INFO 19824 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : + +Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. +2025-08-01T13:13:01.424+09:00 ERROR 19824 --- [booking] [main] o.s.boot.SpringApplication : Application run failed + +org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer' + at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:408) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586) ~[spring-context-6.2.9.jar:6.2.9] + at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na] + at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1006) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:630) ~[spring-context-6.2.9.jar:6.2.9] + at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4] + at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4] + at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4] + at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4] + at com.mnms.booking.BookingApplication.main(BookingApplication.java:10) ~[main/:na] +Caused by: org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis + at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:383) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer.start(RedisMessageListenerContainer.java:361) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.9.jar:6.2.9] + ... 14 common frames omitted +Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1866) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1797) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1594) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1574) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1535) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1571) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1257) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:1063) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$initialize$0(RedisMessageListenerContainer.java:1241) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1455) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.initialize(RedisMessageListenerContainer.java:1235) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer.doSubscribe(RedisMessageListenerContainer.java:428) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:404) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:374) ~[spring-data-redis-3.5.2.jar:3.5.2] + ... 16 common frames omitted +Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool + at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:118) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1795) ~[spring-data-redis-3.5.2.jar:3.5.2] + ... 28 common frames omitted +Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/:6379 + at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:63) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:41) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:354) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.lettuce.core.RedisClient.connect(RedisClient.java:220) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2] + at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na] + at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2] + at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$getConnection$0(LettucePoolingConnectionProvider.java:100) ~[spring-data-redis-3.5.2.jar:3.5.2] + at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:270) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:257) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:68) ~[commons-pool2-2.12.1.jar:2.12.1] + at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:557) ~[commons-pool2-2.12.1.jar:2.12.1] + at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:299) ~[commons-pool2-2.12.1.jar:2.12.1] + at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:231) ~[commons-pool2-2.12.1.jar:2.12.1] + at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:149) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:144) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:113) ~[spring-data-redis-3.5.2.jar:3.5.2] + ... 29 common frames omitted +Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: localhost/127.0.0.1:6379 +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na] + at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:784) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T13:58:06.369+09:00 INFO 20964 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 20964 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T13:58:06.378+09:00 INFO 20964 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T13:58:07.748+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:58:07.748+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T13:58:07.804+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces. +2025-08-01T13:58:07.846+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:58:07.846+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T13:58:07.846+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T13:58:07.860+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:58:07.860+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T13:58:07.873+09:00 INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T13:58:09.261+09:00 INFO 20964 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T13:58:09.308+09:00 INFO 20964 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T13:58:09.312+09:00 INFO 20964 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T13:58:09.463+09:00 INFO 20964 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T13:58:09.465+09:00 INFO 20964 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3023 ms +2025-08-01T13:58:10.077+09:00 INFO 20964 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T13:58:10.177+09:00 INFO 20964 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T13:58:10.217+09:00 INFO 20964 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T13:58:10.768+09:00 INFO 20964 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T13:58:10.831+09:00 INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T13:58:11.170+09:00 INFO 20964 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T13:58:11.172+09:00 INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T13:58:11.218+09:00 WARN 20964 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T13:58:11.248+09:00 INFO 20964 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T13:58:11.782+09:00 INFO 20964 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T13:58:11.791+09:00 INFO 20964 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:58:13.928+09:00 WARN 20964 --- [booking] [main] 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-08-01T13:58:14.269+09:00 INFO 20964 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T13:58:16.234+09:00 INFO 20964 --- [booking] [cluster-ClusterId{value='688c4967205e09c6921815cd', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T13:58:16.278+09:00 INFO 20964 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@27e656e6, com.mongodb.Jep395RecordCodecProvider@3cfab56d, com.mongodb.KotlinCodecProvider@6b6fde93]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T13:58:17.208+09:00 INFO 20964 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T13:58:17.488+09:00 WARN 20964 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 6d6b00f9-7412-4dee-b32c-2021959376e8 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T13:58:17.501+09:00 INFO 20964 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T13:58:17.680+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T13:58:17.680+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2b3e2039]] +2025-08-01T13:58:17.691+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T13:58:17.696+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping... +2025-08-01T13:58:17.696+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2b3e2039]] +2025-08-01T13:58:17.696+09:00 INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped. +2025-08-01T13:58:17.706+09:00 WARN 20964 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop' +2025-08-01T13:58:17.738+09:00 INFO 20964 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:58:17.742+09:00 INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2025-08-01T13:58:17.747+09:00 INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +2025-08-01T13:58:17.761+09:00 INFO 20964 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : + +Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. +2025-08-01T13:58:17.783+09:00 ERROR 20964 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter : + +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Web server failed to start. Port 8080 was already in use. + +Action: + +Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. + +2025-08-01T13:59:31.089+09:00 INFO 4420 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 4420 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T13:59:31.094+09:00 INFO 4420 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T13:59:32.369+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:59:32.369+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T13:59:32.401+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces. +2025-08-01T13:59:32.445+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:59:32.445+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T13:59:32.453+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 MongoDB repository interfaces. +2025-08-01T13:59:32.477+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T13:59:32.479+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T13:59:32.492+09:00 INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T13:59:33.814+09:00 INFO 4420 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T13:59:33.868+09:00 INFO 4420 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T13:59:33.868+09:00 INFO 4420 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T13:59:34.016+09:00 INFO 4420 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T13:59:34.021+09:00 INFO 4420 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2867 ms +2025-08-01T13:59:34.599+09:00 INFO 4420 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T13:59:34.718+09:00 INFO 4420 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T13:59:34.764+09:00 INFO 4420 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T13:59:35.162+09:00 INFO 4420 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T13:59:35.211+09:00 INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T13:59:35.432+09:00 INFO 4420 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T13:59:35.434+09:00 INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T13:59:35.453+09:00 WARN 4420 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T13:59:35.481+09:00 INFO 4420 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T13:59:35.823+09:00 INFO 4420 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T13:59:35.828+09:00 INFO 4420 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:59:37.486+09:00 WARN 4420 --- [booking] [main] 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-08-01T13:59:37.817+09:00 INFO 4420 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T13:59:39.871+09:00 INFO 4420 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3fb42ec7, com.mongodb.Jep395RecordCodecProvider@1f7b1d6a, com.mongodb.KotlinCodecProvider@32d8e58d]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T13:59:39.871+09:00 INFO 4420 --- [booking] [cluster-ClusterId{value='688c49bb4aa34090cf08cdb5', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T13:59:40.824+09:00 INFO 4420 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T13:59:41.218+09:00 WARN 4420 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: f1348f72-af09-4479-9134-b99c9236b3d3 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T13:59:41.236+09:00 INFO 4420 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T13:59:41.575+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T13:59:41.585+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2afa1b1a]] +2025-08-01T13:59:41.586+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T13:59:41.599+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping... +2025-08-01T13:59:41.599+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2afa1b1a]] +2025-08-01T13:59:41.599+09:00 INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped. +2025-08-01T13:59:41.620+09:00 WARN 4420 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop' +2025-08-01T13:59:41.655+09:00 INFO 4420 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T13:59:41.657+09:00 INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2025-08-01T13:59:41.668+09:00 INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +2025-08-01T13:59:41.695+09:00 INFO 4420 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : + +Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. +2025-08-01T13:59:41.742+09:00 ERROR 4420 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter : + +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Web server failed to start. Port 8080 was already in use. + +Action: + +Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. + +2025-08-01T14:02:02.270+09:00 INFO 6696 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 6696 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:02:02.276+09:00 INFO 6696 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:02:04.071+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:04.071+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:02:04.102+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces. +2025-08-01T14:02:04.134+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:04.134+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:02:04.134+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:02:04.151+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:04.151+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:02:04.174+09:00 INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces. +2025-08-01T14:02:05.451+09:00 INFO 6696 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:02:05.482+09:00 INFO 6696 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:02:05.482+09:00 INFO 6696 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:02:05.594+09:00 INFO 6696 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:02:05.594+09:00 INFO 6696 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3214 ms +2025-08-01T14:02:06.194+09:00 INFO 6696 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:02:06.273+09:00 INFO 6696 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:02:06.304+09:00 INFO 6696 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:02:06.687+09:00 INFO 6696 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:02:06.735+09:00 INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:02:06.926+09:00 INFO 6696 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:02:06.926+09:00 INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:02:06.979+09:00 WARN 6696 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:02:07.006+09:00 INFO 6696 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:02:07.420+09:00 INFO 6696 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:02:07.436+09:00 INFO 6696 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:02:08.860+09:00 WARN 6696 --- [booking] [main] 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-08-01T14:02:09.174+09:00 INFO 6696 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:02:10.163+09:00 INFO 6696 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@32d8e58d, com.mongodb.Jep395RecordCodecProvider@4c941d19, com.mongodb.KotlinCodecProvider@5248c05a]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:02:10.171+09:00 INFO 6696 --- [booking] [cluster-ClusterId{value='688c4a52bc323016b51ea9f2', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:02:10.557+09:00 INFO 6696 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:02:10.735+09:00 WARN 6696 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: a1c56098-6888-4780-8743-8b4389f7bbaa + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:02:10.735+09:00 INFO 6696 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:02:10.995+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:02:11.000+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@487f025]] +2025-08-01T14:02:11.000+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:02:11.010+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping... +2025-08-01T14:02:11.010+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@487f025]] +2025-08-01T14:02:11.010+09:00 INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped. +2025-08-01T14:02:11.042+09:00 WARN 6696 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop' +2025-08-01T14:02:11.073+09:00 INFO 6696 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:02:11.073+09:00 INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2025-08-01T14:02:11.088+09:00 INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +2025-08-01T14:02:11.117+09:00 INFO 6696 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : + +Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. +2025-08-01T14:02:11.177+09:00 ERROR 6696 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter : + +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Web server failed to start. Port 8080 was already in use. + +Action: + +Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. + +2025-08-01T14:02:40.757+09:00 INFO 11700 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 11700 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:02:40.760+09:00 INFO 11700 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:02:42.605+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:42.609+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:02:42.668+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 33 ms. Found 0 JPA repository interfaces. +2025-08-01T14:02:42.735+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:42.736+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:02:42.740+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:02:42.765+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:02:42.767+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:02:42.797+09:00 INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:02:44.492+09:00 INFO 11700 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:02:44.540+09:00 INFO 11700 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:02:44.540+09:00 INFO 11700 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:02:44.771+09:00 INFO 11700 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:02:44.773+09:00 INFO 11700 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3908 ms +2025-08-01T14:02:45.289+09:00 INFO 11700 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:02:45.369+09:00 INFO 11700 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:02:45.423+09:00 INFO 11700 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:02:45.830+09:00 INFO 11700 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:02:45.879+09:00 INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:02:46.060+09:00 INFO 11700 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:02:46.062+09:00 INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:02:46.074+09:00 WARN 11700 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:02:46.093+09:00 INFO 11700 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:02:46.461+09:00 INFO 11700 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:02:46.468+09:00 INFO 11700 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:02:47.756+09:00 WARN 11700 --- [booking] [main] 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-08-01T14:02:48.122+09:00 INFO 11700 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:02:49.028+09:00 INFO 11700 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@75f446df, com.mongodb.Jep395RecordCodecProvider@3751baf6, com.mongodb.KotlinCodecProvider@27e656e6]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:02:49.028+09:00 INFO 11700 --- [booking] [cluster-ClusterId{value='688c4a785d6f68bcc6fc9d71', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:02:49.547+09:00 INFO 11700 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:02:49.800+09:00 WARN 11700 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: ae9c07e7-443f-4740-9cf2-2b932be210ef + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:02:49.820+09:00 INFO 11700 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:02:49.995+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:02:50.003+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4dd28982]] +2025-08-01T14:02:50.005+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:02:50.005+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping... +2025-08-01T14:02:50.005+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4dd28982]] +2025-08-01T14:02:50.005+09:00 INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped. +2025-08-01T14:02:50.019+09:00 WARN 11700 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop' +2025-08-01T14:02:50.059+09:00 INFO 11700 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:02:50.059+09:00 INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... +2025-08-01T14:02:50.074+09:00 INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. +2025-08-01T14:02:50.099+09:00 INFO 11700 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : + +Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled. +2025-08-01T14:02:50.125+09:00 ERROR 11700 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter : + +*************************** +APPLICATION FAILED TO START +*************************** + +Description: + +Web server failed to start. Port 8080 was already in use. + +Action: + +Identify and stop the process that's listening on port 8080 or configure this application to listen on another port. + +2025-08-01T14:05:39.564+09:00 INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 19504 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:05:39.569+09:00 INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:05:41.330+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:05:41.332+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:05:41.385+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces. +2025-08-01T14:05:41.424+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:05:41.424+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:05:41.436+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:05:41.449+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:05:41.450+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:05:41.463+09:00 INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:05:42.946+09:00 INFO 19504 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:05:42.997+09:00 INFO 19504 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:05:42.998+09:00 INFO 19504 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:05:43.205+09:00 INFO 19504 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:05:43.207+09:00 INFO 19504 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3559 ms +2025-08-01T14:05:43.810+09:00 INFO 19504 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:05:44.019+09:00 INFO 19504 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:05:44.054+09:00 INFO 19504 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:05:44.528+09:00 INFO 19504 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:05:44.565+09:00 INFO 19504 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:05:44.751+09:00 INFO 19504 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:05:44.753+09:00 INFO 19504 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:05:44.776+09:00 WARN 19504 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:05:44.800+09:00 INFO 19504 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:05:45.116+09:00 INFO 19504 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:05:45.123+09:00 INFO 19504 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:05:46.649+09:00 WARN 19504 --- [booking] [main] 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-08-01T14:05:46.861+09:00 INFO 19504 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:05:48.362+09:00 INFO 19504 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@4c941d19, com.mongodb.Jep395RecordCodecProvider@5248c05a, com.mongodb.KotlinCodecProvider@151f1734]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:05:48.366+09:00 INFO 19504 --- [booking] [cluster-ClusterId{value='688c4b2c0dc1a44ec2a5a5e0', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:05:48.981+09:00 INFO 19504 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:05:49.171+09:00 WARN 19504 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 59ba44ea-4ab1-4b85-a0dc-3a867e307402 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:05:49.179+09:00 INFO 19504 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:05:49.376+09:00 INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:05:49.380+09:00 INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@64547a83]] +2025-08-01T14:05:49.381+09:00 INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:05:49.417+09:00 INFO 19504 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:05:50.098+09:00 INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 11.311 seconds (process running for 11.844) +2025-08-01T14:06:49.384+09:00 INFO 19504 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:06:57.191+09:00 INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 17300 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:06:57.194+09:00 INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:06:58.477+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:06:58.479+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:06:58.524+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces. +2025-08-01T14:06:58.560+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:06:58.562+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:06:58.566+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:06:58.584+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:06:58.585+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:06:58.596+09:00 INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:06:59.836+09:00 INFO 17300 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:06:59.883+09:00 INFO 17300 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:06:59.883+09:00 INFO 17300 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:07:00.037+09:00 INFO 17300 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:07:00.040+09:00 INFO 17300 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2788 ms +2025-08-01T14:07:00.578+09:00 INFO 17300 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:07:00.698+09:00 INFO 17300 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:07:00.724+09:00 INFO 17300 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:07:01.133+09:00 INFO 17300 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:07:01.164+09:00 INFO 17300 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:07:01.362+09:00 INFO 17300 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:73ba27b4-f19d-459c-a234-2e5a3c3a76f0 user=SA +2025-08-01T14:07:01.362+09:00 INFO 17300 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:07:01.387+09:00 WARN 17300 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:07:01.439+09:00 INFO 17300 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:07:01.834+09:00 INFO 17300 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:07:01.847+09:00 INFO 17300 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:07:03.094+09:00 WARN 17300 --- [booking] [main] 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-08-01T14:07:03.362+09:00 INFO 17300 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:07:04.731+09:00 INFO 17300 --- [booking] [cluster-ClusterId{value='688c4b78b902eaa57ce45511', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:07:04.735+09:00 INFO 17300 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@6f12fca0, com.mongodb.Jep395RecordCodecProvider@12c30824, com.mongodb.KotlinCodecProvider@7d0e43d6]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:07:05.279+09:00 INFO 17300 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:73ba27b4-f19d-459c-a234-2e5a3c3a76f0' +2025-08-01T14:07:05.507+09:00 WARN 17300 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 7c164a8c-fe86-4a2e-a864-77b14b87c19e + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:07:05.521+09:00 INFO 17300 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:07:05.642+09:00 INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:07:05.642+09:00 INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3dfe520]] +2025-08-01T14:07:05.642+09:00 INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:07:05.658+09:00 INFO 17300 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:07:06.321+09:00 INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 9.798 seconds (process running for 10.233) +2025-08-01T14:07:24.429+09:00 INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 23496 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:07:24.429+09:00 INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:07:25.647+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:07:25.648+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:07:25.679+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces. +2025-08-01T14:07:25.709+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:07:25.709+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:07:25.709+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:07:25.726+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:07:25.726+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:07:25.740+09:00 INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces. +2025-08-01T14:07:26.904+09:00 INFO 23496 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:07:26.928+09:00 INFO 23496 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:07:26.928+09:00 INFO 23496 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:07:27.028+09:00 INFO 23496 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:07:27.028+09:00 INFO 23496 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2536 ms +2025-08-01T14:07:27.378+09:00 INFO 23496 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:07:27.686+09:00 INFO 23496 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:34fc08bb-d72b-4bfa-bcb9-82651b1ee75e user=SA +2025-08-01T14:07:27.686+09:00 INFO 23496 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:07:27.781+09:00 INFO 23496 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:07:27.839+09:00 INFO 23496 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:07:27.874+09:00 INFO 23496 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:07:28.170+09:00 INFO 23496 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:07:28.255+09:00 INFO 23496 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:07:28.588+09:00 INFO 23496 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:07:28.594+09:00 INFO 23496 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:07:29.631+09:00 WARN 23496 --- [booking] [main] 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-08-01T14:07:29.892+09:00 INFO 23496 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:07:30.915+09:00 INFO 23496 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@7d836c4a, com.mongodb.Jep395RecordCodecProvider@485547ac, com.mongodb.KotlinCodecProvider@6d77d269]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:07:30.915+09:00 INFO 23496 --- [booking] [cluster-ClusterId{value='688c4b92907b81b0f4eecee6', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:07:31.615+09:00 WARN 23496 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 5f35c8ee-aad4-41c8-a0aa-abb14fdcb77f + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:07:31.624+09:00 INFO 23496 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:07:31.791+09:00 INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:07:31.791+09:00 INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2c39c520]] +2025-08-01T14:07:31.791+09:00 INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:07:31.814+09:00 INFO 23496 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:07:32.413+09:00 INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 8.604 seconds (process running for 9.06) +2025-08-01T14:08:31.799+09:00 INFO 23496 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:13:18.339+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:13:18.339+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:13:18.366+09:00 WARN 23496 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:13:18.366+09:00 WARN 23496 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:13:27.429+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:13:27.429+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:13:27.431+09:00 WARN 23496 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:13:27.432+09:00 WARN 23496 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:13:35.641+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-11] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:13:35.641+09:00 INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-12] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:13:35.653+09:00 INFO 23496 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:13:35.653+09:00 INFO 23496 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:13:54.382+09:00 INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 11744 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:13:54.384+09:00 INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:13:55.958+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:13:55.960+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:13:56.003+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 0 JPA repository interfaces. +2025-08-01T14:13:56.036+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:13:56.037+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:13:56.053+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:13:56.074+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:13:56.077+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:13:56.088+09:00 INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T14:13:57.606+09:00 INFO 11744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:13:57.669+09:00 INFO 11744 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:13:57.670+09:00 INFO 11744 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:13:57.852+09:00 INFO 11744 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:13:57.853+09:00 INFO 11744 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3384 ms +2025-08-01T14:13:58.529+09:00 INFO 11744 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:13:58.628+09:00 INFO 11744 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:13:58.686+09:00 INFO 11744 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:13:59.164+09:00 INFO 11744 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:13:59.210+09:00 INFO 11744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:13:59.418+09:00 INFO 11744 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:13:59.420+09:00 INFO 11744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:13:59.441+09:00 WARN 11744 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:13:59.463+09:00 INFO 11744 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:13:59.771+09:00 INFO 11744 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:13:59.781+09:00 INFO 11744 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:14:01.154+09:00 WARN 11744 --- [booking] [main] 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-08-01T14:14:01.392+09:00 INFO 11744 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:14:02.417+09:00 INFO 11744 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3751baf6, com.mongodb.Jep395RecordCodecProvider@27e656e6, com.mongodb.KotlinCodecProvider@3cfab56d]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:14:02.417+09:00 INFO 11744 --- [booking] [cluster-ClusterId{value='688c4d1a696e071f70786fe0', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:14:02.775+09:00 INFO 11744 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:14:02.933+09:00 WARN 11744 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 439c57cd-8c43-4ffc-b923-66bd66f7c96a + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:14:02.946+09:00 INFO 11744 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:14:03.111+09:00 INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:14:03.111+09:00 INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1e8c741c]] +2025-08-01T14:14:03.111+09:00 INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:14:03.150+09:00 INFO 11744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:14:03.841+09:00 INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 10.287 seconds (process running for 10.818) +2025-08-01T14:27:15.596+09:00 WARN 11744 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=13m16s74ms892µs800ns). +2025-08-01T14:27:49.186+09:00 INFO 11744 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:28:01.498+09:00 INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 11180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:28:01.498+09:00 INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:28:02.867+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:28:02.871+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:28:02.914+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces. +2025-08-01T14:28:02.949+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:28:02.949+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:28:02.949+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:28:02.977+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:28:02.977+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:28:02.982+09:00 INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces. +2025-08-01T14:28:04.305+09:00 INFO 11180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:28:04.359+09:00 INFO 11180 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:28:04.359+09:00 INFO 11180 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:28:04.510+09:00 INFO 11180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:28:04.510+09:00 INFO 11180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2948 ms +2025-08-01T14:28:05.144+09:00 INFO 11180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:28:05.229+09:00 INFO 11180 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:28:05.265+09:00 INFO 11180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:28:05.616+09:00 INFO 11180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:28:05.646+09:00 INFO 11180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:28:05.844+09:00 INFO 11180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:28:05.844+09:00 INFO 11180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:28:05.877+09:00 WARN 11180 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:28:05.892+09:00 INFO 11180 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:28:06.208+09:00 INFO 11180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:28:06.208+09:00 INFO 11180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:28:07.554+09:00 WARN 11180 --- [booking] [main] 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-08-01T14:28:07.825+09:00 INFO 11180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:28:08.967+09:00 INFO 11180 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@18d09283, com.mongodb.Jep395RecordCodecProvider@751b901a, com.mongodb.KotlinCodecProvider@6672b0ea]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:28:08.967+09:00 INFO 11180 --- [booking] [cluster-ClusterId{value='688c50689a9964e7cf9cbe48', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:28:09.616+09:00 INFO 11180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:28:09.847+09:00 WARN 11180 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 108ce33e-ed45-4adc-a380-4e3915cede90 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:28:09.872+09:00 INFO 11180 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:28:10.080+09:00 INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:28:10.095+09:00 INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@e417628]] +2025-08-01T14:28:10.095+09:00 INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:28:10.130+09:00 INFO 11180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:28:10.825+09:00 INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 9.999 seconds (process running for 10.478) +2025-08-01T14:29:10.105+09:00 INFO 11180 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:32:56.853+09:00 INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 8236 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:32:56.858+09:00 INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:32:58.106+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:32:58.106+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:32:58.138+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces. +2025-08-01T14:32:58.172+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:32:58.172+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:32:58.172+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:32:58.192+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:32:58.192+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:32:58.207+09:00 INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:32:59.362+09:00 INFO 8236 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:32:59.400+09:00 INFO 8236 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:32:59.402+09:00 INFO 8236 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:32:59.536+09:00 INFO 8236 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:32:59.537+09:00 INFO 8236 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2606 ms +2025-08-01T14:33:00.070+09:00 INFO 8236 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:33:00.195+09:00 INFO 8236 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:33:00.262+09:00 INFO 8236 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:33:00.570+09:00 INFO 8236 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:33:00.602+09:00 INFO 8236 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:33:00.797+09:00 INFO 8236 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:33:00.801+09:00 INFO 8236 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:33:00.825+09:00 WARN 8236 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:33:00.849+09:00 INFO 8236 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:33:01.200+09:00 INFO 8236 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:33:01.206+09:00 INFO 8236 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:33:02.712+09:00 WARN 8236 --- [booking] [main] 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-08-01T14:33:02.952+09:00 INFO 8236 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:33:03.846+09:00 INFO 8236 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@601e7c97, com.mongodb.Jep395RecordCodecProvider@c8ed958, com.mongodb.KotlinCodecProvider@18d09283]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:33:03.845+09:00 INFO 8236 --- [booking] [cluster-ClusterId{value='688c518fbb12843aa17620d2', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:33:04.800+09:00 INFO 8236 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:33:05.211+09:00 WARN 8236 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 00a3577a-77dc-4619-bb25-d23d17d624e0 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:33:05.232+09:00 INFO 8236 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:33:05.576+09:00 INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:33:05.583+09:00 INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@39329d81]] +2025-08-01T14:33:05.585+09:00 INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:33:05.639+09:00 INFO 8236 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:33:06.913+09:00 INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 10.704 seconds (process running for 11.168) +2025-08-01T14:34:05.579+09:00 INFO 8236 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:38:43.198+09:00 INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 22896 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:38:43.198+09:00 INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:38:44.438+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:38:44.438+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:38:44.493+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 33 ms. Found 0 JPA repository interfaces. +2025-08-01T14:38:44.530+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:38:44.530+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:38:44.539+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:38:44.552+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:38:44.552+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:38:44.554+09:00 INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:38:45.786+09:00 INFO 22896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:38:45.835+09:00 INFO 22896 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:38:45.835+09:00 INFO 22896 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:38:45.954+09:00 INFO 22896 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:38:45.957+09:00 INFO 22896 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2688 ms +2025-08-01T14:38:46.370+09:00 INFO 22896 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:38:46.449+09:00 INFO 22896 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:38:46.492+09:00 INFO 22896 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:38:46.906+09:00 INFO 22896 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:38:46.937+09:00 INFO 22896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:38:47.128+09:00 INFO 22896 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:38:47.128+09:00 INFO 22896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:38:47.172+09:00 WARN 22896 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:38:47.191+09:00 INFO 22896 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:38:47.633+09:00 INFO 22896 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:38:47.637+09:00 INFO 22896 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:38:48.778+09:00 WARN 22896 --- [booking] [main] 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-08-01T14:38:49.005+09:00 INFO 22896 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:38:49.919+09:00 INFO 22896 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3cfab56d, com.mongodb.Jep395RecordCodecProvider@6b6fde93, com.mongodb.KotlinCodecProvider@51d34f02]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:38:49.926+09:00 INFO 22896 --- [booking] [cluster-ClusterId{value='688c52e92e94edfb65338ce2', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:38:50.409+09:00 INFO 22896 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:38:50.599+09:00 WARN 22896 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 8d7ba178-efe1-4dd9-96d3-2063903f0fe1 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:38:50.599+09:00 INFO 22896 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:38:50.853+09:00 INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:38:50.853+09:00 INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@6db64abf]] +2025-08-01T14:38:50.869+09:00 INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:38:50.917+09:00 INFO 22896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:38:51.654+09:00 INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 9.106 seconds (process running for 9.517) +2025-08-01T14:43:52.665+09:00 INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 19076 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:43:52.665+09:00 INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:43:53.883+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:43:53.886+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:43:53.915+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces. +2025-08-01T14:43:53.963+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:43:53.963+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:43:53.967+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:43:53.978+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:43:53.978+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:43:53.994+09:00 INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces. +2025-08-01T14:43:55.201+09:00 INFO 19076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:43:55.249+09:00 INFO 19076 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:43:55.249+09:00 INFO 19076 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:43:55.393+09:00 INFO 19076 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:43:55.393+09:00 INFO 19076 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2671 ms +2025-08-01T14:43:55.946+09:00 INFO 19076 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:43:56.025+09:00 INFO 19076 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:43:56.072+09:00 INFO 19076 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:43:56.406+09:00 INFO 19076 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:43:56.422+09:00 INFO 19076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:43:56.646+09:00 INFO 19076 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:43:56.646+09:00 INFO 19076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:43:56.678+09:00 WARN 19076 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:43:56.742+09:00 INFO 19076 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:43:57.127+09:00 INFO 19076 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:43:57.127+09:00 INFO 19076 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:43:58.305+09:00 WARN 19076 --- [booking] [main] 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-08-01T14:43:58.541+09:00 INFO 19076 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:43:59.320+09:00 INFO 19076 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@6672b0ea, com.mongodb.Jep395RecordCodecProvider@1ccce165, com.mongodb.KotlinCodecProvider@943cf5]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:43:59.324+09:00 INFO 19076 --- [booking] [cluster-ClusterId{value='688c541fe05cfa1e7119ca0f', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:43:59.819+09:00 INFO 19076 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:44:00.117+09:00 WARN 19076 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 33385c2b-2f3e-4cef-8ae9-eb008d4728ca + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:44:00.132+09:00 INFO 19076 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:44:00.307+09:00 INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:44:00.307+09:00 INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@592fbd8]] +2025-08-01T14:44:00.307+09:00 INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:44:00.322+09:00 INFO 19076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:44:00.921+09:00 INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 8.9 seconds (process running for 9.359) +2025-08-01T14:44:42.359+09:00 INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 28240 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:44:42.359+09:00 INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:44:43.473+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:44:43.476+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:44:43.507+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces. +2025-08-01T14:44:43.540+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:44:43.540+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:44:43.551+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:44:43.567+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:44:43.570+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:44:43.572+09:00 INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T14:44:44.801+09:00 INFO 28240 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:44:44.827+09:00 INFO 28240 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:44:44.830+09:00 INFO 28240 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:44:44.925+09:00 INFO 28240 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:44:44.938+09:00 INFO 28240 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2500 ms +2025-08-01T14:44:45.444+09:00 INFO 28240 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:44:45.564+09:00 INFO 28240 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:44:45.628+09:00 INFO 28240 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:44:45.979+09:00 INFO 28240 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:44:46.021+09:00 INFO 28240 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:44:46.212+09:00 INFO 28240 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:44:46.212+09:00 INFO 28240 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:44:46.247+09:00 WARN 28240 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:44:46.281+09:00 INFO 28240 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:44:46.664+09:00 INFO 28240 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:44:46.664+09:00 INFO 28240 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:44:47.922+09:00 WARN 28240 --- [booking] [main] 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-08-01T14:44:48.187+09:00 INFO 28240 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:44:49.116+09:00 INFO 28240 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@943cf5, com.mongodb.Jep395RecordCodecProvider@2926f7bd, com.mongodb.KotlinCodecProvider@5a20f793]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:44:49.116+09:00 INFO 28240 --- [booking] [cluster-ClusterId{value='688c5451064128d1307a6279', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:44:49.567+09:00 INFO 28240 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:44:49.763+09:00 WARN 28240 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 9e829b29-2999-4c78-a1cc-0d83b7ef0556 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:44:49.773+09:00 INFO 28240 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:44:49.920+09:00 INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:44:49.920+09:00 INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42516ce2]] +2025-08-01T14:44:49.920+09:00 INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:44:49.935+09:00 INFO 28240 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:44:50.452+09:00 INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 8.711 seconds (process running for 9.146) +2025-08-01T14:45:49.946+09:00 INFO 28240 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:47:50.871+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:47:50.871+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:47:50.904+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:47:50.905+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:47:59.947+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:47:59.947+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:47:59.948+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:47:59.948+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:08.146+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-12] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:08.146+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-11] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:08.148+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:08.148+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:24.545+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:24.545+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:24.560+09:00 INFO 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:48:24.562+09:00 INFO 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:48:31.851+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-15] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:48:31.851+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-16] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/127.0.0.1:6379 +2025-08-01T14:48:31.858+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:48:31.859+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-1] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection closed prematurely + +io.lettuce.core.RedisConnectionException: Connection closed prematurely + at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final] + at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] + +2025-08-01T14:48:40.956+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:40.956+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:40.957+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-9] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:40.957+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-10] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:49.246+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:49.246+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:48:49.248+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:48:49.248+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:49:05.646+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:49:05.646+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:49:05.646+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:49:05.646+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:49:35.746+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-15] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:49:35.746+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-16] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:49:35.748+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:49:35.748+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:50:05.852+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:50:05.852+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:50:05.852+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-1] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:50:05.852+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:50:35.955+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:50:35.955+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:50:35.971+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:50:35.971+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:51:06.061+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:51:06.061+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:51:06.065+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:51:06.065+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-5] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:51:36.160+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:51:36.160+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-7] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:51:36.160+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:51:36.160+09:00 WARN 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:52:06.246+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:52:06.246+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:52:06.249+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-9] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:52:06.249+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-10] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:52:36.353+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:52:36.353+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:52:36.355+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:52:36.355+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:53:06.447+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:53:06.447+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:53:06.447+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:53:06.447+09:00 WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379 +2025-08-01T14:53:36.556+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:53:36.556+09:00 INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was localhost/:6379 +2025-08-01T14:53:36.562+09:00 INFO 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:53:36.562+09:00 INFO 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ReconnectionHandler : Reconnected to localhost/:6379 +2025-08-01T14:53:46.281+09:00 INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 20112 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:53:46.281+09:00 INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:53:47.406+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:53:47.410+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:53:47.468+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces. +2025-08-01T14:53:47.499+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:53:47.499+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:53:47.514+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:53:47.530+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:53:47.530+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:53:47.546+09:00 INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces. +2025-08-01T14:53:48.807+09:00 INFO 20112 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:53:48.849+09:00 INFO 20112 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:53:48.849+09:00 INFO 20112 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:53:48.952+09:00 INFO 20112 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:53:48.952+09:00 INFO 20112 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2622 ms +2025-08-01T14:53:49.438+09:00 INFO 20112 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:53:49.505+09:00 INFO 20112 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:53:49.549+09:00 INFO 20112 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:53:49.868+09:00 INFO 20112 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:53:49.899+09:00 INFO 20112 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:53:50.119+09:00 INFO 20112 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:53:50.123+09:00 INFO 20112 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:53:50.154+09:00 WARN 20112 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:53:50.202+09:00 INFO 20112 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:53:50.625+09:00 INFO 20112 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:53:50.632+09:00 INFO 20112 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:53:51.809+09:00 WARN 20112 --- [booking] [main] 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-08-01T14:53:52.093+09:00 INFO 20112 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:53:53.178+09:00 INFO 20112 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@18d09283, com.mongodb.Jep395RecordCodecProvider@751b901a, com.mongodb.KotlinCodecProvider@6672b0ea]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:53:53.178+09:00 INFO 20112 --- [booking] [cluster-ClusterId{value='688c5671cc4022ccb0cb0709', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:53:53.604+09:00 INFO 20112 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:53:53.784+09:00 WARN 20112 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 83845f15-440e-455c-9e86-fb14ddc85507 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:53:53.784+09:00 INFO 20112 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:53:53.924+09:00 INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:53:53.924+09:00 INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@123a21ad]] +2025-08-01T14:53:53.924+09:00 INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:53:53.943+09:00 INFO 20112 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:53:54.550+09:00 INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 8.908 seconds (process running for 9.299) +2025-08-01T14:55:41.704+09:00 INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 14268 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:55:41.704+09:00 INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:55:43.170+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:55:43.170+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:55:43.218+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces. +2025-08-01T14:55:43.240+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:55:43.240+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode. +2025-08-01T14:55:43.259+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 MongoDB repository interfaces. +2025-08-01T14:55:43.272+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:55:43.280+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:55:43.287+09:00 INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T14:55:44.606+09:00 INFO 14268 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:55:44.624+09:00 INFO 14268 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:55:44.631+09:00 INFO 14268 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:55:44.745+09:00 INFO 14268 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:55:44.745+09:00 INFO 14268 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2976 ms +2025-08-01T14:55:45.177+09:00 INFO 14268 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:55:45.221+09:00 INFO 14268 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:55:45.269+09:00 INFO 14268 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:55:45.621+09:00 INFO 14268 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:55:45.663+09:00 INFO 14268 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:55:45.891+09:00 INFO 14268 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:55:45.891+09:00 INFO 14268 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:55:45.919+09:00 WARN 14268 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:55:45.953+09:00 INFO 14268 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:55:46.324+09:00 INFO 14268 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:55:46.330+09:00 INFO 14268 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:55:47.352+09:00 WARN 14268 --- [booking] [main] 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-08-01T14:55:47.624+09:00 INFO 14268 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T14:55:48.564+09:00 INFO 14268 --- [booking] [main] org.mongodb.driver.client : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@1e37cb10, com.mongodb.Jep395RecordCodecProvider@1659d7d, com.mongodb.KotlinCodecProvider@6892d403]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null} +2025-08-01T14:55:48.570+09:00 INFO 14268 --- [booking] [cluster-ClusterId{value='688c56e4d98e2d7d630ef116', description='null'}-localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017 + +com.mongodb.MongoSocketOpenException: Exception opening socket + at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na] +Caused by: java.net.ConnectException: Connection refused: getsockopt + at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na] + at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na] + at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na] + at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na] + at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na] + at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na] + at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na] + ... 3 common frames omitted + +2025-08-01T14:55:49.011+09:00 INFO 14268 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T14:55:49.247+09:00 WARN 14268 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 82db3859-721c-41b9-ba64-f19d5a9c5f71 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T14:55:49.255+09:00 INFO 14268 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T14:55:49.437+09:00 INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T14:55:49.437+09:00 INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@123a21ad]] +2025-08-01T14:55:49.437+09:00 INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T14:55:49.467+09:00 INFO 14268 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T14:55:50.150+09:00 INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 9.168 seconds (process running for 9.644) +2025-08-01T14:56:49.435+09:00 INFO 14268 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T14:59:52.289+09:00 INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 26176 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T14:59:52.289+09:00 INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T14:59:53.882+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:59:53.888+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T14:59:53.921+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces. +2025-08-01T14:59:53.937+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T14:59:53.946+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T14:59:53.958+09:00 INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T14:59:55.627+09:00 INFO 26176 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T14:59:55.663+09:00 INFO 26176 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T14:59:55.665+09:00 INFO 26176 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T14:59:55.823+09:00 INFO 26176 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T14:59:55.823+09:00 INFO 26176 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3450 ms +2025-08-01T14:59:56.409+09:00 INFO 26176 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T14:59:56.488+09:00 INFO 26176 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T14:59:56.539+09:00 INFO 26176 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T14:59:57.071+09:00 INFO 26176 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T14:59:57.107+09:00 INFO 26176 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T14:59:57.292+09:00 INFO 26176 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T14:59:57.292+09:00 INFO 26176 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T14:59:57.320+09:00 WARN 26176 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T14:59:57.344+09:00 INFO 26176 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T14:59:57.742+09:00 INFO 26176 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T14:59:57.742+09:00 INFO 26176 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T14:59:58.935+09:00 WARN 26176 --- [booking] [main] 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-08-01T14:59:59.242+09:00 INFO 26176 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T15:00:00.545+09:00 INFO 26176 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T15:00:00.826+09:00 WARN 26176 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: 36ca8b44-427d-4e99-9649-35d14ea814dd + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T15:00:00.841+09:00 INFO 26176 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T15:00:01.001+09:00 INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T15:00:01.003+09:00 INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1fb379e4]] +2025-08-01T15:00:01.005+09:00 INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T15:00:01.032+09:00 INFO 26176 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T15:00:01.651+09:00 INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 10.18 seconds (process running for 10.708) +2025-08-01T15:01:01.012+09:00 INFO 26176 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T15:01:03.585+09:00 INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2025-08-01T15:01:03.585+09:00 INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2025-08-01T15:01:03.588+09:00 INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms +2025-08-01T15:35:09.656+09:00 INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 1180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T15:35:09.660+09:00 INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T15:35:10.916+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:35:10.920+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T15:35:10.960+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces. +2025-08-01T15:35:10.978+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:35:10.980+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T15:35:10.995+09:00 INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces. +2025-08-01T15:35:12.126+09:00 INFO 1180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T15:35:12.149+09:00 INFO 1180 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T15:35:12.150+09:00 INFO 1180 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T15:35:12.263+09:00 INFO 1180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T15:35:12.264+09:00 INFO 1180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2544 ms +2025-08-01T15:35:12.636+09:00 INFO 1180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T15:35:12.713+09:00 INFO 1180 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T15:35:12.745+09:00 INFO 1180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T15:35:13.177+09:00 INFO 1180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T15:35:13.209+09:00 INFO 1180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T15:35:13.366+09:00 INFO 1180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T15:35:13.368+09:00 INFO 1180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T15:35:13.389+09:00 WARN 1180 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T15:35:13.411+09:00 INFO 1180 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T15:35:13.764+09:00 INFO 1180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T15:35:13.770+09:00 INFO 1180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T15:35:14.700+09:00 WARN 1180 --- [booking] [main] 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-08-01T15:35:14.955+09:00 INFO 1180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T15:35:15.814+09:00 INFO 1180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T15:35:16.014+09:00 WARN 1180 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : + +Using generated security password: d53b51b7-04ca-41e1-9e04-e213d1b0071a + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-08-01T15:35:16.025+09:00 INFO 1180 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager +2025-08-01T15:35:16.185+09:00 INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T15:35:16.190+09:00 INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@67b1c3af]] +2025-08-01T15:35:16.193+09:00 INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T15:35:16.228+09:00 INFO 1180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T15:35:17.317+09:00 INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 8.297 seconds (process running for 8.74) +2025-08-01T15:35:40.539+09:00 INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2025-08-01T15:35:40.539+09:00 INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2025-08-01T15:35:40.540+09:00 INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms +2025-08-01T15:36:16.197+09:00 INFO 1180 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0] +2025-08-01T15:37:05.332+09:00 INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 12688 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T15:37:05.335+09:00 INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T15:37:06.357+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:37:06.358+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T15:37:06.384+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces. +2025-08-01T15:37:06.405+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:37:06.408+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T15:37:06.422+09:00 INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T15:37:07.479+09:00 INFO 12688 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T15:37:07.502+09:00 INFO 12688 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T15:37:07.503+09:00 INFO 12688 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T15:37:07.591+09:00 INFO 12688 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T15:37:07.592+09:00 INFO 12688 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2198 ms +2025-08-01T15:37:07.982+09:00 INFO 12688 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T15:37:08.064+09:00 INFO 12688 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T15:37:08.101+09:00 INFO 12688 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T15:37:08.419+09:00 INFO 12688 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T15:37:08.453+09:00 INFO 12688 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T15:37:08.620+09:00 INFO 12688 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T15:37:08.623+09:00 INFO 12688 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T15:37:08.651+09:00 WARN 12688 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T15:37:08.686+09:00 INFO 12688 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T15:37:09.048+09:00 INFO 12688 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T15:37:09.054+09:00 INFO 12688 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T15:37:10.206+09:00 WARN 12688 --- [booking] [main] 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-08-01T15:37:10.405+09:00 INFO 12688 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T15:37:11.191+09:00 INFO 12688 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T15:37:11.402+09:00 INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T15:37:11.404+09:00 INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@16e0afab]] +2025-08-01T15:37:11.405+09:00 INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T15:37:11.431+09:00 INFO 12688 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T15:37:12.067+09:00 INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 7.349 seconds (process running for 7.744) +2025-08-01T15:38:00.282+09:00 INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2025-08-01T15:38:00.283+09:00 INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2025-08-01T15:38:00.286+09:00 INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms +2025-08-01T15:38:11.410+09:00 INFO 12688 --- [booking] [MessageBroker-3] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 6, active threads = 1, queued tasks = 2, completed tasks = 3] +2025-08-01T15:41:01.782+09:00 INFO 12688 --- [booking] [clientInboundChannel-10] c.m.b.controller.BookingController : User 12345 subscribed to waiting queue updates. +2025-08-01T15:47:35.632+09:00 INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 12076 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T15:47:35.636+09:00 INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T15:47:36.877+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:47:36.879+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T15:47:36.910+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces. +2025-08-01T15:47:36.936+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T15:47:36.940+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T15:47:36.956+09:00 INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces. +2025-08-01T15:47:38.019+09:00 INFO 12076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T15:47:38.044+09:00 INFO 12076 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T15:47:38.044+09:00 INFO 12076 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T15:47:38.134+09:00 INFO 12076 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T15:47:38.135+09:00 INFO 12076 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2440 ms +2025-08-01T15:47:38.418+09:00 INFO 12076 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T15:47:38.490+09:00 INFO 12076 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T15:47:38.521+09:00 INFO 12076 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T15:47:38.921+09:00 INFO 12076 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T15:47:38.948+09:00 INFO 12076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T15:47:39.120+09:00 INFO 12076 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T15:47:39.122+09:00 INFO 12076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T15:47:39.150+09:00 WARN 12076 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T15:47:39.189+09:00 INFO 12076 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T15:47:39.563+09:00 INFO 12076 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T15:47:39.574+09:00 INFO 12076 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T15:47:40.693+09:00 WARN 12076 --- [booking] [main] 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-08-01T15:47:40.874+09:00 INFO 12076 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T15:47:41.428+09:00 INFO 12076 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T15:47:41.613+09:00 INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T15:47:41.614+09:00 INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@260ccf0]] +2025-08-01T15:47:41.615+09:00 INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T15:47:41.638+09:00 INFO 12076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T15:47:42.183+09:00 INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 7.208 seconds (process running for 7.626) +2025-08-01T15:47:56.436+09:00 INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet' +2025-08-01T15:47:56.438+09:00 INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' +2025-08-01T15:47:56.440+09:00 INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms +2025-08-01T15:48:41.638+09:00 INFO 12076 --- [booking] [MessageBroker-3] o.s.w.s.c.WebSocketMessageBrokerStats : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12] +2025-08-01T15:52:16.958+09:00 INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.w.s.m.SubProtocolWebSocketHandler : No messages received after 260311 ms. Closing WebSocketServerSockJsSession[id=kzq0vdqf]. +2025-08-01T15:52:21.753+09:00 INFO 12076 --- [booking] [clientInboundChannel-13] c.m.b.controller.BookingController : User 12345 subscribed to waiting queue updates. +2025-08-01T15:56:27.718+09:00 INFO 12076 --- [booking] [clientInboundChannel-34] c.m.b.controller.BookingController : User 12345 subscribed to waiting queue updates. +2025-08-01T16:05:35.293+09:00 INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication : Starting BookingApplication using Java 17.0.14 with PID 18896 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking) +2025-08-01T16:05:35.296+09:00 INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication : The following 1 profile is active: "test" +2025-08-01T16:05:36.544+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T16:05:36.547+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-08-01T16:05:36.579+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces. +2025-08-01T16:05:36.606+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode +2025-08-01T16:05:36.608+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode. +2025-08-01T16:05:36.630+09:00 INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces. +2025-08-01T16:05:37.666+09:00 INFO 18896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http) +2025-08-01T16:05:37.684+09:00 INFO 18896 --- [booking] [main] o.apache.catalina.core.StandardService : Starting service [Tomcat] +2025-08-01T16:05:37.685+09:00 INFO 18896 --- [booking] [main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.43] +2025-08-01T16:05:37.776+09:00 INFO 18896 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext +2025-08-01T16:05:37.777+09:00 INFO 18896 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2412 ms +2025-08-01T16:05:38.139+09:00 INFO 18896 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] +2025-08-01T16:05:38.225+09:00 INFO 18896 --- [booking] [main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.22.Final +2025-08-01T16:05:38.255+09:00 INFO 18896 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled +2025-08-01T16:05:38.832+09:00 INFO 18896 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer +2025-08-01T16:05:38.861+09:00 INFO 18896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... +2025-08-01T16:05:39.044+09:00 INFO 18896 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA +2025-08-01T16:05:39.048+09:00 INFO 18896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. +2025-08-01T16:05:39.080+09:00 WARN 18896 --- [booking] [main] org.hibernate.orm.deprecation : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) +2025-08-01T16:05:39.120+09:00 INFO 18896 --- [booking] [main] org.hibernate.orm.connections.pooling : HHH10001005: Database info: + Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)'] + Database driver: undefined/unknown + Database version: 2.3.232 + Autocommit mode: undefined/unknown + Isolation level: undefined/unknown + Minimum pool size: undefined/unknown + Maximum pool size: undefined/unknown +2025-08-01T16:05:39.479+09:00 INFO 18896 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) +2025-08-01T16:05:39.484+09:00 INFO 18896 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-08-01T16:05:40.600+09:00 WARN 18896 --- [booking] [main] 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-08-01T16:05:40.812+09:00 INFO 18896 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html] +2025-08-01T16:05:41.497+09:00 INFO 18896 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb' +2025-08-01T16:05:41.740+09:00 INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting... +2025-08-01T16:05:41.744+09:00 INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@58b30e3e]] +2025-08-01T16:05:41.745+09:00 INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler : Started. +2025-08-01T16:05:41.768+09:00 INFO 18896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/' +2025-08-01T16:05:42.335+09:00 INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication : Started BookingApplication in 7.729 seconds (process running for 8.194) diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java new file mode 100644 index 0000000..df636d9 --- /dev/null +++ b/src/main/java/com/mnms/booking/config/RedisConfig.java @@ -0,0 +1,65 @@ +package com.mnms.booking.config; + +import com.mnms.booking.service.RedisMessageSubscriber; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.data.redis.serializer.StringRedisSerializer; + + + +@Configuration +public class RedisConfig { + + // Redis Pub/Sub 메시지를 구독하고 처리할 컨테이너 + @Bean + public RedisMessageListenerContainer redisMessageListenerContainer( + RedisConnectionFactory connectionFactory, + MessageListenerAdapter listenerAdapter // 아래에서 정의할 리스너 어댑터 + ) { + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(connectionFactory); + // "waiting_notification" 채널을 구독하도록 설정 + container.addMessageListener(listenerAdapter, new ChannelTopic("waiting_notification")); + return container; + } + + // Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결) + @Bean + public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) { + // RedisMessageSubscriber의 "onMessage" 메서드를 호출하도록 설정 + return new MessageListenerAdapter(subscriber, "onMessage"); + } + + // Redis Pub/Sub 메시지를 발행하는 데 사용될 템플릿 + // String, String 형태로 메시지를 발행할 것이므로 StringRedisTemplate을 사용 + @Bean + public org.springframework.data.redis.core.StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) { + return new org.springframework.data.redis.core.StringRedisTemplate(connectionFactory); + } + + // ZSet, Hash 등 일반적인 Redis 데이터 구조 관리에 사용될 RedisTemplate 설정 추가 + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(connectionFactory); + + // Key 직렬화 설정: StringRedisSerializer 사용 (필수) + template.setKeySerializer(new StringRedisSerializer()); + // Value 직렬화 설정: StringRedisSerializer 사용 (필수) + template.setValueSerializer(new StringRedisSerializer()); + + // Hash Key/Value 직렬화 설정 (ZSet에서는 직접 사용되지 않지만, 다른 Redis 자료구조 사용 시 일관성을 위해 설정) + template.setHashKeySerializer(new StringRedisSerializer()); + template.setHashValueSerializer(new StringRedisSerializer()); + + // 초기화 메서드 호출 (설정 적용) + template.afterPropertiesSet(); + + return template; + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java new file mode 100644 index 0000000..1d57f23 --- /dev/null +++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java @@ -0,0 +1,28 @@ +package com.mnms.booking.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + // 구독경로 + config.enableSimpleBroker("/topic"); + // 클라이언트 → 서버 메시지 경로 + config.setApplicationDestinationPrefixes("/app"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + // WebSocket 연결을 위한 endpoint 설정 + registry.addEndpoint("/ws") + .setAllowedOriginPatterns("*") + .withSockJS(); + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java new file mode 100644 index 0000000..03385b6 --- /dev/null +++ b/src/main/java/com/mnms/booking/controller/BookingController.java @@ -0,0 +1,69 @@ +package com.mnms.booking.controller; + +import com.mnms.booking.dto.response.WaitingNumberDto; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.messaging.handler.annotation.DestinationVariable; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import com.mnms.booking.service.WaitingService; + +@Controller +@RequiredArgsConstructor +@Slf4j +@RequestMapping("/api/booking") +public class BookingController { + + private final WaitingService waitingService; + + /** + * 예매하기 버튼 클릭 시 호출되는 API + * userId는 실제 로그인된 사용자 ID를 사용해야 합니다. (수정 예정) + */ + @GetMapping("/enter") + @ResponseBody // JSON 응답을 위해 추가 + public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) { + long waitingNumber = waitingService.enterWaitingQueue(userId); + + if (waitingNumber == 0) { + // 즉시 입장 가능한 경우 + return ResponseEntity.ok(new WaitingNumberDto(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE")); + } else { + // 대기열에 진입한 경우 + return ResponseEntity.ok(new WaitingNumberDto(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED")); + } + } + + /** + * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출 + * (이 사용자는 대기열에서 제거되어야 함) + */ + @GetMapping("/release/{userId}") + public ResponseEntity releaseUser(@PathVariable("userId") String userId) { + try { + boolean removed = waitingService.userExitBookingPage(userId); + if (removed) { + return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다."); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body("해당 사용자는 예매 사용자 목록에 없습니다."); + } + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body("서버 오류로 인해 사용자를 처리하지 못했습니다."); + } + } + + /** + * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트 + * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청) + */ + @MessageMapping("/subscribe/waiting/{userId}") + public void subscribeWaitingQueue(@DestinationVariable("userId") String userId) { + log.info("User {} subscribed to waiting queue updates.", userId); + waitingService.getAndPublishWaitingNumber(userId); + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java b/src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java new file mode 100644 index 0000000..5e1bad8 --- /dev/null +++ b/src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java @@ -0,0 +1,16 @@ +package com.mnms.booking.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class WaitingNumberDto { + private String userId; + private long waitingNumber; // 대기 순번 + // 선택 + private boolean immediateEntry; // 즉시 입장 여부 추가 (또는 다른 상태 필드) + private String message; // 사용자에게 보여줄 메시지 추가 (선택 사항) +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/exception/BusinessException.java b/src/main/java/com/mnms/booking/exception/BusinessException.java new file mode 100644 index 0000000..c508a34 --- /dev/null +++ b/src/main/java/com/mnms/booking/exception/BusinessException.java @@ -0,0 +1,18 @@ +package com.mnms.booking.exception; + +import lombok.Getter; + +@Getter +public class BusinessException extends RuntimeException{ + private final ErrorCode errorCode; + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode=errorCode; + } + + public BusinessException(ErrorCode errorCode, String message) { + super(message); + this.errorCode=errorCode; + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java new file mode 100644 index 0000000..b56fb95 --- /dev/null +++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java @@ -0,0 +1,22 @@ +package com.mnms.booking.exception; + +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +public enum ErrorCode { + + FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND); + + + private final String code; // A001, A002 등 + private final String message; // 사용자에게 보여줄 메시지 + private final HttpStatus status; //http status 코드 + + ErrorCode(String code, String message, HttpStatus status) { + this.code = code; + this.message = message; + this.status = status; + } + +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java new file mode 100644 index 0000000..75c7602 --- /dev/null +++ b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java @@ -0,0 +1,20 @@ +package com.mnms.booking.exception.global; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.mnms.booking.exception.BusinessException; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.http.HttpStatus; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ErrorResponse { + private boolean success; + private String errorCode; + private String errorMessage; +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java new file mode 100644 index 0000000..9d6cd0a --- /dev/null +++ b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java @@ -0,0 +1,54 @@ +package com.mnms.booking.exception.global; + +import com.mnms.booking.exception.BusinessException; +import com.mnms.booking.exception.ErrorCode; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; + + +@ControllerAdvice +public class GlobalExceptionHandler { + + /** + * 비즈니스 로직에서 발생한 커스텀 예외 처리 + */ + @ExceptionHandler(BusinessException.class) + public ResponseEntity handleBusinessException(BusinessException e) { + ErrorCode errorCode = e.getErrorCode(); + ErrorResponse response = new ErrorResponse(false, errorCode.name(), errorCode.getMessage()); + return new ResponseEntity<>(response, errorCode.getStatus()); + } + + /** + * @Valid 검증 실패 (DTO 바인딩 오류 등) + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidationException(MethodArgumentNotValidException e) { + String message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); + ErrorResponse response = new ErrorResponse(false, "VALIDATION_ERROR", message); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + /** + * 잘못된 타입 바인딩 (예: Long 필드에 문자 전달) + */ + @ExceptionHandler(MethodArgumentTypeMismatchException.class) + public ResponseEntity handleTypeMismatch(MethodArgumentTypeMismatchException e) { + ErrorResponse response = new ErrorResponse(false, "TYPE_MISMATCH", "잘못된 타입의 요청입니다."); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + /** + * 모든 예외의 fallback 처리 + */ + @ExceptionHandler(Exception.class) + public ResponseEntity handleOtherExceptions(Exception e) { + e.printStackTrace(); // 🔍 로그로 남겨서 디버깅 + ErrorResponse response = new ErrorResponse(false, "INTERNAL_SERVER_ERROR", "알 수 없는 오류가 발생했습니다."); + return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR); + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/exception/global/SuccessResponse.java b/src/main/java/com/mnms/booking/exception/global/SuccessResponse.java new file mode 100644 index 0000000..0c200ca --- /dev/null +++ b/src/main/java/com/mnms/booking/exception/global/SuccessResponse.java @@ -0,0 +1,18 @@ +package com.mnms.booking.exception.global; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SuccessResponse { + private boolean success; + private T data; + private String message; +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java new file mode 100644 index 0000000..a5c23a0 --- /dev/null +++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java @@ -0,0 +1,43 @@ +package com.mnms.booking.service; + +import com.mnms.booking.dto.response.WaitingNumberDto; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.stereotype.Service; + +// MessageListener 인터페이스 구현 +@Service +@RequiredArgsConstructor +@Slf4j +public class RedisMessageSubscriber implements MessageListener { + + private final SimpMessagingTemplate messagingTemplate; // WebSocket 메시지 전송 + private final ObjectMapper objectMapper; // JSON 파싱을 위한 ObjectMapper + + // Redis로부터 메시지를 수신할 때 호출되는 메서드 + @Override + public void onMessage(Message message, byte[] pattern) { + try { + // Redis에서 받은 메시지 바디를 문자열로 변환 + String receivedMessage = new String(message.getBody()); + log.info("Received message from Redis channel: {}", receivedMessage); + + // 받은 JSON 문자열을 WaitingNumberDto 객체로 변환 + WaitingNumberDto dto = objectMapper.readValue(receivedMessage, WaitingNumberDto.class); + + // WebSocket을 통해 해당 사용자 토픽으로 메시지 전송 + messagingTemplate.convertAndSend("/topic/waiting/" + dto.getUserId(), dto); + log.info("Sent WebSocket message to user {}: {}", dto.getUserId(), dto.getWaitingNumber()); + + } catch (JsonProcessingException e) { + log.error("Error parsing Redis message to WaitingNumberDto: {}", e.getMessage()); + } catch (Exception e) { + log.error("Error processing Redis message: {}", e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java new file mode 100644 index 0000000..41fd1a6 --- /dev/null +++ b/src/main/java/com/mnms/booking/service/WaitingService.java @@ -0,0 +1,199 @@ +package com.mnms.booking.service; + + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mnms.booking.dto.response.WaitingNumberDto; +import jakarta.annotation.PostConstruct; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.ZSetOperations; +import org.springframework.stereotype.Service; +import java.util.Set; + +@Service +@Slf4j +public class WaitingService { + + private final RedisTemplate redisTemplate; // ZSet 관리용 + private final StringRedisTemplate stringRedisTemplate; // Pub/Sub 발행용 + private final ObjectMapper objectMapper; // DTO를 JSON으로 변환용 + private ZSetOperations zSetOperations; + + // redis message + // 대기열큐에 진입한 사용자 ZSet + private static final String WAITING_QUEUE_KEY = "waiting_queue"; + + // 예매 페이지에 진입한 사용자 Set + private static final String BOOKING_USERS_SET_KEY = "booking_users"; + + // Redis Pub/Sub 채널 이름 + private static final String NOTIFICATION_CHANNEL = "waiting_notification"; + + // 예매 페이지 수용인원 + private static final long PERFORMANCE_CAPACITY = 2; // 공연 수용 인원 + private static final double IMMEDIATE_ENTRY_RATIO = 1; // 즉시 입장 비율 (1.5배) + private static final long IMMEDIATE_ENTRY_COUNT = (long) (PERFORMANCE_CAPACITY * IMMEDIATE_ENTRY_RATIO); + + + @PostConstruct + public void init() { + zSetOperations = redisTemplate.opsForZSet(); + } + + public WaitingService( + @Qualifier("redisTemplate") RedisTemplate redisTemplate, // <-- redisTemplate 빈 주입 + @Qualifier("stringRedisTemplate") StringRedisTemplate stringRedisTemplate, // <-- stringRedisTemplate 빈 주입 + ObjectMapper objectMapper) { + this.redisTemplate = redisTemplate; + this.stringRedisTemplate = stringRedisTemplate; + this.objectMapper = objectMapper; + } + + /** + * 사용자 대기열 진입 처리 + * @param userId 사용자 ID + * @return 대기 순번 (즉시 입장 가능한 경우 0) + */ + public long enterWaitingQueue(String userId) { + + // 현재 입장한 사용자 수 + Long currentUserCount = redisTemplate.opsForSet().size(BOOKING_USERS_SET_KEY); + if (currentUserCount == null) currentUserCount = 0L; + + // 입장한 사용자가 제한보다 작을 때 + if(currentUserCount < IMMEDIATE_ENTRY_COUNT){ + log.info("User {} can enter booking page immediately ({} < {}).", userId, currentUserCount, IMMEDIATE_ENTRY_COUNT); + + redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, userId); // 사용자 등록 + return 0L; + } else{ + // 대기열로 보냄 (ZSet) + long timestamp = System.currentTimeMillis(); + zSetOperations.add(WAITING_QUEUE_KEY, userId, timestamp); + + log.info("User {} added to waiting queue with timestamp {}.", userId, timestamp); + return getAndPublishWaitingNumber(userId); + } + } + + /** + * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행 + * @param userId 사용자 ID + * @return 대기 순번 + */ + public long getAndPublishWaitingNumber(String userId) { + // 해당 userId의 대기열 순번을 조회 + Long rank = zSetOperations.rank(WAITING_QUEUE_KEY, userId); + + if (rank != null) { + // Redis rank는 0부터 시작하므로 +1 + long waitingNumber = rank + 1; + log.info("User {}'s waiting number: {}", userId, waitingNumber); + + // Redis Pub/Sub 채널로 메시지 발행 + publishWaitingNumber(userId, waitingNumber); + + return waitingNumber; + } + return -1; // 대기열에 없는 경우 + } + + /** + * Redis Pub/Sub 채널로 대기 순번 정보 발행 + * @param userId 사용자 ID + * @param waitingNumber 대기 순번 + */ + private void publishWaitingNumber(String userId, long waitingNumber) { + try { + // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null + WaitingNumberDto dto = new WaitingNumberDto(userId, waitingNumber, false, null); // <-- 이 부분 수정 + String message = objectMapper.writeValueAsString(dto); // DTO를 JSON 문자열로 변환 + stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message); // Redis 채널로 발행 + log.info("Published message to Redis channel '{}': {}", NOTIFICATION_CHANNEL, message); + } catch (JsonProcessingException e) { + log.error("Error converting DTO to JSON: {}", e.getMessage()); + } + } + + + /** + * 대기열에서 다음 사용자 진입 처리 + * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출) + */ + + public boolean userExitBookingPage(String userId){ + // 예매 완료된 Set에서 제거 + Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, userId); + + if(removed != null && removed > 0){ + log.info("User {} exited booking page and removed from booking user set.", userId); + // 대기열에서 다음 사용자 진입 처리 + releaseWaitingUser(); + return true; + }else{ + log.warn("User {} was not found in booking user set on exit.", userId); + return false; + } + } + + public void releaseWaitingUser() { + // 대기열 큐 가장 앞에 있는 사람 + Set releasedUsers = zSetOperations.range(WAITING_QUEUE_KEY, 0, 0); + + if (releasedUsers != null && !releasedUsers.isEmpty()) { + String releasedUser = releasedUsers.iterator().next(); + + // 대기열에서 삭제 + Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, releasedUser); + + if (removedCount != null && removedCount > 0) { + log.info("User {} removed from waiting queue.", releasedUser); + // 예매 중 사용자 set에 추가 + redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, releasedUser); + log.info("User {} added to booking user set.", releasedUser); + + // 남은 대기열 사용자에게 순번 알림 + notifyAllWaitingUsers(); + + } else { + log.warn("Failed to remove user {} from waiting queue. Removed count: {}", releasedUser, removedCount); + } + } + } + + /** + * 모든 대기열 사용자에게 순번 업데이트 알림 + */ + public void notifyAllWaitingUsers() { + // 대기열 사용자 수 전체 범위 조회 + Set allUsersInQueue = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1); + + if (allUsersInQueue != null) { + for (String userId : allUsersInQueue) { + // 각 사용자에게 순번 알림을 Redis Pub/Sub으로 발행 + getAndPublishWaitingNumber(userId); + } + } + } + + /** + * 특정 사용자가 대기열에서 이탈했음을 처리 + * @param userId + * @return boolean - 사용자가 대기열에서 성공적으로 제거되었으면 true, 아니면 false + */ + public boolean removeUserFromQueue(String userId) { + Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, userId); + if (removedCount != null && removedCount > 0) { + log.info("User {} removed from waiting queue (manual removal).", userId); + notifyAllWaitingUsers(); // 순번 업데이트 알림 + return true; + } else { + // 사용자가 대기열에 없었거나, 제거 과정에서 문제가 발생한 경우 + log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", userId, removedCount); + return false; + } + } +} \ No newline at end of file diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties new file mode 100644 index 0000000..d3edc5c --- /dev/null +++ b/src/main/resources/application-test.properties @@ -0,0 +1,26 @@ +myboot.name=Test Env + +#log level +logging.level.com.basic.myspringboot=debug + +# H2 Database 설정 +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driver-class-name=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password= + +# JPA 설정 +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.jpa.hibernate.ddl-auto=update + +# H2 Console 사용 설정 +spring.h2.console.enabled=true +spring.h2.console.path=/h2-console + +# redis 설정 - 로컬 설정 +spring.redis.host=127.0.0.1 +spring.redis.port=6379 +#spring.redis.password=your_password + + + diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 0000000..9d3aa0d --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,129 @@ + + + + + 공연 예매 대기열 시스템 + + + + + +

공연 예매 대기열 시스템

+ +
+ +
+ + + +
현재 대기 순번: 대기열에 없음
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/static/test-websocket.html b/src/main/resources/static/test-websocket.html new file mode 100644 index 0000000..1d11a52 --- /dev/null +++ b/src/main/resources/static/test-websocket.html @@ -0,0 +1,44 @@ + + + + + WebSocket STOMP 테스트 + + + + +

WebSocket STOMP 테스트

+ + +

+
+
+
+

From f5ebcbb88d933e62ee8cc63b6336454790b2e866 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 1 Aug 2025 17:35:07 +0900
Subject: [PATCH 003/149] =?UTF-8?q?MNMS-143=20feat:=20=EB=B3=B4=EC=95=88?=
 =?UTF-8?q?=EB=AC=B8=EC=9E=90=20=EC=83=9D=EC=84=B1=20=EA=B8=B0=EB=8A=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 build.gradle                                  |   3 +
 logs/spring.log                               | 217 ++++++++++++++++
 .../com/mnms/booking/BookingApplication.java  |   1 +
 .../mnms/booking/config/KaptchaConfig.java    |  29 +++
 .../booking/controller/BookingController.java |  15 ++
 .../booking/controller/CaptchaController.java |  45 ++++
 src/main/resources/static/index.html          | 232 +++++++++---------
 src/main/resources/static/test-websocket.html |  78 +++---
 8 files changed, 465 insertions(+), 155 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/KaptchaConfig.java
 create mode 100644 src/main/java/com/mnms/booking/controller/CaptchaController.java

diff --git a/build.gradle b/build.gradle
index 7161842..afd0be9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -54,6 +54,9 @@ dependencies {
 
 	// mongodb
 	//implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
+
+	// kaptcha
+	implementation 'com.github.penggle:kaptcha:2.3.2'
 }
 
 tasks.named('test') {
diff --git a/logs/spring.log b/logs/spring.log
index befd357..a93d6e7 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -1769,3 +1769,220 @@ This generated password is for development use only. Your security configuration
 2025-08-01T16:05:41.745+09:00  INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
 2025-08-01T16:05:41.768+09:00  INFO 18896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
 2025-08-01T16:05:42.335+09:00  INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.729 seconds (process running for 8.194)
+2025-08-01T16:06:09.517+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6784 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T16:06:09.519+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T16:06:10.689+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T16:06:10.691+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T16:06:10.722+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
+2025-08-01T16:06:10.750+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T16:06:10.754+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T16:06:10.781+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-01T16:06:11.851+09:00  INFO 6784 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T16:06:11.872+09:00  INFO 6784 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T16:06:11.872+09:00  INFO 6784 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T16:06:11.971+09:00  INFO 6784 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T16:06:11.973+09:00  INFO 6784 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2392 ms
+2025-08-01T16:06:12.398+09:00  INFO 6784 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T16:06:12.476+09:00  INFO 6784 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T16:06:12.512+09:00  INFO 6784 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T16:06:13.094+09:00  INFO 6784 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T16:06:13.123+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T16:06:13.282+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T16:06:13.285+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T16:06:13.306+09:00  WARN 6784 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T16:06:13.334+09:00  INFO 6784 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T16:06:13.777+09:00  INFO 6784 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T16:06:13.788+09:00  INFO 6784 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T16:06:14.845+09:00  WARN 6784 --- [booking] [main] 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-08-01T16:06:15.153+09:00  INFO 6784 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T16:06:15.695+09:00  INFO 6784 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T16:06:15.955+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T16:06:15.956+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5f3c866c]]
+2025-08-01T16:06:15.958+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T16:06:15.984+09:00  INFO 6784 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T16:06:16.623+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.834 seconds (process running for 8.242)
+2025-08-01T16:06:26.853+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T16:06:26.854+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T16:06:26.857+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-01T16:06:35.709+09:00  INFO 6784 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
+2025-08-01T16:07:15.972+09:00  INFO 6784 --- [booking] [MessageBroker-11] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12]
+2025-08-01T16:37:15.982+09:00  INFO 6784 --- [booking] [MessageBroker-12] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 517]
+2025-08-01T16:54:26.874+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 29372 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T16:54:26.877+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T16:54:27.915+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T16:54:27.916+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T16:54:27.948+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
+2025-08-01T16:54:27.968+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T16:54:27.969+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T16:54:27.985+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-01T16:54:29.021+09:00  INFO 29372 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T16:54:29.047+09:00  INFO 29372 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T16:54:29.048+09:00  INFO 29372 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T16:54:29.153+09:00  INFO 29372 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T16:54:29.154+09:00  INFO 29372 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2225 ms
+2025-08-01T16:54:29.508+09:00  INFO 29372 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T16:54:29.571+09:00  INFO 29372 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T16:54:29.604+09:00  INFO 29372 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T16:54:30.120+09:00  INFO 29372 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T16:54:30.148+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T16:54:30.309+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T16:54:30.313+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T16:54:30.336+09:00  WARN 29372 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T16:54:30.367+09:00  INFO 29372 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T16:54:30.784+09:00  INFO 29372 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T16:54:30.789+09:00  INFO 29372 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T16:54:31.795+09:00  WARN 29372 --- [booking] [main] 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-08-01T16:54:32.081+09:00  INFO 29372 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T16:54:33.202+09:00  INFO 29372 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T16:54:33.534+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T16:54:33.536+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@341c0dfc]]
+2025-08-01T16:54:33.538+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T16:54:33.571+09:00  INFO 29372 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T16:54:34.142+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.927 seconds (process running for 8.362)
+2025-08-01T16:54:38.822+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T16:54:38.822+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T16:54:38.826+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
+2025-08-01T16:55:33.541+09:00  INFO 29372 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T17:00:45.121+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 13388 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T17:00:45.124+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T17:00:46.344+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:00:46.348+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T17:00:46.396+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
+2025-08-01T17:00:46.415+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:00:46.417+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T17:00:46.429+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-01T17:00:47.449+09:00  INFO 13388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T17:00:47.467+09:00  INFO 13388 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T17:00:47.468+09:00  INFO 13388 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T17:00:47.552+09:00  INFO 13388 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T17:00:47.552+09:00  INFO 13388 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2363 ms
+2025-08-01T17:00:47.955+09:00  INFO 13388 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T17:00:48.043+09:00  INFO 13388 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T17:00:48.073+09:00  INFO 13388 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T17:00:48.563+09:00  INFO 13388 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T17:00:48.594+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T17:00:48.749+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T17:00:48.751+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T17:00:48.773+09:00  WARN 13388 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T17:00:48.792+09:00  INFO 13388 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T17:00:49.097+09:00  INFO 13388 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T17:00:49.102+09:00  INFO 13388 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T17:00:50.155+09:00  WARN 13388 --- [booking] [main] 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-08-01T17:00:50.416+09:00  INFO 13388 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T17:00:51.127+09:00  INFO 13388 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T17:00:51.309+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T17:00:51.310+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7ec75228]]
+2025-08-01T17:00:51.311+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T17:00:51.333+09:00  INFO 13388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T17:00:51.923+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.556 seconds (process running for 7.941)
+2025-08-01T17:01:51.341+09:00  INFO 13388 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T17:02:13.694+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T17:02:13.694+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T17:02:13.696+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-01T17:05:16.464+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18560 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T17:05:16.470+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T17:05:17.662+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:05:17.665+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T17:05:17.716+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
+2025-08-01T17:05:17.735+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:05:17.736+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T17:05:17.751+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-01T17:05:18.976+09:00  INFO 18560 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T17:05:18.998+09:00  INFO 18560 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T17:05:18.999+09:00  INFO 18560 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T17:05:19.090+09:00  INFO 18560 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T17:05:19.091+09:00  INFO 18560 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2546 ms
+2025-08-01T17:05:19.478+09:00  INFO 18560 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T17:05:19.629+09:00  INFO 18560 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T17:05:19.669+09:00  INFO 18560 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T17:05:20.141+09:00  INFO 18560 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T17:05:20.169+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T17:05:20.342+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T17:05:20.345+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T17:05:20.367+09:00  WARN 18560 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T17:05:20.388+09:00  INFO 18560 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T17:05:20.727+09:00  INFO 18560 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T17:05:20.733+09:00  INFO 18560 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T17:05:21.894+09:00  WARN 18560 --- [booking] [main] 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-08-01T17:05:22.119+09:00  INFO 18560 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T17:05:22.733+09:00  INFO 18560 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T17:05:22.895+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T17:05:22.897+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
+2025-08-01T17:05:22.898+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T17:05:22.919+09:00  INFO 18560 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T17:05:23.490+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.763 seconds (process running for 8.168)
+2025-08-01T17:05:33.434+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T17:05:33.435+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T17:05:33.436+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-01T17:06:22.913+09:00  INFO 18560 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T17:21:17.616+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28628 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T17:21:17.619+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T17:21:18.783+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:21:18.786+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T17:21:18.826+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 JPA repository interfaces.
+2025-08-01T17:21:18.843+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:21:18.844+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T17:21:18.859+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-01T17:21:19.892+09:00  INFO 28628 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T17:21:19.911+09:00  INFO 28628 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T17:21:19.911+09:00  INFO 28628 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T17:21:19.991+09:00  INFO 28628 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T17:21:19.992+09:00  INFO 28628 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2314 ms
+2025-08-01T17:21:20.348+09:00  INFO 28628 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T17:21:20.483+09:00  INFO 28628 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T17:21:20.515+09:00  INFO 28628 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T17:21:21.021+09:00  INFO 28628 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T17:21:21.055+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T17:21:21.253+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T17:21:21.256+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T17:21:21.282+09:00  WARN 28628 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T17:21:21.303+09:00  INFO 28628 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T17:21:21.624+09:00  INFO 28628 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T17:21:21.656+09:00  INFO 28628 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T17:21:22.740+09:00  WARN 28628 --- [booking] [main] 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-08-01T17:21:22.996+09:00  INFO 28628 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T17:21:23.669+09:00  INFO 28628 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T17:21:23.840+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T17:21:23.841+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7e0b68e5]]
+2025-08-01T17:21:23.842+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T17:21:23.872+09:00  INFO 28628 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T17:21:24.457+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.501 seconds (process running for 7.959)
+2025-08-01T17:21:34.865+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T17:21:34.865+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T17:21:34.867+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-01T17:22:23.848+09:00  INFO 28628 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
diff --git a/src/main/java/com/mnms/booking/BookingApplication.java b/src/main/java/com/mnms/booking/BookingApplication.java
index ca8955f..0b61851 100644
--- a/src/main/java/com/mnms/booking/BookingApplication.java
+++ b/src/main/java/com/mnms/booking/BookingApplication.java
@@ -2,6 +2,7 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 public class BookingApplication {
diff --git a/src/main/java/com/mnms/booking/config/KaptchaConfig.java b/src/main/java/com/mnms/booking/config/KaptchaConfig.java
new file mode 100644
index 0000000..ce2560f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/KaptchaConfig.java
@@ -0,0 +1,29 @@
+package com.mnms.booking.config;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.Properties;
+
+@Configuration
+public class KaptchaConfig {
+
+    @Bean
+    public DefaultKaptcha captchaProducer() {
+        DefaultKaptcha kaptcha = new DefaultKaptcha();
+        Properties properties = new Properties();
+        properties.setProperty("kaptcha.border", "no");
+        properties.setProperty("kaptcha.textproducer.font.color", "black");
+        properties.setProperty("kaptcha.image.width", "200");
+        properties.setProperty("kaptcha.image.height", "50");
+        properties.setProperty("kaptcha.textproducer.font.size", "40");
+        properties.setProperty("kaptcha.session.key", "captchaCode");
+        properties.setProperty("kaptcha.textproducer.char.length", "5");
+        properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
+        Config config = new Config(properties);
+        kaptcha.setConfig(config);
+        return kaptcha;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 03385b6..76fbed9 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -3,10 +3,13 @@
 import com.mnms.booking.dto.response.WaitingNumberDto;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.messaging.handler.annotation.DestinationVariable;
 import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.handler.annotation.Payload;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
@@ -19,6 +22,10 @@ public class BookingController {
 
     private final WaitingService waitingService;
 
+    @Autowired
+    private SimpMessagingTemplate messagingTemplate;
+
+
     /**
      * 예매하기 버튼 클릭 시 호출되는 API
      * userId는 실제 로그인된 사용자 ID를 사용해야 합니다. (수정 예정)
@@ -66,4 +73,12 @@ public void subscribeWaitingQueue(@DestinationVariable("userId") String userId)
         log.info("User {} subscribed to waiting queue updates.", userId);
         waitingService.getAndPublishWaitingNumber(userId);
     }
+
+//    @MessageMapping("/subscribe/waiting/{userId}")
+//    public void handleSubscribe(@DestinationVariable String userId, @Payload SomePayload payload) {
+//        // 처리 로직 ...
+//
+//        // 구독자에게 메시지 보내기
+//        messagingTemplate.convertAndSend("/topic/waiting/" + userId, "대기열 상태 업데이트 메시지");
+//    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
new file mode 100644
index 0000000..5405019
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -0,0 +1,45 @@
+package com.mnms.booking.controller;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+@RestController
+@RequestMapping("/api/captcha")
+public class CaptchaController {
+
+    private final DefaultKaptcha captchaProducer;
+
+    public CaptchaController(DefaultKaptcha captchaProducer) {
+        this.captchaProducer = captchaProducer;
+    }
+
+    @GetMapping("/image")
+    public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        response.setDateHeader("Expires", 0);
+        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
+        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
+        response.setHeader("Pragma", "no-cache");
+        response.setContentType("image/jpeg");
+
+        // 문자 생성
+        String captchaText = captchaProducer.createText();
+        request.getSession().setAttribute("captcha", captchaText);
+        System.out.println("captchaText : " + captchaText);
+
+        // 이미지 생성
+        BufferedImage image = captchaProducer.createImage(captchaText);
+        ServletOutputStream out = response.getOutputStream();
+        ImageIO.write(image, "jpg", out);
+        out.flush();
+        out.close();
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
index 9d3aa0d..0dda08f 100644
--- a/src/main/resources/static/index.html
+++ b/src/main/resources/static/index.html
@@ -1,129 +1,129 @@
-
-
-
-    
-    공연 예매 대기열 시스템
-    
-    
-    
-
-
-

공연 예매 대기열 시스템

+ + + + + + + + + + + + + + + + + + -
- -
+ + + - + -
현재 대기 순번: 대기열에 없음
-
+ + - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/static/test-websocket.html b/src/main/resources/static/test-websocket.html index 1d11a52..6bba6fe 100644 --- a/src/main/resources/static/test-websocket.html +++ b/src/main/resources/static/test-websocket.html @@ -1,44 +1,44 @@ - - - - - WebSocket STOMP 테스트 - - - - -

WebSocket STOMP 테스트

- - -

+
+
+
+
+
+
+
+
+
+
+
+
+
 
-
-
-
+
+
+
+
+
+

From f628e2914b8526370b5bef390ef312fc23c2db28 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 1 Aug 2025 20:35:36 +0900
Subject: [PATCH 004/149] =?UTF-8?q?MNMS-143=20feat:=20=EB=B3=B4=EC=95=88?=
 =?UTF-8?q?=EB=AC=B8=EC=9E=90=20=EC=9D=B8=EC=A6=9D=20=EB=B0=8F=20=EB=B3=B4?=
 =?UTF-8?q?=EC=95=88=EA=B0=95=ED=99=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

보안 강화 : 인증 후 세션에서 삭제
추가 설명 : 대소문자 상관 없음
---
 logs/spring.log                               | 300 ++++++++++++++++++
 .../mnms/booking/config/KaptchaConfig.java    |   4 +-
 .../booking/controller/CaptchaController.java |  21 +-
 3 files changed, 319 insertions(+), 6 deletions(-)

diff --git a/logs/spring.log b/logs/spring.log
index a93d6e7..64e410a 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -1986,3 +1986,303 @@ This generated password is for development use only. Your security configuration
 2025-08-01T17:21:34.865+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
 2025-08-01T17:21:34.867+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
 2025-08-01T17:22:23.848+09:00  INFO 28628 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T17:36:24.712+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 22676 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T17:36:24.715+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T17:36:25.783+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:36:25.787+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T17:36:25.826+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces.
+2025-08-01T17:36:25.854+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T17:36:25.856+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T17:36:25.877+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-01T17:36:26.921+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T17:36:26.939+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T17:36:26.940+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T17:36:27.022+09:00  INFO 22676 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T17:36:27.023+09:00  INFO 22676 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2246 ms
+2025-08-01T17:36:27.465+09:00  INFO 22676 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T17:36:27.583+09:00  INFO 22676 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T17:36:27.616+09:00  INFO 22676 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T17:36:28.074+09:00  INFO 22676 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T17:36:28.101+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T17:36:28.274+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T17:36:28.278+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T17:36:28.306+09:00  WARN 22676 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T17:36:28.330+09:00  INFO 22676 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T17:36:28.674+09:00  INFO 22676 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T17:36:28.680+09:00  INFO 22676 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T17:36:29.956+09:00  WARN 22676 --- [booking] [main] 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-08-01T17:36:30.244+09:00  INFO 22676 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T17:36:30.933+09:00  INFO 22676 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T17:36:31.104+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T17:36:31.106+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4e53c6ef]]
+2025-08-01T17:36:31.107+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T17:36:31.130+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T17:36:32.014+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.994 seconds (process running for 8.397)
+2025-08-01T17:36:46.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T17:36:46.010+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T17:36:46.013+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-01T17:37:31.140+09:00  INFO 22676 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T19:57:08.250+09:00  INFO 18328 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18328 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T19:57:08.250+09:00  INFO 18328 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T19:57:10.285+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T19:57:10.292+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T19:57:10.341+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 22 ms. Found 0 JPA repository interfaces.
+2025-08-01T19:57:10.384+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T19:57:10.386+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T19:57:10.424+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
+2025-08-01T19:57:11.986+09:00  INFO 18328 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T19:57:12.010+09:00  INFO 18328 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T19:57:12.010+09:00  INFO 18328 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T19:57:12.174+09:00  INFO 18328 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T19:57:12.174+09:00  INFO 18328 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3832 ms
+2025-08-01T19:57:13.120+09:00  INFO 18328 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T19:57:13.266+09:00  INFO 18328 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T19:57:13.324+09:00  INFO 18328 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T19:57:13.903+09:00  INFO 18328 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T19:57:13.954+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T19:57:14.324+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T19:57:14.329+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T19:57:14.390+09:00  WARN 18328 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T19:57:14.440+09:00  INFO 18328 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T19:57:15.019+09:00  INFO 18328 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T19:57:15.025+09:00  INFO 18328 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T19:57:16.548+09:00  WARN 18328 --- [booking] [main] 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-08-01T19:57:17.069+09:00  INFO 18328 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T19:57:18.553+09:00  INFO 18328 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T19:57:18.914+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T19:57:18.922+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
+2025-08-01T19:57:18.922+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T19:57:18.967+09:00  INFO 18328 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T19:57:19.738+09:00  INFO 18328 --- [booking] [main] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
+2025-08-01T19:57:19.948+09:00  INFO 18328 --- [booking] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown complete
+2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
+2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T19:57:19.983+09:00  WARN 18328 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
+2025-08-01T19:57:19.992+09:00  INFO 18328 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T19:57:20.000+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T19:57:20.008+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T19:57:20.035+09:00  INFO 18328 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T19:57:20.076+09:00 ERROR 18328 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
+
+org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
+	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:408) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586) ~[spring-context-6.2.9.jar:6.2.9]
+	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
+	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1006) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:630) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
+	at com.mnms.booking.BookingApplication.main(BookingApplication.java:11) ~[main/:na]
+Caused by: org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:383) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer.start(RedisMessageListenerContainer.java:361) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.9.jar:6.2.9]
+	... 14 common frames omitted
+Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1866) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1797) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1594) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1574) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1535) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1571) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1257) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:1063) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$initialize$0(RedisMessageListenerContainer.java:1241) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1455) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.initialize(RedisMessageListenerContainer.java:1235) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer.doSubscribe(RedisMessageListenerContainer.java:428) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:404) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:374) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	... 16 common frames omitted
+Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool
+	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:118) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1795) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	... 28 common frames omitted
+Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/:6379
+	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:63) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:41) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:354) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at io.lettuce.core.RedisClient.connect(RedisClient.java:220) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
+	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$getConnection$0(LettucePoolingConnectionProvider.java:100) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:270) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:257) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:68) ~[commons-pool2-2.12.1.jar:2.12.1]
+	at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:557) ~[commons-pool2-2.12.1.jar:2.12.1]
+	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:299) ~[commons-pool2-2.12.1.jar:2.12.1]
+	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:231) ~[commons-pool2-2.12.1.jar:2.12.1]
+	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:149) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:144) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
+	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:113) ~[spring-data-redis-3.5.2.jar:3.5.2]
+	... 29 common frames omitted
+Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: localhost/127.0.0.1:6379
+Caused by: java.net.ConnectException: Connection refused: getsockopt
+	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
+	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
+	at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na]
+	at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:784) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
+	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
+	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
+
+2025-08-01T20:02:28.927+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1920 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:02:28.930+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:02:31.019+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:02:31.024+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:02:31.081+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 38 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:02:31.114+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:02:31.116+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:02:31.136+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:02:33.017+09:00  INFO 1920 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:02:33.070+09:00  INFO 1920 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:02:33.073+09:00  INFO 1920 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:02:33.287+09:00  INFO 1920 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:02:33.287+09:00  INFO 1920 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4271 ms
+2025-08-01T20:02:33.834+09:00  INFO 1920 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:02:34.021+09:00  INFO 1920 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:02:34.076+09:00  INFO 1920 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:02:34.932+09:00  INFO 1920 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:02:34.987+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:02:35.381+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:02:35.390+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:02:35.458+09:00  WARN 1920 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:02:35.523+09:00  INFO 1920 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:02:36.693+09:00  INFO 1920 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:02:36.717+09:00  INFO 1920 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:02:39.719+09:00  WARN 1920 --- [booking] [main] 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-08-01T20:02:40.358+09:00  INFO 1920 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T20:02:42.172+09:00  INFO 1920 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T20:02:42.952+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T20:02:42.966+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5e7ea81b]]
+2025-08-01T20:02:42.969+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T20:02:43.060+09:00  INFO 1920 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T20:02:45.086+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 17.196 seconds (process running for 17.876)
+2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-01T20:03:42.917+09:00  INFO 1920 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T20:08:11.716+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 22676 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:08:11.721+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:08:13.413+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:08:13.423+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:08:13.466+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:08:13.496+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:08:13.498+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:08:13.520+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:08:15.142+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:08:15.165+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:08:15.169+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:08:15.306+09:00  INFO 22676 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:08:15.311+09:00  INFO 22676 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3491 ms
+2025-08-01T20:08:15.791+09:00  INFO 22676 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:08:15.925+09:00  INFO 22676 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:08:15.975+09:00  INFO 22676 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:08:16.600+09:00  INFO 22676 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:08:16.636+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:08:16.847+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:08:16.847+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:08:16.894+09:00  WARN 22676 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:08:16.931+09:00  INFO 22676 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:08:17.496+09:00  INFO 22676 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:08:17.503+09:00  INFO 22676 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:08:18.824+09:00  WARN 22676 --- [booking] [main] 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-08-01T20:08:19.205+09:00  INFO 22676 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T20:08:20.166+09:00  INFO 22676 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@22349ad3]]
+2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T20:08:20.551+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T20:08:21.676+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.079 seconds (process running for 11.756)
+2025-08-01T20:08:33.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T20:08:33.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T20:08:33.018+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
+2025-08-01T20:09:20.498+09:00  INFO 22676 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T20:28:04.154+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26932 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:28:04.156+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:28:05.863+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:28:05.867+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:28:05.909+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:28:05.941+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:28:05.950+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:28:05.975+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:28:07.528+09:00  INFO 26932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:28:07.559+09:00  INFO 26932 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:28:07.559+09:00  INFO 26932 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:28:07.701+09:00  INFO 26932 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:28:07.701+09:00  INFO 26932 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3481 ms
+2025-08-01T20:28:08.147+09:00  INFO 26932 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:28:08.283+09:00  INFO 26932 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:28:08.325+09:00  INFO 26932 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:28:08.961+09:00  INFO 26932 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:28:09.012+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:28:09.236+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:28:09.236+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:28:09.279+09:00  WARN 26932 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:28:09.318+09:00  INFO 26932 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:28:09.937+09:00  INFO 26932 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:28:09.945+09:00  INFO 26932 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:28:11.458+09:00  WARN 26932 --- [booking] [main] 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-08-01T20:28:11.909+09:00  INFO 26932 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T20:28:13.234+09:00  INFO 26932 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T20:28:13.525+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T20:28:13.525+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@35217e0]]
+2025-08-01T20:28:13.534+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T20:28:13.568+09:00  INFO 26932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T20:28:14.598+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.568 seconds (process running for 12.193)
+2025-08-01T20:29:13.536+09:00  INFO 26932 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
diff --git a/src/main/java/com/mnms/booking/config/KaptchaConfig.java b/src/main/java/com/mnms/booking/config/KaptchaConfig.java
index ce2560f..9427c09 100644
--- a/src/main/java/com/mnms/booking/config/KaptchaConfig.java
+++ b/src/main/java/com/mnms/booking/config/KaptchaConfig.java
@@ -17,8 +17,8 @@ public DefaultKaptcha captchaProducer() {
         properties.setProperty("kaptcha.border", "no");
         properties.setProperty("kaptcha.textproducer.font.color", "black");
         properties.setProperty("kaptcha.image.width", "200");
-        properties.setProperty("kaptcha.image.height", "50");
-        properties.setProperty("kaptcha.textproducer.font.size", "40");
+        properties.setProperty("kaptcha.image.height", "60");
+        properties.setProperty("kaptcha.textproducer.font.size", "50");
         properties.setProperty("kaptcha.session.key", "captchaCode");
         properties.setProperty("kaptcha.textproducer.char.length", "5");
         properties.setProperty("kaptcha.textproducer.font.names", "Arial,Courier");
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
index 5405019..aed7ff7 100644
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -4,9 +4,10 @@
 import jakarta.servlet.ServletOutputStream;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import jakarta.servlet.http.HttpSession;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
 
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
@@ -32,7 +33,7 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
 
         // 문자 생성
         String captchaText = captchaProducer.createText();
-        request.getSession().setAttribute("captcha", captchaText);
+        request.getSession().setAttribute("captchaCode", captchaText);
         System.out.println("captchaText : " + captchaText);
 
         // 이미지 생성
@@ -42,4 +43,16 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
         out.flush();
         out.close();
     }
+
+    @PostMapping("/verify")
+    public ResponseEntity verifyCaptcha(@RequestParam("captcha") String captcha, HttpSession session) {
+        String sessionCaptcha = (String) session.getAttribute("captchaCode");
+
+        if (sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(captcha)) {
+            session.removeAttribute("captchaCode"); // 검증 후 바로 제거
+            return ResponseEntity.ok("인증 성공");
+        } else {
+            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("보안문자 불일치");
+        }
+    }
 }
\ No newline at end of file

From 7fcf79a548c67f1dc101d5387fa55242c3b7c417 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 1 Aug 2025 21:53:38 +0900
Subject: [PATCH 005/149] =?UTF-8?q?MNMS-143=20refactor:=20=EB=B3=B4?=
 =?UTF-8?q?=EC=95=88=EB=AC=B8=EC=9E=90=20=EB=A6=AC=ED=8C=A9=ED=86=A0?=
 =?UTF-8?q?=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 logs/spring.log                               | 859 ++++++++++++++++++
 .../booking/controller/CaptchaController.java |  58 --
 .../booking/controller/KaptchaController.java |  38 +
 .../mnms/booking/dto/response/KaptchaDto.java |  11 +
 .../mnms/booking/service/KaptchaService.java  |  59 ++
 .../resources/application-test.properties     |   3 -
 6 files changed, 967 insertions(+), 61 deletions(-)
 delete mode 100644 src/main/java/com/mnms/booking/controller/CaptchaController.java
 create mode 100644 src/main/java/com/mnms/booking/controller/KaptchaController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/KaptchaDto.java
 create mode 100644 src/main/java/com/mnms/booking/service/KaptchaService.java

diff --git a/logs/spring.log b/logs/spring.log
index 64e410a..7643556 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -2286,3 +2286,862 @@ Caused by: java.net.ConnectException: Connection refused: getsockopt
 2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
 2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
 2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-01T20:49:04.837+09:00  INFO 14168 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14168 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:49:04.844+09:00  INFO 14168 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:49:06.905+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:49:06.907+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:49:07.033+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 59 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:49:07.067+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:49:07.067+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:49:07.097+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:49:08.814+09:00  INFO 14168 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:49:08.838+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:49:08.838+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:49:09.013+09:00  INFO 14168 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:49:09.015+09:00  INFO 14168 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4091 ms
+2025-08-01T20:49:09.557+09:00  INFO 14168 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:49:09.700+09:00  INFO 14168 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:49:09.752+09:00  INFO 14168 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:49:10.404+09:00  INFO 14168 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:49:10.461+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:49:10.669+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:49:10.669+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:49:10.704+09:00  WARN 14168 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:49:10.736+09:00  INFO 14168 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:49:11.363+09:00  INFO 14168 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:49:11.371+09:00  INFO 14168 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:49:12.626+09:00  WARN 14168 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
+2025-08-01T20:49:12.688+09:00  INFO 14168 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:49:12.704+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T20:49:12.715+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T20:49:12.721+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-01T20:49:12.754+09:00  INFO 14168 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T20:49:12.857+09:00 ERROR 14168 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
+
+
+Action:
+
+Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
+
+2025-08-01T20:52:04.097+09:00  INFO 26748 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26748 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:52:04.107+09:00  INFO 26748 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:52:06.124+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:52:06.126+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:52:06.181+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 32 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:52:06.222+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:52:06.222+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:52:06.247+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:52:08.009+09:00  INFO 26748 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:52:08.042+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:52:08.042+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:52:08.201+09:00  INFO 26748 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:52:08.206+09:00  INFO 26748 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4000 ms
+2025-08-01T20:52:08.731+09:00  INFO 26748 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:52:08.892+09:00  INFO 26748 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:52:08.942+09:00  INFO 26748 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:52:09.535+09:00  INFO 26748 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:52:09.575+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:52:09.822+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:52:09.822+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:52:09.864+09:00  WARN 26748 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:52:09.914+09:00  INFO 26748 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:52:10.463+09:00  INFO 26748 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:52:10.471+09:00  INFO 26748 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:52:11.417+09:00  WARN 26748 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
+2025-08-01T20:52:11.473+09:00  INFO 26748 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:52:11.481+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T20:52:11.481+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T20:52:11.497+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-01T20:52:11.533+09:00  INFO 26748 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T20:52:11.651+09:00 ERROR 26748 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
+
+
+Action:
+
+Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
+
+2025-08-01T20:53:53.629+09:00  INFO 14084 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 14084 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:53:53.636+09:00  INFO 14084 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:53:54.881+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:53:54.889+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:53:54.940+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 34 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:53:54.963+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:53:54.963+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:53:54.988+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:53:56.135+09:00  INFO 14084 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:53:56.160+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:53:56.160+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:53:56.258+09:00  INFO 14084 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:53:56.260+09:00  INFO 14084 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2530 ms
+2025-08-01T20:53:56.507+09:00  INFO 14084 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:53:56.599+09:00  INFO 14084 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:53:56.656+09:00  INFO 14084 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:53:57.186+09:00  INFO 14084 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:53:57.235+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:53:57.501+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:53:57.508+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:53:57.565+09:00  WARN 14084 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:53:57.615+09:00  INFO 14084 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:53:58.242+09:00  INFO 14084 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:53:58.250+09:00  INFO 14084 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:53:59.116+09:00  WARN 14084 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
+2025-08-01T20:53:59.150+09:00  INFO 14084 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:53:59.166+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T20:53:59.175+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T20:53:59.175+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-01T20:53:59.206+09:00  INFO 14084 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T20:53:59.257+09:00 ERROR 14084 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
+
+
+Action:
+
+Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
+
+2025-08-01T20:56:03.159+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14632 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T20:56:03.167+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T20:56:05.333+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:56:05.333+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T20:56:05.381+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
+2025-08-01T20:56:05.416+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T20:56:05.416+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T20:56:05.439+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-01T20:56:07.241+09:00  INFO 14632 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T20:56:07.266+09:00  INFO 14632 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T20:56:07.266+09:00  INFO 14632 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T20:56:07.416+09:00  INFO 14632 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T20:56:07.416+09:00  INFO 14632 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4151 ms
+2025-08-01T20:56:07.991+09:00  INFO 14632 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T20:56:08.099+09:00  INFO 14632 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T20:56:08.167+09:00  INFO 14632 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T20:56:08.774+09:00  INFO 14632 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T20:56:08.816+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T20:56:09.118+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T20:56:09.126+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T20:56:09.192+09:00  WARN 14632 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T20:56:09.275+09:00  INFO 14632 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T20:56:09.943+09:00  INFO 14632 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T20:56:09.961+09:00  INFO 14632 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T20:56:11.708+09:00  WARN 14632 --- [booking] [main] 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-08-01T20:56:12.103+09:00  INFO 14632 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T20:56:13.546+09:00  INFO 14632 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T20:56:14.098+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T20:56:14.103+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@224e7aa5]]
+2025-08-01T20:56:14.104+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T20:56:14.143+09:00  INFO 14632 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T20:56:15.237+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.529 seconds (process running for 14.257)
+2025-08-01T20:57:14.106+09:00  INFO 14632 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T20:57:44.549+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T20:57:44.549+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T20:57:44.552+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
+2025-08-01T21:01:16.407+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18000 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:01:16.416+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:01:18.249+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:01:18.251+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:01:18.318+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:01:18.355+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:01:18.358+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:01:18.391+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:01:20.248+09:00  INFO 18000 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:01:20.273+09:00  INFO 18000 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:01:20.273+09:00  INFO 18000 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:01:20.378+09:00  INFO 18000 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:01:20.379+09:00  INFO 18000 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3848 ms
+2025-08-01T21:01:20.737+09:00  INFO 18000 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:01:20.829+09:00  INFO 18000 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:01:20.869+09:00  INFO 18000 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:01:21.401+09:00  INFO 18000 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:01:21.451+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:01:21.724+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:01:21.732+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:01:21.765+09:00  WARN 18000 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:01:21.807+09:00  INFO 18000 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:01:22.436+09:00  INFO 18000 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:01:22.443+09:00  INFO 18000 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:01:23.937+09:00  WARN 18000 --- [booking] [main] 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-08-01T21:01:24.361+09:00  INFO 18000 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:01:25.500+09:00  INFO 18000 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:01:25.843+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:01:25.847+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5f69462f]]
+2025-08-01T21:01:25.848+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:01:25.880+09:00  INFO 18000 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:01:27.032+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 12.664 seconds (process running for 13.374)
+2025-08-01T21:01:34.575+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:01:34.580+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:01:34.584+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
+2025-08-01T21:02:25.854+09:00  INFO 18000 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:03:15.517+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11340 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:03:15.520+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:03:17.001+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:03:17.012+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:03:17.058+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:03:17.083+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:03:17.091+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:03:17.115+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:03:18.788+09:00  INFO 11340 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:03:18.816+09:00  INFO 11340 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:03:18.816+09:00  INFO 11340 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:03:18.961+09:00  INFO 11340 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:03:18.968+09:00  INFO 11340 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3369 ms
+2025-08-01T21:03:19.530+09:00  INFO 11340 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:03:19.689+09:00  INFO 11340 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:03:19.741+09:00  INFO 11340 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:03:20.314+09:00  INFO 11340 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:03:20.389+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:03:20.701+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:03:20.710+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:03:20.743+09:00  WARN 11340 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:03:20.776+09:00  INFO 11340 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:03:21.362+09:00  INFO 11340 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:03:21.372+09:00  INFO 11340 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:03:23.024+09:00  WARN 11340 --- [booking] [main] 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-08-01T21:03:23.467+09:00  INFO 11340 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:03:25.009+09:00  INFO 11340 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:03:25.626+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:03:25.633+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@67cd193d]]
+2025-08-01T21:03:25.634+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:03:25.700+09:00  INFO 11340 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:03:26.998+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.018 seconds (process running for 13.862)
+2025-08-01T21:03:40.511+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:03:40.511+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:03:40.515+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
+2025-08-01T21:04:25.608+09:00  INFO 11340 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:05:18.692+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1612 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:05:18.699+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:05:20.970+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:05:20.974+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:05:21.019+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:05:21.054+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:05:21.061+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:05:21.087+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:05:22.807+09:00  INFO 1612 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:05:22.831+09:00  INFO 1612 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:05:22.831+09:00  INFO 1612 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:05:22.958+09:00  INFO 1612 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:05:22.958+09:00  INFO 1612 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4115 ms
+2025-08-01T21:05:23.503+09:00  INFO 1612 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:05:23.662+09:00  INFO 1612 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:05:23.705+09:00  INFO 1612 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:05:24.560+09:00  INFO 1612 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:05:24.618+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:05:24.891+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:05:24.895+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:05:24.937+09:00  WARN 1612 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:05:24.984+09:00  INFO 1612 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:05:25.672+09:00  INFO 1612 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:05:25.681+09:00  INFO 1612 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:05:27.631+09:00  WARN 1612 --- [booking] [main] 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-08-01T21:05:27.998+09:00  INFO 1612 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:05:29.215+09:00  INFO 1612 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:05:29.502+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:05:29.510+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@f09c282]]
+2025-08-01T21:05:29.510+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:05:29.564+09:00  INFO 1612 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:05:31.011+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.734 seconds (process running for 15.007)
+2025-08-01T21:05:34.741+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:05:34.742+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:05:34.745+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
+2025-08-01T21:06:29.506+09:00  INFO 1612 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:07:46.314+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11732 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:07:46.314+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:07:47.907+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:07:47.909+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:07:47.959+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:07:47.992+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:07:48.000+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:07:48.026+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:07:49.603+09:00  INFO 11732 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:07:49.625+09:00  INFO 11732 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:07:49.625+09:00  INFO 11732 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:07:49.806+09:00  INFO 11732 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:07:49.806+09:00  INFO 11732 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3392 ms
+2025-08-01T21:07:50.408+09:00  INFO 11732 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:07:50.515+09:00  INFO 11732 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:07:50.574+09:00  INFO 11732 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:07:51.617+09:00  INFO 11732 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:07:51.667+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:07:52.004+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:07:52.012+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:07:52.070+09:00  WARN 11732 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:07:52.112+09:00  INFO 11732 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:07:52.771+09:00  INFO 11732 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:07:52.784+09:00  INFO 11732 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:07:54.291+09:00  WARN 11732 --- [booking] [main] 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-08-01T21:07:54.692+09:00  INFO 11732 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:07:56.227+09:00  INFO 11732 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:07:56.552+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:07:56.561+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5687ade6]]
+2025-08-01T21:07:56.561+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:07:56.604+09:00  INFO 11732 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:07:57.909+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 12.788 seconds (process running for 13.516)
+2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-01T21:08:56.562+09:00  INFO 11732 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:11:00.590+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18796 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:11:00.597+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:11:02.554+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:11:02.558+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:11:02.599+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:11:02.625+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:11:02.625+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:11:02.650+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:11:04.138+09:00  INFO 18796 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:11:04.158+09:00  INFO 18796 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:11:04.162+09:00  INFO 18796 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:11:04.308+09:00  INFO 18796 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:11:04.308+09:00  INFO 18796 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3607 ms
+2025-08-01T21:11:05.162+09:00  INFO 18796 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:11:05.286+09:00  INFO 18796 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:11:05.346+09:00  INFO 18796 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:11:06.145+09:00  INFO 18796 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:11:06.215+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:11:06.458+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:11:06.459+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:11:06.516+09:00  WARN 18796 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:11:06.566+09:00  INFO 18796 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:11:07.197+09:00  INFO 18796 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:11:07.204+09:00  INFO 18796 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:11:08.879+09:00  WARN 18796 --- [booking] [main] 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-08-01T21:11:09.479+09:00  INFO 18796 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:11:11.057+09:00  INFO 18796 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:11:11.762+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:11:11.762+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
+2025-08-01T21:11:11.768+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:11:11.808+09:00  INFO 18796 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:11:12.978+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.484 seconds (process running for 14.061)
+2025-08-01T21:11:19.177+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:11:19.177+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:11:19.183+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 6 ms
+2025-08-01T21:12:11.748+09:00  INFO 18796 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:28:48.462+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 21320 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:28:48.470+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:28:50.260+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:28:50.271+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:28:50.334+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 43 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:28:50.358+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:28:50.358+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:28:50.375+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:28:51.961+09:00  INFO 21320 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:28:51.977+09:00  INFO 21320 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:28:51.986+09:00  INFO 21320 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:28:52.134+09:00  INFO 21320 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:28:52.141+09:00  INFO 21320 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3571 ms
+2025-08-01T21:28:52.708+09:00  INFO 21320 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:28:52.839+09:00  INFO 21320 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:28:52.889+09:00  INFO 21320 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:28:53.493+09:00  INFO 21320 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:28:53.536+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:28:53.767+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:28:53.775+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:28:53.800+09:00  WARN 21320 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:28:53.832+09:00  INFO 21320 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:28:54.342+09:00  INFO 21320 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:28:54.351+09:00  INFO 21320 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:28:56.010+09:00  WARN 21320 --- [booking] [main] 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-08-01T21:28:56.435+09:00  INFO 21320 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:28:59.313+09:00  INFO 21320 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:29:01.194+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:29:01.199+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@22cf1808]]
+2025-08-01T21:29:01.202+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:29:01.240+09:00  INFO 21320 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:29:02.557+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 15.228 seconds (process running for 16.055)
+2025-08-01T21:29:45.719+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:29:45.728+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:29:45.728+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-01T21:29:46.047+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: ba3yg
+2025-08-01T21:30:01.180+09:00  INFO 21320 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:36:43.332+09:00  INFO 26768 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26768 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:36:43.338+09:00  INFO 26768 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:36:45.499+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:36:45.503+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:36:45.548+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:36:45.579+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:36:45.579+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:36:45.613+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:36:47.283+09:00  INFO 26768 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:36:47.306+09:00  INFO 26768 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:36:47.306+09:00  INFO 26768 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:36:47.446+09:00  INFO 26768 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:36:47.454+09:00  INFO 26768 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4026 ms
+2025-08-01T21:36:47.983+09:00  INFO 26768 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:36:48.122+09:00  INFO 26768 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:36:48.183+09:00  INFO 26768 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:36:48.733+09:00  INFO 26768 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:36:48.792+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:36:49.054+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:36:49.054+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:36:49.096+09:00  WARN 26768 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:36:49.136+09:00  INFO 26768 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:36:49.665+09:00  INFO 26768 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:36:49.673+09:00  INFO 26768 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:36:51.541+09:00  WARN 26768 --- [booking] [main] 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-08-01T21:36:52.014+09:00  INFO 26768 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:36:53.560+09:00  INFO 26768 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42fdf45e]]
+2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42fdf45e]]
+2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T21:36:53.906+09:00  WARN 26768 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-01T21:36:53.931+09:00  INFO 26768 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:36:53.941+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T21:36:53.947+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T21:36:53.970+09:00  INFO 26768 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T21:36:54.003+09:00 ERROR 26768 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Web server failed to start. Port 8080 was already in use.
+
+Action:
+
+Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+
+2025-08-01T21:37:27.592+09:00  INFO 552 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 552 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:37:27.594+09:00  INFO 552 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:37:29.004+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:37:29.012+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:37:29.062+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:37:29.110+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:37:29.112+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:37:29.140+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:37:30.247+09:00  INFO 552 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:37:30.272+09:00  INFO 552 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:37:30.272+09:00  INFO 552 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:37:30.389+09:00  INFO 552 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:37:30.390+09:00  INFO 552 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2713 ms
+2025-08-01T21:37:30.586+09:00  INFO 552 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:37:30.655+09:00  INFO 552 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:37:30.704+09:00  INFO 552 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:37:31.083+09:00  INFO 552 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:37:31.120+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:37:31.370+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:37:31.370+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:37:31.411+09:00  WARN 552 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:37:31.461+09:00  INFO 552 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:37:31.971+09:00  INFO 552 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:37:31.987+09:00  INFO 552 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:37:32.712+09:00  WARN 552 --- [booking] [main] 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-08-01T21:37:32.845+09:00  INFO 552 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:37:33.336+09:00  INFO 552 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:37:33.606+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:37:33.613+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@ad6448e]]
+2025-08-01T21:37:33.614+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@ad6448e]]
+2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T21:37:33.640+09:00  WARN 552 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-01T21:37:33.658+09:00  INFO 552 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:37:33.667+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T21:37:33.671+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T21:37:33.694+09:00  INFO 552 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T21:37:33.716+09:00 ERROR 552 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Web server failed to start. Port 8080 was already in use.
+
+Action:
+
+Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+
+2025-08-01T21:39:48.330+09:00  INFO 14820 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 14820 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:39:48.330+09:00  INFO 14820 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:39:49.669+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:39:49.669+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:39:49.721+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:39:49.746+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:39:49.755+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:39:49.777+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:39:51.121+09:00  INFO 14820 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:39:51.146+09:00  INFO 14820 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:39:51.146+09:00  INFO 14820 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:39:51.250+09:00  INFO 14820 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:39:51.250+09:00  INFO 14820 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2807 ms
+2025-08-01T21:39:51.504+09:00  INFO 14820 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:39:51.599+09:00  INFO 14820 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:39:51.661+09:00  INFO 14820 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:39:52.054+09:00  INFO 14820 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:39:52.112+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:39:52.372+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:39:52.379+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:39:52.414+09:00  WARN 14820 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:39:52.446+09:00  INFO 14820 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:39:53.012+09:00  INFO 14820 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:39:53.020+09:00  INFO 14820 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:39:53.834+09:00  WARN 14820 --- [booking] [main] 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-08-01T21:39:54.027+09:00  INFO 14820 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:39:54.544+09:00  INFO 14820 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:39:54.805+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:39:54.807+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@43c3354]]
+2025-08-01T21:39:54.810+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@43c3354]]
+2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T21:39:54.851+09:00  WARN 14820 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-01T21:39:54.878+09:00  INFO 14820 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:39:54.878+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T21:39:54.888+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T21:39:54.923+09:00  INFO 14820 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T21:39:54.989+09:00 ERROR 14820 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Web server failed to start. Port 8080 was already in use.
+
+Action:
+
+Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+
+2025-08-01T21:42:13.606+09:00  INFO 29180 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 29180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:42:13.607+09:00  INFO 29180 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:42:15.019+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:42:15.021+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:42:15.055+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:42:15.078+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:42:15.078+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:42:15.090+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:42:16.294+09:00  INFO 29180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:42:16.310+09:00  INFO 29180 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:42:16.310+09:00  INFO 29180 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:42:16.448+09:00  INFO 29180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:42:16.450+09:00  INFO 29180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2721 ms
+2025-08-01T21:42:16.710+09:00  INFO 29180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:42:16.804+09:00  INFO 29180 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:42:16.872+09:00  INFO 29180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:42:17.304+09:00  INFO 29180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:42:17.344+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:42:17.661+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:42:17.664+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:42:17.704+09:00  WARN 29180 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:42:17.748+09:00  INFO 29180 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:42:18.257+09:00  INFO 29180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:42:18.266+09:00  INFO 29180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:42:19.045+09:00  WARN 29180 --- [booking] [main] 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-08-01T21:42:19.204+09:00  INFO 29180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:42:19.731+09:00  INFO 29180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@53fd59d4]]
+2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@53fd59d4]]
+2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T21:42:19.993+09:00  WARN 29180 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-01T21:42:20.013+09:00  INFO 29180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:42:20.013+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T21:42:20.022+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T21:42:20.044+09:00  INFO 29180 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T21:42:20.079+09:00 ERROR 29180 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Web server failed to start. Port 8080 was already in use.
+
+Action:
+
+Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+
+2025-08-01T21:43:18.573+09:00  INFO 26364 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26364 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:43:18.579+09:00  INFO 26364 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:43:20.681+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:43:20.681+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:43:20.732+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:43:20.766+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:43:20.770+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:43:20.796+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:43:22.548+09:00  INFO 26364 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:43:22.574+09:00  INFO 26364 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:43:22.582+09:00  INFO 26364 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:43:22.771+09:00  INFO 26364 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:43:22.771+09:00  INFO 26364 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4019 ms
+2025-08-01T21:43:23.468+09:00  INFO 26364 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:43:23.644+09:00  INFO 26364 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:43:23.705+09:00  INFO 26364 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:43:24.403+09:00  INFO 26364 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:43:24.452+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:43:24.774+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:43:24.777+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:43:24.832+09:00  WARN 26364 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:43:24.883+09:00  INFO 26364 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:43:25.474+09:00  INFO 26364 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:43:25.481+09:00  INFO 26364 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:43:26.852+09:00  WARN 26364 --- [booking] [main] 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-08-01T21:43:27.320+09:00  INFO 26364 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:43:28.983+09:00  INFO 26364 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:43:29.421+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:43:29.429+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
+2025-08-01T21:43:29.429+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:43:29.454+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-01T21:43:29.456+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
+2025-08-01T21:43:29.456+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-01T21:43:29.479+09:00  WARN 26364 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-01T21:43:29.556+09:00  INFO 26364 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:43:29.570+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-01T21:43:29.578+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-01T21:43:29.628+09:00  INFO 26364 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-01T21:43:29.759+09:00 ERROR 26364 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+
+***************************
+APPLICATION FAILED TO START
+***************************
+
+Description:
+
+Web server failed to start. Port 8080 was already in use.
+
+Action:
+
+Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
+
+2025-08-01T21:44:11.894+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 4524 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:44:11.902+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:44:13.673+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:44:13.674+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:44:13.721+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:44:13.746+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:44:13.746+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:44:13.772+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:44:15.871+09:00  INFO 4524 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:44:15.895+09:00  INFO 4524 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:44:15.895+09:00  INFO 4524 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:44:16.095+09:00  INFO 4524 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:44:16.096+09:00  INFO 4524 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4124 ms
+2025-08-01T21:44:16.652+09:00  INFO 4524 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:44:16.764+09:00  INFO 4524 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:44:16.808+09:00  INFO 4524 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:44:17.472+09:00  INFO 4524 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:44:17.522+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:44:17.816+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:44:17.824+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:44:17.849+09:00  WARN 4524 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:44:17.873+09:00  INFO 4524 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:44:18.410+09:00  INFO 4524 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:44:18.418+09:00  INFO 4524 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:44:20.135+09:00  WARN 4524 --- [booking] [main] 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-08-01T21:44:20.504+09:00  INFO 4524 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:44:22.078+09:00  INFO 4524 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:44:22.696+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:44:22.703+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
+2025-08-01T21:44:22.705+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:44:22.748+09:00  INFO 4524 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:44:24.059+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.394 seconds (process running for 14.261)
+2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-01T21:44:39.716+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: w5eme
+2025-08-01T21:45:16.018+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: g8nne
+2025-08-01T21:45:22.699+09:00  INFO 4524 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-01T21:45:36.586+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: 8pbym
+2025-08-01T21:48:11.250+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 3932 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-01T21:48:11.251+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-01T21:48:13.420+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:48:13.423+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-01T21:48:13.472+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 31 ms. Found 0 JPA repository interfaces.
+2025-08-01T21:48:13.505+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-01T21:48:13.505+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-01T21:48:13.522+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-01T21:48:14.987+09:00  INFO 3932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-01T21:48:15.011+09:00  INFO 3932 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-01T21:48:15.011+09:00  INFO 3932 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-01T21:48:15.142+09:00  INFO 3932 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-01T21:48:15.142+09:00  INFO 3932 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3804 ms
+2025-08-01T21:48:15.826+09:00  INFO 3932 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-01T21:48:16.061+09:00  INFO 3932 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-01T21:48:16.125+09:00  INFO 3932 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-01T21:48:17.080+09:00  INFO 3932 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-01T21:48:17.137+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-01T21:48:17.459+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-01T21:48:17.468+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-01T21:48:17.509+09:00  WARN 3932 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-01T21:48:17.554+09:00  INFO 3932 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-01T21:48:18.084+09:00  INFO 3932 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-01T21:48:18.092+09:00  INFO 3932 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-01T21:48:20.116+09:00  WARN 3932 --- [booking] [main] 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-08-01T21:48:20.488+09:00  INFO 3932 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-01T21:48:22.128+09:00  INFO 3932 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-01T21:48:22.524+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-01T21:48:22.528+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
+2025-08-01T21:48:22.528+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-01T21:48:22.567+09:00  INFO 3932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-01T21:48:23.753+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.445 seconds (process running for 14.07)
+2025-08-01T21:48:31.454+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-01T21:48:31.462+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-01T21:48:31.464+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-01T21:48:31.779+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: 8dp3d
+2025-08-01T21:49:22.529+09:00  INFO 3932 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
deleted file mode 100644
index aed7ff7..0000000
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.mnms.booking.controller;
-
-import com.google.code.kaptcha.impl.DefaultKaptcha;
-import jakarta.servlet.ServletOutputStream;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.servlet.http.HttpSession;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-
-@RestController
-@RequestMapping("/api/captcha")
-public class CaptchaController {
-
-    private final DefaultKaptcha captchaProducer;
-
-    public CaptchaController(DefaultKaptcha captchaProducer) {
-        this.captchaProducer = captchaProducer;
-    }
-
-    @GetMapping("/image")
-    public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
-        response.setDateHeader("Expires", 0);
-        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
-        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
-        response.setHeader("Pragma", "no-cache");
-        response.setContentType("image/jpeg");
-
-        // 문자 생성
-        String captchaText = captchaProducer.createText();
-        request.getSession().setAttribute("captchaCode", captchaText);
-        System.out.println("captchaText : " + captchaText);
-
-        // 이미지 생성
-        BufferedImage image = captchaProducer.createImage(captchaText);
-        ServletOutputStream out = response.getOutputStream();
-        ImageIO.write(image, "jpg", out);
-        out.flush();
-        out.close();
-    }
-
-    @PostMapping("/verify")
-    public ResponseEntity verifyCaptcha(@RequestParam("captcha") String captcha, HttpSession session) {
-        String sessionCaptcha = (String) session.getAttribute("captchaCode");
-
-        if (sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(captcha)) {
-            session.removeAttribute("captchaCode"); // 검증 후 바로 제거
-            return ResponseEntity.ok("인증 성공");
-        } else {
-            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("보안문자 불일치");
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/KaptchaController.java b/src/main/java/com/mnms/booking/controller/KaptchaController.java
new file mode 100644
index 0000000..acc63fc
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/KaptchaController.java
@@ -0,0 +1,38 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.response.KaptchaDto;
+import com.mnms.booking.service.KaptchaService;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.io.IOException;
+
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/captcha")
+public class KaptchaController {
+
+    private final KaptchaService kaptchaService;
+
+    @GetMapping("/image")
+    public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        kaptchaService.writeCaptchaImage(request.getSession(), response);
+    }
+
+    @PostMapping("/verify")
+    public ResponseEntity verifyCaptcha(
+            @RequestParam("captcha") String captcha,
+            HttpSession session) {
+
+        KaptchaDto result = kaptchaService.verifyCaptchaResult(captcha, session);
+        return result.isSuccess()
+                ? ResponseEntity.ok(result)
+                : ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/KaptchaDto.java b/src/main/java/com/mnms/booking/dto/response/KaptchaDto.java
new file mode 100644
index 0000000..4007908
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/KaptchaDto.java
@@ -0,0 +1,11 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data // Lombok 사용 시
+@Builder
+public class KaptchaDto {
+    private boolean success;
+    private String message;
+}
diff --git a/src/main/java/com/mnms/booking/service/KaptchaService.java b/src/main/java/com/mnms/booking/service/KaptchaService.java
new file mode 100644
index 0000000..ac789e0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/KaptchaService.java
@@ -0,0 +1,59 @@
+package com.mnms.booking.service;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.mnms.booking.dto.response.KaptchaDto;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.io.OutputStream;
+
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class KaptchaService {
+
+    private final DefaultKaptcha captchaProducer;
+    private static final String CAPTCHA_SESSION_KEY = "captchaCode";
+
+    // 캡차 이미지 생성
+    public void writeCaptchaImage(HttpSession session, HttpServletResponse response) throws IOException {
+        // 보안 설정
+        response.setDateHeader("Expires", 0);
+        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
+        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
+        response.setHeader("Pragma", "no-cache");
+        response.setContentType("image/jpeg");
+
+        BufferedImage image = generateCaptchaImage(session);
+
+        try (OutputStream out = response.getOutputStream()) {
+            ImageIO.write(image, "jpg", out);
+            out.flush();
+        }
+    }
+
+    private BufferedImage generateCaptchaImage(HttpSession session) {
+        String captchaText = captchaProducer.createText();
+        session.setAttribute(CAPTCHA_SESSION_KEY, captchaText);
+        log.info("Generated Kaptcha Text: {}", captchaText);
+
+        return captchaProducer.createImage(captchaText);
+    }
+
+    public KaptchaDto verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
+        String sessionCaptcha = (String) session.getAttribute(CAPTCHA_SESSION_KEY);
+
+        boolean isValid = sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(userInputCaptcha);
+        if (isValid) {session.removeAttribute(CAPTCHA_SESSION_KEY);}
+
+        return KaptchaDto.builder()
+                .success(isValid)
+                .message(isValid ? "인증 성공" : "보안문자 불일치")
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index d3edc5c..7b260c9 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -21,6 +21,3 @@ spring.h2.console.path=/h2-console
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
 #spring.redis.password=your_password
-
-
-

From dfee8db21c735df312ac321aff962b51f98d1577 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 5 Aug 2025 10:44:01 +0900
Subject: [PATCH 006/149] =?UTF-8?q?MNMS-143=20fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20Schedule=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

대기열에 있는 사용자 대기번호 구독 알림 Schedule 추가 및 테스트 완
---
 .gitignore                                    |    1 +
 logs/spring.log                               | 3588 +++--------------
 logs/spring.log.2025-08-01.0.gz               |  Bin 0 -> 34889 bytes
 .../com/mnms/booking/BookingApplication.java  |    1 +
 .../com/mnms/booking/config/RedisConfig.java  |    1 -
 .../booking/controller/BookingController.java |   14 +-
 .../mnms/booking/service/WaitingService.java  |   33 +-
 src/main/resources/static/test-websocket.html |  106 +-
 8 files changed, 555 insertions(+), 3189 deletions(-)
 create mode 100644 logs/spring.log.2025-08-01.0.gz

diff --git a/.gitignore b/.gitignore
index c2065bc..403113e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ bin/
 out/
 !**/src/main/**/out/
 !**/src/test/**/out/
+!**/logs/
 
 ### NetBeans ###
 /nbproject/private/
diff --git a/logs/spring.log b/logs/spring.log
index 7643556..795075c 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -1,3047 +1,51 @@
-2025-08-01T13:12:53.183+09:00  INFO 19824 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 19824 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T13:12:53.186+09:00  INFO 19824 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T13:12:54.689+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:12:54.692+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T13:12:54.723+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
-2025-08-01T13:12:54.761+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:12:54.761+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T13:12:54.766+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T13:12:54.779+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:12:54.781+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T13:12:54.796+09:00  INFO 19824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T13:12:55.931+09:00  INFO 19824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T13:12:55.955+09:00  INFO 19824 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T13:12:55.956+09:00  INFO 19824 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T13:12:56.085+09:00  INFO 19824 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T13:12:56.086+09:00  INFO 19824 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2832 ms
-2025-08-01T13:12:56.469+09:00  INFO 19824 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T13:12:56.549+09:00  INFO 19824 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T13:12:56.586+09:00  INFO 19824 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T13:12:56.934+09:00  INFO 19824 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T13:12:56.967+09:00  INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T13:12:57.177+09:00  INFO 19824 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T13:12:57.181+09:00  INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T13:12:57.211+09:00  WARN 19824 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T13:12:57.241+09:00  INFO 19824 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T13:12:57.726+09:00  INFO 19824 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T13:12:57.732+09:00  INFO 19824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:12:59.065+09:00  WARN 19824 --- [booking] [main] 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-08-01T13:12:59.272+09:00  INFO 19824 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T13:12:59.885+09:00  INFO 19824 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@24e31f06, com.mongodb.Jep395RecordCodecProvider@5d260494, com.mongodb.KotlinCodecProvider@d43f205]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T13:12:59.886+09:00  INFO 19824 --- [booking] [cluster-ClusterId{value='688c3ecb0a3db11f80b7808c', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T13:13:00.472+09:00  INFO 19824 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T13:13:00.664+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T13:13:00.665+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3ede428e]]
-2025-08-01T13:13:00.666+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T13:13:00.690+09:00  INFO 19824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T13:13:01.210+09:00  INFO 19824 --- [booking] [main] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
-2025-08-01T13:13:01.356+09:00  INFO 19824 --- [booking] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown complete
-2025-08-01T13:13:01.359+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T13:13:01.359+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3ede428e]]
-2025-08-01T13:13:01.360+09:00  INFO 19824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T13:13:01.371+09:00  WARN 19824 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
-2025-08-01T13:13:01.381+09:00  INFO 19824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:13:01.386+09:00  INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T13:13:01.389+09:00  INFO 19824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T13:13:01.405+09:00  INFO 19824 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T13:13:01.424+09:00 ERROR 19824 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
-
-org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:408) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586) ~[spring-context-6.2.9.jar:6.2.9]
-	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
-	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1006) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:630) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
-	at com.mnms.booking.BookingApplication.main(BookingApplication.java:10) ~[main/:na]
-Caused by: org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:383) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.start(RedisMessageListenerContainer.java:361) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.9.jar:6.2.9]
-	... 14 common frames omitted
-Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1866) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1797) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1594) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1574) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1535) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1571) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1257) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:1063) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$initialize$0(RedisMessageListenerContainer.java:1241) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1455) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.initialize(RedisMessageListenerContainer.java:1235) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.doSubscribe(RedisMessageListenerContainer.java:428) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:404) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:374) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 16 common frames omitted
-Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:118) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1795) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 28 common frames omitted
-Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/:6379
-	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:63) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:41) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:354) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.RedisClient.connect(RedisClient.java:220) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
-	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$getConnection$0(LettucePoolingConnectionProvider.java:100) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:270) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:257) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:68) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:557) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:299) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:231) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:149) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:144) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:113) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 29 common frames omitted
-Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: localhost/127.0.0.1:6379
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na]
-	at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:784) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T13:58:06.369+09:00  INFO 20964 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 20964 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T13:58:06.378+09:00  INFO 20964 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T13:58:07.748+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:58:07.748+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T13:58:07.804+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
-2025-08-01T13:58:07.846+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:58:07.846+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T13:58:07.846+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T13:58:07.860+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:58:07.860+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T13:58:07.873+09:00  INFO 20964 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T13:58:09.261+09:00  INFO 20964 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T13:58:09.308+09:00  INFO 20964 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T13:58:09.312+09:00  INFO 20964 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T13:58:09.463+09:00  INFO 20964 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T13:58:09.465+09:00  INFO 20964 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3023 ms
-2025-08-01T13:58:10.077+09:00  INFO 20964 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T13:58:10.177+09:00  INFO 20964 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T13:58:10.217+09:00  INFO 20964 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T13:58:10.768+09:00  INFO 20964 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T13:58:10.831+09:00  INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T13:58:11.170+09:00  INFO 20964 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T13:58:11.172+09:00  INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T13:58:11.218+09:00  WARN 20964 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T13:58:11.248+09:00  INFO 20964 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T13:58:11.782+09:00  INFO 20964 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T13:58:11.791+09:00  INFO 20964 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:58:13.928+09:00  WARN 20964 --- [booking] [main] 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-08-01T13:58:14.269+09:00  INFO 20964 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T13:58:16.234+09:00  INFO 20964 --- [booking] [cluster-ClusterId{value='688c4967205e09c6921815cd', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T13:58:16.278+09:00  INFO 20964 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@27e656e6, com.mongodb.Jep395RecordCodecProvider@3cfab56d, com.mongodb.KotlinCodecProvider@6b6fde93]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T13:58:17.208+09:00  INFO 20964 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T13:58:17.488+09:00  WARN 20964 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 6d6b00f9-7412-4dee-b32c-2021959376e8
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T13:58:17.501+09:00  INFO 20964 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T13:58:17.680+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T13:58:17.680+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2b3e2039]]
-2025-08-01T13:58:17.691+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T13:58:17.696+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T13:58:17.696+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2b3e2039]]
-2025-08-01T13:58:17.696+09:00  INFO 20964 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T13:58:17.706+09:00  WARN 20964 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T13:58:17.738+09:00  INFO 20964 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:58:17.742+09:00  INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T13:58:17.747+09:00  INFO 20964 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T13:58:17.761+09:00  INFO 20964 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T13:58:17.783+09:00 ERROR 20964 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T13:59:31.089+09:00  INFO 4420 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 4420 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T13:59:31.094+09:00  INFO 4420 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T13:59:32.369+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:59:32.369+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T13:59:32.401+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
-2025-08-01T13:59:32.445+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:59:32.445+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T13:59:32.453+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T13:59:32.477+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T13:59:32.479+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T13:59:32.492+09:00  INFO 4420 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T13:59:33.814+09:00  INFO 4420 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T13:59:33.868+09:00  INFO 4420 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T13:59:33.868+09:00  INFO 4420 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T13:59:34.016+09:00  INFO 4420 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T13:59:34.021+09:00  INFO 4420 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2867 ms
-2025-08-01T13:59:34.599+09:00  INFO 4420 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T13:59:34.718+09:00  INFO 4420 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T13:59:34.764+09:00  INFO 4420 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T13:59:35.162+09:00  INFO 4420 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T13:59:35.211+09:00  INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T13:59:35.432+09:00  INFO 4420 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T13:59:35.434+09:00  INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T13:59:35.453+09:00  WARN 4420 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T13:59:35.481+09:00  INFO 4420 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T13:59:35.823+09:00  INFO 4420 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T13:59:35.828+09:00  INFO 4420 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:59:37.486+09:00  WARN 4420 --- [booking] [main] 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-08-01T13:59:37.817+09:00  INFO 4420 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T13:59:39.871+09:00  INFO 4420 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3fb42ec7, com.mongodb.Jep395RecordCodecProvider@1f7b1d6a, com.mongodb.KotlinCodecProvider@32d8e58d]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T13:59:39.871+09:00  INFO 4420 --- [booking] [cluster-ClusterId{value='688c49bb4aa34090cf08cdb5', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T13:59:40.824+09:00  INFO 4420 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T13:59:41.218+09:00  WARN 4420 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: f1348f72-af09-4479-9134-b99c9236b3d3
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T13:59:41.236+09:00  INFO 4420 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T13:59:41.575+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T13:59:41.585+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2afa1b1a]]
-2025-08-01T13:59:41.586+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T13:59:41.599+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T13:59:41.599+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2afa1b1a]]
-2025-08-01T13:59:41.599+09:00  INFO 4420 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T13:59:41.620+09:00  WARN 4420 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T13:59:41.655+09:00  INFO 4420 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T13:59:41.657+09:00  INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T13:59:41.668+09:00  INFO 4420 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T13:59:41.695+09:00  INFO 4420 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T13:59:41.742+09:00 ERROR 4420 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T14:02:02.270+09:00  INFO 6696 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6696 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:02:02.276+09:00  INFO 6696 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:02:04.071+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:04.071+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:02:04.102+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:02:04.134+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:04.134+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:02:04.134+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:02:04.151+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:04.151+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:02:04.174+09:00  INFO 6696 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:02:05.451+09:00  INFO 6696 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:02:05.482+09:00  INFO 6696 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:02:05.482+09:00  INFO 6696 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:02:05.594+09:00  INFO 6696 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:02:05.594+09:00  INFO 6696 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3214 ms
-2025-08-01T14:02:06.194+09:00  INFO 6696 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:02:06.273+09:00  INFO 6696 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:02:06.304+09:00  INFO 6696 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:02:06.687+09:00  INFO 6696 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:02:06.735+09:00  INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:02:06.926+09:00  INFO 6696 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:02:06.926+09:00  INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:02:06.979+09:00  WARN 6696 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:02:07.006+09:00  INFO 6696 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:02:07.420+09:00  INFO 6696 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:02:07.436+09:00  INFO 6696 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:02:08.860+09:00  WARN 6696 --- [booking] [main] 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-08-01T14:02:09.174+09:00  INFO 6696 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:02:10.163+09:00  INFO 6696 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@32d8e58d, com.mongodb.Jep395RecordCodecProvider@4c941d19, com.mongodb.KotlinCodecProvider@5248c05a]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:02:10.171+09:00  INFO 6696 --- [booking] [cluster-ClusterId{value='688c4a52bc323016b51ea9f2', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:02:10.557+09:00  INFO 6696 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:02:10.735+09:00  WARN 6696 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: a1c56098-6888-4780-8743-8b4389f7bbaa
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:02:10.735+09:00  INFO 6696 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:02:10.995+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:02:11.000+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@487f025]]
-2025-08-01T14:02:11.000+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:02:11.010+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T14:02:11.010+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@487f025]]
-2025-08-01T14:02:11.010+09:00  INFO 6696 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T14:02:11.042+09:00  WARN 6696 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T14:02:11.073+09:00  INFO 6696 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:02:11.073+09:00  INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T14:02:11.088+09:00  INFO 6696 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T14:02:11.117+09:00  INFO 6696 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T14:02:11.177+09:00 ERROR 6696 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T14:02:40.757+09:00  INFO 11700 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11700 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:02:40.760+09:00  INFO 11700 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:02:42.605+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:42.609+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:02:42.668+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 33 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:02:42.735+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:42.736+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:02:42.740+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:02:42.765+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:02:42.767+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:02:42.797+09:00  INFO 11700 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:02:44.492+09:00  INFO 11700 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:02:44.540+09:00  INFO 11700 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:02:44.540+09:00  INFO 11700 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:02:44.771+09:00  INFO 11700 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:02:44.773+09:00  INFO 11700 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3908 ms
-2025-08-01T14:02:45.289+09:00  INFO 11700 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:02:45.369+09:00  INFO 11700 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:02:45.423+09:00  INFO 11700 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:02:45.830+09:00  INFO 11700 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:02:45.879+09:00  INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:02:46.060+09:00  INFO 11700 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:02:46.062+09:00  INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:02:46.074+09:00  WARN 11700 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:02:46.093+09:00  INFO 11700 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:02:46.461+09:00  INFO 11700 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:02:46.468+09:00  INFO 11700 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:02:47.756+09:00  WARN 11700 --- [booking] [main] 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-08-01T14:02:48.122+09:00  INFO 11700 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:02:49.028+09:00  INFO 11700 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@75f446df, com.mongodb.Jep395RecordCodecProvider@3751baf6, com.mongodb.KotlinCodecProvider@27e656e6]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:02:49.028+09:00  INFO 11700 --- [booking] [cluster-ClusterId{value='688c4a785d6f68bcc6fc9d71', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:02:49.547+09:00  INFO 11700 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:02:49.800+09:00  WARN 11700 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: ae9c07e7-443f-4740-9cf2-2b932be210ef
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:02:49.820+09:00  INFO 11700 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:02:49.995+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:02:50.003+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4dd28982]]
-2025-08-01T14:02:50.005+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:02:50.005+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T14:02:50.005+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4dd28982]]
-2025-08-01T14:02:50.005+09:00  INFO 11700 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T14:02:50.019+09:00  WARN 11700 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T14:02:50.059+09:00  INFO 11700 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:02:50.059+09:00  INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T14:02:50.074+09:00  INFO 11700 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T14:02:50.099+09:00  INFO 11700 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T14:02:50.125+09:00 ERROR 11700 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T14:05:39.564+09:00  INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 19504 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:05:39.569+09:00  INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:05:41.330+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:05:41.332+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:05:41.385+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:05:41.424+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:05:41.424+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:05:41.436+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:05:41.449+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:05:41.450+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:05:41.463+09:00  INFO 19504 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:05:42.946+09:00  INFO 19504 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:05:42.997+09:00  INFO 19504 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:05:42.998+09:00  INFO 19504 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:05:43.205+09:00  INFO 19504 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:05:43.207+09:00  INFO 19504 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3559 ms
-2025-08-01T14:05:43.810+09:00  INFO 19504 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:05:44.019+09:00  INFO 19504 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:05:44.054+09:00  INFO 19504 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:05:44.528+09:00  INFO 19504 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:05:44.565+09:00  INFO 19504 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:05:44.751+09:00  INFO 19504 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:05:44.753+09:00  INFO 19504 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:05:44.776+09:00  WARN 19504 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:05:44.800+09:00  INFO 19504 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:05:45.116+09:00  INFO 19504 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:05:45.123+09:00  INFO 19504 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:05:46.649+09:00  WARN 19504 --- [booking] [main] 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-08-01T14:05:46.861+09:00  INFO 19504 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:05:48.362+09:00  INFO 19504 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@4c941d19, com.mongodb.Jep395RecordCodecProvider@5248c05a, com.mongodb.KotlinCodecProvider@151f1734]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:05:48.366+09:00  INFO 19504 --- [booking] [cluster-ClusterId{value='688c4b2c0dc1a44ec2a5a5e0', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:05:48.981+09:00  INFO 19504 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:05:49.171+09:00  WARN 19504 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 59ba44ea-4ab1-4b85-a0dc-3a867e307402
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:05:49.179+09:00  INFO 19504 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:05:49.376+09:00  INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:05:49.380+09:00  INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@64547a83]]
-2025-08-01T14:05:49.381+09:00  INFO 19504 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:05:49.417+09:00  INFO 19504 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:05:50.098+09:00  INFO 19504 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.311 seconds (process running for 11.844)
-2025-08-01T14:06:49.384+09:00  INFO 19504 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:06:57.191+09:00  INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 17300 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:06:57.194+09:00  INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:06:58.477+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:06:58.479+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:06:58.524+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:06:58.560+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:06:58.562+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:06:58.566+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:06:58.584+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:06:58.585+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:06:58.596+09:00  INFO 17300 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:06:59.836+09:00  INFO 17300 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:06:59.883+09:00  INFO 17300 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:06:59.883+09:00  INFO 17300 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:07:00.037+09:00  INFO 17300 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:07:00.040+09:00  INFO 17300 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2788 ms
-2025-08-01T14:07:00.578+09:00  INFO 17300 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:07:00.698+09:00  INFO 17300 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:07:00.724+09:00  INFO 17300 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:07:01.133+09:00  INFO 17300 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:07:01.164+09:00  INFO 17300 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:07:01.362+09:00  INFO 17300 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:73ba27b4-f19d-459c-a234-2e5a3c3a76f0 user=SA
-2025-08-01T14:07:01.362+09:00  INFO 17300 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:07:01.387+09:00  WARN 17300 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:07:01.439+09:00  INFO 17300 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:07:01.834+09:00  INFO 17300 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:07:01.847+09:00  INFO 17300 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:07:03.094+09:00  WARN 17300 --- [booking] [main] 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-08-01T14:07:03.362+09:00  INFO 17300 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:07:04.731+09:00  INFO 17300 --- [booking] [cluster-ClusterId{value='688c4b78b902eaa57ce45511', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:07:04.735+09:00  INFO 17300 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@6f12fca0, com.mongodb.Jep395RecordCodecProvider@12c30824, com.mongodb.KotlinCodecProvider@7d0e43d6]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:07:05.279+09:00  INFO 17300 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:73ba27b4-f19d-459c-a234-2e5a3c3a76f0'
-2025-08-01T14:07:05.507+09:00  WARN 17300 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 7c164a8c-fe86-4a2e-a864-77b14b87c19e
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:07:05.521+09:00  INFO 17300 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:07:05.642+09:00  INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:07:05.642+09:00  INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3dfe520]]
-2025-08-01T14:07:05.642+09:00  INFO 17300 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:07:05.658+09:00  INFO 17300 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:07:06.321+09:00  INFO 17300 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 9.798 seconds (process running for 10.233)
-2025-08-01T14:07:24.429+09:00  INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 23496 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:07:24.429+09:00  INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:07:25.647+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:07:25.648+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:07:25.679+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:07:25.709+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:07:25.709+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:07:25.709+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:07:25.726+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:07:25.726+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:07:25.740+09:00  INFO 23496 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:07:26.904+09:00  INFO 23496 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:07:26.928+09:00  INFO 23496 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:07:26.928+09:00  INFO 23496 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:07:27.028+09:00  INFO 23496 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:07:27.028+09:00  INFO 23496 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2536 ms
-2025-08-01T14:07:27.378+09:00  INFO 23496 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:07:27.686+09:00  INFO 23496 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:34fc08bb-d72b-4bfa-bcb9-82651b1ee75e user=SA
-2025-08-01T14:07:27.686+09:00  INFO 23496 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:07:27.781+09:00  INFO 23496 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:07:27.839+09:00  INFO 23496 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:07:27.874+09:00  INFO 23496 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:07:28.170+09:00  INFO 23496 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:07:28.255+09:00  INFO 23496 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:07:28.588+09:00  INFO 23496 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:07:28.594+09:00  INFO 23496 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:07:29.631+09:00  WARN 23496 --- [booking] [main] 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-08-01T14:07:29.892+09:00  INFO 23496 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:07:30.915+09:00  INFO 23496 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@7d836c4a, com.mongodb.Jep395RecordCodecProvider@485547ac, com.mongodb.KotlinCodecProvider@6d77d269]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:07:30.915+09:00  INFO 23496 --- [booking] [cluster-ClusterId{value='688c4b92907b81b0f4eecee6', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:07:31.615+09:00  WARN 23496 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 5f35c8ee-aad4-41c8-a0aa-abb14fdcb77f
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:07:31.624+09:00  INFO 23496 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:07:31.791+09:00  INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:07:31.791+09:00  INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2c39c520]]
-2025-08-01T14:07:31.791+09:00  INFO 23496 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:07:31.814+09:00  INFO 23496 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:07:32.413+09:00  INFO 23496 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.604 seconds (process running for 9.06)
-2025-08-01T14:08:31.799+09:00  INFO 23496 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:13:18.339+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:13:18.339+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:13:18.366+09:00  WARN 23496 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:13:18.366+09:00  WARN 23496 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:13:27.429+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:13:27.429+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:13:27.431+09:00  WARN 23496 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:13:27.432+09:00  WARN 23496 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:13:35.641+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-11] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:13:35.641+09:00  INFO 23496 --- [booking] [lettuce-eventExecutorLoop-1-12] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:13:35.653+09:00  INFO 23496 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:13:35.653+09:00  INFO 23496 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:13:54.382+09:00  INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11744 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:13:54.384+09:00  INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:13:55.958+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:13:55.960+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:13:56.003+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:13:56.036+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:13:56.037+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:13:56.053+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 12 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:13:56.074+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:13:56.077+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:13:56.088+09:00  INFO 11744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:13:57.606+09:00  INFO 11744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:13:57.669+09:00  INFO 11744 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:13:57.670+09:00  INFO 11744 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:13:57.852+09:00  INFO 11744 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:13:57.853+09:00  INFO 11744 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3384 ms
-2025-08-01T14:13:58.529+09:00  INFO 11744 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:13:58.628+09:00  INFO 11744 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:13:58.686+09:00  INFO 11744 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:13:59.164+09:00  INFO 11744 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:13:59.210+09:00  INFO 11744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:13:59.418+09:00  INFO 11744 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:13:59.420+09:00  INFO 11744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:13:59.441+09:00  WARN 11744 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:13:59.463+09:00  INFO 11744 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:13:59.771+09:00  INFO 11744 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:13:59.781+09:00  INFO 11744 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:14:01.154+09:00  WARN 11744 --- [booking] [main] 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-08-01T14:14:01.392+09:00  INFO 11744 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:14:02.417+09:00  INFO 11744 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3751baf6, com.mongodb.Jep395RecordCodecProvider@27e656e6, com.mongodb.KotlinCodecProvider@3cfab56d]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:14:02.417+09:00  INFO 11744 --- [booking] [cluster-ClusterId{value='688c4d1a696e071f70786fe0', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:14:02.775+09:00  INFO 11744 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:14:02.933+09:00  WARN 11744 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 439c57cd-8c43-4ffc-b923-66bd66f7c96a
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:14:02.946+09:00  INFO 11744 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:14:03.111+09:00  INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:14:03.111+09:00  INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1e8c741c]]
-2025-08-01T14:14:03.111+09:00  INFO 11744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:14:03.150+09:00  INFO 11744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:14:03.841+09:00  INFO 11744 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.287 seconds (process running for 10.818)
-2025-08-01T14:27:15.596+09:00  WARN 11744 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=13m16s74ms892µs800ns).
-2025-08-01T14:27:49.186+09:00  INFO 11744 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:28:01.498+09:00  INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:28:01.498+09:00  INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:28:02.867+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:28:02.871+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:28:02.914+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:28:02.949+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:28:02.949+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:28:02.949+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:28:02.977+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:28:02.977+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:28:02.982+09:00  INFO 11180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:28:04.305+09:00  INFO 11180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:28:04.359+09:00  INFO 11180 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:28:04.359+09:00  INFO 11180 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:28:04.510+09:00  INFO 11180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:28:04.510+09:00  INFO 11180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2948 ms
-2025-08-01T14:28:05.144+09:00  INFO 11180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:28:05.229+09:00  INFO 11180 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:28:05.265+09:00  INFO 11180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:28:05.616+09:00  INFO 11180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:28:05.646+09:00  INFO 11180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:28:05.844+09:00  INFO 11180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:28:05.844+09:00  INFO 11180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:28:05.877+09:00  WARN 11180 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:28:05.892+09:00  INFO 11180 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:28:06.208+09:00  INFO 11180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:28:06.208+09:00  INFO 11180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:28:07.554+09:00  WARN 11180 --- [booking] [main] 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-08-01T14:28:07.825+09:00  INFO 11180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:28:08.967+09:00  INFO 11180 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@18d09283, com.mongodb.Jep395RecordCodecProvider@751b901a, com.mongodb.KotlinCodecProvider@6672b0ea]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:28:08.967+09:00  INFO 11180 --- [booking] [cluster-ClusterId{value='688c50689a9964e7cf9cbe48', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:28:09.616+09:00  INFO 11180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:28:09.847+09:00  WARN 11180 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 108ce33e-ed45-4adc-a380-4e3915cede90
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:28:09.872+09:00  INFO 11180 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:28:10.080+09:00  INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:28:10.095+09:00  INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@e417628]]
-2025-08-01T14:28:10.095+09:00  INFO 11180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:28:10.130+09:00  INFO 11180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:28:10.825+09:00  INFO 11180 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 9.999 seconds (process running for 10.478)
-2025-08-01T14:29:10.105+09:00  INFO 11180 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:32:56.853+09:00  INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 8236 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:32:56.858+09:00  INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:32:58.106+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:32:58.106+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:32:58.138+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:32:58.172+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:32:58.172+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:32:58.172+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:32:58.192+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:32:58.192+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:32:58.207+09:00  INFO 8236 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:32:59.362+09:00  INFO 8236 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:32:59.400+09:00  INFO 8236 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:32:59.402+09:00  INFO 8236 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:32:59.536+09:00  INFO 8236 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:32:59.537+09:00  INFO 8236 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2606 ms
-2025-08-01T14:33:00.070+09:00  INFO 8236 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:33:00.195+09:00  INFO 8236 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:33:00.262+09:00  INFO 8236 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:33:00.570+09:00  INFO 8236 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:33:00.602+09:00  INFO 8236 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:33:00.797+09:00  INFO 8236 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:33:00.801+09:00  INFO 8236 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:33:00.825+09:00  WARN 8236 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:33:00.849+09:00  INFO 8236 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:33:01.200+09:00  INFO 8236 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:33:01.206+09:00  INFO 8236 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:33:02.712+09:00  WARN 8236 --- [booking] [main] 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-08-01T14:33:02.952+09:00  INFO 8236 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:33:03.846+09:00  INFO 8236 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@601e7c97, com.mongodb.Jep395RecordCodecProvider@c8ed958, com.mongodb.KotlinCodecProvider@18d09283]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:33:03.845+09:00  INFO 8236 --- [booking] [cluster-ClusterId{value='688c518fbb12843aa17620d2', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:33:04.800+09:00  INFO 8236 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:33:05.211+09:00  WARN 8236 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 00a3577a-77dc-4619-bb25-d23d17d624e0
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:33:05.232+09:00  INFO 8236 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:33:05.576+09:00  INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:33:05.583+09:00  INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@39329d81]]
-2025-08-01T14:33:05.585+09:00  INFO 8236 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:33:05.639+09:00  INFO 8236 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:33:06.913+09:00  INFO 8236 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.704 seconds (process running for 11.168)
-2025-08-01T14:34:05.579+09:00  INFO 8236 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:38:43.198+09:00  INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 22896 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:38:43.198+09:00  INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:38:44.438+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:38:44.438+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:38:44.493+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 33 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:38:44.530+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:38:44.530+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:38:44.539+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:38:44.552+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:38:44.552+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:38:44.554+09:00  INFO 22896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:38:45.786+09:00  INFO 22896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:38:45.835+09:00  INFO 22896 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:38:45.835+09:00  INFO 22896 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:38:45.954+09:00  INFO 22896 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:38:45.957+09:00  INFO 22896 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2688 ms
-2025-08-01T14:38:46.370+09:00  INFO 22896 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:38:46.449+09:00  INFO 22896 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:38:46.492+09:00  INFO 22896 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:38:46.906+09:00  INFO 22896 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:38:46.937+09:00  INFO 22896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:38:47.128+09:00  INFO 22896 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:38:47.128+09:00  INFO 22896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:38:47.172+09:00  WARN 22896 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:38:47.191+09:00  INFO 22896 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:38:47.633+09:00  INFO 22896 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:38:47.637+09:00  INFO 22896 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:38:48.778+09:00  WARN 22896 --- [booking] [main] 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-08-01T14:38:49.005+09:00  INFO 22896 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:38:49.919+09:00  INFO 22896 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@3cfab56d, com.mongodb.Jep395RecordCodecProvider@6b6fde93, com.mongodb.KotlinCodecProvider@51d34f02]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:38:49.926+09:00  INFO 22896 --- [booking] [cluster-ClusterId{value='688c52e92e94edfb65338ce2', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:38:50.409+09:00  INFO 22896 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:38:50.599+09:00  WARN 22896 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 8d7ba178-efe1-4dd9-96d3-2063903f0fe1
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:38:50.599+09:00  INFO 22896 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:38:50.853+09:00  INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:38:50.853+09:00  INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@6db64abf]]
-2025-08-01T14:38:50.869+09:00  INFO 22896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:38:50.917+09:00  INFO 22896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:38:51.654+09:00  INFO 22896 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 9.106 seconds (process running for 9.517)
-2025-08-01T14:43:52.665+09:00  INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 19076 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:43:52.665+09:00  INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:43:53.883+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:43:53.886+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:43:53.915+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:43:53.963+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:43:53.963+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:43:53.967+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:43:53.978+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:43:53.978+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:43:53.994+09:00  INFO 19076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:43:55.201+09:00  INFO 19076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:43:55.249+09:00  INFO 19076 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:43:55.249+09:00  INFO 19076 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:43:55.393+09:00  INFO 19076 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:43:55.393+09:00  INFO 19076 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2671 ms
-2025-08-01T14:43:55.946+09:00  INFO 19076 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:43:56.025+09:00  INFO 19076 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:43:56.072+09:00  INFO 19076 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:43:56.406+09:00  INFO 19076 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:43:56.422+09:00  INFO 19076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:43:56.646+09:00  INFO 19076 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:43:56.646+09:00  INFO 19076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:43:56.678+09:00  WARN 19076 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:43:56.742+09:00  INFO 19076 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:43:57.127+09:00  INFO 19076 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:43:57.127+09:00  INFO 19076 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:43:58.305+09:00  WARN 19076 --- [booking] [main] 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-08-01T14:43:58.541+09:00  INFO 19076 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:43:59.320+09:00  INFO 19076 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@6672b0ea, com.mongodb.Jep395RecordCodecProvider@1ccce165, com.mongodb.KotlinCodecProvider@943cf5]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:43:59.324+09:00  INFO 19076 --- [booking] [cluster-ClusterId{value='688c541fe05cfa1e7119ca0f', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:43:59.819+09:00  INFO 19076 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:44:00.117+09:00  WARN 19076 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 33385c2b-2f3e-4cef-8ae9-eb008d4728ca
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:44:00.132+09:00  INFO 19076 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:44:00.307+09:00  INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:44:00.307+09:00  INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@592fbd8]]
-2025-08-01T14:44:00.307+09:00  INFO 19076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:44:00.322+09:00  INFO 19076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:44:00.921+09:00  INFO 19076 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.9 seconds (process running for 9.359)
-2025-08-01T14:44:42.359+09:00  INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28240 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:44:42.359+09:00  INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:44:43.473+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:44:43.476+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:44:43.507+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:44:43.540+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:44:43.540+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:44:43.551+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:44:43.567+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:44:43.570+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:44:43.572+09:00  INFO 28240 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:44:44.801+09:00  INFO 28240 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:44:44.827+09:00  INFO 28240 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:44:44.830+09:00  INFO 28240 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:44:44.925+09:00  INFO 28240 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:44:44.938+09:00  INFO 28240 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2500 ms
-2025-08-01T14:44:45.444+09:00  INFO 28240 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:44:45.564+09:00  INFO 28240 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:44:45.628+09:00  INFO 28240 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:44:45.979+09:00  INFO 28240 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:44:46.021+09:00  INFO 28240 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:44:46.212+09:00  INFO 28240 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:44:46.212+09:00  INFO 28240 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:44:46.247+09:00  WARN 28240 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:44:46.281+09:00  INFO 28240 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:44:46.664+09:00  INFO 28240 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:44:46.664+09:00  INFO 28240 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:44:47.922+09:00  WARN 28240 --- [booking] [main] 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-08-01T14:44:48.187+09:00  INFO 28240 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:44:49.116+09:00  INFO 28240 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@943cf5, com.mongodb.Jep395RecordCodecProvider@2926f7bd, com.mongodb.KotlinCodecProvider@5a20f793]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:44:49.116+09:00  INFO 28240 --- [booking] [cluster-ClusterId{value='688c5451064128d1307a6279', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:44:49.567+09:00  INFO 28240 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:44:49.763+09:00  WARN 28240 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 9e829b29-2999-4c78-a1cc-0d83b7ef0556
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:44:49.773+09:00  INFO 28240 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:44:49.920+09:00  INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:44:49.920+09:00  INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42516ce2]]
-2025-08-01T14:44:49.920+09:00  INFO 28240 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:44:49.935+09:00  INFO 28240 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:44:50.452+09:00  INFO 28240 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.711 seconds (process running for 9.146)
-2025-08-01T14:45:49.946+09:00  INFO 28240 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:47:50.871+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:47:50.871+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:47:50.904+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:47:50.905+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:47:59.947+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:47:59.947+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:47:59.948+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:47:59.948+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:08.146+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-12] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:08.146+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-11] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:08.148+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:08.148+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:24.545+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:24.545+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:24.560+09:00  INFO 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:48:24.562+09:00  INFO 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:48:31.851+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-15] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:48:31.851+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-16] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/127.0.0.1:6379
-2025-08-01T14:48:31.858+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:48:31.859+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-1] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection closed prematurely
-
-io.lettuce.core.RedisConnectionException: Connection closed prematurely
-	at io.lettuce.core.protocol.RedisHandshakeHandler.channelInactive(RedisHandshakeHandler.java:76) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.ChannelInboundHandlerAdapter.channelInactive(ChannelInboundHandlerAdapter.java:81) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.lettuce.core.ChannelGroupListener.channelInactive(ChannelGroupListener.java:54) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:303) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:274) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1352) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:301) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:281) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:850) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.AbstractChannel$AbstractUnsafe$7.run(AbstractChannel.java:811) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:566) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T14:48:40.956+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-7] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:40.956+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-8] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:40.957+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-9] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:40.957+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-10] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:49.246+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:49.246+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:48:49.248+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:48:49.248+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:49:05.646+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:49:05.646+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:49:05.646+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:49:05.646+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:49:35.746+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-15] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:49:35.746+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-16] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:49:35.748+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:49:35.748+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:50:05.852+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:50:05.852+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:50:05.852+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-1] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:50:05.852+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-2] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:50:35.955+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:50:35.955+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:50:35.971+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:50:35.971+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-3] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:51:06.061+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:51:06.061+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:51:06.065+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-6] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:51:06.065+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-5] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:51:36.160+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:51:36.160+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-7] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:51:36.160+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:51:36.160+09:00  WARN 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:52:06.246+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-9] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:52:06.246+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-10] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:52:06.249+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-9] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:52:06.249+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-10] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:52:36.353+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-14] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:52:36.353+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-13] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:52:36.355+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-11] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:52:36.355+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-12] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:53:06.447+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:53:06.447+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-2] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:53:06.447+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-14] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:53:06.447+09:00  WARN 28240 --- [booking] [lettuce-nioEventLoop-4-13] i.l.core.protocol.ConnectionWatchdog     : Cannot reconnect to [localhost/:6379]: Connection refused: getsockopt: localhost/127.0.0.1:6379
-2025-08-01T14:53:36.556+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-5] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:53:36.556+09:00  INFO 28240 --- [booking] [lettuce-eventExecutorLoop-1-6] i.l.core.protocol.ConnectionWatchdog     : Reconnecting, last destination was localhost/:6379
-2025-08-01T14:53:36.562+09:00  INFO 28240 --- [booking] [lettuce-nioEventLoop-4-15] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:53:36.562+09:00  INFO 28240 --- [booking] [lettuce-nioEventLoop-4-16] i.l.core.protocol.ReconnectionHandler    : Reconnected to localhost/:6379
-2025-08-01T14:53:46.281+09:00  INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 20112 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:53:46.281+09:00  INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:53:47.406+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:53:47.410+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:53:47.468+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:53:47.499+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:53:47.499+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:53:47.514+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:53:47.530+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:53:47.530+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:53:47.546+09:00  INFO 20112 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:53:48.807+09:00  INFO 20112 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:53:48.849+09:00  INFO 20112 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:53:48.849+09:00  INFO 20112 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:53:48.952+09:00  INFO 20112 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:53:48.952+09:00  INFO 20112 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2622 ms
-2025-08-01T14:53:49.438+09:00  INFO 20112 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:53:49.505+09:00  INFO 20112 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:53:49.549+09:00  INFO 20112 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:53:49.868+09:00  INFO 20112 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:53:49.899+09:00  INFO 20112 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:53:50.119+09:00  INFO 20112 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:53:50.123+09:00  INFO 20112 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:53:50.154+09:00  WARN 20112 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:53:50.202+09:00  INFO 20112 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:53:50.625+09:00  INFO 20112 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:53:50.632+09:00  INFO 20112 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:53:51.809+09:00  WARN 20112 --- [booking] [main] 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-08-01T14:53:52.093+09:00  INFO 20112 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:53:53.178+09:00  INFO 20112 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@18d09283, com.mongodb.Jep395RecordCodecProvider@751b901a, com.mongodb.KotlinCodecProvider@6672b0ea]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:53:53.178+09:00  INFO 20112 --- [booking] [cluster-ClusterId{value='688c5671cc4022ccb0cb0709', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:53:53.604+09:00  INFO 20112 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:53:53.784+09:00  WARN 20112 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 83845f15-440e-455c-9e86-fb14ddc85507
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:53:53.784+09:00  INFO 20112 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:53:53.924+09:00  INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:53:53.924+09:00  INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@123a21ad]]
-2025-08-01T14:53:53.924+09:00  INFO 20112 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:53:53.943+09:00  INFO 20112 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:53:54.550+09:00  INFO 20112 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.908 seconds (process running for 9.299)
-2025-08-01T14:55:41.704+09:00  INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14268 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:55:41.704+09:00  INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:55:43.170+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:55:43.170+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:55:43.218+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:55:43.240+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:55:43.240+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
-2025-08-01T14:55:43.259+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 MongoDB repository interfaces.
-2025-08-01T14:55:43.272+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:55:43.280+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:55:43.287+09:00  INFO 14268 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:55:44.606+09:00  INFO 14268 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:55:44.624+09:00  INFO 14268 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:55:44.631+09:00  INFO 14268 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:55:44.745+09:00  INFO 14268 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:55:44.745+09:00  INFO 14268 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2976 ms
-2025-08-01T14:55:45.177+09:00  INFO 14268 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:55:45.221+09:00  INFO 14268 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:55:45.269+09:00  INFO 14268 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:55:45.621+09:00  INFO 14268 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:55:45.663+09:00  INFO 14268 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:55:45.891+09:00  INFO 14268 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:55:45.891+09:00  INFO 14268 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:55:45.919+09:00  WARN 14268 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:55:45.953+09:00  INFO 14268 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:55:46.324+09:00  INFO 14268 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:55:46.330+09:00  INFO 14268 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:55:47.352+09:00  WARN 14268 --- [booking] [main] 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-08-01T14:55:47.624+09:00  INFO 14268 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T14:55:48.564+09:00  INFO 14268 --- [booking] [main] org.mongodb.driver.client                : MongoClient with metadata {"driver": {"name": "mongo-java-driver|sync|spring-boot", "version": "5.5.1"}, "os": {"type": "Windows", "name": "Windows 11", "architecture": "amd64", "version": "10.0"}, "platform": "Java/OpenLogic/17.0.14+7-adhoc..jdk17u"} created with settings MongoClientSettings{readPreference=primary, writeConcern=WriteConcern{w=null, wTimeout=null ms, journal=null}, retryWrites=true, retryReads=true, readConcern=ReadConcern{level=null}, credential=null, transportSettings=null, commandListeners=[], codecRegistry=ProvidersCodecRegistry{codecProviders=[ValueCodecProvider{}, BsonValueCodecProvider{}, DBRefCodecProvider{}, DBObjectCodecProvider{}, DocumentCodecProvider{}, CollectionCodecProvider{}, IterableCodecProvider{}, MapCodecProvider{}, GeoJsonCodecProvider{}, GridFSFileCodecProvider{}, Jsr310CodecProvider{}, JsonObjectCodecProvider{}, BsonCodecProvider{}, EnumCodecProvider{}, com.mongodb.client.model.mql.ExpressionCodecProvider@1e37cb10, com.mongodb.Jep395RecordCodecProvider@1659d7d, com.mongodb.KotlinCodecProvider@6892d403]}, loggerSettings=LoggerSettings{maxDocumentLength=1000}, clusterSettings={hosts=[localhost:27017], srvServiceName=mongodb, mode=SINGLE, requiredClusterType=UNKNOWN, requiredReplicaSetName='null', serverSelector='null', clusterListeners='[]', serverSelectionTimeout='30000 ms', localThreshold='15 ms'}, socketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=0, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, heartbeatSocketSettings=SocketSettings{connectTimeoutMS=10000, readTimeoutMS=10000, receiveBufferSize=0, proxySettings=ProxySettings{host=null, port=null, username=null, password=null}}, connectionPoolSettings=ConnectionPoolSettings{maxSize=100, minSize=0, maxWaitTimeMS=120000, maxConnectionLifeTimeMS=0, maxConnectionIdleTimeMS=0, maintenanceInitialDelayMS=0, maintenanceFrequencyMS=60000, connectionPoolListeners=[], maxConnecting=2}, serverSettings=ServerSettings{heartbeatFrequencyMS=10000, minHeartbeatFrequencyMS=500, serverMonitoringMode=AUTO, serverListeners='[]', serverMonitorListeners='[]'}, sslSettings=SslSettings{enabled=false, invalidHostNameAllowed=false, context=null}, applicationName='null', compressorList=[], uuidRepresentation=JAVA_LEGACY, serverApi=null, autoEncryptionSettings=null, dnsClient=null, inetAddressResolver=null, contextProvider=null, timeoutMS=null}
-2025-08-01T14:55:48.570+09:00  INFO 14268 --- [booking] [cluster-ClusterId{value='688c56e4d98e2d7d630ef116', description='null'}-localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017
-
-com.mongodb.MongoSocketOpenException: Exception opening socket
-	at com.mongodb.internal.connection.SocketStream.lambda$open$0(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at java.base/java.util.Optional.orElseThrow(Optional.java:403) ~[na:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:85) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:233) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.lookupServerDescription(DefaultServerMonitor.java:219) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitor.run(DefaultServerMonitor.java:176) ~[mongodb-driver-core-5.5.1.jar:na]
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) ~[na:na]
-	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) ~[na:na]
-	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[na:na]
-	at java.base/java.net.Socket.connect(Socket.java:633) ~[na:na]
-	at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:76) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:104) ~[mongodb-driver-core-5.5.1.jar:na]
-	at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:79) ~[mongodb-driver-core-5.5.1.jar:na]
-	... 3 common frames omitted
-
-2025-08-01T14:55:49.011+09:00  INFO 14268 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T14:55:49.247+09:00  WARN 14268 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 82db3859-721c-41b9-ba64-f19d5a9c5f71
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T14:55:49.255+09:00  INFO 14268 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T14:55:49.437+09:00  INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T14:55:49.437+09:00  INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@123a21ad]]
-2025-08-01T14:55:49.437+09:00  INFO 14268 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T14:55:49.467+09:00  INFO 14268 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T14:55:50.150+09:00  INFO 14268 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 9.168 seconds (process running for 9.644)
-2025-08-01T14:56:49.435+09:00  INFO 14268 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T14:59:52.289+09:00  INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26176 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T14:59:52.289+09:00  INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T14:59:53.882+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:59:53.888+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T14:59:53.921+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
-2025-08-01T14:59:53.937+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T14:59:53.946+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T14:59:53.958+09:00  INFO 26176 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T14:59:55.627+09:00  INFO 26176 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T14:59:55.663+09:00  INFO 26176 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T14:59:55.665+09:00  INFO 26176 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T14:59:55.823+09:00  INFO 26176 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T14:59:55.823+09:00  INFO 26176 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3450 ms
-2025-08-01T14:59:56.409+09:00  INFO 26176 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T14:59:56.488+09:00  INFO 26176 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T14:59:56.539+09:00  INFO 26176 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T14:59:57.071+09:00  INFO 26176 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T14:59:57.107+09:00  INFO 26176 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T14:59:57.292+09:00  INFO 26176 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T14:59:57.292+09:00  INFO 26176 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T14:59:57.320+09:00  WARN 26176 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T14:59:57.344+09:00  INFO 26176 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T14:59:57.742+09:00  INFO 26176 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T14:59:57.742+09:00  INFO 26176 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T14:59:58.935+09:00  WARN 26176 --- [booking] [main] 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-08-01T14:59:59.242+09:00  INFO 26176 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T15:00:00.545+09:00  INFO 26176 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T15:00:00.826+09:00  WARN 26176 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: 36ca8b44-427d-4e99-9649-35d14ea814dd
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T15:00:00.841+09:00  INFO 26176 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T15:00:01.001+09:00  INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T15:00:01.003+09:00  INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1fb379e4]]
-2025-08-01T15:00:01.005+09:00  INFO 26176 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T15:00:01.032+09:00  INFO 26176 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T15:00:01.651+09:00  INFO 26176 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.18 seconds (process running for 10.708)
-2025-08-01T15:01:01.012+09:00  INFO 26176 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T15:01:03.585+09:00  INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T15:01:03.585+09:00  INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T15:01:03.588+09:00  INFO 26176 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T15:35:09.656+09:00  INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T15:35:09.660+09:00  INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T15:35:10.916+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:35:10.920+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T15:35:10.960+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
-2025-08-01T15:35:10.978+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:35:10.980+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T15:35:10.995+09:00  INFO 1180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 2 ms. Found 0 Redis repository interfaces.
-2025-08-01T15:35:12.126+09:00  INFO 1180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T15:35:12.149+09:00  INFO 1180 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T15:35:12.150+09:00  INFO 1180 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T15:35:12.263+09:00  INFO 1180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T15:35:12.264+09:00  INFO 1180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2544 ms
-2025-08-01T15:35:12.636+09:00  INFO 1180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T15:35:12.713+09:00  INFO 1180 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T15:35:12.745+09:00  INFO 1180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T15:35:13.177+09:00  INFO 1180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T15:35:13.209+09:00  INFO 1180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T15:35:13.366+09:00  INFO 1180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T15:35:13.368+09:00  INFO 1180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T15:35:13.389+09:00  WARN 1180 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T15:35:13.411+09:00  INFO 1180 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T15:35:13.764+09:00  INFO 1180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T15:35:13.770+09:00  INFO 1180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T15:35:14.700+09:00  WARN 1180 --- [booking] [main] 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-08-01T15:35:14.955+09:00  INFO 1180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T15:35:15.814+09:00  INFO 1180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T15:35:16.014+09:00  WARN 1180 --- [booking] [main] .s.s.UserDetailsServiceAutoConfiguration : 
-
-Using generated security password: d53b51b7-04ca-41e1-9e04-e213d1b0071a
-
-This generated password is for development use only. Your security configuration must be updated before running your application in production.
-
-2025-08-01T15:35:16.025+09:00  INFO 1180 --- [booking] [main] r$InitializeUserDetailsManagerConfigurer : Global AuthenticationManager configured with UserDetailsService bean with name inMemoryUserDetailsManager
-2025-08-01T15:35:16.185+09:00  INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T15:35:16.190+09:00  INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@67b1c3af]]
-2025-08-01T15:35:16.193+09:00  INFO 1180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T15:35:16.228+09:00  INFO 1180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T15:35:17.317+09:00  INFO 1180 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.297 seconds (process running for 8.74)
-2025-08-01T15:35:40.539+09:00  INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T15:35:40.539+09:00  INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T15:35:40.540+09:00  INFO 1180 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-01T15:36:16.197+09:00  INFO 1180 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T15:37:05.332+09:00  INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 12688 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T15:37:05.335+09:00  INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T15:37:06.357+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:37:06.358+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T15:37:06.384+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
-2025-08-01T15:37:06.405+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:37:06.408+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T15:37:06.422+09:00  INFO 12688 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T15:37:07.479+09:00  INFO 12688 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T15:37:07.502+09:00  INFO 12688 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T15:37:07.503+09:00  INFO 12688 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T15:37:07.591+09:00  INFO 12688 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T15:37:07.592+09:00  INFO 12688 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2198 ms
-2025-08-01T15:37:07.982+09:00  INFO 12688 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T15:37:08.064+09:00  INFO 12688 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T15:37:08.101+09:00  INFO 12688 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T15:37:08.419+09:00  INFO 12688 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T15:37:08.453+09:00  INFO 12688 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T15:37:08.620+09:00  INFO 12688 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T15:37:08.623+09:00  INFO 12688 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T15:37:08.651+09:00  WARN 12688 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T15:37:08.686+09:00  INFO 12688 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T15:37:09.048+09:00  INFO 12688 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T15:37:09.054+09:00  INFO 12688 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T15:37:10.206+09:00  WARN 12688 --- [booking] [main] 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-08-01T15:37:10.405+09:00  INFO 12688 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T15:37:11.191+09:00  INFO 12688 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T15:37:11.402+09:00  INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T15:37:11.404+09:00  INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@16e0afab]]
-2025-08-01T15:37:11.405+09:00  INFO 12688 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T15:37:11.431+09:00  INFO 12688 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T15:37:12.067+09:00  INFO 12688 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.349 seconds (process running for 7.744)
-2025-08-01T15:38:00.282+09:00  INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T15:38:00.283+09:00  INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T15:38:00.286+09:00  INFO 12688 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-01T15:38:11.410+09:00  INFO 12688 --- [booking] [MessageBroker-3] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 6, active threads = 1, queued tasks = 2, completed tasks = 3]
-2025-08-01T15:41:01.782+09:00  INFO 12688 --- [booking] [clientInboundChannel-10] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-01T15:47:35.632+09:00  INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 12076 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T15:47:35.636+09:00  INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T15:47:36.877+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:47:36.879+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T15:47:36.910+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-01T15:47:36.936+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T15:47:36.940+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T15:47:36.956+09:00  INFO 12076 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-01T15:47:38.019+09:00  INFO 12076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T15:47:38.044+09:00  INFO 12076 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T15:47:38.044+09:00  INFO 12076 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T15:47:38.134+09:00  INFO 12076 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T15:47:38.135+09:00  INFO 12076 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2440 ms
-2025-08-01T15:47:38.418+09:00  INFO 12076 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T15:47:38.490+09:00  INFO 12076 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T15:47:38.521+09:00  INFO 12076 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T15:47:38.921+09:00  INFO 12076 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T15:47:38.948+09:00  INFO 12076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T15:47:39.120+09:00  INFO 12076 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T15:47:39.122+09:00  INFO 12076 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T15:47:39.150+09:00  WARN 12076 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T15:47:39.189+09:00  INFO 12076 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T15:47:39.563+09:00  INFO 12076 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T15:47:39.574+09:00  INFO 12076 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T15:47:40.693+09:00  WARN 12076 --- [booking] [main] 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-08-01T15:47:40.874+09:00  INFO 12076 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T15:47:41.428+09:00  INFO 12076 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T15:47:41.613+09:00  INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T15:47:41.614+09:00  INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@260ccf0]]
-2025-08-01T15:47:41.615+09:00  INFO 12076 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T15:47:41.638+09:00  INFO 12076 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T15:47:42.183+09:00  INFO 12076 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.208 seconds (process running for 7.626)
-2025-08-01T15:47:56.436+09:00  INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T15:47:56.438+09:00  INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T15:47:56.440+09:00  INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-01T15:48:41.638+09:00  INFO 12076 --- [booking] [MessageBroker-3] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12]
-2025-08-01T15:52:16.958+09:00  INFO 12076 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.w.s.m.SubProtocolWebSocketHandler    : No messages received after 260311 ms. Closing WebSocketServerSockJsSession[id=kzq0vdqf].
-2025-08-01T15:52:21.753+09:00  INFO 12076 --- [booking] [clientInboundChannel-13] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-01T15:56:27.718+09:00  INFO 12076 --- [booking] [clientInboundChannel-34] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-01T16:05:35.293+09:00  INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18896 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T16:05:35.296+09:00  INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T16:05:36.544+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:05:36.547+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T16:05:36.579+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-01T16:05:36.606+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:05:36.608+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T16:05:36.630+09:00  INFO 18896 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T16:05:37.666+09:00  INFO 18896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T16:05:37.684+09:00  INFO 18896 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T16:05:37.685+09:00  INFO 18896 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T16:05:37.776+09:00  INFO 18896 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T16:05:37.777+09:00  INFO 18896 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2412 ms
-2025-08-01T16:05:38.139+09:00  INFO 18896 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T16:05:38.225+09:00  INFO 18896 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T16:05:38.255+09:00  INFO 18896 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T16:05:38.832+09:00  INFO 18896 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T16:05:38.861+09:00  INFO 18896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T16:05:39.044+09:00  INFO 18896 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T16:05:39.048+09:00  INFO 18896 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T16:05:39.080+09:00  WARN 18896 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T16:05:39.120+09:00  INFO 18896 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T16:05:39.479+09:00  INFO 18896 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T16:05:39.484+09:00  INFO 18896 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T16:05:40.600+09:00  WARN 18896 --- [booking] [main] 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-08-01T16:05:40.812+09:00  INFO 18896 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T16:05:41.497+09:00  INFO 18896 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T16:05:41.740+09:00  INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T16:05:41.744+09:00  INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@58b30e3e]]
-2025-08-01T16:05:41.745+09:00  INFO 18896 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T16:05:41.768+09:00  INFO 18896 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T16:05:42.335+09:00  INFO 18896 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.729 seconds (process running for 8.194)
-2025-08-01T16:06:09.517+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6784 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T16:06:09.519+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T16:06:10.689+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:06:10.691+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T16:06:10.722+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
-2025-08-01T16:06:10.750+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:06:10.754+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T16:06:10.781+09:00  INFO 6784 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T16:06:11.851+09:00  INFO 6784 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T16:06:11.872+09:00  INFO 6784 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T16:06:11.872+09:00  INFO 6784 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T16:06:11.971+09:00  INFO 6784 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T16:06:11.973+09:00  INFO 6784 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2392 ms
-2025-08-01T16:06:12.398+09:00  INFO 6784 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T16:06:12.476+09:00  INFO 6784 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T16:06:12.512+09:00  INFO 6784 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T16:06:13.094+09:00  INFO 6784 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T16:06:13.123+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T16:06:13.282+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T16:06:13.285+09:00  INFO 6784 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T16:06:13.306+09:00  WARN 6784 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T16:06:13.334+09:00  INFO 6784 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T16:06:13.777+09:00  INFO 6784 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T16:06:13.788+09:00  INFO 6784 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T16:06:14.845+09:00  WARN 6784 --- [booking] [main] 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-08-01T16:06:15.153+09:00  INFO 6784 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T16:06:15.695+09:00  INFO 6784 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T16:06:15.955+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T16:06:15.956+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5f3c866c]]
-2025-08-01T16:06:15.958+09:00  INFO 6784 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T16:06:15.984+09:00  INFO 6784 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T16:06:16.623+09:00  INFO 6784 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.834 seconds (process running for 8.242)
-2025-08-01T16:06:26.853+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T16:06:26.854+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T16:06:26.857+09:00  INFO 6784 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-01T16:06:35.709+09:00  INFO 6784 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-01T16:07:15.972+09:00  INFO 6784 --- [booking] [MessageBroker-11] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12]
-2025-08-01T16:37:15.982+09:00  INFO 6784 --- [booking] [MessageBroker-12] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 517]
-2025-08-01T16:54:26.874+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 29372 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T16:54:26.877+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T16:54:27.915+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:54:27.916+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T16:54:27.948+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
-2025-08-01T16:54:27.968+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T16:54:27.969+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T16:54:27.985+09:00  INFO 29372 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T16:54:29.021+09:00  INFO 29372 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T16:54:29.047+09:00  INFO 29372 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T16:54:29.048+09:00  INFO 29372 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T16:54:29.153+09:00  INFO 29372 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T16:54:29.154+09:00  INFO 29372 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2225 ms
-2025-08-01T16:54:29.508+09:00  INFO 29372 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T16:54:29.571+09:00  INFO 29372 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T16:54:29.604+09:00  INFO 29372 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T16:54:30.120+09:00  INFO 29372 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T16:54:30.148+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T16:54:30.309+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T16:54:30.313+09:00  INFO 29372 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T16:54:30.336+09:00  WARN 29372 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T16:54:30.367+09:00  INFO 29372 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T16:54:30.784+09:00  INFO 29372 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T16:54:30.789+09:00  INFO 29372 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T16:54:31.795+09:00  WARN 29372 --- [booking] [main] 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-08-01T16:54:32.081+09:00  INFO 29372 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T16:54:33.202+09:00  INFO 29372 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T16:54:33.534+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T16:54:33.536+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@341c0dfc]]
-2025-08-01T16:54:33.538+09:00  INFO 29372 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T16:54:33.571+09:00  INFO 29372 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T16:54:34.142+09:00  INFO 29372 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.927 seconds (process running for 8.362)
-2025-08-01T16:54:38.822+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T16:54:38.822+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T16:54:38.826+09:00  INFO 29372 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
-2025-08-01T16:55:33.541+09:00  INFO 29372 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T17:00:45.121+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 13388 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T17:00:45.124+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T17:00:46.344+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:00:46.348+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T17:00:46.396+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
-2025-08-01T17:00:46.415+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:00:46.417+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T17:00:46.429+09:00  INFO 13388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T17:00:47.449+09:00  INFO 13388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T17:00:47.467+09:00  INFO 13388 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T17:00:47.468+09:00  INFO 13388 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T17:00:47.552+09:00  INFO 13388 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T17:00:47.552+09:00  INFO 13388 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2363 ms
-2025-08-01T17:00:47.955+09:00  INFO 13388 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T17:00:48.043+09:00  INFO 13388 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T17:00:48.073+09:00  INFO 13388 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T17:00:48.563+09:00  INFO 13388 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T17:00:48.594+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T17:00:48.749+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T17:00:48.751+09:00  INFO 13388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T17:00:48.773+09:00  WARN 13388 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T17:00:48.792+09:00  INFO 13388 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T17:00:49.097+09:00  INFO 13388 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T17:00:49.102+09:00  INFO 13388 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T17:00:50.155+09:00  WARN 13388 --- [booking] [main] 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-08-01T17:00:50.416+09:00  INFO 13388 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T17:00:51.127+09:00  INFO 13388 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T17:00:51.309+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T17:00:51.310+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7ec75228]]
-2025-08-01T17:00:51.311+09:00  INFO 13388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T17:00:51.333+09:00  INFO 13388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T17:00:51.923+09:00  INFO 13388 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.556 seconds (process running for 7.941)
-2025-08-01T17:01:51.341+09:00  INFO 13388 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T17:02:13.694+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T17:02:13.694+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T17:02:13.696+09:00  INFO 13388 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-01T17:05:16.464+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18560 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T17:05:16.470+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T17:05:17.662+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:05:17.665+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T17:05:17.716+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
-2025-08-01T17:05:17.735+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:05:17.736+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T17:05:17.751+09:00  INFO 18560 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T17:05:18.976+09:00  INFO 18560 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T17:05:18.998+09:00  INFO 18560 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T17:05:18.999+09:00  INFO 18560 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T17:05:19.090+09:00  INFO 18560 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T17:05:19.091+09:00  INFO 18560 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2546 ms
-2025-08-01T17:05:19.478+09:00  INFO 18560 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T17:05:19.629+09:00  INFO 18560 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T17:05:19.669+09:00  INFO 18560 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T17:05:20.141+09:00  INFO 18560 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T17:05:20.169+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T17:05:20.342+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T17:05:20.345+09:00  INFO 18560 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T17:05:20.367+09:00  WARN 18560 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T17:05:20.388+09:00  INFO 18560 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T17:05:20.727+09:00  INFO 18560 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T17:05:20.733+09:00  INFO 18560 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T17:05:21.894+09:00  WARN 18560 --- [booking] [main] 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-08-01T17:05:22.119+09:00  INFO 18560 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T17:05:22.733+09:00  INFO 18560 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T17:05:22.895+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T17:05:22.897+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
-2025-08-01T17:05:22.898+09:00  INFO 18560 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T17:05:22.919+09:00  INFO 18560 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T17:05:23.490+09:00  INFO 18560 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.763 seconds (process running for 8.168)
-2025-08-01T17:05:33.434+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T17:05:33.435+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T17:05:33.436+09:00  INFO 18560 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-01T17:06:22.913+09:00  INFO 18560 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T17:21:17.616+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28628 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T17:21:17.619+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T17:21:18.783+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:21:18.786+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T17:21:18.826+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 JPA repository interfaces.
-2025-08-01T17:21:18.843+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:21:18.844+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T17:21:18.859+09:00  INFO 28628 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T17:21:19.892+09:00  INFO 28628 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T17:21:19.911+09:00  INFO 28628 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T17:21:19.911+09:00  INFO 28628 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T17:21:19.991+09:00  INFO 28628 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T17:21:19.992+09:00  INFO 28628 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2314 ms
-2025-08-01T17:21:20.348+09:00  INFO 28628 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T17:21:20.483+09:00  INFO 28628 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T17:21:20.515+09:00  INFO 28628 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T17:21:21.021+09:00  INFO 28628 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T17:21:21.055+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T17:21:21.253+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T17:21:21.256+09:00  INFO 28628 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T17:21:21.282+09:00  WARN 28628 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T17:21:21.303+09:00  INFO 28628 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T17:21:21.624+09:00  INFO 28628 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T17:21:21.656+09:00  INFO 28628 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T17:21:22.740+09:00  WARN 28628 --- [booking] [main] 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-08-01T17:21:22.996+09:00  INFO 28628 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T17:21:23.669+09:00  INFO 28628 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T17:21:23.840+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T17:21:23.841+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7e0b68e5]]
-2025-08-01T17:21:23.842+09:00  INFO 28628 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T17:21:23.872+09:00  INFO 28628 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T17:21:24.457+09:00  INFO 28628 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.501 seconds (process running for 7.959)
-2025-08-01T17:21:34.865+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T17:21:34.865+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T17:21:34.867+09:00  INFO 28628 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-01T17:22:23.848+09:00  INFO 28628 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T17:36:24.712+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 22676 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T17:36:24.715+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T17:36:25.783+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:36:25.787+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T17:36:25.826+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces.
-2025-08-01T17:36:25.854+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T17:36:25.856+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T17:36:25.877+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T17:36:26.921+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T17:36:26.939+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T17:36:26.940+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T17:36:27.022+09:00  INFO 22676 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T17:36:27.023+09:00  INFO 22676 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2246 ms
-2025-08-01T17:36:27.465+09:00  INFO 22676 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T17:36:27.583+09:00  INFO 22676 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T17:36:27.616+09:00  INFO 22676 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T17:36:28.074+09:00  INFO 22676 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T17:36:28.101+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T17:36:28.274+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T17:36:28.278+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T17:36:28.306+09:00  WARN 22676 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T17:36:28.330+09:00  INFO 22676 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T17:36:28.674+09:00  INFO 22676 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T17:36:28.680+09:00  INFO 22676 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T17:36:29.956+09:00  WARN 22676 --- [booking] [main] 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-08-01T17:36:30.244+09:00  INFO 22676 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T17:36:30.933+09:00  INFO 22676 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T17:36:31.104+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T17:36:31.106+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4e53c6ef]]
-2025-08-01T17:36:31.107+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T17:36:31.130+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T17:36:32.014+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.994 seconds (process running for 8.397)
-2025-08-01T17:36:46.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T17:36:46.010+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T17:36:46.013+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-01T17:37:31.140+09:00  INFO 22676 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T19:57:08.250+09:00  INFO 18328 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18328 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T19:57:08.250+09:00  INFO 18328 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T19:57:10.285+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T19:57:10.292+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T19:57:10.341+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 22 ms. Found 0 JPA repository interfaces.
-2025-08-01T19:57:10.384+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T19:57:10.386+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T19:57:10.424+09:00  INFO 18328 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
-2025-08-01T19:57:11.986+09:00  INFO 18328 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T19:57:12.010+09:00  INFO 18328 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T19:57:12.010+09:00  INFO 18328 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T19:57:12.174+09:00  INFO 18328 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T19:57:12.174+09:00  INFO 18328 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3832 ms
-2025-08-01T19:57:13.120+09:00  INFO 18328 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T19:57:13.266+09:00  INFO 18328 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T19:57:13.324+09:00  INFO 18328 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T19:57:13.903+09:00  INFO 18328 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T19:57:13.954+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T19:57:14.324+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T19:57:14.329+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T19:57:14.390+09:00  WARN 18328 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T19:57:14.440+09:00  INFO 18328 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T19:57:15.019+09:00  INFO 18328 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T19:57:15.025+09:00  INFO 18328 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T19:57:16.548+09:00  WARN 18328 --- [booking] [main] 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-08-01T19:57:17.069+09:00  INFO 18328 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T19:57:18.553+09:00  INFO 18328 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T19:57:18.914+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T19:57:18.922+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
-2025-08-01T19:57:18.922+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T19:57:18.967+09:00  INFO 18328 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T19:57:19.738+09:00  INFO 18328 --- [booking] [main] o.s.b.w.e.tomcat.GracefulShutdown        : Commencing graceful shutdown. Waiting for active requests to complete
-2025-08-01T19:57:19.948+09:00  INFO 18328 --- [booking] [tomcat-shutdown] o.s.b.w.e.tomcat.GracefulShutdown        : Graceful shutdown complete
-2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
-2025-08-01T19:57:19.956+09:00  INFO 18328 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T19:57:19.983+09:00  WARN 18328 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
-2025-08-01T19:57:19.992+09:00  INFO 18328 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T19:57:20.000+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T19:57:20.008+09:00  INFO 18328 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T19:57:20.035+09:00  INFO 18328 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T19:57:20.076+09:00 ERROR 18328 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
-
-org.springframework.context.ApplicationContextException: Failed to start bean 'redisMessageListenerContainer'
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:408) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586) ~[spring-context-6.2.9.jar:6.2.9]
-	at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
-	at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1006) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:630) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
-	at com.mnms.booking.BookingApplication.main(BookingApplication.java:11) ~[main/:na]
-Caused by: org.springframework.data.redis.listener.adapter.RedisListenerExecutionFailedException: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:383) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.start(RedisMessageListenerContainer.java:361) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405) ~[spring-context-6.2.9.jar:6.2.9]
-	... 14 common frames omitted
-Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1866) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1797) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1594) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1574) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1535) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1571) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:1257) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:1063) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.lambda$initialize$0(RedisMessageListenerContainer.java:1241) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.doInLock(RedisMessageListenerContainer.java:1455) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer$Subscriber.initialize(RedisMessageListenerContainer.java:1235) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.doSubscribe(RedisMessageListenerContainer.java:428) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:404) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.listener.RedisMessageListenerContainer.lazyListen(RedisMessageListenerContainer.java:374) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 16 common frames omitted
-Caused by: org.springframework.data.redis.connection.PoolException: Could not get a resource from the pool
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:118) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1795) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 28 common frames omitted
-Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost/:6379
-	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:63) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:41) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.AbstractRedisClient.getConnection(AbstractRedisClient.java:354) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.RedisClient.connect(RedisClient.java:220) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.lambda$getConnection$1(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at java.base/java.util.Optional.orElseGet(Optional.java:364) ~[na:na]
-	at org.springframework.data.redis.connection.lettuce.StandaloneConnectionProvider.getConnection(StandaloneConnectionProvider.java:112) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.lambda$getConnection$0(LettucePoolingConnectionProvider.java:100) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:270) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.support.ConnectionPoolSupport$RedisPooledObjectFactory.create(ConnectionPoolSupport.java:257) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.apache.commons.pool2.BasePooledObjectFactory.makeObject(BasePooledObjectFactory.java:68) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:557) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:299) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:231) ~[commons-pool2-2.12.1.jar:2.12.1]
-	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:149) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at io.lettuce.core.support.ConnectionPoolSupport$1.borrowObject(ConnectionPoolSupport.java:144) ~[lettuce-core-6.6.0.RELEASE.jar:6.6.0.RELEASE/643bd47]
-	at org.springframework.data.redis.connection.lettuce.LettucePoolingConnectionProvider.getConnection(LettucePoolingConnectionProvider.java:113) ~[spring-data-redis-3.5.2.jar:3.5.2]
-	... 29 common frames omitted
-Caused by: io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: localhost/127.0.0.1:6379
-Caused by: java.net.ConnectException: Connection refused: getsockopt
-	at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
-	at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) ~[na:na]
-	at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946) ~[na:na]
-	at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:784) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:732) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:658) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.123.Final.jar:4.1.123.Final]
-	at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
-
-2025-08-01T20:02:28.927+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1920 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:02:28.930+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:02:31.019+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:02:31.024+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:02:31.081+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 38 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:02:31.114+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:02:31.116+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:02:31.136+09:00  INFO 1920 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:02:33.017+09:00  INFO 1920 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:02:33.070+09:00  INFO 1920 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:02:33.073+09:00  INFO 1920 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:02:33.287+09:00  INFO 1920 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:02:33.287+09:00  INFO 1920 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4271 ms
-2025-08-01T20:02:33.834+09:00  INFO 1920 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:02:34.021+09:00  INFO 1920 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:02:34.076+09:00  INFO 1920 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:02:34.932+09:00  INFO 1920 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:02:34.987+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:02:35.381+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:02:35.390+09:00  INFO 1920 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:02:35.458+09:00  WARN 1920 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:02:35.523+09:00  INFO 1920 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:02:36.693+09:00  INFO 1920 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:02:36.717+09:00  INFO 1920 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:02:39.719+09:00  WARN 1920 --- [booking] [main] 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-08-01T20:02:40.358+09:00  INFO 1920 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T20:02:42.172+09:00  INFO 1920 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T20:02:42.952+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T20:02:42.966+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5e7ea81b]]
-2025-08-01T20:02:42.969+09:00  INFO 1920 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T20:02:43.060+09:00  INFO 1920 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T20:02:45.086+09:00  INFO 1920 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 17.196 seconds (process running for 17.876)
-2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T20:03:18.745+09:00  INFO 1920 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T20:03:42.917+09:00  INFO 1920 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T20:08:11.716+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 22676 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:08:11.721+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:08:13.413+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:08:13.423+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:08:13.466+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 26 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:08:13.496+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:08:13.498+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:08:13.520+09:00  INFO 22676 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:08:15.142+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:08:15.165+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:08:15.169+09:00  INFO 22676 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:08:15.306+09:00  INFO 22676 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:08:15.311+09:00  INFO 22676 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3491 ms
-2025-08-01T20:08:15.791+09:00  INFO 22676 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:08:15.925+09:00  INFO 22676 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:08:15.975+09:00  INFO 22676 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:08:16.600+09:00  INFO 22676 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:08:16.636+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:08:16.847+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:08:16.847+09:00  INFO 22676 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:08:16.894+09:00  WARN 22676 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:08:16.931+09:00  INFO 22676 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:08:17.496+09:00  INFO 22676 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:08:17.503+09:00  INFO 22676 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:08:18.824+09:00  WARN 22676 --- [booking] [main] 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-08-01T20:08:19.205+09:00  INFO 22676 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T20:08:20.166+09:00  INFO 22676 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@22349ad3]]
-2025-08-01T20:08:20.508+09:00  INFO 22676 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T20:08:20.551+09:00  INFO 22676 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T20:08:21.676+09:00  INFO 22676 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.079 seconds (process running for 11.756)
-2025-08-01T20:08:33.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T20:08:33.009+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T20:08:33.018+09:00  INFO 22676 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
-2025-08-01T20:09:20.498+09:00  INFO 22676 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T20:28:04.154+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26932 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:28:04.156+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:28:05.863+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:28:05.867+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:28:05.909+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:28:05.941+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:28:05.950+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:28:05.975+09:00  INFO 26932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:28:07.528+09:00  INFO 26932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:28:07.559+09:00  INFO 26932 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:28:07.559+09:00  INFO 26932 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:28:07.701+09:00  INFO 26932 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:28:07.701+09:00  INFO 26932 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3481 ms
-2025-08-01T20:28:08.147+09:00  INFO 26932 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:28:08.283+09:00  INFO 26932 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:28:08.325+09:00  INFO 26932 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:28:08.961+09:00  INFO 26932 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:28:09.012+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:28:09.236+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:28:09.236+09:00  INFO 26932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:28:09.279+09:00  WARN 26932 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:28:09.318+09:00  INFO 26932 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:28:09.937+09:00  INFO 26932 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:28:09.945+09:00  INFO 26932 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:28:11.458+09:00  WARN 26932 --- [booking] [main] 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-08-01T20:28:11.909+09:00  INFO 26932 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T20:28:13.234+09:00  INFO 26932 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T20:28:13.525+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T20:28:13.525+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@35217e0]]
-2025-08-01T20:28:13.534+09:00  INFO 26932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T20:28:13.568+09:00  INFO 26932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T20:28:14.598+09:00  INFO 26932 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.568 seconds (process running for 12.193)
-2025-08-01T20:29:13.536+09:00  INFO 26932 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T20:33:00.226+09:00  INFO 26932 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T20:49:04.837+09:00  INFO 14168 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14168 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:49:04.844+09:00  INFO 14168 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:49:06.905+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:49:06.907+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:49:07.033+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 59 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:49:07.067+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:49:07.067+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:49:07.097+09:00  INFO 14168 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:49:08.814+09:00  INFO 14168 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:49:08.838+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:49:08.838+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:49:09.013+09:00  INFO 14168 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:49:09.015+09:00  INFO 14168 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4091 ms
-2025-08-01T20:49:09.557+09:00  INFO 14168 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:49:09.700+09:00  INFO 14168 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:49:09.752+09:00  INFO 14168 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:49:10.404+09:00  INFO 14168 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:49:10.461+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:49:10.669+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:49:10.669+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:49:10.704+09:00  WARN 14168 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:49:10.736+09:00  INFO 14168 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:49:11.363+09:00  INFO 14168 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:49:11.371+09:00  INFO 14168 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:49:12.626+09:00  WARN 14168 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
-2025-08-01T20:49:12.688+09:00  INFO 14168 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:49:12.704+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T20:49:12.715+09:00  INFO 14168 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T20:49:12.721+09:00  INFO 14168 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-01T20:49:12.754+09:00  INFO 14168 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T20:49:12.857+09:00 ERROR 14168 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
-
-
-Action:
-
-Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
-
-2025-08-01T20:52:04.097+09:00  INFO 26748 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26748 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:52:04.107+09:00  INFO 26748 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:52:06.124+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:52:06.126+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:52:06.181+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 32 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:52:06.222+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:52:06.222+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:52:06.247+09:00  INFO 26748 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:52:08.009+09:00  INFO 26748 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:52:08.042+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:52:08.042+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:52:08.201+09:00  INFO 26748 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:52:08.206+09:00  INFO 26748 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4000 ms
-2025-08-01T20:52:08.731+09:00  INFO 26748 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:52:08.892+09:00  INFO 26748 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:52:08.942+09:00  INFO 26748 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:52:09.535+09:00  INFO 26748 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:52:09.575+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:52:09.822+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:52:09.822+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:52:09.864+09:00  WARN 26748 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:52:09.914+09:00  INFO 26748 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:52:10.463+09:00  INFO 26748 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:52:10.471+09:00  INFO 26748 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:52:11.417+09:00  WARN 26748 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
-2025-08-01T20:52:11.473+09:00  INFO 26748 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:52:11.481+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T20:52:11.481+09:00  INFO 26748 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T20:52:11.497+09:00  INFO 26748 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-01T20:52:11.533+09:00  INFO 26748 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T20:52:11.651+09:00 ERROR 26748 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
-
-
-Action:
-
-Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
-
-2025-08-01T20:53:53.629+09:00  INFO 14084 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 14084 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:53:53.636+09:00  INFO 14084 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:53:54.881+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:53:54.889+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:53:54.940+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 34 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:53:54.963+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:53:54.963+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:53:54.988+09:00  INFO 14084 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:53:56.135+09:00  INFO 14084 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:53:56.160+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:53:56.160+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:53:56.258+09:00  INFO 14084 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:53:56.260+09:00  INFO 14084 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2530 ms
-2025-08-01T20:53:56.507+09:00  INFO 14084 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:53:56.599+09:00  INFO 14084 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:53:56.656+09:00  INFO 14084 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:53:57.186+09:00  INFO 14084 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:53:57.235+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:53:57.501+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:53:57.508+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:53:57.565+09:00  WARN 14084 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:53:57.615+09:00  INFO 14084 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:53:58.242+09:00  INFO 14084 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:53:58.250+09:00  INFO 14084 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:53:59.116+09:00  WARN 14084 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'captchaController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\CaptchaController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'recaptchaService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\RecaptchaService.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.web.client.RestTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
-2025-08-01T20:53:59.150+09:00  INFO 14084 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:53:59.166+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T20:53:59.175+09:00  INFO 14084 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T20:53:59.175+09:00  INFO 14084 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-01T20:53:59.206+09:00  INFO 14084 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T20:53:59.257+09:00 ERROR 14084 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Parameter 0 of constructor in com.mnms.booking.service.RecaptchaService required a bean of type 'org.springframework.web.client.RestTemplate' that could not be found.
-
-
-Action:
-
-Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration.
-
-2025-08-01T20:56:03.159+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14632 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T20:56:03.167+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T20:56:05.333+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:56:05.333+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T20:56:05.381+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24 ms. Found 0 JPA repository interfaces.
-2025-08-01T20:56:05.416+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T20:56:05.416+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T20:56:05.439+09:00  INFO 14632 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-01T20:56:07.241+09:00  INFO 14632 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T20:56:07.266+09:00  INFO 14632 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T20:56:07.266+09:00  INFO 14632 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T20:56:07.416+09:00  INFO 14632 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T20:56:07.416+09:00  INFO 14632 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4151 ms
-2025-08-01T20:56:07.991+09:00  INFO 14632 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T20:56:08.099+09:00  INFO 14632 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T20:56:08.167+09:00  INFO 14632 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T20:56:08.774+09:00  INFO 14632 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T20:56:08.816+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T20:56:09.118+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T20:56:09.126+09:00  INFO 14632 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T20:56:09.192+09:00  WARN 14632 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T20:56:09.275+09:00  INFO 14632 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T20:56:09.943+09:00  INFO 14632 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T20:56:09.961+09:00  INFO 14632 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T20:56:11.708+09:00  WARN 14632 --- [booking] [main] 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-08-01T20:56:12.103+09:00  INFO 14632 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T20:56:13.546+09:00  INFO 14632 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T20:56:14.098+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T20:56:14.103+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@224e7aa5]]
-2025-08-01T20:56:14.104+09:00  INFO 14632 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T20:56:14.143+09:00  INFO 14632 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T20:56:15.237+09:00  INFO 14632 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.529 seconds (process running for 14.257)
-2025-08-01T20:57:14.106+09:00  INFO 14632 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T20:57:44.549+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T20:57:44.549+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T20:57:44.552+09:00  INFO 14632 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
-2025-08-01T21:01:16.407+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18000 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:01:16.416+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:01:18.249+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:01:18.251+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:01:18.318+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:01:18.355+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:01:18.358+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:01:18.391+09:00  INFO 18000 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:01:20.248+09:00  INFO 18000 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:01:20.273+09:00  INFO 18000 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:01:20.273+09:00  INFO 18000 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:01:20.378+09:00  INFO 18000 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:01:20.379+09:00  INFO 18000 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3848 ms
-2025-08-01T21:01:20.737+09:00  INFO 18000 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:01:20.829+09:00  INFO 18000 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:01:20.869+09:00  INFO 18000 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:01:21.401+09:00  INFO 18000 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:01:21.451+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:01:21.724+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:01:21.732+09:00  INFO 18000 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:01:21.765+09:00  WARN 18000 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:01:21.807+09:00  INFO 18000 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:01:22.436+09:00  INFO 18000 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:01:22.443+09:00  INFO 18000 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:01:23.937+09:00  WARN 18000 --- [booking] [main] 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-08-01T21:01:24.361+09:00  INFO 18000 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:01:25.500+09:00  INFO 18000 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:01:25.843+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:01:25.847+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5f69462f]]
-2025-08-01T21:01:25.848+09:00  INFO 18000 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:01:25.880+09:00  INFO 18000 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:01:27.032+09:00  INFO 18000 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 12.664 seconds (process running for 13.374)
-2025-08-01T21:01:34.575+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:01:34.580+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:01:34.584+09:00  INFO 18000 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
-2025-08-01T21:02:25.854+09:00  INFO 18000 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:03:15.517+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11340 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:03:15.520+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:03:17.001+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:03:17.012+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:03:17.058+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:03:17.083+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:03:17.091+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:03:17.115+09:00  INFO 11340 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 7 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:03:18.788+09:00  INFO 11340 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:03:18.816+09:00  INFO 11340 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:03:18.816+09:00  INFO 11340 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:03:18.961+09:00  INFO 11340 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:03:18.968+09:00  INFO 11340 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3369 ms
-2025-08-01T21:03:19.530+09:00  INFO 11340 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:03:19.689+09:00  INFO 11340 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:03:19.741+09:00  INFO 11340 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:03:20.314+09:00  INFO 11340 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:03:20.389+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:03:20.701+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:03:20.710+09:00  INFO 11340 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:03:20.743+09:00  WARN 11340 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:03:20.776+09:00  INFO 11340 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:03:21.362+09:00  INFO 11340 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:03:21.372+09:00  INFO 11340 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:03:23.024+09:00  WARN 11340 --- [booking] [main] 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-08-01T21:03:23.467+09:00  INFO 11340 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:03:25.009+09:00  INFO 11340 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:03:25.626+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:03:25.633+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@67cd193d]]
-2025-08-01T21:03:25.634+09:00  INFO 11340 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:03:25.700+09:00  INFO 11340 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:03:26.998+09:00  INFO 11340 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.018 seconds (process running for 13.862)
-2025-08-01T21:03:40.511+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:03:40.511+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:03:40.515+09:00  INFO 11340 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
-2025-08-01T21:04:25.608+09:00  INFO 11340 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:05:18.692+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1612 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:05:18.699+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:05:20.970+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:05:20.974+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:05:21.019+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:05:21.054+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:05:21.061+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:05:21.087+09:00  INFO 1612 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:05:22.807+09:00  INFO 1612 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:05:22.831+09:00  INFO 1612 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:05:22.831+09:00  INFO 1612 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:05:22.958+09:00  INFO 1612 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:05:22.958+09:00  INFO 1612 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4115 ms
-2025-08-01T21:05:23.503+09:00  INFO 1612 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:05:23.662+09:00  INFO 1612 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:05:23.705+09:00  INFO 1612 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:05:24.560+09:00  INFO 1612 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:05:24.618+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:05:24.891+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:05:24.895+09:00  INFO 1612 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:05:24.937+09:00  WARN 1612 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:05:24.984+09:00  INFO 1612 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:05:25.672+09:00  INFO 1612 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:05:25.681+09:00  INFO 1612 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:05:27.631+09:00  WARN 1612 --- [booking] [main] 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-08-01T21:05:27.998+09:00  INFO 1612 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:05:29.215+09:00  INFO 1612 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:05:29.502+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:05:29.510+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@f09c282]]
-2025-08-01T21:05:29.510+09:00  INFO 1612 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:05:29.564+09:00  INFO 1612 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:05:31.011+09:00  INFO 1612 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.734 seconds (process running for 15.007)
-2025-08-01T21:05:34.741+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:05:34.742+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:05:34.745+09:00  INFO 1612 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 3 ms
-2025-08-01T21:06:29.506+09:00  INFO 1612 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:07:46.314+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11732 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:07:46.314+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:07:47.907+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:07:47.909+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:07:47.959+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 30 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:07:47.992+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:07:48.000+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:07:48.026+09:00  INFO 11732 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:07:49.603+09:00  INFO 11732 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:07:49.625+09:00  INFO 11732 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:07:49.625+09:00  INFO 11732 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:07:49.806+09:00  INFO 11732 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:07:49.806+09:00  INFO 11732 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3392 ms
-2025-08-01T21:07:50.408+09:00  INFO 11732 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:07:50.515+09:00  INFO 11732 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:07:50.574+09:00  INFO 11732 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:07:51.617+09:00  INFO 11732 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:07:51.667+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:07:52.004+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:07:52.012+09:00  INFO 11732 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:07:52.070+09:00  WARN 11732 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:07:52.112+09:00  INFO 11732 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:07:52.771+09:00  INFO 11732 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:07:52.784+09:00  INFO 11732 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:07:54.291+09:00  WARN 11732 --- [booking] [main] 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-08-01T21:07:54.692+09:00  INFO 11732 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:07:56.227+09:00  INFO 11732 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:07:56.552+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:07:56.561+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@5687ade6]]
-2025-08-01T21:07:56.561+09:00  INFO 11732 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:07:56.604+09:00  INFO 11732 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:07:57.909+09:00  INFO 11732 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 12.788 seconds (process running for 13.516)
-2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:08:12.284+09:00  INFO 11732 --- [booking] [http-nio-0.0.0.0-8080-exec-6] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T21:08:56.562+09:00  INFO 11732 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:11:00.590+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 18796 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:11:00.597+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:11:02.554+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:11:02.558+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:11:02.599+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 25 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:11:02.625+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:11:02.625+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:11:02.650+09:00  INFO 18796 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:11:04.138+09:00  INFO 18796 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:11:04.158+09:00  INFO 18796 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:11:04.162+09:00  INFO 18796 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:11:04.308+09:00  INFO 18796 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:11:04.308+09:00  INFO 18796 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3607 ms
-2025-08-01T21:11:05.162+09:00  INFO 18796 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:11:05.286+09:00  INFO 18796 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:11:05.346+09:00  INFO 18796 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:11:06.145+09:00  INFO 18796 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:11:06.215+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:11:06.458+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:11:06.459+09:00  INFO 18796 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:11:06.516+09:00  WARN 18796 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:11:06.566+09:00  INFO 18796 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:11:07.197+09:00  INFO 18796 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:11:07.204+09:00  INFO 18796 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:11:08.879+09:00  WARN 18796 --- [booking] [main] 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-08-01T21:11:09.479+09:00  INFO 18796 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:11:11.057+09:00  INFO 18796 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:11:11.762+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:11:11.762+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7156f8cf]]
-2025-08-01T21:11:11.768+09:00  INFO 18796 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:11:11.808+09:00  INFO 18796 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:11:12.978+09:00  INFO 18796 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.484 seconds (process running for 14.061)
-2025-08-01T21:11:19.177+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:11:19.177+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:11:19.183+09:00  INFO 18796 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 6 ms
-2025-08-01T21:12:11.748+09:00  INFO 18796 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:28:48.462+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 21320 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:28:48.470+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:28:50.260+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:28:50.271+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:28:50.334+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 43 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:28:50.358+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:28:50.358+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:28:50.375+09:00  INFO 21320 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:28:51.961+09:00  INFO 21320 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:28:51.977+09:00  INFO 21320 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:28:51.986+09:00  INFO 21320 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:28:52.134+09:00  INFO 21320 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:28:52.141+09:00  INFO 21320 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3571 ms
-2025-08-01T21:28:52.708+09:00  INFO 21320 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:28:52.839+09:00  INFO 21320 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:28:52.889+09:00  INFO 21320 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:28:53.493+09:00  INFO 21320 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:28:53.536+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:28:53.767+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:28:53.775+09:00  INFO 21320 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:28:53.800+09:00  WARN 21320 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:28:53.832+09:00  INFO 21320 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:28:54.342+09:00  INFO 21320 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:28:54.351+09:00  INFO 21320 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:28:56.010+09:00  WARN 21320 --- [booking] [main] 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-08-01T21:28:56.435+09:00  INFO 21320 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:28:59.313+09:00  INFO 21320 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:29:01.194+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:29:01.199+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@22cf1808]]
-2025-08-01T21:29:01.202+09:00  INFO 21320 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:29:01.240+09:00  INFO 21320 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:29:02.557+09:00  INFO 21320 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 15.228 seconds (process running for 16.055)
-2025-08-01T21:29:45.719+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:29:45.728+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:29:45.728+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T21:29:46.047+09:00  INFO 21320 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: ba3yg
-2025-08-01T21:30:01.180+09:00  INFO 21320 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:36:43.332+09:00  INFO 26768 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26768 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:36:43.338+09:00  INFO 26768 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:36:45.499+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:36:45.503+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:36:45.548+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:36:45.579+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:36:45.579+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:36:45.613+09:00  INFO 26768 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:36:47.283+09:00  INFO 26768 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:36:47.306+09:00  INFO 26768 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:36:47.306+09:00  INFO 26768 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:36:47.446+09:00  INFO 26768 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:36:47.454+09:00  INFO 26768 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4026 ms
-2025-08-01T21:36:47.983+09:00  INFO 26768 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:36:48.122+09:00  INFO 26768 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:36:48.183+09:00  INFO 26768 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:36:48.733+09:00  INFO 26768 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:36:48.792+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:36:49.054+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:36:49.054+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:36:49.096+09:00  WARN 26768 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:36:49.136+09:00  INFO 26768 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:36:49.665+09:00  INFO 26768 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:36:49.673+09:00  INFO 26768 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:36:51.541+09:00  WARN 26768 --- [booking] [main] 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-08-01T21:36:52.014+09:00  INFO 26768 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:36:53.560+09:00  INFO 26768 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42fdf45e]]
-2025-08-01T21:36:53.872+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@42fdf45e]]
-2025-08-01T21:36:53.897+09:00  INFO 26768 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T21:36:53.906+09:00  WARN 26768 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T21:36:53.931+09:00  INFO 26768 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:36:53.941+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T21:36:53.947+09:00  INFO 26768 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T21:36:53.970+09:00  INFO 26768 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T21:36:54.003+09:00 ERROR 26768 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T21:37:27.592+09:00  INFO 552 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 552 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:37:27.594+09:00  INFO 552 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:37:29.004+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:37:29.012+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:37:29.062+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:37:29.110+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:37:29.112+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:37:29.140+09:00  INFO 552 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:37:30.247+09:00  INFO 552 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:37:30.272+09:00  INFO 552 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:37:30.272+09:00  INFO 552 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:37:30.389+09:00  INFO 552 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:37:30.390+09:00  INFO 552 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2713 ms
-2025-08-01T21:37:30.586+09:00  INFO 552 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:37:30.655+09:00  INFO 552 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:37:30.704+09:00  INFO 552 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:37:31.083+09:00  INFO 552 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:37:31.120+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:37:31.370+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:37:31.370+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:37:31.411+09:00  WARN 552 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:37:31.461+09:00  INFO 552 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:37:31.971+09:00  INFO 552 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:37:31.987+09:00  INFO 552 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:37:32.712+09:00  WARN 552 --- [booking] [main] 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-08-01T21:37:32.845+09:00  INFO 552 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:37:33.336+09:00  INFO 552 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:37:33.606+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:37:33.613+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@ad6448e]]
-2025-08-01T21:37:33.614+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@ad6448e]]
-2025-08-01T21:37:33.622+09:00  INFO 552 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T21:37:33.640+09:00  WARN 552 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T21:37:33.658+09:00  INFO 552 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:37:33.667+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T21:37:33.671+09:00  INFO 552 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T21:37:33.694+09:00  INFO 552 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T21:37:33.716+09:00 ERROR 552 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T21:39:48.330+09:00  INFO 14820 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 14820 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:39:48.330+09:00  INFO 14820 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:39:49.669+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:39:49.669+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:39:49.721+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 29 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:39:49.746+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:39:49.755+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:39:49.777+09:00  INFO 14820 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:39:51.121+09:00  INFO 14820 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:39:51.146+09:00  INFO 14820 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:39:51.146+09:00  INFO 14820 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:39:51.250+09:00  INFO 14820 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:39:51.250+09:00  INFO 14820 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2807 ms
-2025-08-01T21:39:51.504+09:00  INFO 14820 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:39:51.599+09:00  INFO 14820 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:39:51.661+09:00  INFO 14820 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:39:52.054+09:00  INFO 14820 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:39:52.112+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:39:52.372+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:39:52.379+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:39:52.414+09:00  WARN 14820 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:39:52.446+09:00  INFO 14820 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:39:53.012+09:00  INFO 14820 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:39:53.020+09:00  INFO 14820 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:39:53.834+09:00  WARN 14820 --- [booking] [main] 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-08-01T21:39:54.027+09:00  INFO 14820 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:39:54.544+09:00  INFO 14820 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:39:54.805+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:39:54.807+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@43c3354]]
-2025-08-01T21:39:54.810+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@43c3354]]
-2025-08-01T21:39:54.828+09:00  INFO 14820 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T21:39:54.851+09:00  WARN 14820 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T21:39:54.878+09:00  INFO 14820 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:39:54.878+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T21:39:54.888+09:00  INFO 14820 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T21:39:54.923+09:00  INFO 14820 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T21:39:54.989+09:00 ERROR 14820 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T21:42:13.606+09:00  INFO 29180 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.2 with PID 29180 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:42:13.607+09:00  INFO 29180 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:42:15.019+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:42:15.021+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:42:15.055+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 23 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:42:15.078+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:42:15.078+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:42:15.090+09:00  INFO 29180 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:42:16.294+09:00  INFO 29180 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:42:16.310+09:00  INFO 29180 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:42:16.310+09:00  INFO 29180 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:42:16.448+09:00  INFO 29180 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:42:16.450+09:00  INFO 29180 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2721 ms
-2025-08-01T21:42:16.710+09:00  INFO 29180 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:42:16.804+09:00  INFO 29180 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:42:16.872+09:00  INFO 29180 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:42:17.304+09:00  INFO 29180 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:42:17.344+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:42:17.661+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:42:17.664+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:42:17.704+09:00  WARN 29180 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:42:17.748+09:00  INFO 29180 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:42:18.257+09:00  INFO 29180 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:42:18.266+09:00  INFO 29180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:42:19.045+09:00  WARN 29180 --- [booking] [main] 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-08-01T21:42:19.204+09:00  INFO 29180 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:42:19.731+09:00  INFO 29180 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@53fd59d4]]
-2025-08-01T21:42:19.969+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@53fd59d4]]
-2025-08-01T21:42:19.985+09:00  INFO 29180 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T21:42:19.993+09:00  WARN 29180 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T21:42:20.013+09:00  INFO 29180 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:42:20.013+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T21:42:20.022+09:00  INFO 29180 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T21:42:20.044+09:00  INFO 29180 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T21:42:20.079+09:00 ERROR 29180 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-01T21:43:18.573+09:00  INFO 26364 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 26364 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:43:18.579+09:00  INFO 26364 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:43:20.681+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:43:20.681+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:43:20.732+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 27 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:43:20.766+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:43:20.770+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:43:20.796+09:00  INFO 26364 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:43:22.548+09:00  INFO 26364 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:43:22.574+09:00  INFO 26364 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:43:22.582+09:00  INFO 26364 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:43:22.771+09:00  INFO 26364 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:43:22.771+09:00  INFO 26364 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4019 ms
-2025-08-01T21:43:23.468+09:00  INFO 26364 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:43:23.644+09:00  INFO 26364 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:43:23.705+09:00  INFO 26364 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:43:24.403+09:00  INFO 26364 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:43:24.452+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:43:24.774+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:43:24.777+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:43:24.832+09:00  WARN 26364 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:43:24.883+09:00  INFO 26364 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:43:25.474+09:00  INFO 26364 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:43:25.481+09:00  INFO 26364 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:43:26.852+09:00  WARN 26364 --- [booking] [main] 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-08-01T21:43:27.320+09:00  INFO 26364 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:43:28.983+09:00  INFO 26364 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:43:29.421+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:43:29.429+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
-2025-08-01T21:43:29.429+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:43:29.454+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-01T21:43:29.456+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
-2025-08-01T21:43:29.456+09:00  INFO 26364 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-01T21:43:29.479+09:00  WARN 26364 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-01T21:43:29.556+09:00  INFO 26364 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:43:29.570+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-01T21:43:29.578+09:00  INFO 26364 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-01T21:43:29.628+09:00  INFO 26364 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+2025-08-04T15:11:10.730+09:00  INFO 6532 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6532 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-04T15:11:10.752+09:00  INFO 6532 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-04T15:11:13.746+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T15:11:13.751+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-04T15:11:13.832+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 44 ms. Found 0 JPA repository interfaces.
+2025-08-04T15:11:13.886+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T15:11:13.890+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-04T15:11:13.932+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
+2025-08-04T15:11:16.427+09:00  INFO 6532 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-04T15:11:16.474+09:00  INFO 6532 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-04T15:11:16.475+09:00  INFO 6532 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-04T15:11:16.663+09:00  INFO 6532 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-04T15:11:16.664+09:00  INFO 6532 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 5757 ms
+2025-08-04T15:11:17.553+09:00  INFO 6532 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-04T15:11:17.850+09:00  INFO 6532 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-04T15:11:18.148+09:00  INFO 6532 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-04T15:11:19.379+09:00  INFO 6532 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-04T15:11:19.478+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-04T15:11:20.067+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-04T15:11:20.071+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-04T15:11:20.154+09:00  WARN 6532 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-04T15:11:20.221+09:00  INFO 6532 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-04T15:11:21.241+09:00  INFO 6532 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-04T15:11:21.257+09:00  INFO 6532 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T15:11:23.159+09:00  WARN 6532 --- [booking] [main] 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-08-04T15:11:23.588+09:00  INFO 6532 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-04T15:11:25.172+09:00  INFO 6532 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-04T15:11:25.727+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-04T15:11:25.730+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1016b44e]]
+2025-08-04T15:11:25.731+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
+2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1016b44e]]
+2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
+2025-08-04T15:11:25.760+09:00  WARN 6532 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
+2025-08-04T15:11:25.780+09:00  INFO 6532 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T15:11:25.785+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-04T15:11:25.789+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-04T15:11:25.805+09:00  INFO 6532 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
 
 Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-01T21:43:29.759+09:00 ERROR 26364 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
+2025-08-04T15:11:25.829+09:00 ERROR 6532 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
 
 ***************************
 APPLICATION FAILED TO START
@@ -3055,93 +59,413 @@ Action:
 
 Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
 
-2025-08-01T21:44:11.894+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 4524 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:44:11.902+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:44:13.673+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:44:13.674+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:44:13.721+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:44:13.746+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:44:13.746+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:44:13.772+09:00  INFO 4524 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:44:15.871+09:00  INFO 4524 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:44:15.895+09:00  INFO 4524 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:44:15.895+09:00  INFO 4524 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:44:16.095+09:00  INFO 4524 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:44:16.096+09:00  INFO 4524 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4124 ms
-2025-08-01T21:44:16.652+09:00  INFO 4524 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:44:16.764+09:00  INFO 4524 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:44:16.808+09:00  INFO 4524 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:44:17.472+09:00  INFO 4524 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:44:17.522+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:44:17.816+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:44:17.824+09:00  INFO 4524 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:44:17.849+09:00  WARN 4524 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:44:17.873+09:00  INFO 4524 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:44:18.410+09:00  INFO 4524 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:44:18.418+09:00  INFO 4524 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:44:20.135+09:00  WARN 4524 --- [booking] [main] 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-08-01T21:44:20.504+09:00  INFO 4524 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:44:22.078+09:00  INFO 4524 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:44:22.696+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:44:22.703+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
-2025-08-01T21:44:22.705+09:00  INFO 4524 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:44:22.748+09:00  INFO 4524 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:44:24.059+09:00  INFO 4524 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.394 seconds (process running for 14.261)
-2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:44:39.530+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-01T21:44:39.716+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: w5eme
-2025-08-01T21:45:16.018+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: g8nne
-2025-08-01T21:45:22.699+09:00  INFO 4524 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-01T21:45:36.586+09:00  INFO 4524 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: 8pbym
-2025-08-01T21:48:11.250+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 3932 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-01T21:48:11.251+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-01T21:48:13.420+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:48:13.423+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-01T21:48:13.472+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 31 ms. Found 0 JPA repository interfaces.
-2025-08-01T21:48:13.505+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-01T21:48:13.505+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-01T21:48:13.522+09:00  INFO 3932 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-01T21:48:14.987+09:00  INFO 3932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-01T21:48:15.011+09:00  INFO 3932 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-01T21:48:15.011+09:00  INFO 3932 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-01T21:48:15.142+09:00  INFO 3932 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-01T21:48:15.142+09:00  INFO 3932 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3804 ms
-2025-08-01T21:48:15.826+09:00  INFO 3932 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-01T21:48:16.061+09:00  INFO 3932 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-01T21:48:16.125+09:00  INFO 3932 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-01T21:48:17.080+09:00  INFO 3932 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-01T21:48:17.137+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-01T21:48:17.459+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-01T21:48:17.468+09:00  INFO 3932 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-01T21:48:17.509+09:00  WARN 3932 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-01T21:48:17.554+09:00  INFO 3932 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-01T21:48:18.084+09:00  INFO 3932 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-01T21:48:18.092+09:00  INFO 3932 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-01T21:48:20.116+09:00  WARN 3932 --- [booking] [main] 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-08-01T21:48:20.488+09:00  INFO 3932 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-01T21:48:22.128+09:00  INFO 3932 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-01T21:48:22.524+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-01T21:48:22.528+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@7568134c]]
-2025-08-01T21:48:22.528+09:00  INFO 3932 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-01T21:48:22.567+09:00  INFO 3932 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-01T21:48:23.753+09:00  INFO 3932 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 13.445 seconds (process running for 14.07)
-2025-08-01T21:48:31.454+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-01T21:48:31.462+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-01T21:48:31.464+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-01T21:48:31.779+09:00  INFO 3932 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.KaptchaService    : Generated Kaptcha Text: 8dp3d
-2025-08-01T21:49:22.529+09:00  INFO 3932 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-04T15:12:30.451+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28936 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-04T15:12:30.457+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-04T15:12:32.070+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T15:12:32.072+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-04T15:12:32.141+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
+2025-08-04T15:12:32.161+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T15:12:32.162+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-04T15:12:32.181+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-04T15:12:33.502+09:00  INFO 28936 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-04T15:12:33.521+09:00  INFO 28936 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-04T15:12:33.522+09:00  INFO 28936 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-04T15:12:33.641+09:00  INFO 28936 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-04T15:12:33.642+09:00  INFO 28936 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3108 ms
+2025-08-04T15:12:34.188+09:00  INFO 28936 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-04T15:12:34.346+09:00  INFO 28936 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-04T15:12:34.377+09:00  INFO 28936 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-04T15:12:34.978+09:00  INFO 28936 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-04T15:12:35.013+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-04T15:12:35.201+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-04T15:12:35.203+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-04T15:12:35.225+09:00  WARN 28936 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-04T15:12:35.248+09:00  INFO 28936 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-04T15:12:35.604+09:00  INFO 28936 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-04T15:12:35.609+09:00  INFO 28936 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T15:12:36.830+09:00  WARN 28936 --- [booking] [main] 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-08-04T15:12:37.123+09:00  INFO 28936 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-04T15:12:38.343+09:00  INFO 28936 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-04T15:12:39.196+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-04T15:12:39.202+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
+2025-08-04T15:12:39.205+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-04T15:12:39.358+09:00  INFO 28936 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-04T15:12:40.522+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.986 seconds (process running for 11.539)
+2025-08-04T15:13:39.179+09:00  INFO 28936 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-04T15:48:07.528+09:00  WARN 28936 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=30m32s140ms607µs).
+2025-08-04T16:57:27.085+09:00  WARN 28936 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1h1m49s478ms585µs600ns).
+2025-08-04T17:15:35.155+09:00  INFO 28936 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 2, active threads = 1, queued tasks = 0, completed tasks = 1]
+2025-08-04T17:44:45.964+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-04T17:44:45.964+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-04T17:44:45.972+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
+2025-08-04T17:45:35.165+09:00  INFO 28936 --- [booking] [MessageBroker-2] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 2]
+2025-08-04T17:55:57.557+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 30600 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-04T17:55:57.560+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-04T17:55:59.377+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T17:55:59.383+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-04T17:55:59.441+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 34 ms. Found 0 JPA repository interfaces.
+2025-08-04T17:55:59.473+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T17:55:59.473+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-04T17:55:59.498+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-04T17:56:01.383+09:00  INFO 30600 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-04T17:56:01.410+09:00  INFO 30600 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-04T17:56:01.410+09:00  INFO 30600 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-04T17:56:01.531+09:00  INFO 30600 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-04T17:56:01.532+09:00  INFO 30600 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3889 ms
+2025-08-04T17:56:02.035+09:00  INFO 30600 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-04T17:56:02.157+09:00  INFO 30600 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-04T17:56:02.206+09:00  INFO 30600 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-04T17:56:02.928+09:00  INFO 30600 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-04T17:56:02.973+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-04T17:56:03.194+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-04T17:56:03.197+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-04T17:56:03.227+09:00  WARN 30600 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-04T17:56:03.275+09:00  INFO 30600 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-04T17:56:03.838+09:00  INFO 30600 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-04T17:56:03.846+09:00  INFO 30600 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T17:56:05.122+09:00  WARN 30600 --- [booking] [main] 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-08-04T17:56:05.439+09:00  INFO 30600 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-04T17:56:06.826+09:00  INFO 30600 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-04T17:56:07.160+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-04T17:56:07.169+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2e2c9e24]]
+2025-08-04T17:56:07.171+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-04T17:56:07.223+09:00  INFO 30600 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-04T17:56:08.260+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.967 seconds (process running for 12.707)
+2025-08-04T17:56:17.817+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-04T17:56:17.817+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-04T17:56:17.826+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
+2025-08-04T17:56:44.349+09:00  INFO 30600 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
+2025-08-04T17:57:07.171+09:00  INFO 30600 --- [booking] [MessageBroker-9] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12]
+2025-08-04T18:02:57.973+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:02:58.022+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
+2025-08-04T18:22:01.546+09:00  INFO 30600 --- [booking] [clientInboundChannel-13] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
+2025-08-04T18:24:16.634+09:00  WARN 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user2 was not found in booking user set on exit.
+2025-08-04T18:24:21.992+09:00  WARN 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User 12345 was not found in booking user set on exit.
+2025-08-04T18:24:49.167+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:24:49.169+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
+2025-08-04T18:26:17.892+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 15184 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-04T18:26:17.902+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-04T18:26:20.128+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T18:26:20.134+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-04T18:26:20.194+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 38 ms. Found 0 JPA repository interfaces.
+2025-08-04T18:26:20.233+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T18:26:20.233+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-04T18:26:20.260+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-04T18:26:22.179+09:00  INFO 15184 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-04T18:26:22.200+09:00  INFO 15184 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-04T18:26:22.200+09:00  INFO 15184 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-04T18:26:22.334+09:00  INFO 15184 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-04T18:26:22.335+09:00  INFO 15184 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4304 ms
+2025-08-04T18:26:22.933+09:00  INFO 15184 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-04T18:26:23.068+09:00  INFO 15184 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-04T18:26:23.113+09:00  INFO 15184 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-04T18:26:24.354+09:00  INFO 15184 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-04T18:26:24.483+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-04T18:26:24.955+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-04T18:26:24.962+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-04T18:26:25.022+09:00  WARN 15184 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-04T18:26:25.080+09:00  INFO 15184 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-04T18:26:26.030+09:00  INFO 15184 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-04T18:26:26.047+09:00  INFO 15184 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T18:26:30.124+09:00  WARN 15184 --- [booking] [main] 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-08-04T18:26:30.802+09:00  INFO 15184 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-04T18:26:33.989+09:00  INFO 15184 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-04T18:26:34.726+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-04T18:26:34.734+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4a249610]]
+2025-08-04T18:26:34.734+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-04T18:26:34.824+09:00  INFO 15184 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-04T18:26:36.925+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 20.206 seconds (process running for 21.271)
+2025-08-04T18:26:52.356+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-04T18:26:52.356+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-04T18:26:52.361+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
+2025-08-04T18:27:03.678+09:00  INFO 15184 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
+2025-08-04T18:27:13.126+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:27:13.175+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
+2025-08-04T18:27:25.437+09:00  INFO 15184 --- [booking] [clientInboundChannel-16] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
+2025-08-04T18:27:29.715+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:27:29.717+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
+2025-08-04T18:27:34.716+09:00  INFO 15184 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(2)-CONNECTED(2)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 18, active threads = 0, queued tasks = 0, completed tasks = 18], outboundChannel[pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 2], sockJsScheduler[pool size = 15, active threads = 1, queued tasks = 3, completed tasks = 9]
+2025-08-04T18:27:55.833+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:27:55.836+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-04T18:28:01.569+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:28:01.570+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:29:10.120+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:29:10.122+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:29:22.224+09:00  INFO 15184 --- [booking] [clientInboundChannel-31] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
+2025-08-04T18:29:29.683+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:29:29.684+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-04T18:29:36.448+09:00  INFO 15184 --- [booking] [clientInboundChannel-40] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
+2025-08-04T18:29:39.730+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:29:39.732+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-04T18:29:50.762+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-04T18:29:50.763+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:47:23.032+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11952 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-04T18:47:23.032+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-04T18:47:24.651+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T18:47:24.652+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-04T18:47:24.725+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 37 ms. Found 0 JPA repository interfaces.
+2025-08-04T18:47:24.751+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-04T18:47:24.758+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-04T18:47:24.782+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-04T18:47:26.327+09:00  INFO 11952 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-04T18:47:26.343+09:00  INFO 11952 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-04T18:47:26.343+09:00  INFO 11952 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-04T18:47:26.450+09:00  INFO 11952 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-04T18:47:26.451+09:00  INFO 11952 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3297 ms
+2025-08-04T18:47:27.044+09:00  INFO 11952 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-04T18:47:27.181+09:00  INFO 11952 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-04T18:47:27.220+09:00  INFO 11952 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-04T18:47:27.700+09:00  INFO 11952 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-04T18:47:27.729+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-04T18:47:27.887+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-04T18:47:27.888+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-04T18:47:27.909+09:00  WARN 11952 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-04T18:47:27.930+09:00  INFO 11952 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-04T18:47:28.300+09:00  INFO 11952 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-04T18:47:28.305+09:00  INFO 11952 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-04T18:47:29.320+09:00  WARN 11952 --- [booking] [main] 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-08-04T18:47:29.564+09:00  INFO 11952 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-04T18:47:30.713+09:00  INFO 11952 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-04T18:47:31.331+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-04T18:47:31.336+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3d8b9dee]]
+2025-08-04T18:47:31.339+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-04T18:47:31.414+09:00  INFO 11952 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-04T18:47:32.156+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.681 seconds (process running for 11.263)
+2025-08-04T18:47:32.174+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:47:37.197+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:47:42.208+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:47:47.222+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:47:52.238+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:47:57.259+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:02.275+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:07.291+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:12.311+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:17.327+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:17.409+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-04T18:48:17.409+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-04T18:48:17.410+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-04T18:48:22.344+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:23.013+09:00  INFO 11952 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
+2025-08-04T18:48:27.356+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:31.311+09:00  INFO 11952 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 14]
+2025-08-04T18:48:32.372+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:37.381+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:38.771+09:00  INFO 11952 --- [booking] [clientInboundChannel-16] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
+2025-08-04T18:48:41.785+09:00  INFO 11952 --- [booking] [clientInboundChannel-25] c.m.b.controller.BookingController       : User user3 subscribed to waiting queue updates.
+2025-08-04T18:48:42.404+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:47.417+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:52.432+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:57.446+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:48:58.385+09:00  INFO 11952 --- [booking] [clientInboundChannel-3] c.m.b.controller.BookingController       : User user4 subscribed to waiting queue updates.
+2025-08-04T18:49:02.454+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:49:07.475+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:49:12.489+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:49:14.080+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
+2025-08-04T18:49:17.507+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:49:22.530+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:49:23.027+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
+2025-08-04T18:49:25.099+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754300965068.
+2025-08-04T18:49:25.104+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:25.147+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:25.148+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:25.215+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:27.550+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:27.553+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:27.553+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:27.554+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:27.555+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:32.570+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:32.575+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:32.576+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:32.576+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:32.578+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:37.600+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:37.604+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:37.605+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:37.606+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:37.608+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:42.624+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:42.629+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:42.629+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:42.630+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:42.632+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:47.656+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:47.658+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:47.659+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:47.660+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:47.662+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:52.679+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:52.686+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:52.687+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:49:52.688+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:52.689+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:56.216+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754300996211.
+2025-08-04T18:49:56.220+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-04T18:49:56.226+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:49:56.226+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:49:56.229+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-04T18:49:57.711+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:49:57.719+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:57.721+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:49:57.723+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:49:57.724+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-04T18:49:57.730+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:49:57.730+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-04T18:49:57.731+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:49:57.734+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-04T18:50:02.748+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:50:02.752+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:02.753+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:02.755+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-04T18:50:02.755+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:50:02.760+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:50:02.761+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-04T18:50:02.762+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:50:02.763+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-04T18:50:07.771+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-04T18:50:07.776+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:07.777+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:07.780+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-04T18:50:07.781+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-04T18:50:07.789+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:50:07.791+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-04T18:50:07.791+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-04T18:50:07.795+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-04T18:50:11.253+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-04T18:50:11.261+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue.
+2025-08-04T18:50:11.264+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 added to booking user set.
+2025-08-04T18:50:11.270+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:11.274+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:11.275+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:11.276+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:12.804+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:12.808+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:12.809+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:12.809+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:12.813+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:17.829+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:17.831+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:17.832+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:17.832+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:17.833+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:22.848+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:22.850+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:22.851+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:22.851+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:22.852+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:27.873+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:27.877+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:27.878+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:27.878+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:27.879+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:29.785+09:00  INFO 11952 --- [booking] [clientInboundChannel-39] c.m.b.controller.BookingController       : User user5 subscribed to waiting queue updates.
+2025-08-04T18:50:32.894+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:32.897+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:32.898+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:32.898+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:32.899+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:37.910+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:37.913+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:37.914+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:37.914+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:37.915+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:42.935+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:42.938+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:42.938+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:42.940+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:42.941+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:47.948+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:47.953+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:47.953+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:47.955+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:47.956+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:52.972+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:52.975+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:52.976+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:52.976+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:52.977+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:50:54.788+09:00  WARN 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user4 was not found in booking user set on exit.
+2025-08-04T18:50:57.990+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:50:57.999+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-04T18:51:00.257+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user3 exited booking page and removed from booking user set.
+2025-08-04T18:51:00.274+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue.
+2025-08-04T18:51:00.278+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 added to booking user set.
+2025-08-04T18:51:03.010+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:51:08.025+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:51:13.042+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:51:14.711+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5 added to waiting queue with timestamp 1754301074709.
+2025-08-04T18:51:14.714+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:14.717+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:14.718+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:14.719+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:18.062+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:18.069+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:23.079+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:23.081+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:23.082+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:23.082+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:23.083+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:28.091+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:28.094+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:28.094+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:28.095+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:28.096+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:33.120+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:33.126+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:33.127+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:33.127+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:33.128+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:38.138+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:38.140+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:38.140+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:38.141+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:38.142+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:43.154+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:43.158+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:48.172+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-04T18:51:48.174+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:48.175+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-04T18:51:48.175+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-04T18:51:48.176+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-04T18:51:50.689+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 exited booking page and removed from booking user set.
+2025-08-04T18:51:50.701+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user5 removed from waiting queue.
+2025-08-04T18:51:50.706+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user5 added to booking user set.
+2025-08-04T18:51:53.191+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-04T18:51:58.204+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
diff --git a/logs/spring.log.2025-08-01.0.gz b/logs/spring.log.2025-08-01.0.gz
new file mode 100644
index 0000000000000000000000000000000000000000..fa33512239d7bb4c762c8bb5b3c11d89597182d9
GIT binary patch
literal 34889
zcma(2W0Y*c5(bF2ZJf4kTc>T?wrzKxwr$(CZQHi(>3e7H;Qe~F_FDC=jMx!7qcS6^
zzNo~DfB^XK>*uoTBYHzDp7;HQnf~T4GfeCIXC?DPzvQ3gh$`BYjqAFte-k`W!5eCF
z#77F6B<0R^9m8BbEu3_A*_T2(rO?9S;$diGL;UcS`Q*nbeWRnJk#vM%(wWg$u2!FL
z3yxCLIN`OjKQU7?)*JOYoj%VI!ELgsOJ`1%FI&WKi+DbtdR;xR?*s5Eshjy5dsiT5
zbh9z%I}vkcv+#lDd>9({z9-91%;>UvR8%L)YeHUkj<+1OwINnPX-`FbU3J@?ZsnSM
z9o#?O_h&CUzUVODrpz+mp#x_(?Q=st4d3|hJlG%!;@odv@NSzoK*cPG(j#$8T@Baq
z`pgZx>3t7AuOF_&s@yi9`|hsDnq5ZpV%-q(deHPw?}4l5vX%Im&wL{%%P$LVj90v83h|^*BA#<}}3q)18Gl%ad#+)|cOP1Zfl}^9s4To;_VRt#o0Jujzpi%?o#Bw#S
z`(|uu|ImNTqRxhtsLs&(c)!Wy3%$|v7;w`<^?EJiJ(IEJW=%k(1hGQ~?#X!p;xn}T
zO{+8&xKHj{kKt+s+!msPI2bF2YkhS}D#X0aNIFzz{7mKkvZoWakD?J04i`{)G^(N^
zZQswT<-hy%a6Yoe_RrcDReZHKmnbIUdK%=<#Ejtdr*)b`L)mdTAP*;EmbTGH61q9$
z>lxa*aQo!Iomi9830VGE@S#8bfqo~%36N*Z*66<4SYDfQ;vCP)157wbHG~r3cS9yJ
zgTurGBbORx05Ua32R#tOKM%Pp2WFZ>+o4LtWA&%^Y2x~;1
zzv|~
zn#Qe5QU~7bn)%zZ9Wtx#u-i`}SZur3_?yg
zLp*#^+pr2FKiiiLH*PG?F)b`SfA4z^j
zvwn~4@Ba6rD=Nv;>L>M|MPXV(5FTWoXE3K@TPz_6TTj~7mOD|ieT>!-y|Tpnz7k_6
zR(t)?L3(SUEdJkktL0%6>m3GM<44~k+K-2)HiCTli-?_hZgb7wdt|B6CE$Ck^hEha
z0PCNS-Z`-X9euD%9jYN-XKHn-(T~B9bs2eK#jyQ#>LRp^^#%3)LXFv*@_`!me$@IV
zA`QMUVohF_hL-lZBNYe3v2s3c2FughxFNX2@iPFK$`y`SCPhJ;_v)p>?njc2n%%FhC|ut|7R78)8|OuquuFk%}dTt
zC5I9-e0TqDZ!YJcN!bnT8(X5c_}4-u(NB~SqVj=}#RW
z&gNP0>wvIjoJYUlg%$P=X^x>K)ByN$v0hoRt3cq95y(U0Qcgb#5BjL+$Ud7zUzN1t
zwG^y^-tqQ8I?5kThPZX&*g}O~eBf6;G5*e48+!jFW|-lJn{U>ikCPHU9gUuDZ}YC6
zMfiXnS=-^U%Y!J?K5gWubiC@W*M=ju?|}h$N%*MYS|z+d7r49wdIr%L(*fCm!wI`H
zTx+ZungDXbM6Z{Yh&5)w;5JYUC{u=)6FSndzg_m`V-7d&pvY@im&-`=wWPbOM?0vW
zO%K(dD@Snx&72~N=2#!6C+4?cv(O362Bj&cNI8;3Zx0>NmW4M>0W^
zmFZ!4hYfj%zR5=
zr&J>oM9eL*X9yTQ>JH0IaHg*jcK?p5>onmViYfl}Q+UfbYPZ>u$36x~tuWHinqynG
z7=QWJ9E<2`O3N3|;yZa3BEXY^eMi|!5>oCCu5$F?<9
z>M)_$mFTT-CwE{hC9IXlyS3X$pSl|C;I^0#Gy&RH!wYLugm!`(M}@xG%Z)Q&NVrb;
z^A&9t{5FNZ)}!I|$1MxLU0fjOJCs-7_W7%)$_^WR!D*?qq-?BSsQRg?#?J5&%nAJw
zU1S^i^vasP+tbJ!16TkZhX6g3tcT|7?r9=n&x+oUD~K*-viM$BjgY(k+wTP~yQ~vn
zcI3{2rs7icxU9_}Rn`f?h0&EASUF1hH5WqrKAVpe)SpFQr5Hq@#&^Q7MjLj+Fn
zc;h!1fWl@ojJSI$5ow3}2VU?PT>}Rf2tH$>YB0d=1PPE%2Rg9a$k@j4J?;^>_BowA
z;)8Pbhf+Iq-X1DkM4ym#wI$`(EJEpM$D#FMo}Wh4;UlM6*unM*Ul)D1rtrQ@-smVa
zdHRQPSMY`;L{nEDu~L1z{ba}s0L^R-)Iyy4V02OdJbmi^oI=m&yskco>K^O-k)X`e
z^S^E8ld|u7+6m~sOgjaX*Y>N3IO)86G5GR+u0W%|q4OpA9MK0@R_Ah(J>a)%c|Kyw
ztE7($wbfeMwJ=q&eo%-Qh>;!bL3>Z@u1w6iVPp(4P@u
zE7bF&hCtC-w?8NH>j))fNZ*K4U(OO$ikQ#ub7c2tGgQ*
z6`6HC=Q>n(Xt&RwgsX&*>YET|xDJ=U1+>FFJJ%lFS0VUW+7-IpoJt36!mM430t
z!xcUKYP`~y-rMCXbSgu7u$6RdgoHS>RmsRS7E}v|J3SvCt`iBdPMwK+h}#>T
zaYxTV8FVcxN7lYS*S395#)KI+A2eVn^UYRJw>ES5tydy_z;~J8&uinV{S`bfS$LH{
zA3A(8AFVibnrm^{)SJw_cwl%+6Z>dl)TX!-vJMH)Xpkrf#0ONfdZ~o*bfymx^{^(2
zbEEWX++}ijAg_XXHx{?S-Nl${YTQe&!?q*{0_I_2+2zKEPxV#qwfAV4y{D;Bi%lia
z+I$lqW&c9myAVbitnF$~F#FqJ^mI@rE*y)z^+IBkf9CzvI}uZ(JonK~mPgzuMWh+i
zO_E$0vGVo#`1fEvU}LcSJ*)8So;eX3kuH?EyTtP==hM0OSj>7_i960b1}`zZt-*CR
zqrt>hr^SM)PHI(bVrN`ZTSgiNrr@2fX!K6%(R$Jkx#>N%dE?`0&{c6Ef2jG)Y5#h}
z9?8uSHHM~UA9+z>F)okv4_nT)wr3iS)=rgMcn6+6Mpgj|jOIJQ!Wvevf#De$khFZA
zDS?D97dt~Ga2O1+rP@Gv$oyUFYX}|czBvcWTt^@=h(~3kw)P8P$K~xN!1~+>1Wbwf!%juo=k7!&anz;SE&lhQ51L`w9Fj-PXlR*07
z_w{gn!tiQ;aa=ovO`(DJpxY#F+9KKEr55MS({ztHodNL)YrhY9P}g71nh`rw8TXxI
z568GWfWOG_ZvO#gor?(Lp<6FpKXh@Xj!M*lJkK~XE&XD@^FqG>1
zVulk)g#lk-YcNmr!l3!^67^1CnR6wOtb`v@HTcno5Pl!3nR&>FU>IU`{
zJkJ?I(&w7VZHiKj<|<+db+0kRkY8?LU&58-SiTkZUvRqU7xds0E%+F*v2`Ni!h#&M
z{lp6~dEv59ml%Vk754gZ<2}-?)t;0X^Castc4Gqz0(5C99rL-wWf6#lR)o34l@l=L
z-iCJ6$ZazzMVpN_1EQ1*;VnBRh-*ABV)0DV{#zi4y#qCR1&$iBhU@Ibkv0trMgW+T
zDIQ+&+@iELNtvz7)AJRbt*gvGamFQ-!luoDqN%K-8<75NY(oJ67I?+IO9k8abfJ9#gLUVGmc_{Bb6Bf=o|XKxd-corZ+92MZRfp0}Q
z!(&!Kq@<_VJ1in8>f3NYsqzcxI6w!ks6lL|56~7g$3`iwA!Az4;;RQ^GIbp+VK|T<
zgeSdOv9;Qig%Q>GB_Rvg2TKWD)D+b;Z09WP*43ckgjiSx4rluP@nH9oo5ILPU{eg&
zE)mD*ur|u~h7=~QsvaIZvWxSi8?6S`6)N^cF?E2LBcz#VeJXzUbSs;C!>%1
zx{%T4+3+b)5X+(MqMy?cZ6?*lO6y^*7nTkeRB~*CY)5_Cg4PD5O*1qZAM&9#$zU~_
zT57WB(pZoEcc#w?ZTP70)v;Nsg~FTK@-8FS3XA)h&$DN
zkz5*r>U3tvt*y1Sgcain`*i$HiojhsM8^x&9=D3YEP7M<`WltL!f=PW$5-p>(rZ}?
ztS6`gqf5G1k_A!bNKHsvxEk$R%fGEy55NTNji$EG%nTJVw&-$^6M%ObwO{Roeu%Cq
z#Ha6vF*%i5%jlfPe*LD#1UQk&2(D#cE9q}dw3cjv2eZX!=cmw1ijQ%3F`_ovVeFEI
z%+CVn=HDjak$Am_dlXNB+_6e^nYo4^U*@9MU#S-dJ!Lg^0YW0%|IRS>@=l~p;_
zQc)K$p)_#JBl_S^x9I;0c0Mb6oE4Y$mWDc1T{M`9{r1XdGEldlDDvZetq?<%md=Y;
z)|lK7wR6$MNC5ctSJ)ZRe3jM1^XdM4|6QV{KDnCP1>;I&@Y`Qq&vtV}?@YN{`$NN{Tbxf`HE--VE$v{OM1sUs
z9V=X0&-_3?my_BexH3&J9Cn|18XCu5X`yp~kcka$>Bg>NWp$=?yKtH(hxdi4%OMjN
zh<<)s)cFA|LO^7I57M(gw*@r>`f?5oX0OxOHtCT0>?_@A68K%lmhqP=gJwLuP>Eg1Agz&QhQ{6(G6>
zLuQ~0E$X235s9uv&)KL2&fuw@?Gg&GuklnOs*p|9;dAZqY1F9;^GOoDDH;qKz)xli
zq{cVlbNS%daZ&^?G(4qw295nf)(3Be;o)eJg*O{J27D&kh`NW@CdiO~dBU(Y$ql6Qe(`FOTioo*0A!5Z*RW
zb~4=Uw#ZdC(c-4?4p2ux;UZ16Cr?7ekO28$NHWleQ~#}rVwuU7o)^{oN$^Z!S|G+-
zNA*G{3@Y5#*Qjz*$A^+kpI#;`++A}+Fv7acjmxKY2}u{GWD8lcpSVQri%Gntr{|w)
z8&pz?aE67JQM8VylD(Kg#ZZ-3&xsC8N>Z%IJ#3XNAt`0ae0(^#K*LbgabA+ht8Cy=LWBu9oknlm
z9S-do$k=@<88BJ=r)Bvq-0uTmF~Md`(RmY^NIGl6%~7W|oMU}P#$
z%_MR;tYB_*FcK$T5Hz6v*1yIV2Sy*)bXYQ#8Xf+ugY(R|U`8yFtWJ>>P!Dm0)A3<4
zNB%j%lY^80Br%
z39gdJTZDi7cBh5E9N)883#N#427vjW)n&S11%s=IKT&alC2Sefples>B1YKaUh$ve
zxJit#xq)E~HOu`-pp$gX=<){>fY`uVON$6Bv5YtfNLC!2C8H@Zgvj*pvb#czsFqR6
zs{BlhV52?cac{|mz1OP3NpgbMV$MyIN#=A0qMc+}sT78iB>Dm_Q%)Y%OgdmQ;l>S?
zM%)*AZ4rslkz(lO;(B8MQqgYJL7?W!^crnZ^P;IfAB&&
z18SmJ;ZdZloUGlkA!%9
zS@n|Pc--1kK2^f|FxnN;#_aY^3k(Jc?#SXjb1Hs8T>5Zh`E-oDU8KA9Qt=2meJ23c
zt5SoZkt~|I0wtG8%EcP#h*BE%z_c~c4?%nx-evoyH8qC_s}IN+1N2_&5wz*dA$o8a
z0apWE2gbr3{W{f^=3hlulE1RrToZFh%B?08#?+zHue3LHWAF$N0ekc@Jzs4<42z9su=
zm_92S4iN%pL|Xje_5?$PNMc8qr9Y8RBqN2prP_b}lu1Vl{j_$d^v2JnqQwzC7Ab0X
z$vHSkLHoqxlw}>q7>svm$T&=*jpFL4T&bl)4%p(b3xWV7JvJVl8^;)?e(l&sATE66
zAWKB2xkjg#8zhV|Kvng4863l1*zd#}CI-3r4=E9iF(4J+PHhqDsApg=kdFM`y5r*z
zDWlII9j#Ab%HHqg>JTZIinlH^`(L58gVcZZl#;QTUT$H4(l!zdfkK=FB}${Vssj)F
zUc~-q=6{;M7FmAh($Ic@5(bYW`WsPi3Wr9+huY7>RDh6ZOUEAI?5G|6Y+F~an7Qa3
z+E|L7r33M3{qB`O9aBY8$}4Xl
zo5@abE%5{_2SZBhr%(q&m#&lXpzb#wx@hb*{i_>gi%Bi+;l|Wr1;cQnDrOcFxRIBO
zz=kAgKs|a^=Mfne7L)A-_au)b%!Y|OD@8*}*(m*8aFb-<+!z-}@R8Ex7!nSV(2*u8
zgc*W0hDiJs7b$)mj1ujD6I4GsHa?Nw$wS#>;0B12tobiwqg>!M&~0&wu#`P!k%-?!WCJRQ-aePpd
zFO;UhpO{GjyxJ*+?#k7yp=eCZX%Su>t%YIp@z%yT$v?>Utc59&3>dps@Yd{K$)O20
z%V6-?d?A(sD8x%c?|?O$f{4I#psJzV591i8ZAG$ZHyjCK#jUQK&PbF?O}^zow%{h`
z!^OcQ0JZ6L+ak_1MLN}cVPFH;v)5Q}VssO^@)A`tMGx;DZE3-OZM+ThfJh38MkY->
zO&@J#Q0Z=cES15rU^2ZKF^MsA#&9gcvoMKq&e4kXxVe?aG#H^h61BzZSUiu_Pq^YX9KUSP+q+^#acvY$*B8@Ror|Tj%>M_k7co+o`I#cF>2bub
zVfY%afZ!m2DnXJ-ByWk=8qDc3H@X;!lPnk-_+2dDZOqZ^wP7Z2z8U;Ds88B~WWVc$
zDMh4j5*tq)Zc<<*^wN7Z@)Ce(82IBg@wW|Vd@@g7y4IMpj(U`X86%E6o&qK6ov=y)E0HC)UEum@E$
zs*M>l>+Yh0C}r5*O@}rr=-kjya6ybVipU`$xmm^~ppqp;B+oJOy_#u@vq;gjK1Zq
zVb5Hd)J_$dJDRU+rQ7nRkp3v8O|>zftub~un%4$;t`=1OPx|X(s;G=HMWn+GOtR#v
zjaeIMT|N|ecs~|IW_QpfLvrDGzOjwjnpXOM@acGd)I94W*flkp@Hbv%NRng+SL^)L
zd?~|w+IwRlIDee%L!7-!ko`Ot^89Z+7@BxY5*9{_=IWW@>a&Gtqb^aNpyIeBMvLU9
z-a+%v$x-wo!uYXTr6mVU;{k8hL;N@sy))cKEb~F7dI~S
zNDPH-5bqNm*T;DPJUHcFPuR37qz7M`L0xRAVfJlTOrPPiPVh}x2#S5X0P)~>`Rc9I
z`lJK>UlHJt_PoHh^clNh!2-E1CS_7Q;x~Aa`Ejv`86qqB@rs4t9-PS5!-ZY?;0=1<
z7xh6r;46#}m#{lm2m?cOzwh6lmX5dp1${d`D8Jp__dV{E-yxRfS`1Q-y3|&D5U3ui
z@yoThK>(m}Gr{Pq$dbRr9txi{ob#){I3i354{@Y;�gsWj$)|Q50XIgq^=u4LL)^(
z+dQ4;Zh;gYK_jMi%+-&<2S?fdSUH>-HZ&vPOK-^eDO!&fzsjU8x;gh_9p$G>@4rEa
z#h@ZKSC`(P3>kV|-mnV1p1S#JL^yx=*w3pBHah+2K24wz{U&O9Lnu!6=
zT&-cXeTBG|Fx&J5?0Z&xoEHl|YwkTuQqWs;(pt5BMLB#NUEG@!NcwPY`uy&lsg9{G
z%hU~cJBoS^rY8KC*bO>irQU6}p)2rA823dzJ{R!2iHD9&QhNk;9dxFVK5N9I1XuA_Q^jtUa`A1bS7x6~iz^C7r8
z$Iu^TNpHbgq;)5#Sp0LcZ(tEL`3C|O%)1<-m=7+uA6BG}e2!E|!N|&KT)nim4RmOQ@j+K6tFZVRt8K0i2ZUgic^J+I+n39CCPAv9dOYsyZ!q$Fiv
zUTeR%RQZ{ZmpoZQZRCW&^4KA^q?yB?@9I-Y4Z87`1%+rc
zhQ_}|(u|n_u+l}Qe;TNGf8<)b>)I-^;U(4S8oz8>klhP6
z^tW_o&;Ds|--TW5(ncH3gtgr2!(YjSd8zsB8{efJp;^_3}1_EaeMktQ_=G)
z%`}kl_GjM}Za~c7;v$%Nvc``Tl;&`
zVT|Gv<|G)%cp}3XSrA1-r}ZV5FDfKyl+UxtD&G_4v=cx}l}Svx3N4k}u_=#5anljf
z+LlSsD3=vcHYpV)mn+dIk1Y;u#2F1kwscj;bhyL}(IXhPNHba{Os*3*u#Q#!54I;v
zl8am$XzVmWs`C3^<2noQMRV~Z)WHqp?Lc1QpMq@Bnskw0dg$CJnYI5`TeqJlA+z>b
ziWs!e$|RwMs>-#4ytDY&dpl&=7LB?SaQQrGJXJA7iog;{NQ2ZrVH_#_3r}&D4OiUS
z(N?ZJlm``T<_J&L6^<=SZSd98QD+>_h%EXTy#>V$^w)#^pW0ub4TY=3;_>p}uA|@;
zF<{~A%=0%0G?~vk0p@PVBzRA=h*)iB4)1X+5PAl|s63xV|7KG3>eV#(h67lL1#ow%
zJvs?LTlGJyJ2na=?gDq{Oz|PJoXrSMQ*z70cD0KOoYK`IzAi?77_g$3o@F0%kZwYf
zno@9Y3hceGLfMyhWnNio;pSFRpv0NAJ}G@MQeMdSzD)2~Z{oemQ`1S=`bwOl13+W3
zJ?Z{gh-Dt_G&O>V6_ID@_u19WZB(SFqOGXTQ|PqauNpUEG29GbV^W(IyP6lA=2MXu
z>?vUZY^9rI``>(HM9vw5?LP06Dkp8rAX+;g57!U$+KvQK@$-_av>RrXk
z*Qq~!-hLFl%jJv2<5rFHUb9d^d+^O?lPndC{-IIq=x*^ME^pl{Iy&2Je!1XsagO(l
z{rYWeg$`B;J)gTUx-LS*lN<_}dAL_DTJt*=5*mw6W--#iACZ
zwTO48!dtW_o_@BmCiicN
zBvg9GT(OfZQL5Ac0fx_lf%-`c3)+NkgkoHGsLlm-rFvgxOOPGVv`KrY3Ao@l2$a>o
zsG{}1qIG4hj&MzlA;g(Vki}*-!W!D-*5=xZQs`BiZg|qPY^*;Et!nHqwM$NLcu$>T
zud2^Umpdy4c`qg(62d(6!141cTb1-Gw)q)Fk9h*!LFRbazzU0`Src1T8o5&cX3$XT
zNnX#1TRrlQ=ZVVw&*_D}q{^f&8J0I0Uh1C;$ZJx=|5Na~Ca9p~;P%%P3Vy#BDzY%c
z@_K%HQ0z)l*O2SAk2afw(nDwITwki|$h+cu5Gt|5
zY5B_H?_Y$B+OnBHE$=8IK(eyZCM`ZGk)yM!RGwdWgfGc2ZYi}X0+Tw2SxX+tzy?=c
z!~TaMJS6s{0bN;LY;h*es3a=WNjcdgY<@R77dzj68}71fjxHRn8-(DRTnyOk;f$9M
zN<_PL#401AunWJ`Ie4KS
z!d-F-r&vX{R#7T;4M)hIsjz@Ecpst1C=W3UT>$6C+Bo3RRl9H$9ZZ;-uZW_rrPtFFNtmk4>d7rkZ+{trJFw@0I5|F)jTWP1%?Wx+*@V`o
zgzjxZoiZP;7oKqHZF^$=#QVIGFEPk9LO*2Z+7hP?N1nYytT)O##2~dA0y3?<9Gm!M
zx`gA0+0S{Ez!DmWs5V^|KA%m)0-*}NunSq-vYO>~>9X&5|MS&@ywe<#fVZp!?lH>V
zPYM&=Ja4Lb_OL6FGl(Y7Gu+UK40BxA1_CBFZM3LQvi~>R);KkPQ)r7dnFc-%1
z%Catqu`4MhCr8gQeZM^JryeRL^&%xVi=(H`dIU)!&ax{hBUg%Kfhe2@en@u8TPgo3
zE3QfjsB7U90M?!it=3Xp+x37f1dpEY;u2_L2yZbeJDZAqaHlHlBd~@)J}E1=n#tnv
zz-sk$M1~@wD(C~WH#svViy((%rxc|fKzfgiB37R)REJ@d^#+NVrTM$)GIMef+Sog`
zw=L$+r(|alR$K&Is`({mWaY@c9ItFS`SL(|jgQF8$f41MZ8b6A#%+oD_$BqD{%ZY&
zvi1@1euLb1_9tnHYT=ckF*kq?e#Ho+*e%q1c{sOwZ^`jmbKH4ak^qRdq7_Q3}WTWo09#7l#{aL
zyZhEtvUXN0Cx9ok5nZ(-12&VN|C9f}R4smeFL2UfQgJ4Kf`D$D4l{(_KOom$g)kJ^
zlSQX4=<}nv0G)5({85a~qK`JP$r17iNG>wP9%B#w1UXGy^?QK61sVU1>D0ZzMl)GT
z4g%9HWN1%zww&<`TM=0)D+A4Av89Zx96I#naY}M_FXD-psSD79Lp^e9Vg)2m`O$UD
z=2u|bM`CEe$l7`}Z=U4{{-VfMN)#TbBOhwCZnxbt={2+zFFM2u!UDsb71f{)p|x&7
zVXuq-%JkW;
zxA%NtZ21+XS(e!+RAQ5j;n;E0ixTw7Aq6aTU4F;XGipsLRX$KtPTcd{^N!{W!KD(E
zTY?RymHPLzcPOIi%FhJbom#-}SIvuL)^fxa4g$y_)AKIV`G$R(Lr_tzz)rk$kJ4sGj4nLDKeep)$s-q0)4znpZ
z_#O{JxxQ^|e8%5x+umr{dXA1;Hb0XybP3q_oNrxhJFH8N4SQCu4EC8YK>{`mMGK3L
zTNXc)({~geG%b82r)%&0zZK_J*ptpw!rqR$VsHbZx1~vhZxz2hPkzB4or+ebXgI9ODx-K(5$2(>p42a
zn;v_a!4PIwq|ZjkVG|u!{rwR})gy3sDLVl!2g6_ib6z^yh#EkbkXobXpaD23V6^Ui
zaaIAxo>thFpb&4-n=&=EBIiC3zK-osszU_BIO)?w&S~
z-Tasf7tlR;s5pYH2nzER&z~qUm$KU0w!Snmw{ps@=+qSZ_|@t04pbiT+hd|&>7P%*
z$6(5iJ})|>a@t%~QJq;x32oILEnJdXR7EJeLn!-K22ai%B%YTfSD^GY0GKkoq$<~`
z++1~+`>8VeE&+voW16nf>@#KM{noB!(Fw#$)82iZ_1lX|t%0}mK6LLc18oZl^4851
zvfKdmx-~)nKq4Cn=59=`-%)th9RFsMT`T!-Q8AKObM3I93+LFHT647%QlBBEG3`0J
zY{~peZrE{nt~k7;LW@DSqO>NvN=O~>rH=N{Udda8KS*xeiGS9d_mNz;75|_y?;*Kb
zky?M5!NFqK@H#n8Rr^5d9B4a(Gk9zC=DTkPeEyW#jIa+8M!d0O%f~V3NZe>N9XMLZ
zy)rd!lSGsWXrbdus+#T;?2yF2R$aZkqkq{dy{OOKn9#qj`0faf9M4&fcpVJQ%DwbmcB(;m&o{trv5`VLoLhg6k&)^`#ltGITvYvYxGyNzg_p_VMwpKO%?s&u|pVBir<kbzaY(I98;xO3v0?
z)Z|bGT~HA$d9{a4+Y~UKR(CQFlA__~6qm)bUwoP_{DU;-ChtL{ZHf;VnFRNpD6)x_q|r$k6{go&
z%|uCQ|IPGA3ec^*`OSvEv?X4OM%bwSFKyZ6SOzK+ObhddT{x1f4c#0!$?vm*Vez)cXRiMBIDsyKTu7nJ|At)&Z8)FPvvfQArIdJCc6iL#-gc
zx_5jY6t~VI`4;B$U&r&M|5JXNFFk71@guf3VzvOdp*csoUgx9E5t%Z~xuxC1
z>F2nqoqgZ}gd2#)d277*{R^%AredBvw0io&jZBaTjjTLHuO4}rh_-seh+u)qV4n?o
zf)=iGlfe!`R1j;!NlD7sK1HA?P5BR3a6k*mT`5nbD?=HB;|h^PGzt}y+Vj~;(Y7`?
z6(p5GL~L>9oXR!e=t7tPU(cR~HGX#sO|6HaKAdj{Z-ehCH#kMb8U5D)XV^ltb1oAL!ye=|rzZLs2Wik_^C@N`3$)OAuU9-_qg#umY>-ZjoUS%c~H96&H8m
zw+AM7ju}@jWeT6Q7IBKPLDQU#2#=C-OG0*r3-X-Ol|$Db2S2H>BNh*o@3LVp1LNcJ
zF)wrM-LOJ1Hg;s#SZc!NR#3sjfwVqJJrGl#iMLw~@ENY+yvmc(2^qVJoZ@}=($QUL
zf-J<-_ct0Ey@d*i)t!22Yo}LB6BQ8`RA=)wTJD#O>rtsM`f#v+3>P{Y<(=kG8@KJs
zVf}2R8-VqX?*4CDfF*Am2I>E#1@xBuA(b=PAzh9nrtrgJEP>Z9VqOAH>yQYh0mU+E
zHabEB=9oocTed5kkKvGa#?j}hzL;f93Y=!VkqehH9(l#N=-2)0*o3-F=B~QVV)prc
z(fQn})gbGaDrt{@glwPWLa=`{i(R~J-^7&c2P7vJ`mAqOTrbawU+}*^R`!Tbhv2!}
zCbHWoSbB{iM8Vv8Q|2p5II=5@$rSzEz-eFAzgs+de8-y0rUor)A=*m$_N&~qTCBKN
zc1PfZUZJT6(!FTGfC=))){Z-r3MYv|_9dJ}t$uoR9EyvoE4Abn4(f>|6ceMiyn2bF
zaSV1h>5iTzTSlBE+v8OGP66ZCm#ZyJ)03)jX7n(MFcVPLS{m|*LB$XI8LKk1;$0l+_9t5objSzNg_LpsWV-p*F~l3oev`Jxxk1}JQ<8i*M8O6k(Q^sjvKw;@)OXdqp3$JtIz>3^hpa
z9-LTMN~=gNcG}sb$_>9!X@4Ad*~5xSX<5Qk7o~22*Y$fnK%;#M{^5Ol
z^pr)w{s9-d1$Vk}-8$XhQTIjo!VR#I-XFUOSby#Chkk~qn4r;@m4
z(0o$XcT-dzdoo=m5tT>%BHX{4y)m3YJ)v3&*r%a-v~#nInWTeHwWGKeReH?Hs3iM!
zw1sB@7lkj;)n2WGmygqv`36jCa#e|#936B|Ix?5T%nY5J3_3GOA0@KjG4>o4+$5i_
zTa|nznu7*waOu|27u~dz+#hCB7@cN+!tvrO*efV`(-1}m#lQ)eHQV^WY6y%IEnhOx
z1&!v9#_ii3IF+;hvFJZK*qBG{2tmJ;&TPq~QCE6SXP~;|A+5k=EF>L<$Zao_6KEdA
zf5!I7G%yJJNI-_f@RZx7AAP+hDLyN-N
zU%F87`apOKx@tY0-o}tyO}rO5;e!?eN(S>_PQt@uu$@$rf`
z`r#_&;E?DY2nQ&~MGrGR-1`ejPT`paBz7LQ8}e;?(rBXw8$Fj8f`Sp
z?jzX58Bg^pm|9pMj@Ep@sbP2lg4vBRX*3#H^IBt%4eJ(@@U9#!S#i1Fh|d3=upNG~
zcJrV`6qG_sj=6mvz8e7R30NZi=Tu{SRsu)xnv-0BN-jBW)WOly!F=vvvyvD1H@<9N
zY1mdBIbe*CRVu7u6WMH3)fhS4M;GrW&JPK-fiGw40`y%-#4_PiP{{Hcd$;r7Z=N4UTUU?>ecc@`>kezJeT)@=@Xw%;Y&e^
zGTImm;^wMhhTIsuF#@8ej~R99l)o)~S+!uZbR0>-D$EHFnO@uMU`Ywm>Z;Hm3ADHS
zQS7@{=WAHQlz#6>kwXfkvO*who2%OuL*jlxqHmhqeskzO{%nP8D!OOFIg6^Paf2sx
z=d_j}Em;>~o+!P9!k2XtTz5W5k6NShKiOB+~BG2SRRo0?Bav(-Tc6!C4_m+KiUxIJYqSqzcC`Vl)$f~P)80e>0xg_mgqU`
zNk`ZQZj2hIl?*@)C&SB%*0z#2hvNMJy#stRLa5mO`N69}7Ge_*oyD6YyPWF&X+e!X
z&`Ynzd}3x%PabXRepW8*>jA_809AR-C@b~0uw>Ff1%Z^VuT
zvkSL3LDEq6iJS}(Q^~j66=+IH2k>amjk7bBBa48TE`?=6m{W+C=jKo`vsg4{|2!2JI33*4R|TyT#{Hus9GHurTiB#y03tNT-V
zoB8K@?86ry8TG%|0IHp~wCGV52p~@hPQxRbBUo5Yn_|wy24YHlgqD)S0Dj
z7eI?{oo?W%}2ZfAJ_96FSi9Mf(%U5O2LuwA0Vfa<%#F(8RozJA@o&|e{b_Y2y
zpvPkQUihF8-`^HrIE2-nI<*61+-Kd@7%LgC_V09tRPz(Rhwrw*eE$!|-a4qwHjWl7?(SOL-6goYyA>}G
z+=3Q&*S0{4ySuv-cXxL!Rw%If?%lh)cV>5HXY$wkCU2fR^3!upimuPB0sjQLe5e4-
zvju&qX~5f#8Vj*cxVGK=E~)?$zua%Bx3*pJcf@ghIPvGn_a0#59?;wTI5Q{ud-j9G
zB!sfJ9Zc(UcYgk@^Zl@8IhK8U*zFYEag1IBSMlQ}c_R@^K5UO>|F3nt3nw9Y_eWA2
zi8MH2H&VNGk|XA`s3sP-28E?tDr!DGMjdsvREbQjfGKMGIb?YD-?YVU7n^X?tA?NV
z@;fnyzkK;9|!UsrHz_A-LP+GCWn}+r9ObbzUJhGCrd7>i{l+@dxY4I5?Uda}ln!9W*r_
z$iB2~+v5v`^KqxwA504W1>7X}#6u42?O-N~Glt9^{XDFLR_$f8D8Sw%@b5Y7pI_du
z({aPUf6o8qu(cFyquu}W*;-C`))c{~6K|6c`S+|C*BxuN{gx7#E~a{qq1%JYKp)%U
z*7f{P=QT>rx9Mn^`(|qT=HdExoAEhT!;D$~6G~-;xj=Vnkq~!-4No@1FYymF
z^fz38!0dq$9^2>XV?88+rh-!-;4@7ZiCgKT-g{5Mdt
zzt&;k8+cMeNCSX060pk7TKCPnURGe+AFEbtCr0@|=BPhITV
zvcGB={h*V<%R4lX_ca~6L40y7vp>rh**zYA^YqCow`lwq_jh>PLY&fZy!g{KK3d4S
z6D|OA+ULu!D*vL`hG;Ii7uU5>9X!e+W@aVEQDk|+htvbMOLlAq3i)BZ+&&H&8ndY*
z0v$MZlOfLk54NJtqKKlBbiUH53H$m_1mX~psPiC#?OkGva2tje4aR6-~{&RQ>YFG~5N!PF0
zJ5|B9PG34es*!jdqFq(d%dB4i8`s?o!|o&pLj$xe+)H=YXXZa4uHGV_M&}osX=(||
z88`iBpYo^o!c(U-9@y7E|et_`E#Dk?|YWx^&-t#TC_wwt){QWCR3bN
zD>gb!-F+Uu!%Lqitu&N$RvUaRZzSk+-PV7p%0LPihTe{r<#O!<9#S*z&|~Oe85X`k
zJ@1``1O}|s%2snb1l+;fn_INg6KC@Lp{2(&m2-{c4KnE%z_tK9)C&E{ax_Pu)>nso
zJ&*I}X;#W|Gi%b_0vDn~z6lz1+x_=@r>oOnMxqZt<_Abr%!qZV9P==RlD?U>m2uUDloBIDI39xeP
z&Aqnbh?%&_gp8ENQlPx-PA3lBBuK9LJTglE9kDOc
z^djHpdoIadj1F%_ce}b&k=Uo9B+~V#KYax)2hD(!uA73zh*BPm+^AnORh@G8w$MG&
zCVvOo);Z3nOfozgE_*ogp!y{4%?G?(!XX8##4tXCzN$Ma05~lOrGRl90)s0f(6#^g
zx4UobH-z~;tUPM;6WcL5;fv^AGrO_^R~+5as{AeI(URnMiUh>tb57dhZ1V%_BZP^l
zbN=BXT}V$NvmMftm@a}>wxk4>Xm&!@lD6vPk;VTy-1UFG6|s|Hqf9
zZ(BevA0W}i^+L=veCVTw;C=$T+UqegA(WY)e2lN|WqAmw_^H+Z!G1LVgZ)HQhbdKw
zs~clSX|^q3XJrbC1qwG4w=KxbF7_22fwM-6;7id#Y{UC4kU}%8LR1^w(pZu1iShnu
zy)Rpn^Z|a7-kY&K+-#A|62+l=87=ZJ5|naRwujvyrF~5$2GSZX%Kr+Mkm|LjOWZ^2
zp(g)Wk(V^FAnTrf4mMJh!U9=`-R1Nno_(;q@1ahc+sO^^mi2_CQqdzr?Lgs^!6f6J%u7&a_
zJ3_jU4c3z-G~HH_*T%q#Sr=?JArDUf#g#CfCR=ob*dbiDz-D<)NvqeT2-A>jmg(!ghX_My
zJ_N*?OXL0z-{>Qxaq=I&k?cQwqpmZ{#P0vXH(K+O{fBSF_@DU3p8th!^!Cr{^8NGLt8!-eOp^V5FJD8h*&?{R^z2g~#amcldB#G42f=
z@eX>>{&#yn^srZPk5yjaJVZY3S6BWr*NKrCT;TS
zjz2BkDg51kP7i+q{8t9VRk>B++vqa>4Qw3AU$-NWphq6>P9CrFxvSXO7#D*ou(&-3
zWjyg{EO&esQSu9Rx1X
zJ_SakY2CR0z>Rs9%(<#~Yn|V)?j=2dC&4>x#ODfR9>8!$Dcy~jGH9V@_}w(vd~KoT
z!6RFxPNyMVYO)T7cH)zjG(j(NGLqc(sMX;=e$*a7xHRI7{Cph-f-y0fkz^i?yK3zzq^)+cqKF)K32Cbd
zc};o%|F#2c0D-Ep2_}u+X!CVY)fmh?BM|V0ln`H(JZv`di35xW5Fxkk8>Hp3ggk=1
zsMPm5$h$ajSKzyV2GcXHABn|&R{Q-Ax;N3aI(hO>2}y$Qyv#&a)qqvWK~)Tb+{^r>bqnZ*cD2pbnzA_p
zt1mzy(T3Xx9#f3H2VXe2@$_nYycoO#7FVVBx*{+^#m5PE=#a5WY6%dke5U
z{)u|X)QIZS?D$pW%7}(P9do+4<5E9%f&4cf2ibw;A5Kqzt8wtA44+MeqJAJDzuVX4
zK9d^D296UB(tY$q$E9ebVyvsR=E%@g#C>}WY%NETaE9tLoX6O>-ht58b{(hg712Jz
z>T^$5`Oqz2RQ}8Ezaj5CnAP?vm|DNugAuEPPAFqk^xSE|E>f*6B0=W^_59N$=8wc9
zf*3a$6c|o)KXu6;$3pFh?H>mdnDU%ri*`G!X!X!eHp|zCZ`TFh`&|9ca@NuFiA2%q
zs<(GW4eKBF5x4Ab1@NM5KTcSK+^{?Wkfs@4_WaHpq-jRfqr<_CpaCIx$h)9ld)Mo(
zLD`TvT-`DvHJt0D1W2|bGjQ_#lFI;B`0h|1xz3X>U=5~!CtcSsPnUM(MKpwXnSoYh
zqsN7$sulaVeS44LnwkW0wxd9B3u~TRPf#&0<|tf}Xnn)$jgj~g@mTsvt%*26MZ%$?
zG%5j?9WR1A-rxlz_xjt|T|pamcvjIIo`i5^#O54S9@8LEJGS3j%?m&8;Zh
z>3IE7%$INEF1?InY?Vdyx>$lYr_%+2`Hx0ewu5uOVMAzu6i*zb%re?vu-3J;30y3~
zVxRZraF^0|43Zah8H0s4E8Fz^Vv>a~hP`G`+69w^H$NoX1HPW9HvJHRYMmH*->nl?
zQ74pMhOXpy9i-73M#SWye{gcyFly#Hk2)pNZ(EQJi_PvQKf;$Y9J|!MF
zGCsS-nTN_O+QTN2>dH3zfq~Em6H=meq>sb9>$zxguQZeCz`ly2l4iK=WV0pc
znbd*r+(^QLP-!R@1F~cSR|Ydn0sKZt;1~%0u5Lt4<|Z(vrG-p8!Dm2q4}uCpMwe~k
zxxV1X@Ly$dlnZ~UZW}3~0gR)RLu_#rzkTki^6T2-;HvNzgYOQtpQC#q1mXm_uFTSb
zyBSjU4`c}eImPia0l(w->6&$N%4C`-I7{ovbtcz!DiR?x4XmQAu!dBMZIw#cFfKyY
zn8;cCgfwMyV1=&Vem@>rqdDyZJyqAaQ$xyl{dxOLFN53}mqDQ4;dU6B;VhoNI0&Um
zw>+BPofXO@9Ta%+AzuDxm*1qUGw@`YBc}Zmd~)MM#HUa&^Yjb
zO*7ofAnBFBS)1x^a{H^)t!yw3=>rgX$timT(^-3G6KI}txr33&Up$HL+d@y^OjAu3
zA>t>p@!e}1l&me;s?nl=Qf^nZD;t~~Bxhb3Pa8oJ-Bqws5ox@4G%38-il185%&Nh$
zrrgR2=bVev(W^)9w4krj45u_;$YYlDci6IW!G+oYoj(Qgj5+02EcQqeSH@l0_HW8b
zSBU&a)(=FY#Mg?1JhA+98@8!UKL#nOq95Bo`1~LK-@N+WKS9H(r*}@Ah`4_GsIC80
zFLzYNBkZ!r`zof=ZJYB_oXqGLImK4!ifL7loj|ILYm!zrBRUz_r+;4D27CPF52fYDO*$(2^rX~g
z#5m+PemWy`{t=pc{BoJx*Y(G7TI`>Ul{P}8J?WQjw6OMov9--RI`454PvV@@`u9e@
zah+rTdB)D&E;l_=nqzjpaWDNuzgC^A819Q&O9)Z7NsGrSd1`t&U~F2Ea)C9xB>u(}VIkrQoP|laP_F8PFdZqAsyI02p+DW{+yef6dH^wlGxo
zHMGSS9Ci=zjl9zC`UMtQl-w>;|}@>U_ekGMTa
z7M(cCs~}ipg8D^zoF!F1Tj12scn6eLLZ1yzh+|~0WtEmrx+E~pULaq^7wAK@QoZ2r
z^+C;Zgxku4i<2a(yKFSrkIzj-b<&EE53(Dx-J-CT0S*H>8hyoFCl)H*zD
zSvL60N5575%;&khzYblW=x_1q?=$oUZAcBEKgWW%mZ&ML)ov>zgnERKo6zzH!UoX|G;d#T3#<0fD-}odlzWG`MXL2UapU-XEMbRLoRFk^jS9rbH$n+lyNK7f
z4r9W4T6)#qks~>Y{ig-F{t6Kc&6to&7H;VOj6!S
z23n6|b>fEGI=yDa?@U4ohwC!yNZ%Z(cTU_I6^GtsMeR%$^-j{~^Mx$y!>V<$C0qcT
z+Af=4q^Ur5*R_t7aVoMmG{y-3gh&2c9M+J`m?-mo9S}7ZARLEU89A=PGJ2~yTuH09v5><#`K|D!c}!p`J+VK`vlkQ&4&s~X3dLD=U`>b;B<
zn7#WDji6M=6{@!i@3@vbxhp|J#pKdTS21EK%vrB}gC`e9ppW)1F+w%&UV72!g6hbo
zf>OA8(->B*Igk_!KugYURM3ukd-1ssMt$$35a@XqpPRrWP|#;P&XNh$J%I=gJGEX$
zhpYnjPfFl6BKWM=Q1Bc_6Pw+y)D;5gSA$i9nsj1Zs-}ZOB|c9awWE;a
zltEVuXH^CH_!KLLYI(wr;IT9)ZTMwb99B(&hro~*3lJT`WhqyGiwK4XUMy%6_Gzi(
zv)}~8r0hZxJ}QtRa(CMskQxM;_k;7h`s4`6Vt7!2%Dq?LP9eNBfe-{2&N~7lgASJ8
zB5^yxQHcGmLC&+vuxfiOxju4ueW^PEPJpru+`joq{8|}$$V3Bc2qHy(;`GhGvDe-U
z07B^34`fEPy08Gf@>twv>lr@iSxVmEfuk2691OVM3tw;o#%0Cq81nP`NKijab}AA}
zzgEI$=@gl>l4`gv5^{e>S#xnBnGzAmR;ooUwTdNvVY6dHfSd7xw_^wFL~MS6oChJx^m1ARj0RF~lH9SRAZNDU
zFVrAp8tz}$4)HsT9;(g7Pr6vTBz-thH@@aOmvmKIh~S75LX@f$M6jep{SYWNx0F95
z6Pm5ju#7IGB#%Y4Q=Rul8R3v0yH86q_YquN7QeGd(x(M!+zkglD9GG+Tu)R>a;bsKYK;O{H-r!C&A(}#1oH92jU@X99@P)Z{Ng++37prL<#5MHI
zi#HrwL3aNuIJCrfhYGxTwY3pSOa&sw`H!}exMPR88h*L;-~1y1IUH;pmYs)m&0yJO
zYyo16Zs?{?=-`mC`teLhNO%n~fiAtf$u_E&ji8n9|XBRjFU*mt{FosFx|
zf%{0ZH~JSdGx2`skP9EfMhLXhHy&AV#pjUy0!=N!$99mG;fYReD?Ht|Z@M)&U~FYO
zojMij@2`W#3j*fi#Ov`Y*AcI*8kQ5Mbh5&!C2*z&6hI86>|c;$P}^+wrpPI+M^cTD9Tb!BGpjcSVsELO
zY|p;~dF?!9Z;mj@AfR4M$P(x$>n#IeouLGb;L4fm93j3U?`9E|cwgeLiu8>pBZrNX
z7$hsS!~#6Dlit|HjZ7oS+#GdL51;SRLC#urY&Jy2C=;&D8DfE{FjgIgioID>?Gttw
zvqjyqCCNuzArHABC2-k6PlWgc+F=q2dZNBRwfm3%Tv$W&96$b0gCLPB!bIkOk!wf^
zhugs{&~tW^P|HOuK9u8X68=9;K-h*IMV=#kmIlJ7&krg~(%a#c+ad2fXp5(0kFKaT
zE?hZ?q3JIne}e?MKUIG6nxjK8|6oJ`5m1!OWF*wt(9T6T5zgrFcKC@uh4dXD%6b&J
zZFA)3sr>pWgauIpTyto9VUDxj?z2Tq{h?pWUi<-31mrUjs^vpiwx!qv-7tQ^?+T9o
zO1zy=e5|`gGJ_#`j(K$X%V>Isw}LmZk$opANbk{wBcQdd2Z;NU^QhOR_i=(rMs3xzG>liUbo2RK}%q&Qg4IjDeFw-;@f8PDO+|GREQqY
zL%6I-06Khwc)SCrN|&-||2Q-cL{am4+a$WQQIqFZbr}zb)aJCOzx+Uzt!UuBO&9R3
zcH`UU*j_nX00~4M(1BS$26}81lP6dB^_jzSjNj8UaCmWXy``sfQ;>*mRQuYhDx56S
zizuT92hqL=;sO|K)2|s_!*~>CZBi={6j{?<39!b
zKsf*C*1Pn$-xp@1iW)%McmI1T6(7W4`|!z^qvw8J;79z-AZ*Tl$MDG@Mw0$FK*le4
zsEJbcFa4PI@x9L`aJ!SM|3dsbkE2R3LjRbn$4prN3KIce;C2|Lt|Zs8yPxKZa;d{EjBLkCpn2X$`3{|hUg8i)DI}=g2&W4
zf~pPf;3Arw?|Z3qc*{DP%dBO6{<2O-Wc@5ysc8^YHZgYgOK@BQL!Bf3Pr*QYMK9%z
zJN+N~<6roav%>zWcC64!|8J^+R-X(1{9810704R<^veY;!#|uXF)t;+`#fD3MrttgIITV~KPb-JJrsTg4)J6-1
z0@A#hS-D0U+g&p{J1K%T#iY8l_%@RB&V6R-QUA5jB8#lGrA;c9Dr5vu`tCV$!a04*
z-c6je*^oa^7zNPxQ&6$-{A+DRp?PTg+&7+e=1jma%_pLnXtV99v@n3&e$NSJtG+sm
zAL)wlbq~PlO~hY@yIKxj`M)#-Kf|_cGJtBS{vkY0p@YyoKLLNo?vB&^Ys8`SOpqB2
z$6dcg=lkuai2ubV?;2VuJ3`i+^T(Rgo7N3Xm&QgqdMK$S$`my!M`#-nj&3m5#HK_XR)R#qTNq5HiSe
zUPkHTTCDY%p7q~B@ucVu7P?RMv8Cw~ZpdG0O8Y)v{rO`A$iQQ9Bbf01XQPN*kBc`z
z6nTV`1$l}uu;ytj4E7#IcrTc&@2Kg25rTcwn>-Hd#=r7gY(+Bdlp0h^3!Iwf*?Y|-
zM$X429Bk&rg%2<#$J&-SlcTZZ
zhySr_@`pev4(o*~{L=!6WSJRmRczzY3FN+3tZDkzFmqh2FS~ZIbUG3Q|I)ejIJP~#
zo!M$?e-UTuXvLK4@sNqIwohzw{r#3sj=z;RkS|(l&*-s(sM-*I5LVDS4T}_F`~R*k
z80|qCtq`yQCz+%%qt@Sb7FmuqYs&QffnB>%9jWMNamOeq+kX~%
zLY81%?gYQRWb#$88*|?%yjM&6e0zMv9k0zK
z@ZXx!&)>hsB21rB(-HC*e46Jb*3ia!^2+gUSEf3-WFvzod&A1pgv&IU_4szN#5IS4
zACKA_TJQe{S2_-M>03(3K5b|yK8^by>y)@8wma7
z4}^zGDeAIb?9zXL+M6j(2RaEJ%72}!oyPEw^=H3X)L&Zt)551t9-kPgxknNkM$PF9DFw8QIxWx`
z4W(^@Q+0zHB8a)#VQ?p+$~J4-!zQ3pZ0#MDYA71Qf-^$%8lkz|zYg+$v-Dg{T!k@4
zJG3OcU79k=qJAhV^Q`RhjT`>Gq)M|LQrEo4iQ)n-JFRH;njpn2DGXw)sPmYB&bvKf
z=y8jK-=(m>SmH4hunEp2aP4L;CE=Fq&sJVU7}$MgO^g45(nmSWZE3_?TvpEc;uwr|
zd=xlQh8zFGdy4zfgrt(FVAf519Ia|Zgqf&-W)LV%)-z*RxD~@mTwI#0KR7KA6T<0!
zvB4Pf*6Yg|tJ|Q1IsWwlG&UqqM}Q!D6}Xbi0Wd-?lr$
z^WBK7HIPGI=)&g`rCIEX0e(lej#~xuYXp0oV&knDh&k-YaNMcf4hbBe3VO3XAFiv%
zsrGr0h*fQF^2?V9^;VpSn<)0jt64j;DANZE4L(0N#4HT1im4vQLbrX#6L{`;5zpz@
zK0v)hrt&0~Hjo?6BrZ=~`I?-Hejc~T=&=HttK6?d7znZ{*xxLwdalB}c))y;oJDFnr_cj@k=5d^!#T)e&IjEwD3Z;f0KB%iMAG
zbk_LThAY6^^2>3ddbBi$-Ts(BA2(ZfMfGv2Etn+P(H1>{hOMNqjSvicW3T{~fj0ir=tNZua!b0_)KVY81uOLZ
zSNP?ODEV@C(WwiGo1?uR!JLp3W+M0xeG$z@or6w_hy{rFs~1d%7w@Xrvg&=W6#A`-
zpSl#Pnx$JDf*BrXCxiz_G@!KtSO>W*6Av)QRc8=_e-RAes0X-+#@QCoSwJ$!+xX*G
zLrV}c*`zFCOHAz=Ay{&76S|<_iVz(1+niA`<~hA+UgdAB&*NQ2|?&%eQ)(;pdP`gS?
zf75#(B_KGNlAh!fqqCH+5h8|k19g}j=8;Fh(e9Zw@pF;mLUH^WDQQz4ZX>Gh0sKod
zZAx?&5>X~%_g#`Jj()6702iBucHnT?2x^BBx>ilQaxrA$B|(OOxc>wZq#(H?NmUmgExOz>5ZQFyk4MoM{aCUO6~xDTFqY$;OnQ^IaE
z+w<>fe4WjWaAL@E;5`J#!IR)_nvhkn8Fw
zZ=&na(5~{%V{D!_|GkYWME@II=rZkkmnVOI1N|w|4HQK6C$i(~OwL`h0DuJUsnz8d
z11XuQP-Mwxy=0BuWd4cYyQ^yo_qjsV1M{skIIjGeo<82mV#qo#
zZ8t&)B<&x&N7XI9r{3mlSM#(dpCe9#rULQVb;q4sDyEf8BF`%zpt?5;bEAf-?TNYH
z&IpxAZ`Hm>*S>Z(PoJy3Xy4w~ScSR8KD+}Quc|eXZH<^kR!j#h9=u9t`7R${R3j~J
z9m}K&ExLdERa9+%Ds~Z8h&FK$zWn>Pz{vk4UgzoKILBU(;Hd-I%!I}1x~J@nkC(cu
zxh+J=PHpl0Lz!1#aZ`uJYkxSJjoeh$UbM}C-PwsC9PRLUe9_hj46bKiG_xmt4=kJ0
zTLe$DPd^AWthC5K{N&DDJ|&nM-TU@YQ)HBJ;`3{S;m+6Hvtbe|G@b(c*9mzNdO&xF
zh@La9@Yj>LQo&!^fahqlPv9%m_=PETl%^OLI28FP9ayx!*~H&tZ}HtPH~%zS=2|`s
zovt#zL_CZ||FkN{FQB+D(&K2~050R4v4;X(ZMrknP0qFo11c`BO)9;6Rx0sK&UM-|
zm%Ysho|x`q4>6RMY&tb3Z{{~Yvp0VZZXE2`m@L``gS*8p%@l-|8*DCzzQOxFE26nS
zmBWZz$7e>AzZboIoBq}Ha<|A(mFah%d*Ww?2^E2!k`HZtz`WzE_RwIQaJ1`;~n8H
zQDqWO+Hd5&K=CGD|C9Er8LyvS!7
zct+=!5P0<>KWqa%ig^;6AQonSC1ty$pz6C*`ed{ex^gbn&Ffg<$i_zaQK}^`4DX}#
zJ~V9gwCClE6?n!^E)1bo8e#6}B+Xi)*rBi*rO5Z%2VawhdF0PriCizQ=&wjCY%P<3
zmozWdqSX>}txO&3+pBZ@A*5(?vlL`#n!r%2jw0#AZIg{5&Sct@#iGmPu;SUm;^7k=V*PgR+rHloNMYEg!prMteT
z*n-8WviXo{LdP70Erg*3L&TwfBfpI)Gbf?u?3~~-c8hCDb1`pp^marx4nmJoVE-#6
zk)t3&1{dIr&cda@$tL
z=2OwhuDdV1!ioDcq7?rMDu5BBeUGvK^Jk6)1Zh
zpT>7A)D(`aU3>U4GOjWSE)Q}>P5)4kjZ@6z%HJYu=L`fIcB(&JkCGGBj;WZ?YSbttZK2HB@&UJ9Gry{TaGpz(=i3G8!o!z;LRr#
zzMm!EaA3jo-qMxtt7s!^OBbz?Se}K4>SKT3QqhLmE!dW}HgJ%;AF;Y@kB(WwuZv0T
z6kwDd-k8o+3OJkkiawnt3KiLclGw3?O#^@-BNsn){>#L&;Bh~J4kp0b2^H*QE%sCL
zB2;FNq(>0!G=UTNG{wtR(5=7_2`A*XQ%h)RAb&Sq)aRKQIGQk%c}K*l(MYiaNARW_vz6{B0E21_KcXtpvWg%C9TGz!x|!e11z!>e@mF4Z?2zpSYK
zWuV#OL#7RU2c?1b6#yV(XdTh(4y*q(lu!)c%(rG^;A3>x8uG9x>xISo
zfYj7MYzzUP;mr=oSHY1?kkK>twxgtcXFwf!*%K-)c@HKY&Ov`V==H@(m@!Ex1Z)0}Xv;089SO+gHX5I`x?Nt2P398X89y-NL|N#o?{l>vQP
z9Qo;fAN_YB`t*!~H@&khBDFBUp0wUwLSs59V`UeL>OC2vEE*xX2Qe9BMZ1jf!yuKtsBF~yMT$SzWw5Id9a*3J#^
zt*d@PiVV!C)m|-lVD;e=SwbkI+x99sP$lo}I5-|#zr33s!qere559#?R#2PS4G&Gc
zzF}du=yL=_jwnxiVPrd7K!#Q@AiS~b+O6w^SiKk{)+8qnT>F3#Is9O!^1$GneYttb)SA(LD7aC6(qjpamfvl
zffDLCYI)%ShK-^nui?U}sov4-eHcQ6RoAyVQE%subJ8(v5@9KZ4U@MVA1jc#ErsG!
z2O&n(VE5FW#kzsCiLJaniA~bxZQY6xV#q60qa0>JJzHMoz75gnqCrmRy}vP;_EgtN
zZj&2zg;4cVdQ^boDz`5{Ld%v)+oQV&q#|E4x)Bn8Kmg#w%LSP_cjZ-f`2TE
zX#u~0b8{Om-bB9ni`iMcp4*~!
ziP%nX)5dHz(;>m5!e0WE>%cgCXwkxa809DA-xS~NNXfK&7q9-<(G)4BZLs(4@ug5^
zpo=@0(HA?>ExM?b*sELjH{t!a)lY+>TYqVIa>!tMLY(7Ip#j}?1q*s3Nu6V*Oshx}
znVDysNiynww8IKH43d#hcM(4x`o%PB-U$j>Wwp1*(r?G0Us>
z%B|#rnMhH0YU&qL5i%QvIGUUOz7c*9b*&d;XQ!P;UKlu@P(2a-`s4=P3lwhe<}=Lv
zlxAcQeM<^v48TTrCLwRtaww#-j=@J}W
zs-p)GFQA=UOmVazzt@Z43Bpe+h@6(6lt%RewZpS8Gqj7*xqvc|#AF9uK=}QWgYZ&e
z9-v-XlZS=TjHz9p`63q(RVLbLv+Q9YhG5qKjJ#(16Hb#Mag|F8o`Z)YB
z#MB6NhLVvpKFDGpbt))GjDq+#B~DXaKzx9yA8F?O+$+0`3}9R7+`QsKTb9m0j9&?#
zgU~TJ%G}X?2$eqz4xB(1f_bNMdb0e#!0_ybrPN)?^~I(iK^R~Xn(t+2D2IkE02n`@
zNzYN
zK0TKXYF|ND!znuj$pl0+Hlkx-3d&%xX^@hu%LkL&j(CCa2|wE7k8eH|O?$x%qU>gut@Sv^2~Jo(iJX<0oU-)%EZh6~>KAkZ-!yHL1
z0GKQlyL(bp91s9h(+LK=-Yi5-`n)Y_<#2#Up=ZCB9N(}2B$Pwsyg`<=FINNeapgZa
zq*1PHj75OUUPDZ;>vvhuCRch*xcg?yOy3ObWnY~MY;9By=2NzoO)Gf#rJSP);S*AB
z8Hg}4;ti#!sF?wL}8VfUbRg8*t{UlJkOPE?G&&6+tsGknFiSG
z%;x^lYI(FHyn3sN{bknmdU%;NwE8+U(x6vj
zDZwy$
z&+_eXsOv|^R;g2W&g#z^DJL;@XR{3!zT(VN+ozpzf(P}d=<-p?Z~o*l2!W~}Gn$j_
zIx)b&6$*hwnX`_*G5Tt
z8u3?hx5}gzF{_MyQ(Cpj07;K*sSQahxV%aFAY`i->~%kAG(L?u2a#Yn2VI*BfQroF
zl`OgoSY&l@79`6DPJa)~(L4^}(WMj3dPF!z3RfHOm5rNnxi;u)>A}Od*R*G*@|SkeIQT+4nxY0NV3PYIA$ToI5lC
zU%y1<(k;|tJ?YM?Hixk-WU_^$v69qe!fIb_$uHvl#`0$nZ`UL97N_IQk5ENSgraH2
zshTjwd3w3LqGYYZ^SlmddN>WG?pPr#V7@x-{zW|v{(yS0$ae?w`6A~$khkpAAg^>)!{TM1623}3^782NhYsvUjXdq_CLYG>`GfO&s!&!T28AoyoY
zfX-48&HqOM{d%x*8SB#d>eN&QS9^Y11AH?4B0HeiCGu61VP0^VTl>f5FpotYj$3g+
zqLAsz`e$DDTK3G6BNa-~E81cSxA2*x1p?k?VK^`st=bbH&KfU|oVnKhp+tRg^Bv))
zq|0Dj&RveSDnQFnQi#R5FwJ|Ier|WmE1GpsJK?Wj>ct*UP#y!M!WV69QC4UDOG26sQQUp6P_Z8CXcJX<~fvc
z4(hzgqMYjv@=6ZstW;9evYe&jyJOA}vkmWwlFbApJV|6mN=NZ#sKP!
zN`Uv24lVzz_XF!`ukotRmk)k%Ni{c<3-Tk0TgL9*=*GIS4o-=*5wULlQWL+Z2Wz$4
z3Ou^2_T@tR)6R@5n4{WHSd>_*3w8+{FZzV)#gac}6w0I<yI
zI)7Wj8|pR%f0xp^rS!?@(6fOX#fKKwc3$|6zIfM403~yHnjLLN{Lk388+}n%N7SRV
z%V&5tPu8ncTMYoZ?8jiz*Nl9*xzjXx;h`x#
zgiFKGoo*Q{^x;b6LrX`KLuo2%575#2VyZA}1e~TAn;L4XVC&?~#UUjwiG@h>CiUmg
zdWh4dmqw@_U4?^8DC1Z(@UX`9F9YwVAbVXJPC9|ycu!tiit={<;skpUx})W25ZP#X
zVKX=Fepe#vMD?#e4U=@9mwTNYZUQ!Mp0rM4tnCDS-Op6%@U`8N3~D9qaOV1y0=Xo5
z292`r*C_0JfD21>xxjek9U*)P4dj|~MBA?>?*W9Q(q{epxiuEr@`HR91|#06rl<$!
z^ip-3%eyBI>t-cwBNpFuD=>D`lYtzPc!hL0*OSt6Kuu-|ora3P!26Fl1`Q~@9#UeX
zd_(g4as}gP`>(JP^Aq~{Kg$)b9EwbZ|)m3)q)l2CFbX5Bh
zY+EI)ZJaADyVifu9S*YyH`m1tR;A4l2R07~sqsfTq
zyu)g$KTRt}J037DFjDA{#^d&7M_3~=ss7ly&3w(Jy)VW`Uw78}IxmU0m8*hQwzC2j
zj^X8v)BLiXYFES<8c;_o8kC&FINz~L=*vPb@q<`W)&K7I&G3SF8eDU10-JJh=JSLy
z)n82tbBxS_T1c9DqKOFYyXD$gRIsL5EcR|ag@m#R$x^M#sz@Kvce#ZDX1)M(dY#@h4DW;DiE%R>d~+*M~yQUNK$pC5KZ^Wz5~D&eUWE-qWTc
z@mC$0lR}>S(Xwnn@xyx4BEtDBM_#1e`%>PI_lG?(;w-9hH&YoyS6v|5NBB=ne4YY4
ztU
zf+f?U47B<8&djr#&ox)KGq!P$-Fm!={*M4v1giTG|GHK=i`JP7`)?O#X7S@YUw^4D
zpmMVigUF3K_+${iKT4IRH}IJkQGf5Z;~orxFAMur&AO2um#$X-Sl>SQZ&dHUy#b`%
zfACQ+!d!j*Enlqeu2mXyyZE1vf6D*-^1oE&Ki*!imtVI3^xX*NM|Ld=BU!Q3V`?qi3=zneYy{$c-Qzizhs
zL-m`l?rvlK>KpZN{`=;m>XBLQyu)n&Yxlxhv@}TZo1nCatw@>$9YJ8Q_Tr5`hlm2>P`&b0~psg-P|Rfh!1hh>ovcOD%@fxZ*LCCDyNo
zu%Ot%HjaKZ5X@Qj@_|UKUxC-zULGxIUHa9K@cf~E#dgQXqF*5h&h{6dARP5;Lj785
zLz$Q8r!_163YDv{$;Qa~wKV#5zhK)ldOSh>Y9ho+>_|VBel7LNaY1}BC!t>rJ16+@
zAc%gorTRo{cKWqr=VH9-x9V3YQpB6qAFf|ZbLI`lE&_(suZ;0t{hG_B7Y;3ITYsC7
zCum=RUG%>!$G5K*_3$tUv9F|g^*|v?**}SjZePpuZ?rxau3*UN=R4ZXquo5%Zu0zu
zsX38*T39Jr+FL{)oPcXepM*cO;c-@z!-QwBK-5qy6Ov=0rsRh#yn9$o5cq%!5iq3`
z5iouHkmLg$B2=Jc`FtBm>7Mx*xseR8h!)g6CN+IC8LSa?4MaxWL($r6kia8aCih(7
zE~fAzaSI^>L4-7kz{U%o0Hsrj-gGHkBB5o&Y(S%G^Mrntjv*5Pk`R0sO=%M?oqIe_
zX9(l!L?Ei%TOGQGw6s1^BbN1>;Jfq6;6f27DEG>4$25vtV02H2rxYzpwObm51IDnO
z@{u@2hyr8i7Ic(~V@gH+xT-AA(dp`}tfH-5fqt2fs}&V4FS6X()!Bjj^t>X3sCGDO
z-{d5@Sk#;(tK4fu`#Gmz7B##Y!F(nH~qV5)B*1t_ILYb6#
zWyXo^qGr_JHGAcFVe}%&WL5U)MHRk=-JQHR$yx32qDJTrt;EL>j9Yj_OYDP>ZWw{J
zz+^DNSi2Ns(+A4HNK3?wxSKJ6WBfwClJ5 enterBookingPage(@RequestParam("userId")
 
     /**
      * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출
-     * (이 사용자는 대기열에서 제거되어야 함)
+     * (이 사용자는 대기열에서 제거됨)
+     * userId는 수정할 예정 (추후)
      */
     @GetMapping("/release/{userId}")
     public ResponseEntity releaseUser(@PathVariable("userId") String userId) {
@@ -67,18 +68,11 @@ public ResponseEntity releaseUser(@PathVariable("userId") String userId)
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
+     * userId는 수정할 예정 (추후)
      */
     @MessageMapping("/subscribe/waiting/{userId}")
     public void subscribeWaitingQueue(@DestinationVariable("userId") String userId) {
         log.info("User {} subscribed to waiting queue updates.", userId);
         waitingService.getAndPublishWaitingNumber(userId);
     }
-
-//    @MessageMapping("/subscribe/waiting/{userId}")
-//    public void handleSubscribe(@DestinationVariable String userId, @Payload SomePayload payload) {
-//        // 처리 로직 ...
-//
-//        // 구독자에게 메시지 보내기
-//        messagingTemplate.convertAndSend("/topic/waiting/" + userId, "대기열 상태 업데이트 메시지");
-//    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 41fd1a6..f4912ce 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -10,7 +10,12 @@
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Set;
 
 @Service
@@ -34,7 +39,7 @@ public class WaitingService {
 
     // 예매 페이지 수용인원
     private static final long PERFORMANCE_CAPACITY = 2; // 공연 수용 인원
-    private static final double IMMEDIATE_ENTRY_RATIO = 1; // 즉시 입장 비율 (1.5배)
+    private static final double IMMEDIATE_ENTRY_RATIO = 1; // 기준 : 즉시 입장 비율 (1.5배), 테스트 (1배)
     private static final long IMMEDIATE_ENTRY_COUNT = (long) (PERFORMANCE_CAPACITY * IMMEDIATE_ENTRY_RATIO);
 
 
@@ -79,6 +84,31 @@ public long enterWaitingQueue(String userId) {
         }
     }
 
+    /**
+     * 대기열에 있는 사용자에게 주기적으로 대기 번호 발행
+     * 5초마다 실행
+     */
+    @Scheduled(fixedDelay = 5000)
+    public void publishAllWaitingNumbers() {
+        List waitingUsers = getWaitingUsers();
+        for (String userId : waitingUsers) {
+            getAndPublishWaitingNumber(userId);
+        }
+        log.info("주기적 대기번호 발행 완료. 대상자 수: {}", waitingUsers.size());
+    }
+
+    /**
+     * 대기열에 있는 사용자 리스트 반환하기
+     */
+    public List getWaitingUsers() {
+        Set userSet = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1);
+        if (userSet == null) {
+            return Collections.emptyList();
+        }
+        return new ArrayList<>(userSet);
+    }
+
+
     /**
      * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
      * @param userId 사용자 ID
@@ -89,7 +119,6 @@ public long getAndPublishWaitingNumber(String userId) {
         Long rank = zSetOperations.rank(WAITING_QUEUE_KEY, userId);
 
         if (rank != null) {
-            // Redis rank는 0부터 시작하므로 +1
             long waitingNumber = rank + 1;
             log.info("User {}'s waiting number: {}", userId, waitingNumber);
 
diff --git a/src/main/resources/static/test-websocket.html b/src/main/resources/static/test-websocket.html
index 6bba6fe..28d3b52 100644
--- a/src/main/resources/static/test-websocket.html
+++ b/src/main/resources/static/test-websocket.html
@@ -1,44 +1,62 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+  
+  WebSocket STOMP 테스트
+  
+  
+
+
+

WebSocket STOMP 테스트

+ +
+ + + +
+ +

+
+
+
+

From 83bfde6d7269edc4430d89ddadb5d927e502e981 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 5 Aug 2025 11:23:50 +0900
Subject: [PATCH 007/149] =?UTF-8?q?MNMS-184=20feat:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20=EB=8C=80=EA=B8=B0=EC=9E=90=20=ED=87=B4=EC=9E=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 logs/spring.log                               | 439 ++++++++++++++++++
 .../booking/controller/BookingController.java |  21 +
 2 files changed, 460 insertions(+)

diff --git a/logs/spring.log b/logs/spring.log
index 795075c..1336131 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -469,3 +469,442 @@ Identify and stop the process that's listening on port 8080 or configure this ap
 2025-08-04T18:51:50.706+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user5 added to booking user set.
 2025-08-04T18:51:53.191+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
 2025-08-04T18:51:58.204+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:03.790+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 23016 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T11:03:03.794+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T11:03:05.221+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:03:05.223+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T11:03:05.258+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
+2025-08-05T11:03:05.281+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:03:05.282+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T11:03:05.302+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T11:03:06.382+09:00  INFO 23016 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T11:03:06.399+09:00  INFO 23016 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T11:03:06.400+09:00  INFO 23016 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T11:03:06.497+09:00  INFO 23016 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T11:03:06.497+09:00  INFO 23016 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2633 ms
+2025-08-05T11:03:06.890+09:00  INFO 23016 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T11:03:06.993+09:00  INFO 23016 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T11:03:07.043+09:00  INFO 23016 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T11:03:07.555+09:00  INFO 23016 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T11:03:07.594+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T11:03:07.830+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T11:03:07.833+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T11:03:07.868+09:00  WARN 23016 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T11:03:07.894+09:00  INFO 23016 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T11:03:08.233+09:00  INFO 23016 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T11:03:08.239+09:00  INFO 23016 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T11:03:09.506+09:00  WARN 23016 --- [booking] [main] 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-08-05T11:03:09.787+09:00  INFO 23016 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T11:03:10.846+09:00  INFO 23016 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T11:03:11.193+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T11:03:11.197+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3d8b9dee]]
+2025-08-05T11:03:11.199+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T11:03:11.227+09:00  INFO 23016 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T11:03:11.874+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.804 seconds (process running for 9.198)
+2025-08-05T11:03:11.888+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:16.899+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:21.914+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:26.928+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:31.937+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:36.955+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:41.962+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:46.975+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:51.998+09:00  INFO 23016 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:03:57.008+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:02.017+09:00  INFO 23016 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:04.400+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T11:04:04.400+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T11:04:04.402+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-05T11:04:07.035+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:11.216+09:00  INFO 23016 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
+2025-08-05T11:04:12.050+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:17.061+09:00  INFO 23016 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:18.782+09:00  INFO 23016 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
+2025-08-05T11:04:22.072+09:00  INFO 23016 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:27.084+09:00  INFO 23016 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:32.096+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:37.112+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:42.124+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:47.140+09:00  INFO 23016 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:52.156+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:04:57.162+09:00  INFO 23016 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:02.175+09:00  INFO 23016 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:07.188+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:12.209+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:17.223+09:00  INFO 23016 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:22.245+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:27.261+09:00  INFO 23016 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:32.278+09:00  INFO 23016 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:37.285+09:00  INFO 23016 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:42.304+09:00  INFO 23016 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:47.311+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:52.316+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:05:57.333+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:14:56.878+09:00  INFO 1352 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1352 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T11:14:56.881+09:00  INFO 1352 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T11:14:57.909+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:14:57.911+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T11:14:57.937+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
+2025-08-05T11:14:57.956+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:14:57.958+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T11:14:57.972+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T11:14:59.086+09:00  INFO 1352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T11:14:59.104+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T11:14:59.104+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T11:14:59.203+09:00  INFO 1352 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T11:14:59.203+09:00  INFO 1352 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2259 ms
+2025-08-05T11:14:59.596+09:00  INFO 1352 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T11:14:59.699+09:00  INFO 1352 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T11:14:59.743+09:00  INFO 1352 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T11:15:00.174+09:00  INFO 1352 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T11:15:00.206+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T11:15:00.372+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T11:15:00.373+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T11:15:00.397+09:00  WARN 1352 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T11:15:00.419+09:00  INFO 1352 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T11:15:00.816+09:00  INFO 1352 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T11:15:00.823+09:00  INFO 1352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T11:15:01.943+09:00  WARN 1352 --- [booking] [main] 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-08-05T11:15:02.146+09:00  INFO 1352 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T11:15:02.310+09:00  WARN 1352 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'bookingController' method 
+com.mnms.booking.controller.BookingController#exitWaitingUser(String)
+to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
+com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
+2025-08-05T11:15:02.368+09:00  INFO 1352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T11:15:02.377+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-05T11:15:02.382+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-05T11:15:02.390+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-05T11:15:02.417+09:00  INFO 1352 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-05T11:15:02.477+09:00 ERROR 1352 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
+
+org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'bookingController' method 
+com.mnms.booking.controller.BookingController#exitWaitingUser(String)
+to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
+com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1826) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
+	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
+Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'bookingController' method 
+com.mnms.booking.controller.BookingController#exitWaitingUser(String)
+to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
+com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.validateMethodMapping(AbstractHandlerMethodMapping.java:676) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:637) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:331) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:507) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:84) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$2(AbstractHandlerMethodMapping.java:298) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:296) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(AbstractHandlerMethodMapping.java:265) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:224) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:212) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:237) ~[spring-webmvc-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1873) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1822) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 18 common frames omitted
+
+2025-08-05T11:16:07.621+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 25232 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T11:16:07.626+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T11:16:08.861+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:16:08.863+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T11:16:08.903+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
+2025-08-05T11:16:08.922+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T11:16:08.924+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T11:16:08.942+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-05T11:16:10.127+09:00  INFO 25232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T11:16:10.145+09:00  INFO 25232 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T11:16:10.145+09:00  INFO 25232 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T11:16:10.242+09:00  INFO 25232 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T11:16:10.243+09:00  INFO 25232 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2534 ms
+2025-08-05T11:16:10.677+09:00  INFO 25232 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T11:16:10.748+09:00  INFO 25232 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T11:16:10.783+09:00  INFO 25232 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T11:16:11.369+09:00  INFO 25232 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T11:16:11.397+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T11:16:11.556+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T11:16:11.559+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T11:16:11.580+09:00  WARN 25232 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T11:16:11.610+09:00  INFO 25232 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T11:16:12.013+09:00  INFO 25232 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T11:16:12.022+09:00  INFO 25232 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T11:16:13.060+09:00  WARN 25232 --- [booking] [main] 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-08-05T11:16:13.323+09:00  INFO 25232 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T11:16:14.261+09:00  INFO 25232 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T11:16:14.580+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T11:16:14.585+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@45cddfd3]]
+2025-08-05T11:16:14.586+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T11:16:14.616+09:00  INFO 25232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T11:16:15.263+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.321 seconds (process running for 8.769)
+2025-08-05T11:16:15.281+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:20.296+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:20.801+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T11:16:20.803+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T11:16:20.805+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-05T11:16:25.306+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:30.326+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:35.346+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:40.361+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:45.379+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:50.397+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:16:55.418+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:00.427+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:05.436+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:10.462+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:14.617+09:00  INFO 25232 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 25]
+2025-08-05T11:17:15.479+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:20.497+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:25.516+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:30.538+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:35.558+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:40.575+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:45.590+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:50.605+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:17:55.619+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:00.635+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:05.646+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:10.667+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:15.677+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:20.693+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:25.700+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:30.712+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:35.732+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:40.748+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:45.757+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:50.779+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:18:55.800+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:00.813+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:05.825+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:08.234+09:00  INFO 25232 --- [booking] [clientInboundChannel-10] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
+2025-08-05T11:19:10.837+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:15.852+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:20.867+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:25.876+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:30.888+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:35.904+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:40.911+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:45.922+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:46.266+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
+2025-08-05T11:19:46.305+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:19:50.934+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:19:55.938+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:00.950+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:03.496+09:00  INFO 25232 --- [booking] [clientInboundChannel-19] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
+2025-08-05T11:20:05.962+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:08.674+09:00  INFO 25232 --- [booking] [clientInboundChannel-28] c.m.b.controller.BookingController       : User user3 subscribed to waiting queue updates.
+2025-08-05T11:20:10.973+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:15.989+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:20.588+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (1 < 2).
+2025-08-05T11:20:21.001+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:20:23.571+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
+2025-08-05T11:20:25.523+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754360425490.
+2025-08-05T11:20:25.528+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:25.571+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:25.572+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:25.575+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:26.029+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:26.033+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:26.033+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:26.035+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:26.038+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:31.054+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:31.061+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:31.063+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:31.064+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:31.065+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:36.078+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:36.085+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:36.085+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:36.086+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:36.089+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:41.103+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:41.105+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:41.114+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:41.116+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:41.117+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:46.130+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:46.139+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:51.144+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:51.147+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:20:56.157+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:20:56.159+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:56.160+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:20:56.161+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:20:56.161+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:01.176+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:01.181+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:01.182+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:01.186+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:01.190+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:06.193+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:06.196+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:06.197+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:06.197+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:06.198+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:11.212+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:11.214+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:11.214+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:11.215+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:11.215+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:16.230+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:16.232+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:16.232+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:16.233+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:16.234+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:21.240+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:21.243+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:26.267+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:26.272+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:31.290+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:31.292+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:31.292+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:31.293+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:31.294+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:36.312+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:36.315+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:36.315+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:36.316+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:36.316+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:41.323+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:41.324+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:41.325+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:41.325+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:41.326+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:46.338+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:46.341+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:46.341+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:46.342+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:46.344+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:51.361+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:51.362+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:51.363+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:51.363+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:51.364+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:21:56.376+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:21:56.378+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:56.379+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:21:56.379+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:21:56.380+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:01.397+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:01.398+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:01.399+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:01.400+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:01.401+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:06.423+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:06.429+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:06.429+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:06.431+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:06.433+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:11.449+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:11.453+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:11.454+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:11.455+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:11.456+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:16.463+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:16.466+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:16.466+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:16.467+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:16.471+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:21.471+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:21.472+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:21.472+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:21.473+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:21.474+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:26.493+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:26.497+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:31.499+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:31.502+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:36.523+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:36.527+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:36.527+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:36.528+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:36.529+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:41.547+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:41.549+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:46.567+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:46.570+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:46.571+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:46.574+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:46.576+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:51.589+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:51.592+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:22:56.613+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:22:56.615+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:56.616+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:22:56.616+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:22:56.617+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:23:01.620+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T11:23:01.622+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T11:23:06.226+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
+2025-08-05T11:23:06.633+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:23:11.638+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:23:16.647+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:23:21.663+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:23:26.678+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T11:23:31.685+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 621fb8f..d49f7d7 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -65,6 +65,27 @@ public ResponseEntity releaseUser(@PathVariable("userId") String userId)
         }
     }
 
+    /**
+     * 대기열에 있는 사용자가 대기열을 나간다 (예매 입장 아님)
+     * (이 사용자는 대기열에서 제거됨)
+     * userId는 수정할 예정 (추후)
+     */
+    @GetMapping("/exit/{userId}")
+    public ResponseEntity exitWaitingUser(@PathVariable("userId") String userId) {
+        try {
+            boolean removed = waitingService.removeUserFromQueue(userId);
+            if (removed) {
+                return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
+            } else {
+                return ResponseEntity.status(HttpStatus.NOT_FOUND)
+                        .body("해당 사용자는 대기열 목록에 없습니다.");
+            }
+        } catch (Exception e) {
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+        }
+    }
+
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)

From 54cf1b061764f2b3bf5563c04e7c6bbb0ae12077 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 5 Aug 2025 14:07:48 +0900
Subject: [PATCH 008/149] =?UTF-8?q?MNMS-184=20fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20=EC=9E=85=EC=9E=A5=20=EC=8B=9C=20=EC=9B=B9=EC=86=8C?=
 =?UTF-8?q?=EC=BC=93=20=EA=B5=AC=EB=8F=85=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 logs/spring.log                               | 1414 +++++++++++++++++
 .../com/mnms/booking/config/RedisConfig.java  |    7 +-
 .../booking/controller/BookingController.java |    1 +
 .../mnms/booking/service/WaitingService.java  |    1 -
 4 files changed, 1419 insertions(+), 4 deletions(-)

diff --git a/logs/spring.log b/logs/spring.log
index 1336131..8a14731 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -908,3 +908,1417 @@ com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
 2025-08-05T11:23:21.663+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
 2025-08-05T11:23:26.678+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
 2025-08-05T11:23:31.685+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:07.346+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14388 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T13:28:07.348+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T13:28:08.504+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T13:28:08.505+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T13:28:08.547+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
+2025-08-05T13:28:08.565+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T13:28:08.566+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T13:28:08.581+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T13:28:09.576+09:00  INFO 14388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T13:28:09.594+09:00  INFO 14388 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T13:28:09.595+09:00  INFO 14388 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T13:28:09.693+09:00  INFO 14388 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T13:28:09.694+09:00  INFO 14388 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2275 ms
+2025-08-05T13:28:10.364+09:00  INFO 14388 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T13:28:10.460+09:00  INFO 14388 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T13:28:10.493+09:00  INFO 14388 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T13:28:11.008+09:00  INFO 14388 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T13:28:11.037+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T13:28:11.213+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T13:28:11.216+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T13:28:11.237+09:00  WARN 14388 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T13:28:11.268+09:00  INFO 14388 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T13:28:11.641+09:00  INFO 14388 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T13:28:11.651+09:00  INFO 14388 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T13:28:12.783+09:00  WARN 14388 --- [booking] [main] 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-08-05T13:28:13.059+09:00  INFO 14388 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T13:28:14.255+09:00  INFO 14388 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T13:28:14.722+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T13:28:14.727+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@45cddfd3]]
+2025-08-05T13:28:14.729+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T13:28:14.763+09:00  INFO 14388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T13:28:15.376+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.658 seconds (process running for 9.148)
+2025-08-05T13:28:15.393+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:20.412+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:25.437+09:00  INFO 14388 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:26.214+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T13:28:26.215+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T13:28:26.216+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-05T13:28:30.446+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:35.458+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:40.472+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:45.493+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:50.510+09:00  INFO 14388 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:28:51.954+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754368131943.
+2025-08-05T13:28:51.957+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:28:51.984+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:51.987+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:51.990+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:28:51.995+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:51.996+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:52.085+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:28:52.085+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:28:55.526+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.542+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:28:55.618+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2 added to waiting queue with timestamp 1754368135613.
+2025-08-05T13:28:55.624+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:28:55.631+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.633+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.634+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:28:55.637+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:28:55.643+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.645+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:28:55.647+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:00.547+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:00.551+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:00.554+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:00.556+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:00.556+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:00.567+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:05.578+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:05.581+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:05.582+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:05.583+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:05.583+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:05.587+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:05.588+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:05.588+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:05.589+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:10.600+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:10.601+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:10.602+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:10.602+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:10.603+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:14.716+09:00  INFO 14388 --- [booking] [MessageBroker-4] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
+2025-08-05T13:29:15.619+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:15.622+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:15.622+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:15.624+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:15.624+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:15.629+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:15.629+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:15.630+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:15.631+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:20.639+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:20.642+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:20.642+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:20.643+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:20.644+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:20.648+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:25.657+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:25.661+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:25.662+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:25.663+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:29:25.667+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:25.668+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:30.135+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368170132.
+2025-08-05T13:29:30.138+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:29:30.140+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.142+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.143+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:29:30.143+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:29:30.154+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.155+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.156+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:29:30.680+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:30.688+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.689+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.690+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:30.691+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:30.695+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.695+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.696+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:30.697+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:29:30.700+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.701+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:29:30.701+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:30.703+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:29:35.719+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:29:35.722+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.722+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.723+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:29:35.724+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:29:35.727+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.727+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.728+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:29:35.728+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:29:35.732+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:29:52.947+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 30352 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T13:29:52.949+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T13:29:54.100+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T13:29:54.102+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T13:29:54.145+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 20 ms. Found 0 JPA repository interfaces.
+2025-08-05T13:29:54.164+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T13:29:54.166+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T13:29:54.181+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-05T13:29:55.199+09:00  INFO 30352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T13:29:55.216+09:00  INFO 30352 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T13:29:55.217+09:00  INFO 30352 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T13:29:55.299+09:00  INFO 30352 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T13:29:55.300+09:00  INFO 30352 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2289 ms
+2025-08-05T13:29:55.667+09:00  INFO 30352 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T13:29:55.760+09:00  INFO 30352 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T13:29:55.797+09:00  INFO 30352 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T13:29:56.241+09:00  INFO 30352 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T13:29:56.275+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T13:29:56.437+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T13:29:56.439+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T13:29:56.459+09:00  WARN 30352 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T13:29:56.481+09:00  INFO 30352 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T13:29:56.812+09:00  INFO 30352 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T13:29:56.821+09:00  INFO 30352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T13:29:58.057+09:00  WARN 30352 --- [booking] [main] 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-08-05T13:29:58.367+09:00  INFO 30352 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T13:29:59.467+09:00  INFO 30352 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T13:29:59.778+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T13:29:59.780+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@32675dd4]]
+2025-08-05T13:29:59.781+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T13:29:59.803+09:00  INFO 30352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T13:30:00.425+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.128 seconds (process running for 8.521)
+2025-08-05T13:30:00.444+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:30:00.491+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.492+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.493+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:30:00.495+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.496+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.497+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:30:00.499+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.500+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:00.500+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:30:05.513+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:30:05.517+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.518+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.520+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:30:05.520+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:30:05.529+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.530+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.531+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:30:05.535+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:30:05.542+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.542+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:30:05.543+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:05.544+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:30:10.564+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:30:10.568+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.569+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.570+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:30:10.570+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:30:10.575+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.575+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.578+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:30:10.580+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:30:10.584+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.585+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:30:10.585+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:10.587+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:30:15.607+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:30:15.614+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.614+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.615+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:30:15.618+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
+2025-08-05T13:30:15.623+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.624+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.626+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
+2025-08-05T13:30:15.629+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:30:15.634+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.635+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:30:15.635+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:30:15.636+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:30:20.006+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T13:30:20.006+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T13:30:20.009+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-05T13:30:20.211+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-05T13:30:20.217+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
+2025-08-05T13:30:20.225+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
+2025-08-05T13:30:20.234+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 1
+2025-08-05T13:30:20.240+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.240+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.242+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 1
+2025-08-05T13:30:20.243+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:30:20.246+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.249+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:30:20.652+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 1
+2025-08-05T13:30:20.656+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.657+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.658+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 1
+2025-08-05T13:30:20.659+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:30:20.662+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.663+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:30:20.663+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:30:20.665+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:30:22.658+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
+2025-08-05T13:30:22.667+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 removed from waiting queue.
+2025-08-05T13:30:22.671+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 added to booking user set.
+2025-08-05T13:30:22.680+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:30:22.684+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:22.685+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:22.686+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:30:24.127+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3 was not found in booking user set on exit.
+2025-08-05T13:30:25.683+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:30:25.688+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:25.689+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:30:25.690+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:25.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:30:30.717+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:30:30.721+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:30.722+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:30:30.723+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:30.724+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:30:35.738+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:30:35.739+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:35.740+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:30:35.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:35.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:30:40.761+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:30:40.764+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:40.765+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:30:40.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:30:40.766+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:30:41.125+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
+2025-08-05T13:30:45.777+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:30:50.793+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:30:53.259+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Attempted to remove user user from queue, but user was not found or removal failed. Removed count: 0
+2025-08-05T13:30:55.804+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:30:59.789+09:00  INFO 30352 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
+2025-08-05T13:31:00.810+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:01.137+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754368261113.
+2025-08-05T13:31:01.141+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:31:01.146+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:01.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:01.149+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:31:01.150+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:31:01.154+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:01.156+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:01.157+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:31:05.818+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:31:05.820+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:05.820+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:31:05.821+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:05.822+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:31:10.835+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:31:10.838+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:10.838+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:31:10.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:10.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:31:15.858+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T13:31:15.860+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:15.860+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:31:15.861+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:15.862+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T13:31:17.270+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-05T13:31:17.272+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
+2025-08-05T13:31:17.274+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
+2025-08-05T13:31:20.469+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
+2025-08-05T13:31:20.870+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:25.876+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:30.902+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:35.914+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:36.936+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user6 can enter booking page immediately (1 < 2).
+2025-08-05T13:31:40.926+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:45.947+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:50.962+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:31:54.068+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7 added to waiting queue with timestamp 1754368314066.
+2025-08-05T13:31:54.070+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:31:54.074+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:54.075+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:54.078+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:31:54.079+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:31:54.082+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:54.083+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:54.085+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:31:55.972+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:31:55.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:32:00.989+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:32:00.994+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:00.994+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:32:00.995+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:00.996+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:32:06.017+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:32:06.019+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:32:11.035+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:32:11.038+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:11.038+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:32:11.039+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:11.040+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:32:16.053+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
+2025-08-05T13:32:16.055+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:16.056+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:32:16.056+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:32:16.057+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
+2025-08-05T13:32:18.472+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user6 exited booking page and removed from booking user set.
+2025-08-05T13:32:18.478+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user7 removed from waiting queue.
+2025-08-05T13:32:18.481+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user7 added to booking user set.
+2025-08-05T13:32:21.073+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:26.081+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:31.097+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:36.101+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:41.120+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:46.137+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:51.152+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:32:56.162+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:01.172+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:06.182+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:11.198+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:16.218+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:18.646+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-05T13:33:20.937+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user7 exited booking page and removed from booking user set.
+2025-08-05T13:33:21.233+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:26.252+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:31.268+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:36.274+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:41.284+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:46.295+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:51.308+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:33:52.075+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
+2025-08-05T13:33:54.731+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
+2025-08-05T13:33:56.318+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:34:01.329+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:34:01.933+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368441931.
+2025-08-05T13:34:01.935+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:01.937+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:01.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:01.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:01.939+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:01.940+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:01.942+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:01.942+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:06.343+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:06.347+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:11.356+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:11.360+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:16.384+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:16.387+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:16.387+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:16.388+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:16.389+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:21.405+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:21.409+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:26.418+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:26.421+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:26.421+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:26.422+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:26.423+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:29.895+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368469892.
+2025-08-05T13:34:29.899+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:29.902+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:29.903+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:29.905+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:29.906+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:29.909+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:29.910+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:29.911+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:31.438+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:31.443+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:31.443+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:31.444+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:31.445+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:36.470+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:36.475+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:36.475+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:36.476+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:36.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:41.483+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:41.485+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:41.486+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:34:41.486+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:41.487+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:43.944+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754368483942.
+2025-08-05T13:34:43.948+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T13:34:43.951+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:43.953+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:43.954+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T13:34:43.956+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T13:34:43.960+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:43.961+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:43.962+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T13:34:46.500+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:46.502+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:46.503+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:46.505+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T13:34:46.505+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:46.509+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:46.509+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:34:46.510+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:46.510+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T13:34:47.183+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5 added to waiting queue with timestamp 1754368487180.
+2025-08-05T13:34:47.187+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
+2025-08-05T13:34:47.191+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:47.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:47.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
+2025-08-05T13:34:47.193+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
+2025-08-05T13:34:47.195+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:47.196+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:47.197+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
+2025-08-05T13:34:51.523+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:34:51.525+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T13:34:51.528+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.528+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.529+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T13:34:51.529+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
+2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:51.532+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
+2025-08-05T13:34:53.035+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368493032.
+2025-08-05T13:34:53.038+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:34:53.042+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:53.042+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:53.044+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:34:53.044+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:34:53.047+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:53.047+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:53.048+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:34:56.538+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:34:56.541+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.542+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.543+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:34:56.544+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:34:56.548+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.549+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.550+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:34:56.552+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:34:56.554+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.555+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:34:56.556+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:34:56.557+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:01.566+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:01.569+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.570+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.571+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:01.573+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:01.577+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.578+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.579+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:01.581+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:01.585+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.586+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:01.587+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:01.588+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:06.594+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:06.597+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.597+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.598+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:06.599+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:06.602+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.602+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.603+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:06.603+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:06.606+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.607+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:06.608+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:06.608+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:11.616+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:11.622+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.624+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:11.625+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:11.632+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.633+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.634+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:11.637+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:11.643+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.643+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:11.645+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:11.646+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:16.657+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:16.659+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.660+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.661+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:16.662+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:16.664+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.664+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-70] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.665+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-70] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:16.666+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-71] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-71] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:21.686+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:21.689+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.689+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-72] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.690+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-72] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:21.691+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:21.692+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-73] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.694+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-73] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:21.694+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:21.696+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.696+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:21.698+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-74] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:21.699+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-74] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:26.706+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:26.708+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.709+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-75] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.710+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:26.710+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-75] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:26.712+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.712+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-76] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.713+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-76] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:26.713+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:26.715+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.715+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:26.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-77] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:26.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-77] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:31.727+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:31.728+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.729+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-78] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.730+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-78] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:31.730+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:31.732+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.732+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-79] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.733+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-79] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:31.733+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-80] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-80] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:36.752+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:36.754+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.755+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-81] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.756+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-81] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:36.756+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:36.758+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.759+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-82] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.760+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-82] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:36.760+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:36.763+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.763+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:36.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-83] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:36.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-83] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:41.781+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:41.784+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.785+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-84] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.785+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-84] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:41.786+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:41.789+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.792+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-85] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.793+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-85] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:41.793+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:41.798+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.798+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:41.799+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-86] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:41.800+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-86] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:46.817+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:46.824+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.824+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-87] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.825+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-87] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:46.833+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:46.837+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.838+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-88] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-88] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:46.840+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:46.843+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.844+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:46.845+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-89] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:46.846+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-89] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:51.858+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:51.861+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.861+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-90] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.862+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-90] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:51.863+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:51.865+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-91] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-91] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:51.869+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.869+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:51.870+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-92] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:51.871+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-92] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:35:56.883+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:35:56.886+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.886+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-93] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.887+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-93] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:35:56.887+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:35:56.889+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.890+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-94] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.890+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-94] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:35:56.891+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:35:56.893+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.893+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:35:56.894+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-95] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:35:56.894+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-95] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:01.919+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:01.922+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.923+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-96] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.924+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-96] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:01.924+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:01.926+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.927+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-97] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.927+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-97] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:01.928+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-98] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:01.931+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-98] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:06.939+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:06.942+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.943+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-99] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.944+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-99] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:06.944+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:06.946+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.947+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-100] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.947+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-100] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:06.949+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:06.951+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-101] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-101] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:11.970+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:11.973+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.975+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-102] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-102] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:11.977+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:11.991+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.991+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-103] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.992+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-103] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:11.995+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-104] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-104] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:17.012+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:17.016+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-105] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-105] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:17.019+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:17.022+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.022+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-106] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.023+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-106] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:17.031+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:17.036+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.036+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:17.037+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-107] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:17.037+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-107] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:22.047+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:22.049+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.050+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-108] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.051+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-108] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:22.051+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:22.052+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.053+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-109] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.054+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-109] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:22.054+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:22.056+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.056+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:22.058+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-110] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:22.058+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-110] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:27.071+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:27.074+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.076+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-111] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.077+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-111] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:27.078+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:27.083+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.084+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-112] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.085+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-112] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:27.087+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:27.090+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.090+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:27.091+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-113] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:27.092+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-113] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:32.109+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:32.112+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-114] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-114] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:32.114+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:32.116+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.116+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-115] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.117+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-115] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:32.118+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:32.119+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.119+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:32.121+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-116] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:32.121+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-116] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:37.132+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:37.134+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.135+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-117] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.136+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-117] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:37.139+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:37.142+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.143+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-118] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.143+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-118] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:37.144+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:37.146+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.146+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:37.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-119] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:37.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-119] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:42.155+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:42.158+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.159+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-120] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.160+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-120] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:42.160+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:42.163+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.164+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-121] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.165+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-121] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:42.166+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:42.168+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.168+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:42.169+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-122] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:42.170+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-122] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:47.195+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
+2025-08-05T13:36:47.198+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.200+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-123] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.202+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-123] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T13:36:47.202+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
+2025-08-05T13:36:47.207+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-124] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-124] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
+2025-08-05T13:36:47.214+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
+2025-08-05T13:36:47.218+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.218+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
+2025-08-05T13:36:47.219+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-125] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
+2025-08-05T13:36:47.220+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-125] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
+2025-08-05T13:36:48.195+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Attempted to remove user user1 from queue, but user was not found or removal failed. Removed count: 0
+2025-08-05T13:36:51.915+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-05T13:36:51.921+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue.
+2025-08-05T13:36:51.925+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 added to booking user set.
+2025-08-05T13:36:51.931+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:36:51.935+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:51.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-126] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:51.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-126] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:36:51.940+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:36:51.944+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:51.949+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-127] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:51.949+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-127] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:36:52.231+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:36:52.236+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:52.237+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-128] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:52.238+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:36:52.239+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-128] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:36:52.241+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:52.241+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:36:52.242+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-129] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:52.243+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-129] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:36:57.260+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:36:57.262+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:57.263+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-130] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:36:57.264+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-130] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:36:57.265+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:36:57.268+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:57.268+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:36:57.269+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-131] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:36:57.272+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-131] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:02.278+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:02.279+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:02.280+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-132] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:02.281+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-132] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:02.281+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-133] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-133] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:07.301+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:07.303+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:07.305+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:07.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-134] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:07.306+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-134] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:07.307+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:07.308+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:07.309+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-135] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:07.309+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-135] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:12.317+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:12.319+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:12.320+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-136] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:12.321+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-136] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:12.321+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:12.322+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-137] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-137] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:17.355+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-138] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-138] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:17.366+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:17.368+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:17.368+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:17.370+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-139] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:17.370+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-139] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:22.390+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:22.392+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:22.393+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-140] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:22.393+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-140] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:22.394+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-141] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-141] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:27.410+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:27.413+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:27.414+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-142] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:27.414+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:27.415+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-142] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:27.416+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-143] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-143] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:32.432+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:32.433+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:32.433+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-144] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:32.434+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-144] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:32.434+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-145] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:32.436+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-145] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:37.449+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:37.451+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:37.452+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-146] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:37.453+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:37.453+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-146] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:37.455+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:37.455+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:37.456+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-147] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:37.456+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-147] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:42.466+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:42.471+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:42.472+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-148] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:42.472+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-148] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:42.475+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:42.477+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:42.477+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:42.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-149] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:42.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-149] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:47.488+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:47.492+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:47.493+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-150] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:47.494+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-150] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:47.496+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-151] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:47.499+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-151] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:52.510+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-152] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-152] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:52.513+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-153] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-153] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:37:57.529+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:37:57.536+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:57.536+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-154] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:37:57.537+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-154] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:37:57.537+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:37:57.540+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:57.540+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:37:57.541+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-155] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:37:57.541+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-155] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:02.548+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:02.549+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:02.549+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-156] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:02.550+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:02.550+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-156] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-157] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:02.552+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-157] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:07.564+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:07.567+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:07.568+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-158] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:07.569+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-158] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:07.569+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:07.571+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:07.571+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:07.572+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-159] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:07.573+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-159] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:12.586+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:12.587+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:12.588+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-160] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:12.589+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-160] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:12.589+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-161] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-161] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:17.616+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:17.618+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:17.619+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-162] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:17.619+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-162] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:17.620+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:17.622+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:17.622+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:17.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-163] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:17.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-163] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:22.636+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:22.638+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:22.639+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-164] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:22.640+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-164] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:22.640+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:22.642+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:22.642+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:22.643+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-165] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:22.643+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-165] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:27.664+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:27.666+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:27.667+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-166] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:27.668+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:27.668+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-166] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-167] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:27.671+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-167] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:32.689+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:32.692+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:32.692+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-168] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:32.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-168] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:32.693+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:32.695+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:32.696+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:32.696+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-169] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:32.697+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-169] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:37.712+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:37.714+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:37.715+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-170] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:37.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-170] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:37.716+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:37.718+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:37.718+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:37.719+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-171] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:37.719+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-171] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:42.732+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:42.735+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:42.736+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-172] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:42.737+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-172] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:42.737+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:42.740+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:42.740+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:42.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-173] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:42.742+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-173] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:47.758+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:47.761+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:47.762+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-174] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:47.762+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-174] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:47.763+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:47.765+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:47.765+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:47.766+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-175] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:47.767+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-175] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:52.774+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:52.775+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:52.779+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-176] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:52.779+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-176] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:52.780+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-177] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-177] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:38:57.796+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:38:57.799+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:57.801+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-178] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:38:57.802+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-178] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:38:57.803+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-179] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:38:57.806+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-179] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:02.810+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:02.814+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:02.815+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:02.815+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-180] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:02.816+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-180] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-181] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-181] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:07.837+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:07.839+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-182] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-182] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:07.843+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:07.843+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:07.844+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-183] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:07.844+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-183] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:12.860+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:12.863+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:12.864+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-184] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:12.864+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:12.865+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-184] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:12.867+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:12.867+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:12.869+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-185] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:12.869+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-185] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:17.877+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:17.879+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:17.879+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-186] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:17.880+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-186] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:17.880+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:17.882+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:17.882+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:17.883+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-187] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:17.883+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-187] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:22.891+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:22.895+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:22.896+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-188] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:22.896+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-188] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:22.897+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:22.899+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-189] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-189] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:27.913+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:27.915+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:27.916+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-190] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:27.917+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-190] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:27.917+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-191] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:27.921+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-191] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:32.929+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:32.931+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:32.932+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-192] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:32.933+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:32.935+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-192] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-193] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-193] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:37.953+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:37.954+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:37.956+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-194] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:37.956+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:37.957+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-194] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:37.958+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-195] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-195] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:42.970+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:42.972+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-196] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-196] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:42.975+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:42.976+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:42.976+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-197] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:42.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-197] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:47.997+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:47.999+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:48.000+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-198] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:48.001+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-198] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:48.002+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:48.003+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:48.004+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:48.004+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-199] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:48.005+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-199] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:53.010+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:53.012+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:53.013+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-200] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:53.014+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-200] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:53.014+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:53.016+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:53.017+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:53.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-201] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:53.018+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-201] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:39:58.035+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:39:58.037+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-202] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-202] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-203] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:39:58.041+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-203] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:03.059+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:03.062+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:03.062+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-204] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:03.063+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-204] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:03.063+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-205] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:03.070+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-205] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:08.086+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:08.088+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:08.089+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-206] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:08.090+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:08.091+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-206] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:08.092+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-207] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-207] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:13.103+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:13.105+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:13.107+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-208] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:13.108+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:13.109+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-208] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:13.111+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:13.111+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:13.112+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-209] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:13.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-209] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:18.129+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:18.131+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:18.132+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-210] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:18.133+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-210] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:18.133+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:18.134+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:18.135+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:18.135+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-211] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:18.136+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-211] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:23.155+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:23.160+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:23.161+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-212] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:23.162+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-212] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:23.163+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-213] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:23.166+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-213] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:28.187+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:28.191+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:28.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-214] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:28.193+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-214] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:28.194+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:28.197+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-215] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-215] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:33.206+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:33.207+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-216] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-216] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-217] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-217] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:38.219+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:38.222+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:38.223+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-218] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:38.224+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:38.224+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-218] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:38.226+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:38.226+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:38.227+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-219] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:38.227+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-219] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:43.243+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:43.244+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:43.245+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-220] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:43.245+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-220] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:43.246+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-221] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-221] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:48.265+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:48.267+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:48.269+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-222] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:48.270+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-222] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:48.270+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:48.274+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-223] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-223] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:53.297+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:53.300+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:53.301+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-224] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:53.301+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-224] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:53.302+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:53.304+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:53.304+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:53.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-225] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:53.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-225] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:40:58.313+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:40:58.319+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:58.320+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-226] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:40:58.321+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-226] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:40:58.322+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-227] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:40:58.325+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-227] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:41:03.337+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
+2025-08-05T13:41:03.338+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-228] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-228] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
+2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
+2025-08-05T13:41:03.341+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:41:03.341+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
+2025-08-05T13:41:03.342+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-229] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T13:41:03.342+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-229] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
+2025-08-05T13:41:06.096+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user5 removed from waiting queue (manual removal).
+2025-08-05T13:41:06.100+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:41:06.103+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:06.104+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-230] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:06.104+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-230] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:41:08.363+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:41:08.365+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:08.366+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:41:08.366+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-231] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:08.367+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-231] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:41:12.900+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Attempted to remove user user4 from queue, but user was not found or removal failed. Removed count: 0
+2025-08-05T13:41:13.371+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T13:41:13.373+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:13.373+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
+2025-08-05T13:41:13.374+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-232] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T13:41:13.374+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-232] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T13:41:14.355+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
+2025-08-05T13:41:18.386+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:23.406+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:28.415+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:33.434+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:38.448+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:43.462+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:48.472+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:53.480+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:41:58.491+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:03.499+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:08.508+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:13.522+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:18.540+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:23.556+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:28.568+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:33.582+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:38.591+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:43.598+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:48.615+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:53.629+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:42:58.643+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:03.651+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:08.661+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:13.687+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:18.701+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:23.710+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:28.717+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:33.731+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:38.735+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:43.741+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:48.749+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:53.768+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:43:58.780+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:03.793+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:08.800+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:13.818+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:18.824+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:23.842+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:28.852+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:33.874+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:38.891+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:43.904+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:48.913+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:53.924+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:44:58.934+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:03.949+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:08.956+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:13.964+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:18.972+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:23.987+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:28.998+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:34.005+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:39.021+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:44.031+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:49.042+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:54.059+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:45:59.069+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:04.086+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:09.096+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:14.113+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:19.132+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:24.150+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:29.166+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:34.181+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:39.191+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:44.209+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:49.223+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:54.239+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:46:59.247+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:04.263+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:09.268+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:14.274+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:19.291+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:24.298+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:29.305+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:34.320+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:39.330+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:44.347+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:49.361+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:54.375+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:47:59.392+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:04.405+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:09.411+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:14.417+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:19.431+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:24.444+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:29.459+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:34.471+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:39.482+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:44.492+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:49.499+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:54.515+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:48:59.525+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:04.542+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:09.558+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:14.562+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:19.568+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:24.580+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:29.592+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:34.606+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:39.619+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:44.634+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:49.644+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:54.659+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:49:59.668+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:50:04.679+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:50:09.696+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:50:14.708+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:50:19.728+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T13:50:24.734+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 199dadd..e60c71a 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -9,6 +9,7 @@
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.data.redis.core.StringRedisTemplate;
 
 
 @Configuration
@@ -37,8 +38,8 @@ public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber)
     // Redis Pub/Sub 메시지를 발행하는 데 사용될 템플릿
     // String, String 형태로 메시지를 발행할 것이므로 StringRedisTemplate을 사용
     @Bean
-    public org.springframework.data.redis.core.StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
-        return new org.springframework.data.redis.core.StringRedisTemplate(connectionFactory);
+    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
+        return new StringRedisTemplate(connectionFactory);
     }
 
     // ZSet, Hash 등 일반적인 Redis 데이터 구조 관리에 사용될 RedisTemplate 설정 추가
@@ -49,7 +50,7 @@ public RedisTemplate redisTemplate(RedisConnectionFactory connec
 
         // Key 직렬화 설정: StringRedisSerializer 사용 (필수)
         template.setKeySerializer(new StringRedisSerializer());
-        // Value 직렬화 설정: StringRedisSerializer 사용 (필수)
+        // Value 직렬화 설정
         template.setValueSerializer(new StringRedisSerializer());
 
         // Hash Key/Value 직렬화 설정 (ZSet에서는 직접 사용되지 않지만, 다른 Redis 자료구조 사용 시 일관성을 위해 설정)
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index d49f7d7..fde403d 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -40,6 +40,7 @@ public ResponseEntity enterBookingPage(@RequestParam("userId")
             return ResponseEntity.ok(new WaitingNumberDto(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
             // 대기열에 진입한 경우
+            waitingService.getAndPublishWaitingNumber(userId);
             return ResponseEntity.ok(new WaitingNumberDto(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index f4912ce..117d9d9 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -152,7 +152,6 @@ private void publishWaitingNumber(String userId, long waitingNumber) {
      * 대기열에서 다음 사용자 진입 처리
      * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출)
      */
-
     public boolean userExitBookingPage(String userId){
         // 예매 완료된 Set에서 제거
         Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, userId);

From 918a2fdbff7bf47890a1ed44f90594de3a4c03ea Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 5 Aug 2025 16:47:47 +0900
Subject: [PATCH 009/149] =?UTF-8?q?MNMS-184=20fix:=20=EC=A1=B0=EA=B1=B4=20?=
 =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

스케줄러 5초 간격으로 수정
서버 중단 후 재실행 시 실행 테스트 완료
---
 logs/spring.log                               | 941 ++++++++++++++++++
 .../booking/controller/BookingController.java |   1 -
 .../mnms/booking/service/WaitingService.java  |  77 +-
 3 files changed, 999 insertions(+), 20 deletions(-)

diff --git a/logs/spring.log b/logs/spring.log
index 8a14731..8f80b24 100644
--- a/logs/spring.log
+++ b/logs/spring.log
@@ -2322,3 +2322,944 @@ com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
 2025-08-05T13:50:14.708+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
 2025-08-05T13:50:19.728+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
 2025-08-05T13:50:24.734+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
+2025-08-05T16:03:11.896+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1548 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:03:11.899+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:03:13.005+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:03:13.005+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:03:13.034+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:03:13.057+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:03:13.057+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:03:13.068+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:03:14.256+09:00  INFO 1548 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:03:14.273+09:00  INFO 1548 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:03:14.277+09:00  INFO 1548 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:03:14.368+09:00  INFO 1548 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:03:14.368+09:00  INFO 1548 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2409 ms
+2025-08-05T16:03:14.699+09:00  INFO 1548 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:03:14.797+09:00  INFO 1548 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:03:14.826+09:00  INFO 1548 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:03:15.299+09:00  INFO 1548 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:03:15.330+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:03:15.490+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:03:15.504+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:03:15.530+09:00  WARN 1548 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:03:15.562+09:00  INFO 1548 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:03:15.916+09:00  INFO 1548 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:03:15.935+09:00  INFO 1548 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:03:17.014+09:00  WARN 1548 --- [booking] [main] 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-08-05T16:03:17.270+09:00  INFO 1548 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:03:18.459+09:00  INFO 1548 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:03:18.981+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:03:18.994+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@24890021]]
+2025-08-05T16:03:18.994+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:03:19.047+09:00  INFO 1548 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:03:19.673+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.387 seconds (process running for 8.798)
+2025-08-05T16:03:38.542+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T16:03:38.543+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T16:03:38.547+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
+2025-08-05T16:03:38.790+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754377418773.
+2025-08-05T16:03:38.791+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
+2025-08-05T16:04:18.980+09:00  INFO 1548 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-05T16:05:15.246+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6100 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:05:15.248+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:05:16.371+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:05:16.374+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:05:16.417+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 22 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:05:16.432+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:05:16.432+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:05:16.448+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:05:17.503+09:00  INFO 6100 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:05:17.526+09:00  INFO 6100 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:05:17.526+09:00  INFO 6100 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:05:17.637+09:00  INFO 6100 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:05:17.638+09:00  INFO 6100 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2326 ms
+2025-08-05T16:05:18.181+09:00  INFO 6100 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:05:18.255+09:00  INFO 6100 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:05:18.291+09:00  INFO 6100 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:05:18.798+09:00  INFO 6100 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:05:18.824+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:05:19.001+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:05:19.001+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:05:19.032+09:00  WARN 6100 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:05:19.064+09:00  INFO 6100 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:05:19.464+09:00  INFO 6100 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:05:19.482+09:00  INFO 6100 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:05:20.429+09:00  WARN 6100 --- [booking] [main] 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-08-05T16:05:20.698+09:00  INFO 6100 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:05:21.646+09:00  INFO 6100 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:05:22.035+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:05:22.037+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@613ba54e]]
+2025-08-05T16:05:22.039+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:05:22.055+09:00  INFO 6100 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:05:22.679+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.094 seconds (process running for 8.519)
+2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-05T16:05:27.499+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754377527490.
+2025-08-05T16:05:27.500+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
+2025-08-05T16:05:27.503+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:27.508+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:27.557+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.557+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.558+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:27.562+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.563+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:32.578+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:32.583+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:32.584+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:32.586+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:32.587+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:37.608+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:37.615+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:37.616+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:37.618+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:37.619+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:42.642+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:42.646+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:42.647+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:42.647+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:42.649+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:47.666+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:47.669+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:52.690+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
+2025-08-05T16:05:52.693+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:52.694+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:05:52.694+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:05:52.696+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
+2025-08-05T16:05:54.872+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
+2025-08-05T16:05:54.881+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
+2025-08-05T16:05:54.886+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
+2025-08-05T16:05:57.711+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열이 비어 스케줄러 중지됨.
+2025-08-05T16:06:06.101+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
+2025-08-05T16:06:08.094+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user4 exited booking page and removed from booking user set.
+2025-08-05T16:06:20.940+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
+2025-08-05T16:06:22.029+09:00  INFO 6100 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-05T16:07:19.229+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 7968 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:07:19.231+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:07:20.239+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:07:20.241+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:07:20.273+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:07:20.294+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:07:20.295+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:07:20.310+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:07:21.268+09:00  INFO 7968 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:07:21.282+09:00  INFO 7968 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:07:21.283+09:00  INFO 7968 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:07:21.370+09:00  INFO 7968 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:07:21.371+09:00  INFO 7968 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2071 ms
+2025-08-05T16:07:21.763+09:00  INFO 7968 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:07:21.874+09:00  INFO 7968 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:07:21.908+09:00  INFO 7968 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:07:22.379+09:00  INFO 7968 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:07:22.410+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:07:22.584+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:07:22.589+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:07:22.613+09:00  WARN 7968 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:07:22.643+09:00  INFO 7968 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:07:23.012+09:00  INFO 7968 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:07:23.017+09:00  INFO 7968 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:07:24.116+09:00  WARN 7968 --- [booking] [main] 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-08-05T16:07:24.401+09:00  INFO 7968 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:07:25.290+09:00  INFO 7968 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:07:25.567+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:07:25.570+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1028a747]]
+2025-08-05T16:07:25.571+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:07:25.599+09:00  INFO 7968 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:07:26.208+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.657 seconds (process running for 8.055)
+2025-08-05T16:08:25.567+09:00  INFO 7968 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-05T16:09:23.057+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T16:09:23.057+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T16:09:23.058+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
+2025-08-05T16:09:23.166+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
+2025-08-05T16:09:24.851+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754377764836.
+2025-08-05T16:09:24.853+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
+2025-08-05T16:09:24.858+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:24.870+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:09:24.885+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.885+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.886+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:24.888+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.889+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:29.892+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:29.895+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:29.896+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:29.896+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:09:29.897+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:34.912+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:34.915+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:34.915+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:09:34.916+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:34.916+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:39.935+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:39.938+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:39.939+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:09:39.940+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:39.941+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:44.960+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
+2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:44.965+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:49.847+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754377789841.
+2025-08-05T16:09:49.852+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:09:49.858+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.859+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.860+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:09:49.861+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:09:49.865+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.867+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.868+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:09:49.975+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:49.977+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.977+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.978+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:49.979+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:09:54.998+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:09:55.005+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:55.005+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:09:55.008+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:09:55.010+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:09:55.019+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:00.044+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:00.049+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:00.050+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:00.051+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:00.052+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:00.055+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:00.055+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:00.056+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:00.056+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:05.066+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:05.068+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:05.069+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:05.071+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:05.071+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:05.076+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:10.091+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:10.094+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:10.095+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:10.095+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:10.100+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:10.104+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:10.104+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:10.105+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:10.106+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:15.126+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:15.140+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:15.143+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:15.143+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:15.144+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:15.145+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:20.160+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:20.163+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:20.164+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:20.166+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:20.166+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:20.168+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:25.178+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:25.183+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:25.184+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:25.184+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:25.186+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:25.188+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:25.189+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:25.189+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:25.190+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:30.207+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:30.210+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:30.210+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:30.211+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:30.212+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:30.215+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:35.225+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:35.228+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:35.229+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:35.229+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:35.230+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:40.248+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:40.251+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:40.251+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:40.253+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:40.253+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:40.255+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:40.256+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:40.256+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:40.257+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:45.269+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:45.272+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:45.273+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:45.274+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:45.275+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:50.288+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:50.291+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:50.293+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:50.294+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:50.295+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:50.298+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:50.300+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:50.300+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:50.301+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:10:55.314+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:10:55.316+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:55.318+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:10:55.318+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:10:55.319+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:10:55.322+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:55.322+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:10:55.323+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:10:55.323+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:00.342+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:00.344+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:00.345+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:00.346+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:00.347+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:00.349+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:00.350+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:00.350+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:00.351+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:05.365+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:05.367+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:05.369+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:05.369+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:05.370+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:05.372+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:05.373+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:05.373+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:05.374+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:10.385+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:10.389+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:10.391+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:10.391+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:10.393+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:10.396+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:10.396+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:10.397+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:10.398+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:15.406+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:15.408+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:15.409+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:15.409+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:15.410+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:15.412+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:15.412+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:15.413+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:15.413+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:20.432+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:20.436+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:20.437+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:20.438+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:20.440+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:20.443+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:25.465+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:25.468+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:25.468+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:25.469+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:25.470+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:25.473+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:25.473+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:25.474+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:25.474+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:30.492+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:30.497+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:30.498+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:30.500+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:30.501+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:30.505+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:30.505+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:30.506+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:30.507+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:35.517+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:35.520+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:35.520+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:35.521+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:35.522+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:35.524+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:35.525+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:35.525+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:35.526+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:40.535+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:40.540+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:40.542+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:40.543+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:40.545+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:40.550+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:40.551+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:40.552+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:40.554+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:45.571+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:45.573+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:45.573+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:45.574+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:45.575+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:50.589+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:50.592+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:50.592+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:50.593+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:50.595+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:50.598+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:50.598+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:50.599+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:50.600+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:11:55.613+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:11:55.617+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:55.621+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:11:55.622+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:11:55.622+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:11:55.626+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:55.626+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:11:55.627+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:11:55.628+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:12:00.642+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:12:00.644+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:00.646+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:00.646+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:12:00.648+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:12:00.653+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:00.655+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:12:00.655+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:00.656+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:12:05.666+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:12:05.668+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:05.669+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:05.671+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:12:05.671+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:12:05.673+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:05.673+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:12:05.674+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:05.675+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:12:10.695+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:12:10.699+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:10.701+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:10.703+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:12:10.705+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:12:10.709+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:10.709+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:12:10.710+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:10.711+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:12:15.725+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:12:15.727+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:15.728+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:12:15.729+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:12:15.729+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:12:15.730+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:15.731+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:12:15.732+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:12:15.732+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:13.822+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 10744 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:14:13.826+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:14:14.968+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:14:14.968+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:14:15.000+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:14:15.016+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:14:15.016+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:14:15.040+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:14:16.096+09:00  INFO 10744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:14:16.115+09:00  INFO 10744 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:14:16.115+09:00  INFO 10744 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:14:16.214+09:00  INFO 10744 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:14:16.214+09:00  INFO 10744 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2318 ms
+2025-08-05T16:14:16.600+09:00  INFO 10744 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:14:16.705+09:00  INFO 10744 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:14:16.743+09:00  INFO 10744 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:14:17.244+09:00  INFO 10744 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:14:17.283+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:14:17.459+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:14:17.474+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:14:17.496+09:00  WARN 10744 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:14:17.526+09:00  INFO 10744 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:14:17.833+09:00  INFO 10744 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:14:17.842+09:00  INFO 10744 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:14:18.941+09:00  WARN 10744 --- [booking] [main] 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-08-05T16:14:19.208+09:00  INFO 10744 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:14:20.018+09:00  INFO 10744 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@69e736bf]]
+2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:14:20.240+09:00  INFO 10744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:14:20.907+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.74 seconds (process running for 8.197)
+2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
+2025-08-05T16:14:29.241+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754378069234.
+2025-08-05T16:14:29.241+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
+2025-08-05T16:14:29.247+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:29.251+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:14:29.320+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.320+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.322+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.323+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.325+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:29.333+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.334+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:29.334+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:14:34.361+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:14:34.362+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:34.363+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:34.364+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:14:34.364+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:34.366+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:39.378+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:14:39.381+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:39.383+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:39.383+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:14:39.384+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:39.388+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:39.389+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:39.389+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:14:39.391+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:44.409+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:14:44.412+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:44.413+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:44.415+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:14:44.415+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:14:49.439+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
+2025-08-05T16:14:49.443+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:49.445+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:14:49.447+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:14:49.451+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
+2025-08-05T16:14:49.458+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:49.459+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:14:49.459+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:14:49.462+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:20:36.056+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 23824 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:20:36.060+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:20:37.042+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:20:37.042+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:20:37.084+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:20:37.112+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:20:37.112+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:20:37.132+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:20:38.165+09:00  INFO 23824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:20:38.189+09:00  INFO 23824 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:20:38.189+09:00  INFO 23824 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:20:38.279+09:00  INFO 23824 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:20:38.279+09:00  INFO 23824 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2156 ms
+2025-08-05T16:20:38.753+09:00  INFO 23824 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:20:38.861+09:00  INFO 23824 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:20:38.897+09:00  INFO 23824 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:20:39.372+09:00  INFO 23824 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:20:39.408+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:20:39.605+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:20:39.605+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:20:39.631+09:00  WARN 23824 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:20:39.652+09:00  INFO 23824 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:20:39.984+09:00  INFO 23824 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:20:39.984+09:00  INFO 23824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:20:40.994+09:00  WARN 23824 --- [booking] [main] 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-08-05T16:20:41.272+09:00  INFO 23824 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:20:42.182+09:00  INFO 23824 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:20:42.493+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:20:42.497+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@304704ae]]
+2025-08-05T16:20:42.497+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:20:42.528+09:00  INFO 23824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:20:43.241+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.871 seconds (process running for 8.253)
+2025-08-05T16:21:42.488+09:00  INFO 23824 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
+2025-08-05T16:43:22.583+09:00  INFO 1956 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1956 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:43:22.586+09:00  INFO 1956 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:43:23.822+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:43:23.824+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:43:23.867+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:43:23.883+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:43:23.885+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:43:23.899+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:43:25.069+09:00  INFO 1956 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:43:25.085+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:43:25.086+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:43:25.196+09:00  INFO 1956 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:43:25.197+09:00  INFO 1956 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2543 ms
+2025-08-05T16:43:25.604+09:00  INFO 1956 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:43:25.707+09:00  INFO 1956 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:43:25.740+09:00  INFO 1956 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:43:26.217+09:00  INFO 1956 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:43:26.244+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:43:26.411+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:43:26.413+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:43:26.434+09:00  WARN 1956 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:43:26.460+09:00  INFO 1956 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:43:26.830+09:00  INFO 1956 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:43:26.834+09:00  INFO 1956 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:43:27.280+09:00  WARN 1956 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+2025-08-05T16:43:27.306+09:00  INFO 1956 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:43:27.316+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-05T16:43:27.325+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-05T16:43:27.331+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-05T16:43:27.355+09:00  INFO 1956 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-05T16:43:27.399+09:00 ERROR 1956 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
+
+org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
+	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
+Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:321) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:309) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1683) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 21 common frames omitted
+Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:146) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:318) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 34 common frames omitted
+Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis.core.ZSetOperations.range(Object, long, long)" because "this.zSetOperations" is null
+	at com.mnms.booking.service.WaitingService.getWaitingUsers(WaitingService.java:166) ~[main/:na]
+	at com.mnms.booking.service.WaitingService.(WaitingService.java:68) ~[main/:na]
+	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
+	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
+	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
+	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
+	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
+	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 36 common frames omitted
+
+2025-08-05T16:44:01.979+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 29296 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:44:01.983+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:44:03.411+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:44:03.414+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:44:03.457+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:44:03.475+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:44:03.477+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:44:03.492+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:44:04.585+09:00  INFO 29296 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:44:04.605+09:00  INFO 29296 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:44:04.606+09:00  INFO 29296 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:44:04.703+09:00  INFO 29296 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:44:04.704+09:00  INFO 29296 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2650 ms
+2025-08-05T16:44:05.022+09:00  INFO 29296 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:44:05.155+09:00  INFO 29296 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:44:05.205+09:00  INFO 29296 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:44:05.707+09:00  INFO 29296 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:44:05.759+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:44:05.973+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:44:05.976+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:44:05.998+09:00  WARN 29296 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:44:06.022+09:00  INFO 29296 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:44:06.347+09:00  INFO 29296 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:44:06.355+09:00  INFO 29296 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:44:07.335+09:00  WARN 29296 --- [booking] [main] 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-08-05T16:44:07.605+09:00  INFO 29296 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:44:08.543+09:00  INFO 29296 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:44:08.985+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:44:08.988+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3497ecea]]
+2025-08-05T16:44:08.990+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:44:09.016+09:00  INFO 29296 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:44:09.637+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.45 seconds (process running for 8.922)
+2025-08-05T16:44:50.918+09:00  INFO 27656 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 27656 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:44:50.921+09:00  INFO 27656 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:44:52.054+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:44:52.056+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:44:52.088+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:44:52.106+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:44:52.107+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:44:52.123+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:44:53.268+09:00  INFO 27656 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:44:53.285+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:44:53.285+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:44:53.383+09:00  INFO 27656 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:44:53.384+09:00  INFO 27656 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2397 ms
+2025-08-05T16:44:53.860+09:00  INFO 27656 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:44:53.961+09:00  INFO 27656 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:44:53.995+09:00  INFO 27656 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:44:54.542+09:00  INFO 27656 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:44:54.572+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:44:54.754+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:44:54.757+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:44:54.778+09:00  WARN 27656 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:44:54.805+09:00  INFO 27656 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:44:55.148+09:00  INFO 27656 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:44:55.154+09:00  INFO 27656 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:44:55.836+09:00  WARN 27656 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+2025-08-05T16:44:55.892+09:00  INFO 27656 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:44:55.903+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
+2025-08-05T16:44:55.910+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
+2025-08-05T16:44:55.918+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
+2025-08-05T16:44:55.943+09:00  INFO 27656 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
+
+Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
+2025-08-05T16:44:56.018+09:00 ERROR 27656 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
+
+org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
+	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
+	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
+	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
+Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:321) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:309) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1683) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 21 common frames omitted
+Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
+	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:146) ~[spring-beans-6.2.9.jar:6.2.9]
+	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:318) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 34 common frames omitted
+Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis.core.ZSetOperations.range(Object, long, long)" because "this.zSetOperations" is null
+	at com.mnms.booking.service.WaitingService.getWaitingUsers(WaitingService.java:142) ~[main/:na]
+	at com.mnms.booking.service.WaitingService.(WaitingService.java:68) ~[main/:na]
+	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
+	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
+	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
+	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
+	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
+	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210) ~[spring-beans-6.2.9.jar:6.2.9]
+	... 36 common frames omitted
+
+2025-08-05T16:46:43.343+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28232 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
+2025-08-05T16:46:43.346+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
+2025-08-05T16:46:44.360+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:46:44.363+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
+2025-08-05T16:46:44.391+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
+2025-08-05T16:46:44.410+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
+2025-08-05T16:46:44.411+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
+2025-08-05T16:46:44.427+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
+2025-08-05T16:46:45.465+09:00  INFO 28232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
+2025-08-05T16:46:45.480+09:00  INFO 28232 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
+2025-08-05T16:46:45.481+09:00  INFO 28232 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
+2025-08-05T16:46:45.568+09:00  INFO 28232 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
+2025-08-05T16:46:45.569+09:00  INFO 28232 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2158 ms
+2025-08-05T16:46:46.160+09:00  INFO 28232 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
+2025-08-05T16:46:46.293+09:00  INFO 28232 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
+2025-08-05T16:46:46.326+09:00  INFO 28232 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
+2025-08-05T16:46:46.802+09:00  INFO 28232 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
+2025-08-05T16:46:46.831+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
+2025-08-05T16:46:46.987+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
+2025-08-05T16:46:46.989+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
+2025-08-05T16:46:47.008+09:00  WARN 28232 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
+2025-08-05T16:46:47.029+09:00  INFO 28232 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
+	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
+	Database driver: undefined/unknown
+	Database version: 2.3.232
+	Autocommit mode: undefined/unknown
+	Isolation level: undefined/unknown
+	Minimum pool size: undefined/unknown
+	Maximum pool size: undefined/unknown
+2025-08-05T16:46:47.373+09:00  INFO 28232 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
+2025-08-05T16:46:47.382+09:00  INFO 28232 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
+2025-08-05T16:46:48.675+09:00  INFO 28232 --- [booking] [main] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
+2025-08-05T16:46:48.910+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:46:49.005+09:00  WARN 28232 --- [booking] [main] 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-08-05T16:46:49.163+09:00  INFO 28232 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
+2025-08-05T16:46:50.165+09:00  INFO 28232 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
+2025-08-05T16:46:50.544+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
+2025-08-05T16:46:50.546+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@f28ee19]]
+2025-08-05T16:46:50.547+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
+2025-08-05T16:46:50.559+09:00  INFO 28232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
+2025-08-05T16:46:50.655+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.919 seconds (process running for 8.303)
+2025-08-05T16:46:53.936+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:46:53.940+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:46:53.941+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:46:54.005+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:46:54.005+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:46:58.958+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:46:58.959+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:46:58.962+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:46:58.962+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:46:58.963+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:03.987+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:03.988+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:47:03.991+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:47:03.992+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:47:03.993+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:09.011+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:09.014+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:47:09.021+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:47:09.021+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:47:09.022+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:14.040+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:14.042+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:47:14.045+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:47:14.046+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:47:14.047+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:19.059+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:19.060+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:47:19.065+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:47:19.065+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:47:19.066+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:24.095+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:24.096+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
+2025-08-05T16:47:24.102+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
+2025-08-05T16:47:24.103+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
+2025-08-05T16:47:24.104+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
+2025-08-05T16:47:25.350+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
+2025-08-05T16:47:25.352+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
+2025-08-05T16:47:25.354+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
+2025-08-05T16:47:25.590+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
+2025-08-05T16:47:25.600+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
+2025-08-05T16:47:25.602+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
+2025-08-05T16:47:28.624+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue (manual removal).
+2025-08-05T16:47:29.109+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열이 비어 스케줄러 중지됨.
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index fde403d..d49f7d7 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -40,7 +40,6 @@ public ResponseEntity enterBookingPage(@RequestParam("userId")
             return ResponseEntity.ok(new WaitingNumberDto(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
             // 대기열에 진입한 경우
-            waitingService.getAndPublishWaitingNumber(userId);
             return ResponseEntity.ok(new WaitingNumberDto(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 117d9d9..e5ddc3a 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -1,22 +1,25 @@
 package com.mnms.booking.service;
 
-
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.mnms.booking.dto.response.WaitingNumberDto;
 import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.ScheduledFuture;
 
 @Service
 @Slf4j
@@ -42,10 +45,18 @@ public class WaitingService {
     private static final double IMMEDIATE_ENTRY_RATIO = 1; // 기준 : 즉시 입장 비율 (1.5배), 테스트 (1배)
     private static final long IMMEDIATE_ENTRY_COUNT = (long) (PERFORMANCE_CAPACITY * IMMEDIATE_ENTRY_RATIO);
 
+    // scheduled
+    private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+    private ScheduledFuture scheduledTask;
+
 
     @PostConstruct
     public void init() {
         zSetOperations = redisTemplate.opsForZSet();
+        List waitingUsers = getWaitingUsers();
+        if (!waitingUsers.isEmpty()) {
+            startScheduler();
+        }
     }
 
     public WaitingService(
@@ -55,6 +66,9 @@ public WaitingService(
         this.redisTemplate = redisTemplate;
         this.stringRedisTemplate = stringRedisTemplate;
         this.objectMapper = objectMapper;
+
+        // scheduler 초기화
+        scheduler.initialize();
     }
 
     /**
@@ -80,32 +94,53 @@ public long enterWaitingQueue(String userId) {
             zSetOperations.add(WAITING_QUEUE_KEY, userId, timestamp);
 
             log.info("User {} added to waiting queue with timestamp {}.", userId, timestamp);
+
+            // 조건부 스케줄러 시작
+            startScheduler();
+
             return getAndPublishWaitingNumber(userId);
         }
     }
 
     /**
-     * 대기열에 있는 사용자에게 주기적으로 대기 번호 발행
-     * 5초마다 실행
+     * 스케줄러 시작 (중복 시작 방지)
      */
-    @Scheduled(fixedDelay = 5000)
-    public void publishAllWaitingNumbers() {
+    public synchronized void startScheduler() {
+        if (scheduledTask == null || scheduledTask.isCancelled() || scheduledTask.isDone()) {
+            log.info("대기열 감시 스케줄러 시작됨.");
+            scheduledTask = scheduler.scheduleWithFixedDelay(this::runSchedulerLogic, Duration.ofSeconds(5));
+        }
+    }
+
+    /**
+     * 스케줄러 중지
+     */
+    public synchronized void stopScheduler() {
+        if (scheduledTask != null && !scheduledTask.isCancelled()) {
+            log.info("대기열이 비어 스케줄러 중지됨.");
+            scheduledTask.cancel(false);
+        }
+    }
+
+    /**
+     * 주기적으로 대기열 순번 발행
+     */
+    public void runSchedulerLogic() {
         List waitingUsers = getWaitingUsers();
+        if (waitingUsers.isEmpty()) {
+            stopScheduler(); // 비었으면 중지
+            return;
+        }
+
         for (String userId : waitingUsers) {
             getAndPublishWaitingNumber(userId);
         }
-        log.info("주기적 대기번호 발행 완료. 대상자 수: {}", waitingUsers.size());
+        log.info("대기열 사용자 {}명에게 대기번호 발행 완료.", waitingUsers.size());
     }
 
-    /**
-     * 대기열에 있는 사용자 리스트 반환하기
-     */
     public List getWaitingUsers() {
         Set userSet = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1);
-        if (userSet == null) {
-            return Collections.emptyList();
-        }
-        return new ArrayList<>(userSet);
+        return (userSet == null) ? Collections.emptyList() : new ArrayList<>(userSet);
     }
 
 
@@ -120,7 +155,7 @@ public long getAndPublishWaitingNumber(String userId) {
 
         if (rank != null) {
             long waitingNumber = rank + 1;
-            log.info("User {}'s waiting number: {}", userId, waitingNumber);
+            //log.info("User {}'s waiting number: {}", userId, waitingNumber);
 
             // Redis Pub/Sub 채널로 메시지 발행
             publishWaitingNumber(userId, waitingNumber);
@@ -138,16 +173,15 @@ public long getAndPublishWaitingNumber(String userId) {
     private void publishWaitingNumber(String userId, long waitingNumber) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberDto dto = new WaitingNumberDto(userId, waitingNumber, false, null); // <-- 이 부분 수정
-            String message = objectMapper.writeValueAsString(dto); // DTO를 JSON 문자열로 변환
-            stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message); // Redis 채널로 발행
-            log.info("Published message to Redis channel '{}': {}", NOTIFICATION_CHANNEL, message);
+            WaitingNumberDto dto = new WaitingNumberDto(userId, waitingNumber, false, null);
+            String message = objectMapper.writeValueAsString(dto);
+            // Redis 채널로 발행
+            stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
         } catch (JsonProcessingException e) {
             log.error("Error converting DTO to JSON: {}", e.getMessage());
         }
     }
 
-
     /**
      * 대기열에서 다음 사용자 진입 처리
      * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출)
@@ -224,4 +258,9 @@ public boolean removeUserFromQueue(String userId) {
             return false;
         }
     }
+
+    @PreDestroy
+    public void cleanup() {
+        scheduler.shutdown();
+    }
 }
\ No newline at end of file

From 5c333af4dd96a38500a80e99264d099de8d16b86 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 6 Aug 2025 14:56:06 +0900
Subject: [PATCH 010/149] =?UTF-8?q?MNMS-205=20feat:=20kafka=20=EC=97=B0?=
 =?UTF-8?q?=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

kafka 기본 연결 및 user-events topic 구독
추구 user-events topic 제거 후 festival, payment topic 구독 예정
---
 .gitignore                                    |    9 +
 build.gradle                                  |    8 +
 logs/spring.log                               | 3265 -----------------
 logs/spring.log.2025-08-01.0.gz               |  Bin 34889 -> 0 bytes
 .../booking/config/KafkaConsumerConfig.java   |   56 +
 .../booking/config/KafkaProducerConfig.java   |   31 +
 .../mnms/booking/config/KafkaTopicConfig.java |   18 +
 .../booking/controller/BookingController.java |    9 +-
 .../booking/controller/KaptchaController.java |    6 +-
 .../booking/dto/response/FestivalDTO.java     |   32 +
 .../{KaptchaDto.java => KaptchaDTO.java}      |    2 +-
 ...ngNumberDto.java => WaitingNumberDTO.java} |    2 +-
 .../mnms/booking/kafka/UserEventListener.java |   38 +
 .../mnms/booking/service/KaptchaService.java  |    6 +-
 .../service/RedisMessageSubscriber.java       |    4 +-
 .../mnms/booking/service/WaitingService.java  |    5 +-
 .../resources/application-test.properties     |   10 +
 17 files changed, 218 insertions(+), 3283 deletions(-)
 delete mode 100644 logs/spring.log
 delete mode 100644 logs/spring.log.2025-08-01.0.gz
 create mode 100644 src/main/java/com/mnms/booking/config/KafkaConsumerConfig.java
 create mode 100644 src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
 create mode 100644 src/main/java/com/mnms/booking/config/KafkaTopicConfig.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/FestivalDTO.java
 rename src/main/java/com/mnms/booking/dto/response/{KaptchaDto.java => KaptchaDTO.java} (87%)
 rename src/main/java/com/mnms/booking/dto/response/{WaitingNumberDto.java => WaitingNumberDTO.java} (93%)
 create mode 100644 src/main/java/com/mnms/booking/kafka/UserEventListener.java

diff --git a/.gitignore b/.gitignore
index 403113e..224b9b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,12 @@ out/
 
 ### VS Code ###
 .vscode/
+
+
+# 로그 파일
+logs/
+*.log
+*.gz
+
+# 힙 덤프 파일
+*.hprof
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index afd0be9..9077b47 100644
--- a/build.gradle
+++ b/build.gradle
@@ -57,6 +57,14 @@ dependencies {
 
 	// kaptcha
 	implementation 'com.github.penggle:kaptcha:2.3.2'
+
+	// Kafka
+	implementation 'org.springframework.kafka:spring-kafka'
+
+	// JSON 직렬화용
+	implementation 'com.fasterxml.jackson.core:jackson-databind'
+	implementation 'org.springframework.boot:spring-boot-starter-json'
+	testImplementation 'org.springframework.kafka:spring-kafka-test'
 }
 
 tasks.named('test') {
diff --git a/logs/spring.log b/logs/spring.log
deleted file mode 100644
index 8f80b24..0000000
--- a/logs/spring.log
+++ /dev/null
@@ -1,3265 +0,0 @@
-2025-08-04T15:11:10.730+09:00  INFO 6532 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6532 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-04T15:11:10.752+09:00  INFO 6532 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-04T15:11:13.746+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T15:11:13.751+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-04T15:11:13.832+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 44 ms. Found 0 JPA repository interfaces.
-2025-08-04T15:11:13.886+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T15:11:13.890+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-04T15:11:13.932+09:00  INFO 6532 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8 ms. Found 0 Redis repository interfaces.
-2025-08-04T15:11:16.427+09:00  INFO 6532 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-04T15:11:16.474+09:00  INFO 6532 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-04T15:11:16.475+09:00  INFO 6532 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-04T15:11:16.663+09:00  INFO 6532 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-04T15:11:16.664+09:00  INFO 6532 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 5757 ms
-2025-08-04T15:11:17.553+09:00  INFO 6532 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-04T15:11:17.850+09:00  INFO 6532 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-04T15:11:18.148+09:00  INFO 6532 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-04T15:11:19.379+09:00  INFO 6532 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-04T15:11:19.478+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-04T15:11:20.067+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-04T15:11:20.071+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-04T15:11:20.154+09:00  WARN 6532 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-04T15:11:20.221+09:00  INFO 6532 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-04T15:11:21.241+09:00  INFO 6532 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-04T15:11:21.257+09:00  INFO 6532 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T15:11:23.159+09:00  WARN 6532 --- [booking] [main] 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-08-04T15:11:23.588+09:00  INFO 6532 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-04T15:11:25.172+09:00  INFO 6532 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-04T15:11:25.727+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-04T15:11:25.730+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1016b44e]]
-2025-08-04T15:11:25.731+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
-2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1016b44e]]
-2025-08-04T15:11:25.748+09:00  INFO 6532 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
-2025-08-04T15:11:25.760+09:00  WARN 6532 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'webServerStartStop'
-2025-08-04T15:11:25.780+09:00  INFO 6532 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T15:11:25.785+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-04T15:11:25.789+09:00  INFO 6532 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-04T15:11:25.805+09:00  INFO 6532 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-04T15:11:25.829+09:00 ERROR 6532 --- [booking] [main] o.s.b.d.LoggingFailureAnalysisReporter   : 
-
-***************************
-APPLICATION FAILED TO START
-***************************
-
-Description:
-
-Web server failed to start. Port 8080 was already in use.
-
-Action:
-
-Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
-
-2025-08-04T15:12:30.451+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28936 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-04T15:12:30.457+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-04T15:12:32.070+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T15:12:32.072+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-04T15:12:32.141+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 35 ms. Found 0 JPA repository interfaces.
-2025-08-04T15:12:32.161+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T15:12:32.162+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-04T15:12:32.181+09:00  INFO 28936 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-04T15:12:33.502+09:00  INFO 28936 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-04T15:12:33.521+09:00  INFO 28936 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-04T15:12:33.522+09:00  INFO 28936 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-04T15:12:33.641+09:00  INFO 28936 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-04T15:12:33.642+09:00  INFO 28936 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3108 ms
-2025-08-04T15:12:34.188+09:00  INFO 28936 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-04T15:12:34.346+09:00  INFO 28936 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-04T15:12:34.377+09:00  INFO 28936 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-04T15:12:34.978+09:00  INFO 28936 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-04T15:12:35.013+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-04T15:12:35.201+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-04T15:12:35.203+09:00  INFO 28936 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-04T15:12:35.225+09:00  WARN 28936 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-04T15:12:35.248+09:00  INFO 28936 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-04T15:12:35.604+09:00  INFO 28936 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-04T15:12:35.609+09:00  INFO 28936 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T15:12:36.830+09:00  WARN 28936 --- [booking] [main] 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-08-04T15:12:37.123+09:00  INFO 28936 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-04T15:12:38.343+09:00  INFO 28936 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-04T15:12:39.196+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-04T15:12:39.202+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@507fecf3]]
-2025-08-04T15:12:39.205+09:00  INFO 28936 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-04T15:12:39.358+09:00  INFO 28936 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-04T15:12:40.522+09:00  INFO 28936 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.986 seconds (process running for 11.539)
-2025-08-04T15:13:39.179+09:00  INFO 28936 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-04T15:48:07.528+09:00  WARN 28936 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=30m32s140ms607µs).
-2025-08-04T16:57:27.085+09:00  WARN 28936 --- [booking] [HikariPool-1:housekeeper] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta=1h1m49s478ms585µs600ns).
-2025-08-04T17:15:35.155+09:00  INFO 28936 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 2, active threads = 1, queued tasks = 0, completed tasks = 1]
-2025-08-04T17:44:45.964+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-04T17:44:45.964+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-04T17:44:45.972+09:00  INFO 28936 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 8 ms
-2025-08-04T17:45:35.165+09:00  INFO 28936 --- [booking] [MessageBroker-2] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 2]
-2025-08-04T17:55:57.557+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 30600 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-04T17:55:57.560+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-04T17:55:59.377+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T17:55:59.383+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-04T17:55:59.441+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 34 ms. Found 0 JPA repository interfaces.
-2025-08-04T17:55:59.473+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T17:55:59.473+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-04T17:55:59.498+09:00  INFO 30600 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-04T17:56:01.383+09:00  INFO 30600 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-04T17:56:01.410+09:00  INFO 30600 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-04T17:56:01.410+09:00  INFO 30600 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-04T17:56:01.531+09:00  INFO 30600 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-04T17:56:01.532+09:00  INFO 30600 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3889 ms
-2025-08-04T17:56:02.035+09:00  INFO 30600 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-04T17:56:02.157+09:00  INFO 30600 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-04T17:56:02.206+09:00  INFO 30600 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-04T17:56:02.928+09:00  INFO 30600 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-04T17:56:02.973+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-04T17:56:03.194+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-04T17:56:03.197+09:00  INFO 30600 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-04T17:56:03.227+09:00  WARN 30600 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-04T17:56:03.275+09:00  INFO 30600 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-04T17:56:03.838+09:00  INFO 30600 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-04T17:56:03.846+09:00  INFO 30600 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T17:56:05.122+09:00  WARN 30600 --- [booking] [main] 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-08-04T17:56:05.439+09:00  INFO 30600 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-04T17:56:06.826+09:00  INFO 30600 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-04T17:56:07.160+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-04T17:56:07.169+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@2e2c9e24]]
-2025-08-04T17:56:07.171+09:00  INFO 30600 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-04T17:56:07.223+09:00  INFO 30600 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-04T17:56:08.260+09:00  INFO 30600 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 11.967 seconds (process running for 12.707)
-2025-08-04T17:56:17.817+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-04T17:56:17.817+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-04T17:56:17.826+09:00  INFO 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 9 ms
-2025-08-04T17:56:44.349+09:00  INFO 30600 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-04T17:57:07.171+09:00  INFO 30600 --- [booking] [MessageBroker-9] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 12]
-2025-08-04T18:02:57.973+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:02:58.022+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
-2025-08-04T18:22:01.546+09:00  INFO 30600 --- [booking] [clientInboundChannel-13] c.m.b.controller.BookingController       : User 12345 subscribed to waiting queue updates.
-2025-08-04T18:24:16.634+09:00  WARN 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user2 was not found in booking user set on exit.
-2025-08-04T18:24:21.992+09:00  WARN 30600 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User 12345 was not found in booking user set on exit.
-2025-08-04T18:24:49.167+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:24:49.169+09:00  INFO 30600 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
-2025-08-04T18:26:17.892+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 15184 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-04T18:26:17.902+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-04T18:26:20.128+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T18:26:20.134+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-04T18:26:20.194+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 38 ms. Found 0 JPA repository interfaces.
-2025-08-04T18:26:20.233+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T18:26:20.233+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-04T18:26:20.260+09:00  INFO 15184 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-04T18:26:22.179+09:00  INFO 15184 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-04T18:26:22.200+09:00  INFO 15184 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-04T18:26:22.200+09:00  INFO 15184 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-04T18:26:22.334+09:00  INFO 15184 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-04T18:26:22.335+09:00  INFO 15184 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4304 ms
-2025-08-04T18:26:22.933+09:00  INFO 15184 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-04T18:26:23.068+09:00  INFO 15184 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-04T18:26:23.113+09:00  INFO 15184 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-04T18:26:24.354+09:00  INFO 15184 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-04T18:26:24.483+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-04T18:26:24.955+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-04T18:26:24.962+09:00  INFO 15184 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-04T18:26:25.022+09:00  WARN 15184 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-04T18:26:25.080+09:00  INFO 15184 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-04T18:26:26.030+09:00  INFO 15184 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-04T18:26:26.047+09:00  INFO 15184 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T18:26:30.124+09:00  WARN 15184 --- [booking] [main] 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-08-04T18:26:30.802+09:00  INFO 15184 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-04T18:26:33.989+09:00  INFO 15184 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-04T18:26:34.726+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-04T18:26:34.734+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@4a249610]]
-2025-08-04T18:26:34.734+09:00  INFO 15184 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-04T18:26:34.824+09:00  INFO 15184 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-04T18:26:36.925+09:00  INFO 15184 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 20.206 seconds (process running for 21.271)
-2025-08-04T18:26:52.356+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-04T18:26:52.356+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-04T18:26:52.361+09:00  INFO 15184 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 5 ms
-2025-08-04T18:27:03.678+09:00  INFO 15184 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
-2025-08-04T18:27:13.126+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:27:13.175+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
-2025-08-04T18:27:25.437+09:00  INFO 15184 --- [booking] [clientInboundChannel-16] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
-2025-08-04T18:27:29.715+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"12345","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:27:29.717+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user 12345: 1
-2025-08-04T18:27:34.716+09:00  INFO 15184 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[2 current WS(2)-HttpStream(0)-HttpPoll(0), 2 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(2)-CONNECTED(2)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 18, active threads = 0, queued tasks = 0, completed tasks = 18], outboundChannel[pool size = 2, active threads = 0, queued tasks = 0, completed tasks = 2], sockJsScheduler[pool size = 15, active threads = 1, queued tasks = 3, completed tasks = 9]
-2025-08-04T18:27:55.833+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:27:55.836+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-04T18:28:01.569+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:28:01.570+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:29:10.120+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:29:10.122+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:29:22.224+09:00  INFO 15184 --- [booking] [clientInboundChannel-31] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
-2025-08-04T18:29:29.683+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:29:29.684+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-04T18:29:36.448+09:00  INFO 15184 --- [booking] [clientInboundChannel-40] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
-2025-08-04T18:29:39.730+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:29:39.732+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-04T18:29:50.762+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-04T18:29:50.763+09:00  INFO 15184 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:47:23.032+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 11952 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-04T18:47:23.032+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-04T18:47:24.651+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T18:47:24.652+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-04T18:47:24.725+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 37 ms. Found 0 JPA repository interfaces.
-2025-08-04T18:47:24.751+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-04T18:47:24.758+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-04T18:47:24.782+09:00  INFO 11952 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-04T18:47:26.327+09:00  INFO 11952 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-04T18:47:26.343+09:00  INFO 11952 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-04T18:47:26.343+09:00  INFO 11952 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-04T18:47:26.450+09:00  INFO 11952 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-04T18:47:26.451+09:00  INFO 11952 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3297 ms
-2025-08-04T18:47:27.044+09:00  INFO 11952 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-04T18:47:27.181+09:00  INFO 11952 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-04T18:47:27.220+09:00  INFO 11952 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-04T18:47:27.700+09:00  INFO 11952 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-04T18:47:27.729+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-04T18:47:27.887+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-04T18:47:27.888+09:00  INFO 11952 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-04T18:47:27.909+09:00  WARN 11952 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-04T18:47:27.930+09:00  INFO 11952 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-04T18:47:28.300+09:00  INFO 11952 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-04T18:47:28.305+09:00  INFO 11952 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-04T18:47:29.320+09:00  WARN 11952 --- [booking] [main] 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-08-04T18:47:29.564+09:00  INFO 11952 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-04T18:47:30.713+09:00  INFO 11952 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-04T18:47:31.331+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-04T18:47:31.336+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3d8b9dee]]
-2025-08-04T18:47:31.339+09:00  INFO 11952 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-04T18:47:31.414+09:00  INFO 11952 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-04T18:47:32.156+09:00  INFO 11952 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 10.681 seconds (process running for 11.263)
-2025-08-04T18:47:32.174+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:47:37.197+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:47:42.208+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:47:47.222+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:47:52.238+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:47:57.259+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:02.275+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:07.291+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:12.311+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:17.327+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:17.409+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-04T18:48:17.409+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-04T18:48:17.410+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-04T18:48:22.344+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:23.013+09:00  INFO 11952 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
-2025-08-04T18:48:27.356+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:31.311+09:00  INFO 11952 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 9, active threads = 0, queued tasks = 0, completed tasks = 9], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 14]
-2025-08-04T18:48:32.372+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:37.381+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:38.771+09:00  INFO 11952 --- [booking] [clientInboundChannel-16] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
-2025-08-04T18:48:41.785+09:00  INFO 11952 --- [booking] [clientInboundChannel-25] c.m.b.controller.BookingController       : User user3 subscribed to waiting queue updates.
-2025-08-04T18:48:42.404+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:47.417+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:52.432+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:57.446+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:48:58.385+09:00  INFO 11952 --- [booking] [clientInboundChannel-3] c.m.b.controller.BookingController       : User user4 subscribed to waiting queue updates.
-2025-08-04T18:49:02.454+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:49:07.475+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:49:12.489+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:49:14.080+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
-2025-08-04T18:49:17.507+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:49:22.530+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:49:23.027+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
-2025-08-04T18:49:25.099+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754300965068.
-2025-08-04T18:49:25.104+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:25.147+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:25.148+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:25.215+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:27.550+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:27.553+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:27.553+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:27.554+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:27.555+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:32.570+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:32.575+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:32.576+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:32.576+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:32.578+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:37.600+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:37.604+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:37.605+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:37.606+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:37.608+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:42.624+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:42.629+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:42.629+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:42.630+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:42.632+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:47.656+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:47.658+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:47.659+09:00  INFO 11952 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:47.660+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:47.662+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:52.679+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:52.686+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:52.687+09:00  INFO 11952 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:49:52.688+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:52.689+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:56.216+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754300996211.
-2025-08-04T18:49:56.220+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-04T18:49:56.226+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:49:56.226+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:49:56.229+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-04T18:49:57.711+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:49:57.719+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:57.721+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:49:57.723+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:49:57.724+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-04T18:49:57.730+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:49:57.730+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-04T18:49:57.731+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:49:57.734+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-04T18:50:02.748+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:50:02.752+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:02.753+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:02.755+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-04T18:50:02.755+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:50:02.760+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:50:02.761+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-04T18:50:02.762+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:50:02.763+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-04T18:50:07.771+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-04T18:50:07.776+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:07.777+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:07.780+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-04T18:50:07.781+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-04T18:50:07.789+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:50:07.791+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-04T18:50:07.791+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-04T18:50:07.795+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-04T18:50:11.253+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-04T18:50:11.261+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue.
-2025-08-04T18:50:11.264+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 added to booking user set.
-2025-08-04T18:50:11.270+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:11.274+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:11.275+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:11.276+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:12.804+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:12.808+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:12.809+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:12.809+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:12.813+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:17.829+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:17.831+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:17.832+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:17.832+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:17.833+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:22.848+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:22.850+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:22.851+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:22.851+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:22.852+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:27.873+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:27.877+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:27.878+09:00  INFO 11952 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:27.878+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:27.879+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:29.785+09:00  INFO 11952 --- [booking] [clientInboundChannel-39] c.m.b.controller.BookingController       : User user5 subscribed to waiting queue updates.
-2025-08-04T18:50:32.894+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:32.897+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:32.898+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:32.898+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:32.899+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:37.910+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:37.913+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:37.914+09:00  INFO 11952 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:37.914+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:37.915+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:42.935+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:42.938+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:42.938+09:00  INFO 11952 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:42.940+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:42.941+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:47.948+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:47.953+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:47.953+09:00  INFO 11952 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:47.955+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:47.956+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:52.972+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:52.975+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:52.976+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:52.976+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:52.977+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:50:54.788+09:00  WARN 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user4 was not found in booking user set on exit.
-2025-08-04T18:50:57.990+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:50:57.997+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:50:57.999+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-04T18:51:00.257+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user3 exited booking page and removed from booking user set.
-2025-08-04T18:51:00.274+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue.
-2025-08-04T18:51:00.278+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 added to booking user set.
-2025-08-04T18:51:03.010+09:00  INFO 11952 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:51:08.025+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:51:13.042+09:00  INFO 11952 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:51:14.711+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5 added to waiting queue with timestamp 1754301074709.
-2025-08-04T18:51:14.714+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:14.717+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:14.718+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:14.719+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:18.062+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:18.067+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:18.069+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:23.079+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:23.081+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:23.082+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:23.082+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:23.083+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:28.091+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:28.094+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:28.094+09:00  INFO 11952 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:28.095+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:28.096+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:33.120+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:33.126+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:33.127+09:00  INFO 11952 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:33.127+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:33.128+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:38.138+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:38.140+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:38.140+09:00  INFO 11952 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:38.141+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:38.142+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:43.154+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:43.157+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:43.158+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:48.172+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-04T18:51:48.174+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:48.175+09:00  INFO 11952 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-04T18:51:48.175+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-04T18:51:48.176+09:00  INFO 11952 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-04T18:51:50.689+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 exited booking page and removed from booking user set.
-2025-08-04T18:51:50.701+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user5 removed from waiting queue.
-2025-08-04T18:51:50.706+09:00  INFO 11952 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user5 added to booking user set.
-2025-08-04T18:51:53.191+09:00  INFO 11952 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-04T18:51:58.204+09:00  INFO 11952 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:03.790+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 23016 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T11:03:03.794+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T11:03:05.221+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:03:05.223+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T11:03:05.258+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-05T11:03:05.281+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:03:05.282+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T11:03:05.302+09:00  INFO 23016 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T11:03:06.382+09:00  INFO 23016 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T11:03:06.399+09:00  INFO 23016 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T11:03:06.400+09:00  INFO 23016 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T11:03:06.497+09:00  INFO 23016 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T11:03:06.497+09:00  INFO 23016 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2633 ms
-2025-08-05T11:03:06.890+09:00  INFO 23016 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T11:03:06.993+09:00  INFO 23016 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T11:03:07.043+09:00  INFO 23016 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T11:03:07.555+09:00  INFO 23016 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T11:03:07.594+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T11:03:07.830+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T11:03:07.833+09:00  INFO 23016 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T11:03:07.868+09:00  WARN 23016 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T11:03:07.894+09:00  INFO 23016 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T11:03:08.233+09:00  INFO 23016 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T11:03:08.239+09:00  INFO 23016 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T11:03:09.506+09:00  WARN 23016 --- [booking] [main] 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-08-05T11:03:09.787+09:00  INFO 23016 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T11:03:10.846+09:00  INFO 23016 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T11:03:11.193+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T11:03:11.197+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3d8b9dee]]
-2025-08-05T11:03:11.199+09:00  INFO 23016 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T11:03:11.227+09:00  INFO 23016 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T11:03:11.874+09:00  INFO 23016 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.804 seconds (process running for 9.198)
-2025-08-05T11:03:11.888+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:16.899+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:21.914+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:26.928+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:31.937+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:36.955+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:41.962+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:46.975+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:51.998+09:00  INFO 23016 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:03:57.008+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:02.017+09:00  INFO 23016 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:04.400+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T11:04:04.400+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T11:04:04.402+09:00  INFO 23016 --- [booking] [http-nio-0.0.0.0-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-05T11:04:07.035+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:11.216+09:00  INFO 23016 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
-2025-08-05T11:04:12.050+09:00  INFO 23016 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:17.061+09:00  INFO 23016 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:18.782+09:00  INFO 23016 --- [booking] [clientInboundChannel-7] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
-2025-08-05T11:04:22.072+09:00  INFO 23016 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:27.084+09:00  INFO 23016 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:32.096+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:37.112+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:42.124+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:47.140+09:00  INFO 23016 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:52.156+09:00  INFO 23016 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:04:57.162+09:00  INFO 23016 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:02.175+09:00  INFO 23016 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:07.188+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:12.209+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:17.223+09:00  INFO 23016 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:22.245+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:27.261+09:00  INFO 23016 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:32.278+09:00  INFO 23016 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:37.285+09:00  INFO 23016 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:42.304+09:00  INFO 23016 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:47.311+09:00  INFO 23016 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:52.316+09:00  INFO 23016 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:05:57.333+09:00  INFO 23016 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:14:56.878+09:00  INFO 1352 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1352 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T11:14:56.881+09:00  INFO 1352 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T11:14:57.909+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:14:57.911+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T11:14:57.937+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
-2025-08-05T11:14:57.956+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:14:57.958+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T11:14:57.972+09:00  INFO 1352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T11:14:59.086+09:00  INFO 1352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T11:14:59.104+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T11:14:59.104+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T11:14:59.203+09:00  INFO 1352 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T11:14:59.203+09:00  INFO 1352 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2259 ms
-2025-08-05T11:14:59.596+09:00  INFO 1352 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T11:14:59.699+09:00  INFO 1352 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T11:14:59.743+09:00  INFO 1352 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T11:15:00.174+09:00  INFO 1352 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T11:15:00.206+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T11:15:00.372+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T11:15:00.373+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T11:15:00.397+09:00  WARN 1352 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T11:15:00.419+09:00  INFO 1352 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T11:15:00.816+09:00  INFO 1352 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T11:15:00.823+09:00  INFO 1352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T11:15:01.943+09:00  WARN 1352 --- [booking] [main] 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-08-05T11:15:02.146+09:00  INFO 1352 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T11:15:02.310+09:00  WARN 1352 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'bookingController' method 
-com.mnms.booking.controller.BookingController#exitWaitingUser(String)
-to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
-com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
-2025-08-05T11:15:02.368+09:00  INFO 1352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T11:15:02.377+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-05T11:15:02.382+09:00  INFO 1352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-05T11:15:02.390+09:00  INFO 1352 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-05T11:15:02.417+09:00  INFO 1352 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-05T11:15:02.477+09:00 ERROR 1352 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
-
-org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Ambiguous mapping. Cannot map 'bookingController' method 
-com.mnms.booking.controller.BookingController#exitWaitingUser(String)
-to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
-com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1826) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
-	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
-Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'bookingController' method 
-com.mnms.booking.controller.BookingController#exitWaitingUser(String)
-to {GET [/api/booking/release/{userId}]}: There is already 'bookingController' bean method
-com.mnms.booking.controller.BookingController#releaseUser(String) mapped.
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.validateMethodMapping(AbstractHandlerMethodMapping.java:676) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:637) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:331) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:507) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.registerHandlerMethod(RequestMappingHandlerMapping.java:84) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$2(AbstractHandlerMethodMapping.java:298) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:721) ~[na:na]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:296) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(AbstractHandlerMethodMapping.java:265) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:224) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:212) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:237) ~[spring-webmvc-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1873) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1822) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 18 common frames omitted
-
-2025-08-05T11:16:07.621+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 25232 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T11:16:07.626+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T11:16:08.861+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:16:08.863+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T11:16:08.903+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-05T11:16:08.922+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T11:16:08.924+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T11:16:08.942+09:00  INFO 25232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-05T11:16:10.127+09:00  INFO 25232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T11:16:10.145+09:00  INFO 25232 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T11:16:10.145+09:00  INFO 25232 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T11:16:10.242+09:00  INFO 25232 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T11:16:10.243+09:00  INFO 25232 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2534 ms
-2025-08-05T11:16:10.677+09:00  INFO 25232 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T11:16:10.748+09:00  INFO 25232 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T11:16:10.783+09:00  INFO 25232 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T11:16:11.369+09:00  INFO 25232 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T11:16:11.397+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T11:16:11.556+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T11:16:11.559+09:00  INFO 25232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T11:16:11.580+09:00  WARN 25232 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T11:16:11.610+09:00  INFO 25232 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T11:16:12.013+09:00  INFO 25232 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T11:16:12.022+09:00  INFO 25232 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T11:16:13.060+09:00  WARN 25232 --- [booking] [main] 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-08-05T11:16:13.323+09:00  INFO 25232 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T11:16:14.261+09:00  INFO 25232 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T11:16:14.580+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T11:16:14.585+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@45cddfd3]]
-2025-08-05T11:16:14.586+09:00  INFO 25232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T11:16:14.616+09:00  INFO 25232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T11:16:15.263+09:00  INFO 25232 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.321 seconds (process running for 8.769)
-2025-08-05T11:16:15.281+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:20.296+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:20.801+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T11:16:20.803+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T11:16:20.805+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-05T11:16:25.306+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:30.326+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:35.346+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:40.361+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:45.379+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:50.397+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:16:55.418+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:00.427+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:05.436+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:10.462+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:14.617+09:00  INFO 25232 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[1 current WS(1)-HttpStream(0)-HttpPoll(0), 1 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(1)-CONNECTED(1)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 3], outboundChannel[pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 1], sockJsScheduler[pool size = 16, active threads = 1, queued tasks = 3, completed tasks = 25]
-2025-08-05T11:17:15.479+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:20.497+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:25.516+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:30.538+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:35.558+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:40.575+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:45.590+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:50.605+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:17:55.619+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:00.635+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:05.646+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:10.667+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:15.677+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:20.693+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:25.700+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:30.712+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:35.732+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:40.748+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:45.757+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:50.779+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:18:55.800+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:00.813+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:05.825+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:08.234+09:00  INFO 25232 --- [booking] [clientInboundChannel-10] c.m.b.controller.BookingController       : User user1 subscribed to waiting queue updates.
-2025-08-05T11:19:10.837+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:15.852+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:20.867+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:25.876+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:30.888+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:35.904+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:40.911+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:45.922+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:46.266+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":"조금만 기다려주세요"}
-2025-08-05T11:19:46.305+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:19:50.934+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:19:55.938+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:00.950+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:03.496+09:00  INFO 25232 --- [booking] [clientInboundChannel-19] c.m.b.controller.BookingController       : User user2 subscribed to waiting queue updates.
-2025-08-05T11:20:05.962+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:08.674+09:00  INFO 25232 --- [booking] [clientInboundChannel-28] c.m.b.controller.BookingController       : User user3 subscribed to waiting queue updates.
-2025-08-05T11:20:10.973+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:15.989+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:20.588+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (1 < 2).
-2025-08-05T11:20:21.001+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:20:23.571+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
-2025-08-05T11:20:25.523+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754360425490.
-2025-08-05T11:20:25.528+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:25.571+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:25.572+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:25.575+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:26.029+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:26.033+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:26.033+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:26.035+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:26.038+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:31.054+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:31.061+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:31.063+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:31.064+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:31.065+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:36.078+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:36.085+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:36.085+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:36.086+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:36.089+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:41.103+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:41.105+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:41.114+09:00  INFO 25232 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:41.116+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:41.117+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:46.130+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:46.134+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:46.139+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:51.144+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:51.146+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:51.147+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:20:56.157+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:20:56.159+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:56.160+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:20:56.161+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:20:56.161+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:01.176+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:01.181+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:01.182+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:01.186+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:01.190+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:06.193+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:06.196+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:06.197+09:00  INFO 25232 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:06.197+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:06.198+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:11.212+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:11.214+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:11.214+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:11.215+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:11.215+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:16.230+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:16.232+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:16.232+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:16.233+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:16.234+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:21.240+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:21.242+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:21.243+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:26.267+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:26.271+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:26.272+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:31.290+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:31.292+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:31.292+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:31.293+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:31.294+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:36.312+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:36.315+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:36.315+09:00  INFO 25232 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:36.316+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:36.316+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:41.323+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:41.324+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:41.325+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:41.325+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:41.326+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:46.338+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:46.341+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:46.341+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:46.342+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:46.344+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:51.361+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:51.362+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:51.363+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:51.363+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:51.364+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:21:56.376+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:21:56.378+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:56.379+09:00  INFO 25232 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:21:56.379+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:21:56.380+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:01.397+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:01.398+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:01.399+09:00  INFO 25232 --- [booking] [MessageBroker-12] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:01.400+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:01.401+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:06.423+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:06.429+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:06.429+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:06.431+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:06.433+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:11.449+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:11.453+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:11.454+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:11.455+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:11.456+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:16.463+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:16.466+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:16.466+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:16.467+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:16.471+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:21.471+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:21.472+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:21.472+09:00  INFO 25232 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:21.473+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:21.474+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:26.493+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:26.496+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:26.497+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:31.499+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:31.501+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:31.502+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:36.523+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:36.527+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:36.527+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:36.528+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:36.529+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:41.547+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:41.548+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:41.549+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:46.567+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:46.570+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:46.571+09:00  INFO 25232 --- [booking] [MessageBroker-16] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:46.574+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:46.576+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:51.589+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:51.591+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:51.592+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:22:56.613+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:22:56.615+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:56.616+09:00  INFO 25232 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:22:56.616+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:22:56.617+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:23:01.620+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T11:23:01.621+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T11:23:01.622+09:00  INFO 25232 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T11:23:06.226+09:00  INFO 25232 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
-2025-08-05T11:23:06.633+09:00  INFO 25232 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:23:11.638+09:00  INFO 25232 --- [booking] [MessageBroker-15] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:23:16.647+09:00  INFO 25232 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:23:21.663+09:00  INFO 25232 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:23:26.678+09:00  INFO 25232 --- [booking] [MessageBroker-11] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T11:23:31.685+09:00  INFO 25232 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:07.346+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 14388 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T13:28:07.348+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T13:28:08.504+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T13:28:08.505+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T13:28:08.547+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-05T13:28:08.565+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T13:28:08.566+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T13:28:08.581+09:00  INFO 14388 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T13:28:09.576+09:00  INFO 14388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T13:28:09.594+09:00  INFO 14388 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T13:28:09.595+09:00  INFO 14388 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T13:28:09.693+09:00  INFO 14388 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T13:28:09.694+09:00  INFO 14388 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2275 ms
-2025-08-05T13:28:10.364+09:00  INFO 14388 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T13:28:10.460+09:00  INFO 14388 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T13:28:10.493+09:00  INFO 14388 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T13:28:11.008+09:00  INFO 14388 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T13:28:11.037+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T13:28:11.213+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T13:28:11.216+09:00  INFO 14388 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T13:28:11.237+09:00  WARN 14388 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T13:28:11.268+09:00  INFO 14388 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T13:28:11.641+09:00  INFO 14388 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T13:28:11.651+09:00  INFO 14388 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T13:28:12.783+09:00  WARN 14388 --- [booking] [main] 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-08-05T13:28:13.059+09:00  INFO 14388 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T13:28:14.255+09:00  INFO 14388 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T13:28:14.722+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T13:28:14.727+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@45cddfd3]]
-2025-08-05T13:28:14.729+09:00  INFO 14388 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T13:28:14.763+09:00  INFO 14388 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T13:28:15.376+09:00  INFO 14388 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.658 seconds (process running for 9.148)
-2025-08-05T13:28:15.393+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:20.412+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:25.437+09:00  INFO 14388 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:26.214+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T13:28:26.215+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T13:28:26.216+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-05T13:28:30.446+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:35.458+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:40.472+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:45.493+09:00  INFO 14388 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:50.510+09:00  INFO 14388 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:28:51.954+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754368131943.
-2025-08-05T13:28:51.957+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:28:51.984+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:51.987+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:51.990+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:28:51.995+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:51.996+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:52.085+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:28:52.085+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:28:55.526+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:28:55.530+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.542+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:28:55.618+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2 added to waiting queue with timestamp 1754368135613.
-2025-08-05T13:28:55.624+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:28:55.631+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.633+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.634+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:28:55.637+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:28:55.643+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.645+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:28:55.647+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:00.547+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:00.551+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:00.554+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:00.556+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:00.556+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:00.559+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:00.567+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:05.578+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:05.581+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:05.582+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:05.583+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:05.583+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:05.587+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:05.588+09:00  INFO 14388 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:05.588+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:05.589+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:10.600+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:10.601+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:10.602+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:10.602+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:10.603+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:10.604+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:14.716+09:00  INFO 14388 --- [booking] [MessageBroker-4] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
-2025-08-05T13:29:15.619+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:15.622+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:15.622+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:15.624+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:15.624+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:15.629+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:15.629+09:00  INFO 14388 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:15.630+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:15.631+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:20.639+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:20.642+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:20.642+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:20.643+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:20.644+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:20.647+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:20.648+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:25.657+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:25.661+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:25.662+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:25.663+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:25.666+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:29:25.667+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:25.668+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:30.135+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368170132.
-2025-08-05T13:29:30.138+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:29:30.140+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.142+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.143+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:29:30.143+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:29:30.154+09:00  INFO 14388 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.155+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.156+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:29:30.680+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:30.688+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.689+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.690+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:30.691+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:30.695+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.695+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.696+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:30.697+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:29:30.700+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.701+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:29:30.701+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:30.703+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:29:35.719+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:29:35.722+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.722+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.723+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:29:35.724+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:29:35.727+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.727+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.728+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:29:35.728+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:29:35.731+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:29:35.732+09:00  INFO 14388 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:29:52.947+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 30352 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T13:29:52.949+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T13:29:54.100+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T13:29:54.102+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T13:29:54.145+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 20 ms. Found 0 JPA repository interfaces.
-2025-08-05T13:29:54.164+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T13:29:54.166+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T13:29:54.181+09:00  INFO 30352 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-05T13:29:55.199+09:00  INFO 30352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T13:29:55.216+09:00  INFO 30352 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T13:29:55.217+09:00  INFO 30352 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T13:29:55.299+09:00  INFO 30352 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T13:29:55.300+09:00  INFO 30352 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2289 ms
-2025-08-05T13:29:55.667+09:00  INFO 30352 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T13:29:55.760+09:00  INFO 30352 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T13:29:55.797+09:00  INFO 30352 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T13:29:56.241+09:00  INFO 30352 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T13:29:56.275+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T13:29:56.437+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T13:29:56.439+09:00  INFO 30352 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T13:29:56.459+09:00  WARN 30352 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T13:29:56.481+09:00  INFO 30352 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T13:29:56.812+09:00  INFO 30352 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T13:29:56.821+09:00  INFO 30352 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T13:29:58.057+09:00  WARN 30352 --- [booking] [main] 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-08-05T13:29:58.367+09:00  INFO 30352 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T13:29:59.467+09:00  INFO 30352 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T13:29:59.778+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T13:29:59.780+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@32675dd4]]
-2025-08-05T13:29:59.781+09:00  INFO 30352 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T13:29:59.803+09:00  INFO 30352 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T13:30:00.425+09:00  INFO 30352 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.128 seconds (process running for 8.521)
-2025-08-05T13:30:00.444+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:30:00.491+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.492+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.493+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:30:00.495+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.496+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.497+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:30:00.499+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.500+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:00.500+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:30:00.525+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:30:05.513+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:30:05.517+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.518+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.520+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:30:05.520+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:30:05.529+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.530+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.531+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:30:05.535+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:30:05.542+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.542+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:30:05.543+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:05.544+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:30:10.564+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:30:10.568+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.569+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.570+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:30:10.570+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:30:10.575+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.575+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.578+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:30:10.580+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:30:10.584+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.585+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:30:10.585+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:10.587+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:30:15.607+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:30:15.614+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.614+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.615+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:30:15.618+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 2
-2025-08-05T13:30:15.623+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.624+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.626+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 2
-2025-08-05T13:30:15.629+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:30:15.634+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.635+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:30:15.635+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:30:15.636+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:30:20.006+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T13:30:20.006+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T13:30:20.009+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-05T13:30:20.211+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-05T13:30:20.217+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
-2025-08-05T13:30:20.225+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
-2025-08-05T13:30:20.234+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user2's waiting number: 1
-2025-08-05T13:30:20.240+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.240+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.242+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 1
-2025-08-05T13:30:20.243+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:30:20.246+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.249+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:30:20.652+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user2's waiting number: 1
-2025-08-05T13:30:20.656+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.657+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user2","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.658+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user2: 1
-2025-08-05T13:30:20.659+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:30:20.662+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.663+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:30:20.663+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:30:20.665+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:30:22.658+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
-2025-08-05T13:30:22.667+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 removed from waiting queue.
-2025-08-05T13:30:22.671+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user2 added to booking user set.
-2025-08-05T13:30:22.680+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:30:22.684+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:22.685+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:22.686+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:30:24.127+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3 was not found in booking user set on exit.
-2025-08-05T13:30:25.683+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:30:25.688+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:25.689+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:30:25.690+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:25.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:30:30.717+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:30:30.721+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:30.722+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:30:30.723+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:30.724+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:30:35.738+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:30:35.739+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:35.740+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:30:35.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:35.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:30:40.761+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:30:40.764+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:40.765+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:30:40.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:30:40.766+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:30:41.125+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
-2025-08-05T13:30:45.777+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:30:50.793+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:30:53.259+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Attempted to remove user user from queue, but user was not found or removal failed. Removed count: 0
-2025-08-05T13:30:55.804+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:30:59.789+09:00  INFO 30352 --- [booking] [MessageBroker-8] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 14, active threads = 1, queued tasks = 1, completed tasks = 12]
-2025-08-05T13:31:00.810+09:00  INFO 30352 --- [booking] [MessageBroker-1] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:01.137+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754368261113.
-2025-08-05T13:31:01.141+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:31:01.146+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:01.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:01.149+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:31:01.150+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:31:01.154+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:01.156+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:01.157+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:31:05.818+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:31:05.820+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:05.820+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:31:05.821+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:05.822+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:31:10.835+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:31:10.838+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:10.838+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:31:10.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:10.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:31:15.858+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T13:31:15.860+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:15.860+09:00  INFO 30352 --- [booking] [MessageBroker-10] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:31:15.861+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:15.862+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T13:31:17.270+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-05T13:31:17.272+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
-2025-08-05T13:31:17.274+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
-2025-08-05T13:31:20.469+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
-2025-08-05T13:31:20.870+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:25.876+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:30.902+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:35.914+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:36.936+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user6 can enter booking page immediately (1 < 2).
-2025-08-05T13:31:40.926+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:45.947+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:50.962+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:31:54.068+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7 added to waiting queue with timestamp 1754368314066.
-2025-08-05T13:31:54.070+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:31:54.074+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:54.075+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:54.078+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:31:54.079+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:31:54.082+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:54.083+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:54.085+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:31:55.972+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:31:55.976+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:31:55.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:32:00.989+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:32:00.994+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:00.994+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:32:00.995+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:00.996+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:32:06.017+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:32:06.019+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:06.020+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:32:11.035+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:32:11.038+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:11.038+09:00  INFO 30352 --- [booking] [MessageBroker-7] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:32:11.039+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:11.040+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:32:16.053+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : User user7's waiting number: 1
-2025-08-05T13:32:16.055+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:16.056+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:32:16.056+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user7","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:32:16.057+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user7: 1
-2025-08-05T13:32:18.472+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user6 exited booking page and removed from booking user set.
-2025-08-05T13:32:18.478+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user7 removed from waiting queue.
-2025-08-05T13:32:18.481+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user7 added to booking user set.
-2025-08-05T13:32:21.073+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:26.081+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:31.097+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:36.101+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:41.120+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:46.137+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:51.152+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:32:56.162+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:01.172+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:06.182+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:11.198+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:16.218+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:18.646+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-05T13:33:20.937+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user7 exited booking page and removed from booking user set.
-2025-08-05T13:33:21.233+09:00  INFO 30352 --- [booking] [MessageBroker-3] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:26.252+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:31.268+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:36.274+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:41.284+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:46.295+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:51.308+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:33:52.075+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
-2025-08-05T13:33:54.731+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-8] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
-2025-08-05T13:33:56.318+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:34:01.329+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:34:01.933+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368441931.
-2025-08-05T13:34:01.935+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:01.937+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:01.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:01.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:01.939+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:01.940+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:01.942+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:01.942+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:06.343+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:06.346+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:06.347+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:11.356+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:11.359+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:11.360+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:16.384+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:16.387+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:16.387+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:16.388+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:16.389+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:21.405+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:21.408+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:21.409+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:26.418+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:26.421+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:26.421+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:26.422+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:26.423+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:29.895+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368469892.
-2025-08-05T13:34:29.899+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:29.902+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:29.903+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:29.905+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:29.906+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:29.909+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:29.910+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:29.911+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:31.438+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:31.443+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:31.443+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:31.444+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:31.445+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:36.470+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:36.475+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:36.475+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:36.476+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:36.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:41.483+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:41.485+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:41.486+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:34:41.486+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:41.487+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:43.944+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754368483942.
-2025-08-05T13:34:43.948+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T13:34:43.951+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:43.953+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:43.954+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T13:34:43.956+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T13:34:43.960+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:43.961+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:43.962+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T13:34:46.500+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:46.502+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:46.503+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:46.505+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T13:34:46.505+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:46.509+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:46.509+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:34:46.510+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:46.510+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T13:34:47.183+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5 added to waiting queue with timestamp 1754368487180.
-2025-08-05T13:34:47.187+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
-2025-08-05T13:34:47.191+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:47.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:47.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
-2025-08-05T13:34:47.193+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
-2025-08-05T13:34:47.195+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:47.196+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:47.197+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
-2025-08-05T13:34:51.523+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:34:51.525+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:34:51.526+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T13:34:51.528+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.528+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.529+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T13:34:51.529+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 3
-2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:34:51.531+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:51.532+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 3
-2025-08-05T13:34:53.035+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754368493032.
-2025-08-05T13:34:53.038+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:34:53.042+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:53.042+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:53.044+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:34:53.044+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:34:53.047+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:53.047+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:53.048+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:34:56.538+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:34:56.541+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.542+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.543+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:34:56.544+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:34:56.548+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.549+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.550+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:34:56.552+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:34:56.554+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.555+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:34:56.556+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:34:56.557+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:01.566+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:01.569+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.570+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.571+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:01.573+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:01.577+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.578+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.579+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:01.581+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:01.585+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.586+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:01.587+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:01.588+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:06.594+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:06.597+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.597+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.598+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:06.599+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:06.602+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.602+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.603+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:06.603+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:06.606+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.607+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:06.608+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:06.608+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:11.616+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:11.622+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.624+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:11.625+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:11.632+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.633+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.634+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:11.637+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:11.643+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.643+09:00  INFO 30352 --- [booking] [MessageBroker-8] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:11.645+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:11.646+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:16.657+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:16.659+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.660+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.661+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:16.662+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:16.664+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.664+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-70] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.665+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-70] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:16.666+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-71] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:16.669+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-71] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:21.686+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:21.689+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.689+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-72] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.690+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-72] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:21.691+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:21.692+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-73] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.694+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-73] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:21.694+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:21.696+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.696+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:21.698+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-74] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:21.699+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-74] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:26.706+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:26.708+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.709+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-75] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.710+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:26.710+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-75] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:26.712+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.712+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-76] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.713+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-76] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:26.713+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:26.715+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.715+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:26.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-77] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:26.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-77] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:31.727+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:31.728+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.729+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-78] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.730+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-78] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:31.730+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:31.732+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.732+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-79] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.733+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-79] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:31.733+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-80] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:31.735+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-80] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:36.752+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:36.754+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.755+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-81] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.756+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-81] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:36.756+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:36.758+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.759+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-82] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.760+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-82] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:36.760+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:36.763+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.763+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:36.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-83] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:36.765+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-83] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:41.781+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:41.784+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.785+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-84] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.785+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-84] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:41.786+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:41.789+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.792+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-85] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.793+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-85] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:41.793+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:41.798+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.798+09:00  INFO 30352 --- [booking] [MessageBroker-4] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:41.799+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-86] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:41.800+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-86] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:46.817+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:46.824+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.824+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-87] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.825+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-87] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:46.833+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:46.837+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.838+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-88] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.839+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-88] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:46.840+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:46.843+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.844+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:46.845+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-89] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:46.846+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-89] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:51.858+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:51.861+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.861+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-90] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.862+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-90] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:51.863+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:51.865+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-91] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-91] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:51.866+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:51.869+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.869+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:51.870+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-92] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:51.871+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-92] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:35:56.883+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:35:56.886+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.886+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-93] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.887+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-93] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:35:56.887+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:35:56.889+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.890+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-94] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.890+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-94] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:35:56.891+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:35:56.893+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.893+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:35:56.894+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-95] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:35:56.894+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-95] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:01.919+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:01.922+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.923+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-96] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.924+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-96] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:01.924+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:01.926+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.927+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-97] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.927+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-97] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:01.928+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:01.930+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-98] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:01.931+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-98] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:06.939+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:06.942+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.943+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-99] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.944+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-99] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:06.944+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:06.946+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.947+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-100] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.947+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-100] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:06.949+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:06.951+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-101] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:06.952+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-101] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:11.970+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:11.973+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.975+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-102] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-102] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:11.977+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:11.991+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.991+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-103] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.992+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-103] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:11.995+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-104] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:11.998+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-104] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:17.012+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:17.016+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-105] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-105] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:17.019+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:17.022+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.022+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-106] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.023+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-106] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:17.031+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:17.036+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.036+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:17.037+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-107] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:17.037+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-107] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:22.047+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:22.049+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.050+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-108] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.051+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-108] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:22.051+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:22.052+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.053+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-109] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.054+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-109] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:22.054+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:22.056+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.056+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:22.058+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-110] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:22.058+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-110] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:27.071+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:27.074+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.076+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-111] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.077+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-111] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:27.078+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:27.083+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.084+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-112] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.085+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-112] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:27.087+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:27.090+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.090+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:27.091+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-113] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:27.092+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-113] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:32.109+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:32.112+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-114] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-114] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:32.114+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:32.116+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.116+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-115] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.117+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-115] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:32.118+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:32.119+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.119+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:32.121+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-116] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:32.121+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-116] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:37.132+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:37.134+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.135+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-117] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.136+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-117] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:37.139+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:37.142+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.143+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-118] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.143+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-118] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:37.144+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:37.146+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.146+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:37.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-119] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:37.147+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-119] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:42.155+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:42.158+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.159+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-120] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.160+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-120] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:42.160+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:42.163+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.164+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-121] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.165+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-121] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:42.166+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:42.168+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.168+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:42.169+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-122] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:42.170+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-122] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:47.195+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user4's waiting number: 1
-2025-08-05T13:36:47.198+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.200+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-123] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.202+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-123] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T13:36:47.202+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user5's waiting number: 2
-2025-08-05T13:36:47.207+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-124] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-124] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 2
-2025-08-05T13:36:47.214+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : User user3's waiting number: 3
-2025-08-05T13:36:47.218+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.218+09:00  INFO 30352 --- [booking] [MessageBroker-9] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 3
-2025-08-05T13:36:47.219+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-125] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":3,"immediateEntry":false,"message":null}
-2025-08-05T13:36:47.220+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-125] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 3
-2025-08-05T13:36:48.195+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : Attempted to remove user user1 from queue, but user was not found or removal failed. Removed count: 0
-2025-08-05T13:36:51.915+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-05T13:36:51.921+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue.
-2025-08-05T13:36:51.925+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 added to booking user set.
-2025-08-05T13:36:51.931+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:36:51.935+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:51.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-126] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:51.938+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-126] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:36:51.940+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:36:51.944+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:51.949+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-127] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:51.949+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-127] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:36:52.231+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:36:52.236+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:52.237+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-128] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:52.238+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:36:52.239+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-128] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:36:52.241+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:52.241+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:36:52.242+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-129] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:52.243+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-129] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:36:57.260+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:36:57.262+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:57.263+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-130] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:36:57.264+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-130] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:36:57.265+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:36:57.268+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:57.268+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:36:57.269+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-131] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:36:57.272+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-131] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:02.278+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:02.279+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:02.280+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-132] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:02.281+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-132] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:02.281+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-133] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:02.283+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-133] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:07.301+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:07.303+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:07.305+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:07.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-134] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:07.306+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-134] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:07.307+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:07.308+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:07.309+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-135] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:07.309+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-135] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:12.317+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:12.319+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:12.320+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-136] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:12.321+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-136] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:12.321+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:12.322+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-137] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:12.323+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-137] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:17.355+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-138] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:17.362+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-138] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:17.366+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:17.368+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:17.368+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:17.370+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-139] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:17.370+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-139] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:22.390+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:22.392+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:22.393+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-140] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:22.393+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-140] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:22.394+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-141] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:22.395+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-141] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:27.410+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:27.413+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:27.414+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-142] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:27.414+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:27.415+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-142] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:27.416+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-143] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:27.417+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-143] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:32.432+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:32.433+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:32.433+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-144] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:32.434+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-144] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:32.434+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:32.435+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-145] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:32.436+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-145] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:37.449+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:37.451+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:37.452+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-146] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:37.453+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:37.453+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-146] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:37.455+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:37.455+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:37.456+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-147] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:37.456+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-147] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:42.466+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:42.471+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:42.472+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-148] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:42.472+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-148] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:42.475+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:42.477+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:42.477+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:42.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-149] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:42.478+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-149] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:47.488+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:47.492+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:47.493+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-150] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:47.494+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-150] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:47.496+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:47.498+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-151] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:47.499+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-151] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:52.510+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-152] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:52.512+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-152] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:52.513+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-153] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:52.514+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-153] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:37:57.529+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:37:57.536+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:57.536+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-154] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:37:57.537+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-154] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:37:57.537+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:37:57.540+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:57.540+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:37:57.541+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-155] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:37:57.541+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-155] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:02.548+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:02.549+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:02.549+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-156] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:02.550+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:02.550+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-156] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:02.551+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-157] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:02.552+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-157] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:07.564+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:07.567+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:07.568+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-158] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:07.569+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-158] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:07.569+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:07.571+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:07.571+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:07.572+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-159] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:07.573+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-159] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:12.586+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:12.587+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:12.588+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-160] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:12.589+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-160] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:12.589+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-161] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:12.591+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-161] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:17.616+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:17.618+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:17.619+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-162] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:17.619+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-162] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:17.620+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:17.622+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:17.622+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:17.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-163] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:17.623+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-163] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:22.636+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:22.638+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:22.639+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-164] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:22.640+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-164] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:22.640+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:22.642+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:22.642+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:22.643+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-165] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:22.643+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-165] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:27.664+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:27.666+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:27.667+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-166] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:27.668+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:27.668+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-166] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:27.670+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-167] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:27.671+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-167] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:32.689+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:32.692+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:32.692+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-168] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:32.693+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-168] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:32.693+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:32.695+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:32.696+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:32.696+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-169] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:32.697+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-169] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:37.712+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:37.714+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:37.715+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-170] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:37.716+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-170] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:37.716+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:37.718+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:37.718+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:37.719+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-171] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:37.719+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-171] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:42.732+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:42.735+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:42.736+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-172] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:42.737+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-172] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:42.737+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:42.740+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:42.740+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:42.741+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-173] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:42.742+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-173] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:47.758+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:47.761+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:47.762+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-174] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:47.762+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-174] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:47.763+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:47.765+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:47.765+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:47.766+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-175] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:47.767+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-175] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:52.774+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:52.775+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:52.779+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-176] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:52.779+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-176] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:52.780+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-177] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:52.781+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-177] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:38:57.796+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:38:57.799+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:57.801+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-178] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:38:57.802+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-178] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:38:57.803+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:38:57.805+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-179] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:38:57.806+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-179] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:02.810+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:02.814+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:02.815+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:02.815+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-180] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:02.816+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-180] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-181] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:02.818+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-181] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:07.837+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:07.839+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-182] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-182] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:07.841+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:07.843+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:07.843+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:07.844+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-183] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:07.844+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-183] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:12.860+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:12.863+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:12.864+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-184] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:12.864+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:12.865+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-184] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:12.867+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:12.867+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:12.869+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-185] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:12.869+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-185] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:17.877+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:17.879+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:17.879+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-186] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:17.880+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-186] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:17.880+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:17.882+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:17.882+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:17.883+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-187] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:17.883+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-187] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:22.891+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:22.895+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:22.896+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-188] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:22.896+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-188] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:22.897+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:22.899+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [MessageBroker-5] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-189] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:22.900+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-189] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:27.913+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:27.915+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:27.916+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-190] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:27.917+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-190] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:27.917+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:27.920+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-191] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:27.921+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-191] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:32.929+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:32.931+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:32.932+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-192] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:32.933+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:32.935+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-192] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-193] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:32.936+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-193] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:37.953+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:37.954+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:37.956+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-194] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:37.956+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:37.957+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-194] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:37.958+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-195] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:37.959+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-195] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:42.970+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:42.972+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-196] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-196] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:42.973+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:42.975+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:42.976+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:42.976+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-197] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:42.977+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-197] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:47.997+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:47.999+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:48.000+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-198] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:48.001+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-198] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:48.002+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:48.003+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:48.004+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:48.004+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-199] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:48.005+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-199] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:53.010+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:53.012+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:53.013+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-200] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:53.014+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-200] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:53.014+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:53.016+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:53.017+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:53.017+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-201] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:53.018+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-201] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:39:58.035+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:39:58.037+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-202] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-202] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:39:58.038+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:39:58.040+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-203] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:39:58.041+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-203] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:03.059+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:03.062+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:03.062+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-204] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:03.063+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-204] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:03.063+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:03.069+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-205] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:03.070+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-205] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:08.086+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:08.088+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:08.089+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-206] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:08.090+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:08.091+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-206] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:08.092+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-207] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:08.093+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-207] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:13.103+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:13.105+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:13.107+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-208] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:13.108+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:13.109+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-208] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:13.111+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:13.111+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:13.112+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-209] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:13.113+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-209] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:18.129+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:18.131+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:18.132+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-210] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:18.133+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-210] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:18.133+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:18.134+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:18.135+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:18.135+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-211] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:18.136+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-211] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:23.155+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:23.160+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:23.161+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-212] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:23.162+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-212] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:23.163+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:23.165+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-213] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:23.166+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-213] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:28.187+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:28.191+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:28.192+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-214] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:28.193+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-214] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:28.194+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:28.197+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-215] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:28.198+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-215] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:33.206+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:33.207+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-216] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-216] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:33.208+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-217] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:33.210+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-217] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:38.219+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:38.222+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:38.223+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-218] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:38.224+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:38.224+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-218] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:38.226+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:38.226+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:38.227+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-219] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:38.227+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-219] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:43.243+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:43.244+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:43.245+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-220] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:43.245+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-220] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:43.246+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-221] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:43.247+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-221] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:48.265+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:48.267+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:48.269+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-222] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:48.270+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-222] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:48.270+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:48.274+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-223] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:48.275+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-223] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:53.297+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:53.300+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:53.301+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-224] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:53.301+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-224] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:53.302+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:53.304+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:53.304+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:53.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-225] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:53.305+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-225] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:40:58.313+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:40:58.319+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:58.320+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-226] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:40:58.321+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-226] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:40:58.322+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:40:58.324+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-227] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:40:58.325+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-227] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:41:03.337+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user5's waiting number: 1
-2025-08-05T13:41:03.338+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-228] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user5","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-228] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user5: 1
-2025-08-05T13:41:03.339+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 2
-2025-08-05T13:41:03.341+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:41:03.341+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 2
-2025-08-05T13:41:03.342+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-229] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T13:41:03.342+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-229] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 2
-2025-08-05T13:41:06.096+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user5 removed from waiting queue (manual removal).
-2025-08-05T13:41:06.100+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:41:06.103+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-10] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:06.104+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-230] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:06.104+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-230] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:41:08.363+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:41:08.365+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:08.366+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:41:08.366+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-231] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:08.367+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-231] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:41:12.900+09:00  WARN 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-1] c.mnms.booking.service.WaitingService    : Attempted to remove user user4 from queue, but user was not found or removal failed. Removed count: 0
-2025-08-05T13:41:13.371+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T13:41:13.373+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:13.373+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 1
-2025-08-05T13:41:13.374+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-232] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T13:41:13.374+09:00  INFO 30352 --- [booking] [redisMessageListenerContainer-232] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T13:41:14.355+09:00  INFO 30352 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
-2025-08-05T13:41:18.386+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:23.406+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:28.415+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:33.434+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:38.448+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:43.462+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:48.472+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:53.480+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:41:58.491+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:03.499+09:00  INFO 30352 --- [booking] [MessageBroker-6] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:08.508+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:13.522+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:18.540+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:23.556+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:28.568+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:33.582+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:38.591+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:43.598+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:48.615+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:53.629+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:42:58.643+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:03.651+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:08.661+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:13.687+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:18.701+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:23.710+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:28.717+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:33.731+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:38.735+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:43.741+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:48.749+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:53.768+09:00  INFO 30352 --- [booking] [MessageBroker-2] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:43:58.780+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:03.793+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:08.800+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:13.818+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:18.824+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:23.842+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:28.852+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:33.874+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:38.891+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:43.904+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:48.913+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:53.924+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:44:58.934+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:03.949+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:08.956+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:13.964+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:18.972+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:23.987+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:28.998+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:34.005+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:39.021+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:44.031+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:49.042+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:54.059+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:45:59.069+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:04.086+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:09.096+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:14.113+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:19.132+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:24.150+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:29.166+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:34.181+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:39.191+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:44.209+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:49.223+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:54.239+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:46:59.247+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:04.263+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:09.268+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:14.274+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:19.291+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:24.298+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:29.305+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:34.320+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:39.330+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:44.347+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:49.361+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:54.375+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:47:59.392+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:04.405+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:09.411+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:14.417+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:19.431+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:24.444+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:29.459+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:34.471+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:39.482+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:44.492+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:49.499+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:54.515+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:48:59.525+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:04.542+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:09.558+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:14.562+09:00  INFO 30352 --- [booking] [MessageBroker-13] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:19.568+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:24.580+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:29.592+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:34.606+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:39.619+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:44.634+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:49.644+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:54.659+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:49:59.668+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:50:04.679+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:50:09.696+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:50:14.708+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:50:19.728+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T13:50:24.734+09:00  INFO 30352 --- [booking] [MessageBroker-14] c.mnms.booking.service.WaitingService    : 주기적 대기번호 발행 완료. 대상자 수: 0
-2025-08-05T16:03:11.896+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1548 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:03:11.899+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:03:13.005+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:03:13.005+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:03:13.034+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:03:13.057+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:03:13.057+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:03:13.068+09:00  INFO 1548 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:03:14.256+09:00  INFO 1548 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:03:14.273+09:00  INFO 1548 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:03:14.277+09:00  INFO 1548 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:03:14.368+09:00  INFO 1548 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:03:14.368+09:00  INFO 1548 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2409 ms
-2025-08-05T16:03:14.699+09:00  INFO 1548 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:03:14.797+09:00  INFO 1548 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:03:14.826+09:00  INFO 1548 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:03:15.299+09:00  INFO 1548 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:03:15.330+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:03:15.490+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:03:15.504+09:00  INFO 1548 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:03:15.530+09:00  WARN 1548 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:03:15.562+09:00  INFO 1548 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:03:15.916+09:00  INFO 1548 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:03:15.935+09:00  INFO 1548 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:03:17.014+09:00  WARN 1548 --- [booking] [main] 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-08-05T16:03:17.270+09:00  INFO 1548 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:03:18.459+09:00  INFO 1548 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:03:18.981+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:03:18.994+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@24890021]]
-2025-08-05T16:03:18.994+09:00  INFO 1548 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:03:19.047+09:00  INFO 1548 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:03:19.673+09:00  INFO 1548 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.387 seconds (process running for 8.798)
-2025-08-05T16:03:38.542+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T16:03:38.543+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T16:03:38.547+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
-2025-08-05T16:03:38.790+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754377418773.
-2025-08-05T16:03:38.791+09:00  INFO 1548 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
-2025-08-05T16:04:18.980+09:00  INFO 1548 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-05T16:05:15.246+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 6100 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:05:15.248+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:05:16.371+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:05:16.374+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:05:16.417+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 22 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:05:16.432+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:05:16.432+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:05:16.448+09:00  INFO 6100 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:05:17.503+09:00  INFO 6100 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:05:17.526+09:00  INFO 6100 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:05:17.526+09:00  INFO 6100 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:05:17.637+09:00  INFO 6100 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:05:17.638+09:00  INFO 6100 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2326 ms
-2025-08-05T16:05:18.181+09:00  INFO 6100 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:05:18.255+09:00  INFO 6100 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:05:18.291+09:00  INFO 6100 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:05:18.798+09:00  INFO 6100 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:05:18.824+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:05:19.001+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:05:19.001+09:00  INFO 6100 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:05:19.032+09:00  WARN 6100 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:05:19.064+09:00  INFO 6100 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:05:19.464+09:00  INFO 6100 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:05:19.482+09:00  INFO 6100 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:05:20.429+09:00  WARN 6100 --- [booking] [main] 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-08-05T16:05:20.698+09:00  INFO 6100 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:05:21.646+09:00  INFO 6100 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:05:22.035+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:05:22.037+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@613ba54e]]
-2025-08-05T16:05:22.039+09:00  INFO 6100 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:05:22.055+09:00  INFO 6100 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:05:22.679+09:00  INFO 6100 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.094 seconds (process running for 8.519)
-2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T16:05:27.388+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-05T16:05:27.499+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1 added to waiting queue with timestamp 1754377527490.
-2025-08-05T16:05:27.500+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
-2025-08-05T16:05:27.503+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:27.508+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:27.557+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.557+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.558+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.559+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:27.562+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.563+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:27.603+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:32.578+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:32.583+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:32.584+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:32.586+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:32.587+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:37.608+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:37.615+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:37.616+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:37.618+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:37.619+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:42.642+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:42.646+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:42.647+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:42.647+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:42.649+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:47.666+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:47.668+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:47.669+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:52.690+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user1's waiting number: 1
-2025-08-05T16:05:52.693+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:52.694+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:05:52.694+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user1","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:05:52.696+09:00  INFO 6100 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user1: 1
-2025-08-05T16:05:54.872+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user2 exited booking page and removed from booking user set.
-2025-08-05T16:05:54.881+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 removed from waiting queue.
-2025-08-05T16:05:54.886+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user1 added to booking user set.
-2025-08-05T16:05:57.711+09:00  INFO 6100 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열이 비어 스케줄러 중지됨.
-2025-08-05T16:06:06.101+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user1 exited booking page and removed from booking user set.
-2025-08-05T16:06:08.094+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-5] c.mnms.booking.service.WaitingService    : User user4 exited booking page and removed from booking user set.
-2025-08-05T16:06:20.940+09:00  INFO 6100 --- [booking] [http-nio-0.0.0.0-8080-exec-6] c.mnms.booking.service.WaitingService    : User user1 can enter booking page immediately (0 < 2).
-2025-08-05T16:06:22.029+09:00  INFO 6100 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-05T16:07:19.229+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 7968 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:07:19.231+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:07:20.239+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:07:20.241+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:07:20.273+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:07:20.294+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:07:20.295+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:07:20.310+09:00  INFO 7968 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:07:21.268+09:00  INFO 7968 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:07:21.282+09:00  INFO 7968 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:07:21.283+09:00  INFO 7968 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:07:21.370+09:00  INFO 7968 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:07:21.371+09:00  INFO 7968 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2071 ms
-2025-08-05T16:07:21.763+09:00  INFO 7968 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:07:21.874+09:00  INFO 7968 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:07:21.908+09:00  INFO 7968 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:07:22.379+09:00  INFO 7968 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:07:22.410+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:07:22.584+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:07:22.589+09:00  INFO 7968 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:07:22.613+09:00  WARN 7968 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:07:22.643+09:00  INFO 7968 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:07:23.012+09:00  INFO 7968 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:07:23.017+09:00  INFO 7968 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:07:24.116+09:00  WARN 7968 --- [booking] [main] 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-08-05T16:07:24.401+09:00  INFO 7968 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:07:25.290+09:00  INFO 7968 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:07:25.567+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:07:25.570+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@1028a747]]
-2025-08-05T16:07:25.571+09:00  INFO 7968 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:07:25.599+09:00  INFO 7968 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:07:26.208+09:00  INFO 7968 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.657 seconds (process running for 8.055)
-2025-08-05T16:08:25.567+09:00  INFO 7968 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-05T16:09:23.057+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T16:09:23.057+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T16:09:23.058+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
-2025-08-05T16:09:23.166+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user2 can enter booking page immediately (1 < 2).
-2025-08-05T16:09:24.851+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3 added to waiting queue with timestamp 1754377764836.
-2025-08-05T16:09:24.853+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
-2025-08-05T16:09:24.858+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:24.870+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.884+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:09:24.885+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.885+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.886+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:24.888+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-3] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.889+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:24.932+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:29.892+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:29.895+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:29.896+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:29.896+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:09:29.897+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:34.912+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:34.915+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:34.915+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:09:34.916+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:34.916+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:39.935+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:39.938+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:39.939+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:09:39.940+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:39.941+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:44.960+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 1명에게 대기번호 발행 완료.
-2025-08-05T16:09:44.963+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:44.965+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:49.847+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754377789841.
-2025-08-05T16:09:49.852+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:09:49.858+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.859+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.860+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:09:49.861+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:09:49.865+09:00  INFO 7968 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.867+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.868+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:09:49.975+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:49.977+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.977+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.978+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:49.979+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:49.984+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:09:54.998+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:09:55.005+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:55.005+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:09:55.008+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:09:55.010+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:09:55.017+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:09:55.019+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:00.044+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:00.049+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:00.050+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:00.051+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:00.052+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:00.055+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:00.055+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:00.056+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:00.056+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:05.066+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:05.068+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:05.069+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:05.071+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:05.071+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-16] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:05.074+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:05.076+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-17] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:10.091+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:10.094+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:10.095+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:10.095+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-18] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:10.100+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:10.104+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:10.104+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:10.105+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:10.106+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-19] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:15.126+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:15.133+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-20] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:15.140+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:15.143+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:15.143+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:15.144+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:15.145+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-21] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:20.160+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:20.163+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:20.164+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:20.166+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:20.166+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-22] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:20.168+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:20.169+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-23] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:25.178+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:25.183+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:25.184+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:25.184+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-24] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:25.186+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:25.188+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:25.189+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:25.189+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:25.190+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-25] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:30.207+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:30.210+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:30.210+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:30.211+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-26] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:30.212+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:30.215+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:30.216+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-27] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:35.225+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:35.228+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:35.229+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:35.229+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-28] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:35.230+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:35.235+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-29] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:40.248+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:40.251+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:40.251+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:40.253+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-30] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:40.253+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:40.255+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:40.256+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:40.256+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:40.257+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-31] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:45.269+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:45.272+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:45.273+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:45.274+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:45.275+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-32] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:45.278+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-33] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:50.288+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:50.291+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:50.293+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:50.294+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:50.295+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-34] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:50.298+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:50.300+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:50.300+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:50.301+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-35] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:10:55.314+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:10:55.316+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:55.318+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:10:55.318+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-36] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:10:55.319+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:10:55.322+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:55.322+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:10:55.323+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:10:55.323+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-37] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:00.342+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:00.344+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:00.345+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:00.346+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-38] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:00.347+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:00.349+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:00.350+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:00.350+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:00.351+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-39] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:05.365+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:05.367+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:05.369+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:05.369+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-40] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:05.370+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:05.372+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:05.373+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:05.373+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:05.374+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-41] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:10.385+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:10.389+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:10.391+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:10.391+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-42] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:10.393+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:10.396+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:10.396+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:10.397+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:10.398+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-43] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:15.406+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:15.408+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:15.409+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:15.409+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-44] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:15.410+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:15.412+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:15.412+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:15.413+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:15.413+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-45] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:20.432+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:20.436+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:20.437+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:20.438+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-46] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:20.440+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:20.443+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:20.444+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-47] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:25.465+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:25.468+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:25.468+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:25.469+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-48] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:25.470+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:25.473+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:25.473+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:25.474+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:25.474+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-49] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:30.492+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:30.497+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:30.498+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:30.500+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-50] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:30.501+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:30.505+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:30.505+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:30.506+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:30.507+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-51] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:35.517+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:35.520+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:35.520+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:35.521+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-52] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:35.522+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:35.524+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:35.525+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:35.525+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:35.526+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-53] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:40.535+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:40.540+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:40.542+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:40.543+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-54] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:40.545+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:40.550+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:40.551+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:40.552+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:40.554+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-55] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:45.571+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:45.573+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:45.573+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:45.574+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-56] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:45.575+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:45.578+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-57] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:50.589+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:50.592+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:50.592+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:50.593+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-58] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:50.595+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:50.598+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:50.598+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:50.599+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:50.600+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-59] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:11:55.613+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:11:55.617+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:55.621+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:11:55.622+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-60] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:11:55.622+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:11:55.626+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:55.626+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:11:55.627+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:11:55.628+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-61] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:12:00.642+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:12:00.644+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:00.646+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:00.646+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-62] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:12:00.648+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:12:00.653+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:00.655+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:12:00.655+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:00.656+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-63] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:12:05.666+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:12:05.668+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:05.669+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:05.671+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-64] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:12:05.671+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:12:05.673+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:05.673+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:12:05.674+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:05.675+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-65] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:12:10.695+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:12:10.699+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:10.701+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:10.703+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-66] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:12:10.705+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:12:10.709+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:10.709+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:12:10.710+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:10.711+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-67] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:12:15.725+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:12:15.727+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:15.728+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:12:15.729+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-68] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:12:15.729+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:12:15.730+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:15.731+09:00  INFO 7968 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:12:15.732+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:12:15.732+09:00  INFO 7968 --- [booking] [redisMessageListenerContainer-69] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:13.822+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 10744 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:14:13.826+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:14:14.968+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:14:14.968+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:14:15.000+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 17 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:14:15.016+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:14:15.016+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:14:15.040+09:00  INFO 10744 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:14:16.096+09:00  INFO 10744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:14:16.115+09:00  INFO 10744 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:14:16.115+09:00  INFO 10744 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:14:16.214+09:00  INFO 10744 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:14:16.214+09:00  INFO 10744 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2318 ms
-2025-08-05T16:14:16.600+09:00  INFO 10744 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:14:16.705+09:00  INFO 10744 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:14:16.743+09:00  INFO 10744 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:14:17.244+09:00  INFO 10744 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:14:17.283+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:14:17.459+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:14:17.474+09:00  INFO 10744 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:14:17.496+09:00  WARN 10744 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:14:17.526+09:00  INFO 10744 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:14:17.833+09:00  INFO 10744 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:14:17.842+09:00  INFO 10744 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:14:18.941+09:00  WARN 10744 --- [booking] [main] 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-08-05T16:14:19.208+09:00  INFO 10744 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:14:20.018+09:00  INFO 10744 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@69e736bf]]
-2025-08-05T16:14:20.209+09:00  INFO 10744 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:14:20.240+09:00  INFO 10744 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:14:20.907+09:00  INFO 10744 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.74 seconds (process running for 8.197)
-2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T16:14:29.147+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] o.s.web.servlet.DispatcherServlet        : Completed initialization in 0 ms
-2025-08-05T16:14:29.241+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4 added to waiting queue with timestamp 1754378069234.
-2025-08-05T16:14:29.241+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
-2025-08-05T16:14:29.247+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:29.251+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:14:29.320+09:00  INFO 10744 --- [booking] [http-nio-0.0.0.0-8080-exec-4] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.320+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.322+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.323+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.325+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:29.333+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.334+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:29.334+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:29.388+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:14:34.361+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:14:34.362+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:34.363+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:34.364+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:14:34.364+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:34.366+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:34.367+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:39.378+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:14:39.381+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:39.383+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:39.383+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:14:39.384+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:39.388+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:39.389+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:39.389+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:14:39.391+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:44.409+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:14:44.412+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:44.413+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:44.415+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:14:44.415+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:44.418+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:14:49.439+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user3's waiting number: 1
-2025-08-05T16:14:49.443+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:49.445+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:14:49.447+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:14:49.451+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : User user4's waiting number: 2
-2025-08-05T16:14:49.458+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : Published message to Redis channel 'waiting_notification': {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:49.459+09:00  INFO 10744 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:14:49.459+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:14:49.462+09:00  INFO 10744 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:20:36.056+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 23824 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:20:36.060+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:20:37.042+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:20:37.042+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:20:37.084+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 21 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:20:37.112+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:20:37.112+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:20:37.132+09:00  INFO 23824 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 6 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:20:38.165+09:00  INFO 23824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:20:38.189+09:00  INFO 23824 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:20:38.189+09:00  INFO 23824 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:20:38.279+09:00  INFO 23824 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:20:38.279+09:00  INFO 23824 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2156 ms
-2025-08-05T16:20:38.753+09:00  INFO 23824 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:20:38.861+09:00  INFO 23824 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:20:38.897+09:00  INFO 23824 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:20:39.372+09:00  INFO 23824 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:20:39.408+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:20:39.605+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:20:39.605+09:00  INFO 23824 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:20:39.631+09:00  WARN 23824 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:20:39.652+09:00  INFO 23824 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:20:39.984+09:00  INFO 23824 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:20:39.984+09:00  INFO 23824 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:20:40.994+09:00  WARN 23824 --- [booking] [main] 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-08-05T16:20:41.272+09:00  INFO 23824 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:20:42.182+09:00  INFO 23824 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:20:42.493+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:20:42.497+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@304704ae]]
-2025-08-05T16:20:42.497+09:00  INFO 23824 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:20:42.528+09:00  INFO 23824 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:20:43.241+09:00  INFO 23824 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.871 seconds (process running for 8.253)
-2025-08-05T16:21:42.488+09:00  INFO 23824 --- [booking] [MessageBroker-1] o.s.w.s.c.WebSocketMessageBrokerStats    : WebSocketSession[0 current WS(0)-HttpStream(0)-HttpPoll(0), 0 total, 0 closed abnormally (0 connect failure, 0 send limit, 0 transport error)], stompSubProtocol[processed CONNECT(0)-CONNECTED(0)-DISCONNECT(0)], stompBrokerRelay[null], inboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], outboundChannel[pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0], sockJsScheduler[pool size = 1, active threads = 1, queued tasks = 0, completed tasks = 0]
-2025-08-05T16:43:22.583+09:00  INFO 1956 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 1956 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:43:22.586+09:00  INFO 1956 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:43:23.822+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:43:23.824+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:43:23.867+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:43:23.883+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:43:23.885+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:43:23.899+09:00  INFO 1956 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:43:25.069+09:00  INFO 1956 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:43:25.085+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:43:25.086+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:43:25.196+09:00  INFO 1956 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:43:25.197+09:00  INFO 1956 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2543 ms
-2025-08-05T16:43:25.604+09:00  INFO 1956 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:43:25.707+09:00  INFO 1956 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:43:25.740+09:00  INFO 1956 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:43:26.217+09:00  INFO 1956 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:43:26.244+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:43:26.411+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:43:26.413+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:43:26.434+09:00  WARN 1956 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:43:26.460+09:00  INFO 1956 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:43:26.830+09:00  INFO 1956 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:43:26.834+09:00  INFO 1956 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:43:27.280+09:00  WARN 1956 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-2025-08-05T16:43:27.306+09:00  INFO 1956 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:43:27.316+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-05T16:43:27.325+09:00  INFO 1956 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-05T16:43:27.331+09:00  INFO 1956 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-05T16:43:27.355+09:00  INFO 1956 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-05T16:43:27.399+09:00 ERROR 1956 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
-
-org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
-	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
-Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:321) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:309) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1683) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 21 common frames omitted
-Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:146) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:318) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 34 common frames omitted
-Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis.core.ZSetOperations.range(Object, long, long)" because "this.zSetOperations" is null
-	at com.mnms.booking.service.WaitingService.getWaitingUsers(WaitingService.java:166) ~[main/:na]
-	at com.mnms.booking.service.WaitingService.(WaitingService.java:68) ~[main/:na]
-	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
-	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
-	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
-	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
-	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
-	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 36 common frames omitted
-
-2025-08-05T16:44:01.979+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 29296 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:44:01.983+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:44:03.411+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:44:03.414+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:44:03.457+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 18 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:44:03.475+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:44:03.477+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:44:03.492+09:00  INFO 29296 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:44:04.585+09:00  INFO 29296 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:44:04.605+09:00  INFO 29296 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:44:04.606+09:00  INFO 29296 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:44:04.703+09:00  INFO 29296 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:44:04.704+09:00  INFO 29296 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2650 ms
-2025-08-05T16:44:05.022+09:00  INFO 29296 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:44:05.155+09:00  INFO 29296 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:44:05.205+09:00  INFO 29296 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:44:05.707+09:00  INFO 29296 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:44:05.759+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:44:05.973+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:44:05.976+09:00  INFO 29296 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:44:05.998+09:00  WARN 29296 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:44:06.022+09:00  INFO 29296 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:44:06.347+09:00  INFO 29296 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:44:06.355+09:00  INFO 29296 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:44:07.335+09:00  WARN 29296 --- [booking] [main] 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-08-05T16:44:07.605+09:00  INFO 29296 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:44:08.543+09:00  INFO 29296 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:44:08.985+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:44:08.988+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@3497ecea]]
-2025-08-05T16:44:08.990+09:00  INFO 29296 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:44:09.016+09:00  INFO 29296 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:44:09.637+09:00  INFO 29296 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 8.45 seconds (process running for 8.922)
-2025-08-05T16:44:50.918+09:00  INFO 27656 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 27656 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:44:50.921+09:00  INFO 27656 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:44:52.054+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:44:52.056+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:44:52.088+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 19 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:44:52.106+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:44:52.107+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:44:52.123+09:00  INFO 27656 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 3 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:44:53.268+09:00  INFO 27656 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:44:53.285+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:44:53.285+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:44:53.383+09:00  INFO 27656 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:44:53.384+09:00  INFO 27656 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2397 ms
-2025-08-05T16:44:53.860+09:00  INFO 27656 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:44:53.961+09:00  INFO 27656 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:44:53.995+09:00  INFO 27656 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:44:54.542+09:00  INFO 27656 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:44:54.572+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:44:54.754+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:44:54.757+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:44:54.778+09:00  WARN 27656 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:44:54.805+09:00  INFO 27656 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:44:55.148+09:00  INFO 27656 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:44:55.154+09:00  INFO 27656 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:44:55.836+09:00  WARN 27656 --- [booking] [main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-2025-08-05T16:44:55.892+09:00  INFO 27656 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:44:55.903+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
-2025-08-05T16:44:55.910+09:00  INFO 27656 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
-2025-08-05T16:44:55.918+09:00  INFO 27656 --- [booking] [main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
-2025-08-05T16:44:55.943+09:00  INFO 27656 --- [booking] [main] .s.b.a.l.ConditionEvaluationReportLogger : 
-
-Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
-2025-08-05T16:44:56.018+09:00 ERROR 27656 --- [booking] [main] o.s.boot.SpringApplication               : Application run failed
-
-org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'bookingController' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\controller\BookingController.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:804) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.9.jar:6.2.9]
-	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.4.jar:3.5.4]
-	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.4.jar:3.5.4]
-	at com.mnms.booking.BookingApplication.main(BookingApplication.java:12) ~[main/:na]
-Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'waitingService' defined in file [C:\sk\final_project\booking\booking\build\classes\java\main\com\mnms\booking\service\WaitingService.class]: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:321) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:309) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1683) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 21 common frames omitted
-Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mnms.booking.service.WaitingService]: Constructor threw exception
-	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:146) ~[spring-beans-6.2.9.jar:6.2.9]
-	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:318) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 34 common frames omitted
-Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.data.redis.core.ZSetOperations.range(Object, long, long)" because "this.zSetOperations" is null
-	at com.mnms.booking.service.WaitingService.getWaitingUsers(WaitingService.java:142) ~[main/:na]
-	at com.mnms.booking.service.WaitingService.(WaitingService.java:68) ~[main/:na]
-	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
-	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
-	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]
-	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[na:na]
-	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~[na:na]
-	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210) ~[spring-beans-6.2.9.jar:6.2.9]
-	... 36 common frames omitted
-
-2025-08-05T16:46:43.343+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : Starting BookingApplication using Java 17.0.14 with PID 28232 (C:\sk\final_project\booking\booking\build\classes\java\main started by yondu in C:\sk\final_project\booking\booking)
-2025-08-05T16:46:43.346+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : The following 1 profile is active: "test"
-2025-08-05T16:46:44.360+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:46:44.363+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
-2025-08-05T16:46:44.391+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 16 ms. Found 0 JPA repository interfaces.
-2025-08-05T16:46:44.410+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
-2025-08-05T16:46:44.411+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
-2025-08-05T16:46:44.427+09:00  INFO 28232 --- [booking] [main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 4 ms. Found 0 Redis repository interfaces.
-2025-08-05T16:46:45.465+09:00  INFO 28232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
-2025-08-05T16:46:45.480+09:00  INFO 28232 --- [booking] [main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
-2025-08-05T16:46:45.481+09:00  INFO 28232 --- [booking] [main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.43]
-2025-08-05T16:46:45.568+09:00  INFO 28232 --- [booking] [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
-2025-08-05T16:46:45.569+09:00  INFO 28232 --- [booking] [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2158 ms
-2025-08-05T16:46:46.160+09:00  INFO 28232 --- [booking] [main] o.hibernate.jpa.internal.util.LogHelper  : HHH000204: Processing PersistenceUnitInfo [name: default]
-2025-08-05T16:46:46.293+09:00  INFO 28232 --- [booking] [main] org.hibernate.Version                    : HHH000412: Hibernate ORM core version 6.6.22.Final
-2025-08-05T16:46:46.326+09:00  INFO 28232 --- [booking] [main] o.h.c.internal.RegionFactoryInitiator    : HHH000026: Second-level cache disabled
-2025-08-05T16:46:46.802+09:00  INFO 28232 --- [booking] [main] o.s.o.j.p.SpringPersistenceUnitInfo      : No LoadTimeWeaver setup: ignoring JPA class transformer
-2025-08-05T16:46:46.831+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
-2025-08-05T16:46:46.987+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
-2025-08-05T16:46:46.989+09:00  INFO 28232 --- [booking] [main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
-2025-08-05T16:46:47.008+09:00  WARN 28232 --- [booking] [main] org.hibernate.orm.deprecation            : HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
-2025-08-05T16:46:47.029+09:00  INFO 28232 --- [booking] [main] org.hibernate.orm.connections.pooling    : HHH10001005: Database info:
-	Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
-	Database driver: undefined/unknown
-	Database version: 2.3.232
-	Autocommit mode: undefined/unknown
-	Isolation level: undefined/unknown
-	Minimum pool size: undefined/unknown
-	Maximum pool size: undefined/unknown
-2025-08-05T16:46:47.373+09:00  INFO 28232 --- [booking] [main] o.h.e.t.j.p.i.JtaPlatformInitiator       : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
-2025-08-05T16:46:47.382+09:00  INFO 28232 --- [booking] [main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
-2025-08-05T16:46:48.675+09:00  INFO 28232 --- [booking] [main] c.mnms.booking.service.WaitingService    : 대기열 감시 스케줄러 시작됨.
-2025-08-05T16:46:48.910+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:46:49.005+09:00  WARN 28232 --- [booking] [main] 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-08-05T16:46:49.163+09:00  INFO 28232 --- [booking] [main] o.s.b.a.w.s.WelcomePageHandlerMapping    : Adding welcome page: class path resource [static/index.html]
-2025-08-05T16:46:50.165+09:00  INFO 28232 --- [booking] [main] o.s.b.a.h2.H2ConsoleAutoConfiguration    : H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:testdb'
-2025-08-05T16:46:50.544+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Starting...
-2025-08-05T16:46:50.546+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@f28ee19]]
-2025-08-05T16:46:50.547+09:00  INFO 28232 --- [booking] [main] o.s.m.s.b.SimpleBrokerMessageHandler     : Started.
-2025-08-05T16:46:50.559+09:00  INFO 28232 --- [booking] [main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
-2025-08-05T16:46:50.655+09:00  INFO 28232 --- [booking] [main] com.mnms.booking.BookingApplication      : Started BookingApplication in 7.919 seconds (process running for 8.303)
-2025-08-05T16:46:53.936+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:46:53.940+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:46:53.941+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:46:54.005+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-2] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:46:54.005+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-1] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:46:58.958+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:46:58.959+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-3] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:46:58.962+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:46:58.962+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:46:58.963+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-4] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:03.987+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:03.988+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-5] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:47:03.991+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:47:03.992+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:47:03.993+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-6] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:09.011+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:09.014+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-7] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:47:09.021+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:47:09.021+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:47:09.022+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-8] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:14.040+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:14.042+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-9] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:47:14.045+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:47:14.046+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:47:14.047+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-10] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:19.059+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:19.060+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-11] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:47:19.065+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:47:19.065+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:47:19.066+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-12] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:24.095+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user3","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:24.096+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-13] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user3: 1
-2025-08-05T16:47:24.102+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열 사용자 2명에게 대기번호 발행 완료.
-2025-08-05T16:47:24.103+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":2,"immediateEntry":false,"message":null}
-2025-08-05T16:47:24.104+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-14] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 2
-2025-08-05T16:47:25.350+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
-2025-08-05T16:47:25.352+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
-2025-08-05T16:47:25.354+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
-2025-08-05T16:47:25.590+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-2] c.mnms.booking.service.WaitingService    : User user3 removed from waiting queue (manual removal).
-2025-08-05T16:47:25.600+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Received message from Redis channel: {"userId":"user4","waitingNumber":1,"immediateEntry":false,"message":null}
-2025-08-05T16:47:25.602+09:00  INFO 28232 --- [booking] [redisMessageListenerContainer-15] c.m.b.service.RedisMessageSubscriber     : Sent WebSocket message to user user4: 1
-2025-08-05T16:47:28.624+09:00  INFO 28232 --- [booking] [http-nio-0.0.0.0-8080-exec-7] c.mnms.booking.service.WaitingService    : User user4 removed from waiting queue (manual removal).
-2025-08-05T16:47:29.109+09:00  INFO 28232 --- [booking] [ThreadPoolTaskScheduler-1] c.mnms.booking.service.WaitingService    : 대기열이 비어 스케줄러 중지됨.
diff --git a/logs/spring.log.2025-08-01.0.gz b/logs/spring.log.2025-08-01.0.gz
deleted file mode 100644
index fa33512239d7bb4c762c8bb5b3c11d89597182d9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 34889
zcma(2W0Y*c5(bF2ZJf4kTc>T?wrzKxwr$(CZQHi(>3e7H;Qe~F_FDC=jMx!7qcS6^
zzNo~DfB^XK>*uoTBYHzDp7;HQnf~T4GfeCIXC?DPzvQ3gh$`BYjqAFte-k`W!5eCF
z#77F6B<0R^9m8BbEu3_A*_T2(rO?9S;$diGL;UcS`Q*nbeWRnJk#vM%(wWg$u2!FL
z3yxCLIN`OjKQU7?)*JOYoj%VI!ELgsOJ`1%FI&WKi+DbtdR;xR?*s5Eshjy5dsiT5
zbh9z%I}vkcv+#lDd>9({z9-91%;>UvR8%L)YeHUkj<+1OwINnPX-`FbU3J@?ZsnSM
z9o#?O_h&CUzUVODrpz+mp#x_(?Q=st4d3|hJlG%!;@odv@NSzoK*cPG(j#$8T@Baq
z`pgZx>3t7AuOF_&s@yi9`|hsDnq5ZpV%-q(deHPw?}4l5vX%Im&wL{%%P$LVj90v83h|^*BA#<}}3q)18Gl%ad#+)|cOP1Zfl}^9s4To;_VRt#o0Jujzpi%?o#Bw#S
z`(|uu|ImNTqRxhtsLs&(c)!Wy3%$|v7;w`<^?EJiJ(IEJW=%k(1hGQ~?#X!p;xn}T
zO{+8&xKHj{kKt+s+!msPI2bF2YkhS}D#X0aNIFzz{7mKkvZoWakD?J04i`{)G^(N^
zZQswT<-hy%a6Yoe_RrcDReZHKmnbIUdK%=<#Ejtdr*)b`L)mdTAP*;EmbTGH61q9$
z>lxa*aQo!Iomi9830VGE@S#8bfqo~%36N*Z*66<4SYDfQ;vCP)157wbHG~r3cS9yJ
zgTurGBbORx05Ua32R#tOKM%Pp2WFZ>+o4LtWA&%^Y2x~;1
zzv|~
zn#Qe5QU~7bn)%zZ9Wtx#u-i`}SZur3_?yg
zLp*#^+pr2FKiiiLH*PG?F)b`SfA4z^j
zvwn~4@Ba6rD=Nv;>L>M|MPXV(5FTWoXE3K@TPz_6TTj~7mOD|ieT>!-y|Tpnz7k_6
zR(t)?L3(SUEdJkktL0%6>m3GM<44~k+K-2)HiCTli-?_hZgb7wdt|B6CE$Ck^hEha
z0PCNS-Z`-X9euD%9jYN-XKHn-(T~B9bs2eK#jyQ#>LRp^^#%3)LXFv*@_`!me$@IV
zA`QMUVohF_hL-lZBNYe3v2s3c2FughxFNX2@iPFK$`y`SCPhJ;_v)p>?njc2n%%FhC|ut|7R78)8|OuquuFk%}dTt
zC5I9-e0TqDZ!YJcN!bnT8(X5c_}4-u(NB~SqVj=}#RW
z&gNP0>wvIjoJYUlg%$P=X^x>K)ByN$v0hoRt3cq95y(U0Qcgb#5BjL+$Ud7zUzN1t
zwG^y^-tqQ8I?5kThPZX&*g}O~eBf6;G5*e48+!jFW|-lJn{U>ikCPHU9gUuDZ}YC6
zMfiXnS=-^U%Y!J?K5gWubiC@W*M=ju?|}h$N%*MYS|z+d7r49wdIr%L(*fCm!wI`H
zTx+ZungDXbM6Z{Yh&5)w;5JYUC{u=)6FSndzg_m`V-7d&pvY@im&-`=wWPbOM?0vW
zO%K(dD@Snx&72~N=2#!6C+4?cv(O362Bj&cNI8;3Zx0>NmW4M>0W^
zmFZ!4hYfj%zR5=
zr&J>oM9eL*X9yTQ>JH0IaHg*jcK?p5>onmViYfl}Q+UfbYPZ>u$36x~tuWHinqynG
z7=QWJ9E<2`O3N3|;yZa3BEXY^eMi|!5>oCCu5$F?<9
z>M)_$mFTT-CwE{hC9IXlyS3X$pSl|C;I^0#Gy&RH!wYLugm!`(M}@xG%Z)Q&NVrb;
z^A&9t{5FNZ)}!I|$1MxLU0fjOJCs-7_W7%)$_^WR!D*?qq-?BSsQRg?#?J5&%nAJw
zU1S^i^vasP+tbJ!16TkZhX6g3tcT|7?r9=n&x+oUD~K*-viM$BjgY(k+wTP~yQ~vn
zcI3{2rs7icxU9_}Rn`f?h0&EASUF1hH5WqrKAVpe)SpFQr5Hq@#&^Q7MjLj+Fn
zc;h!1fWl@ojJSI$5ow3}2VU?PT>}Rf2tH$>YB0d=1PPE%2Rg9a$k@j4J?;^>_BowA
z;)8Pbhf+Iq-X1DkM4ym#wI$`(EJEpM$D#FMo}Wh4;UlM6*unM*Ul)D1rtrQ@-smVa
zdHRQPSMY`;L{nEDu~L1z{ba}s0L^R-)Iyy4V02OdJbmi^oI=m&yskco>K^O-k)X`e
z^S^E8ld|u7+6m~sOgjaX*Y>N3IO)86G5GR+u0W%|q4OpA9MK0@R_Ah(J>a)%c|Kyw
ztE7($wbfeMwJ=q&eo%-Qh>;!bL3>Z@u1w6iVPp(4P@u
zE7bF&hCtC-w?8NH>j))fNZ*K4U(OO$ikQ#ub7c2tGgQ*
z6`6HC=Q>n(Xt&RwgsX&*>YET|xDJ=U1+>FFJJ%lFS0VUW+7-IpoJt36!mM430t
z!xcUKYP`~y-rMCXbSgu7u$6RdgoHS>RmsRS7E}v|J3SvCt`iBdPMwK+h}#>T
zaYxTV8FVcxN7lYS*S395#)KI+A2eVn^UYRJw>ES5tydy_z;~J8&uinV{S`bfS$LH{
zA3A(8AFVibnrm^{)SJw_cwl%+6Z>dl)TX!-vJMH)Xpkrf#0ONfdZ~o*bfymx^{^(2
zbEEWX++}ijAg_XXHx{?S-Nl${YTQe&!?q*{0_I_2+2zKEPxV#qwfAV4y{D;Bi%lia
z+I$lqW&c9myAVbitnF$~F#FqJ^mI@rE*y)z^+IBkf9CzvI}uZ(JonK~mPgzuMWh+i
zO_E$0vGVo#`1fEvU}LcSJ*)8So;eX3kuH?EyTtP==hM0OSj>7_i960b1}`zZt-*CR
zqrt>hr^SM)PHI(bVrN`ZTSgiNrr@2fX!K6%(R$Jkx#>N%dE?`0&{c6Ef2jG)Y5#h}
z9?8uSHHM~UA9+z>F)okv4_nT)wr3iS)=rgMcn6+6Mpgj|jOIJQ!Wvevf#De$khFZA
zDS?D97dt~Ga2O1+rP@Gv$oyUFYX}|czBvcWTt^@=h(~3kw)P8P$K~xN!1~+>1Wbwf!%juo=k7!&anz;SE&lhQ51L`w9Fj-PXlR*07
z_w{gn!tiQ;aa=ovO`(DJpxY#F+9KKEr55MS({ztHodNL)YrhY9P}g71nh`rw8TXxI
z568GWfWOG_ZvO#gor?(Lp<6FpKXh@Xj!M*lJkK~XE&XD@^FqG>1
zVulk)g#lk-YcNmr!l3!^67^1CnR6wOtb`v@HTcno5Pl!3nR&>FU>IU`{
zJkJ?I(&w7VZHiKj<|<+db+0kRkY8?LU&58-SiTkZUvRqU7xds0E%+F*v2`Ni!h#&M
z{lp6~dEv59ml%Vk754gZ<2}-?)t;0X^Castc4Gqz0(5C99rL-wWf6#lR)o34l@l=L
z-iCJ6$ZazzMVpN_1EQ1*;VnBRh-*ABV)0DV{#zi4y#qCR1&$iBhU@Ibkv0trMgW+T
zDIQ+&+@iELNtvz7)AJRbt*gvGamFQ-!luoDqN%K-8<75NY(oJ67I?+IO9k8abfJ9#gLUVGmc_{Bb6Bf=o|XKxd-corZ+92MZRfp0}Q
z!(&!Kq@<_VJ1in8>f3NYsqzcxI6w!ks6lL|56~7g$3`iwA!Az4;;RQ^GIbp+VK|T<
zgeSdOv9;Qig%Q>GB_Rvg2TKWD)D+b;Z09WP*43ckgjiSx4rluP@nH9oo5ILPU{eg&
zE)mD*ur|u~h7=~QsvaIZvWxSi8?6S`6)N^cF?E2LBcz#VeJXzUbSs;C!>%1
zx{%T4+3+b)5X+(MqMy?cZ6?*lO6y^*7nTkeRB~*CY)5_Cg4PD5O*1qZAM&9#$zU~_
zT57WB(pZoEcc#w?ZTP70)v;Nsg~FTK@-8FS3XA)h&$DN
zkz5*r>U3tvt*y1Sgcain`*i$HiojhsM8^x&9=D3YEP7M<`WltL!f=PW$5-p>(rZ}?
ztS6`gqf5G1k_A!bNKHsvxEk$R%fGEy55NTNji$EG%nTJVw&-$^6M%ObwO{Roeu%Cq
z#Ha6vF*%i5%jlfPe*LD#1UQk&2(D#cE9q}dw3cjv2eZX!=cmw1ijQ%3F`_ovVeFEI
z%+CVn=HDjak$Am_dlXNB+_6e^nYo4^U*@9MU#S-dJ!Lg^0YW0%|IRS>@=l~p;_
zQc)K$p)_#JBl_S^x9I;0c0Mb6oE4Y$mWDc1T{M`9{r1XdGEldlDDvZetq?<%md=Y;
z)|lK7wR6$MNC5ctSJ)ZRe3jM1^XdM4|6QV{KDnCP1>;I&@Y`Qq&vtV}?@YN{`$NN{Tbxf`HE--VE$v{OM1sUs
z9V=X0&-_3?my_BexH3&J9Cn|18XCu5X`yp~kcka$>Bg>NWp$=?yKtH(hxdi4%OMjN
zh<<)s)cFA|LO^7I57M(gw*@r>`f?5oX0OxOHtCT0>?_@A68K%lmhqP=gJwLuP>Eg1Agz&QhQ{6(G6>
zLuQ~0E$X235s9uv&)KL2&fuw@?Gg&GuklnOs*p|9;dAZqY1F9;^GOoDDH;qKz)xli
zq{cVlbNS%daZ&^?G(4qw295nf)(3Be;o)eJg*O{J27D&kh`NW@CdiO~dBU(Y$ql6Qe(`FOTioo*0A!5Z*RW
zb~4=Uw#ZdC(c-4?4p2ux;UZ16Cr?7ekO28$NHWleQ~#}rVwuU7o)^{oN$^Z!S|G+-
zNA*G{3@Y5#*Qjz*$A^+kpI#;`++A}+Fv7acjmxKY2}u{GWD8lcpSVQri%Gntr{|w)
z8&pz?aE67JQM8VylD(Kg#ZZ-3&xsC8N>Z%IJ#3XNAt`0ae0(^#K*LbgabA+ht8Cy=LWBu9oknlm
z9S-do$k=@<88BJ=r)Bvq-0uTmF~Md`(RmY^NIGl6%~7W|oMU}P#$
z%_MR;tYB_*FcK$T5Hz6v*1yIV2Sy*)bXYQ#8Xf+ugY(R|U`8yFtWJ>>P!Dm0)A3<4
zNB%j%lY^80Br%
z39gdJTZDi7cBh5E9N)883#N#427vjW)n&S11%s=IKT&alC2Sefples>B1YKaUh$ve
zxJit#xq)E~HOu`-pp$gX=<){>fY`uVON$6Bv5YtfNLC!2C8H@Zgvj*pvb#czsFqR6
zs{BlhV52?cac{|mz1OP3NpgbMV$MyIN#=A0qMc+}sT78iB>Dm_Q%)Y%OgdmQ;l>S?
zM%)*AZ4rslkz(lO;(B8MQqgYJL7?W!^crnZ^P;IfAB&&
z18SmJ;ZdZloUGlkA!%9
zS@n|Pc--1kK2^f|FxnN;#_aY^3k(Jc?#SXjb1Hs8T>5Zh`E-oDU8KA9Qt=2meJ23c
zt5SoZkt~|I0wtG8%EcP#h*BE%z_c~c4?%nx-evoyH8qC_s}IN+1N2_&5wz*dA$o8a
z0apWE2gbr3{W{f^=3hlulE1RrToZFh%B?08#?+zHue3LHWAF$N0ekc@Jzs4<42z9su=
zm_92S4iN%pL|Xje_5?$PNMc8qr9Y8RBqN2prP_b}lu1Vl{j_$d^v2JnqQwzC7Ab0X
z$vHSkLHoqxlw}>q7>svm$T&=*jpFL4T&bl)4%p(b3xWV7JvJVl8^;)?e(l&sATE66
zAWKB2xkjg#8zhV|Kvng4863l1*zd#}CI-3r4=E9iF(4J+PHhqDsApg=kdFM`y5r*z
zDWlII9j#Ab%HHqg>JTZIinlH^`(L58gVcZZl#;QTUT$H4(l!zdfkK=FB}${Vssj)F
zUc~-q=6{;M7FmAh($Ic@5(bYW`WsPi3Wr9+huY7>RDh6ZOUEAI?5G|6Y+F~an7Qa3
z+E|L7r33M3{qB`O9aBY8$}4Xl
zo5@abE%5{_2SZBhr%(q&m#&lXpzb#wx@hb*{i_>gi%Bi+;l|Wr1;cQnDrOcFxRIBO
zz=kAgKs|a^=Mfne7L)A-_au)b%!Y|OD@8*}*(m*8aFb-<+!z-}@R8Ex7!nSV(2*u8
zgc*W0hDiJs7b$)mj1ujD6I4GsHa?Nw$wS#>;0B12tobiwqg>!M&~0&wu#`P!k%-?!WCJRQ-aePpd
zFO;UhpO{GjyxJ*+?#k7yp=eCZX%Su>t%YIp@z%yT$v?>Utc59&3>dps@Yd{K$)O20
z%V6-?d?A(sD8x%c?|?O$f{4I#psJzV591i8ZAG$ZHyjCK#jUQK&PbF?O}^zow%{h`
z!^OcQ0JZ6L+ak_1MLN}cVPFH;v)5Q}VssO^@)A`tMGx;DZE3-OZM+ThfJh38MkY->
zO&@J#Q0Z=cES15rU^2ZKF^MsA#&9gcvoMKq&e4kXxVe?aG#H^h61BzZSUiu_Pq^YX9KUSP+q+^#acvY$*B8@Ror|Tj%>M_k7co+o`I#cF>2bub
zVfY%afZ!m2DnXJ-ByWk=8qDc3H@X;!lPnk-_+2dDZOqZ^wP7Z2z8U;Ds88B~WWVc$
zDMh4j5*tq)Zc<<*^wN7Z@)Ce(82IBg@wW|Vd@@g7y4IMpj(U`X86%E6o&qK6ov=y)E0HC)UEum@E$
zs*M>l>+Yh0C}r5*O@}rr=-kjya6ybVipU`$xmm^~ppqp;B+oJOy_#u@vq;gjK1Zq
zVb5Hd)J_$dJDRU+rQ7nRkp3v8O|>zftub~un%4$;t`=1OPx|X(s;G=HMWn+GOtR#v
zjaeIMT|N|ecs~|IW_QpfLvrDGzOjwjnpXOM@acGd)I94W*flkp@Hbv%NRng+SL^)L
zd?~|w+IwRlIDee%L!7-!ko`Ot^89Z+7@BxY5*9{_=IWW@>a&Gtqb^aNpyIeBMvLU9
z-a+%v$x-wo!uYXTr6mVU;{k8hL;N@sy))cKEb~F7dI~S
zNDPH-5bqNm*T;DPJUHcFPuR37qz7M`L0xRAVfJlTOrPPiPVh}x2#S5X0P)~>`Rc9I
z`lJK>UlHJt_PoHh^clNh!2-E1CS_7Q;x~Aa`Ejv`86qqB@rs4t9-PS5!-ZY?;0=1<
z7xh6r;46#}m#{lm2m?cOzwh6lmX5dp1${d`D8Jp__dV{E-yxRfS`1Q-y3|&D5U3ui
z@yoThK>(m}Gr{Pq$dbRr9txi{ob#){I3i354{@Y;�gsWj$)|Q50XIgq^=u4LL)^(
z+dQ4;Zh;gYK_jMi%+-&<2S?fdSUH>-HZ&vPOK-^eDO!&fzsjU8x;gh_9p$G>@4rEa
z#h@ZKSC`(P3>kV|-mnV1p1S#JL^yx=*w3pBHah+2K24wz{U&O9Lnu!6=
zT&-cXeTBG|Fx&J5?0Z&xoEHl|YwkTuQqWs;(pt5BMLB#NUEG@!NcwPY`uy&lsg9{G
z%hU~cJBoS^rY8KC*bO>irQU6}p)2rA823dzJ{R!2iHD9&QhNk;9dxFVK5N9I1XuA_Q^jtUa`A1bS7x6~iz^C7r8
z$Iu^TNpHbgq;)5#Sp0LcZ(tEL`3C|O%)1<-m=7+uA6BG}e2!E|!N|&KT)nim4RmOQ@j+K6tFZVRt8K0i2ZUgic^J+I+n39CCPAv9dOYsyZ!q$Fiv
zUTeR%RQZ{ZmpoZQZRCW&^4KA^q?yB?@9I-Y4Z87`1%+rc
zhQ_}|(u|n_u+l}Qe;TNGf8<)b>)I-^;U(4S8oz8>klhP6
z^tW_o&;Ds|--TW5(ncH3gtgr2!(YjSd8zsB8{efJp;^_3}1_EaeMktQ_=G)
z%`}kl_GjM}Za~c7;v$%Nvc``Tl;&`
zVT|Gv<|G)%cp}3XSrA1-r}ZV5FDfKyl+UxtD&G_4v=cx}l}Svx3N4k}u_=#5anljf
z+LlSsD3=vcHYpV)mn+dIk1Y;u#2F1kwscj;bhyL}(IXhPNHba{Os*3*u#Q#!54I;v
zl8am$XzVmWs`C3^<2noQMRV~Z)WHqp?Lc1QpMq@Bnskw0dg$CJnYI5`TeqJlA+z>b
ziWs!e$|RwMs>-#4ytDY&dpl&=7LB?SaQQrGJXJA7iog;{NQ2ZrVH_#_3r}&D4OiUS
z(N?ZJlm``T<_J&L6^<=SZSd98QD+>_h%EXTy#>V$^w)#^pW0ub4TY=3;_>p}uA|@;
zF<{~A%=0%0G?~vk0p@PVBzRA=h*)iB4)1X+5PAl|s63xV|7KG3>eV#(h67lL1#ow%
zJvs?LTlGJyJ2na=?gDq{Oz|PJoXrSMQ*z70cD0KOoYK`IzAi?77_g$3o@F0%kZwYf
zno@9Y3hceGLfMyhWnNio;pSFRpv0NAJ}G@MQeMdSzD)2~Z{oemQ`1S=`bwOl13+W3
zJ?Z{gh-Dt_G&O>V6_ID@_u19WZB(SFqOGXTQ|PqauNpUEG29GbV^W(IyP6lA=2MXu
z>?vUZY^9rI``>(HM9vw5?LP06Dkp8rAX+;g57!U$+KvQK@$-_av>RrXk
z*Qq~!-hLFl%jJv2<5rFHUb9d^d+^O?lPndC{-IIq=x*^ME^pl{Iy&2Je!1XsagO(l
z{rYWeg$`B;J)gTUx-LS*lN<_}dAL_DTJt*=5*mw6W--#iACZ
zwTO48!dtW_o_@BmCiicN
zBvg9GT(OfZQL5Ac0fx_lf%-`c3)+NkgkoHGsLlm-rFvgxOOPGVv`KrY3Ao@l2$a>o
zsG{}1qIG4hj&MzlA;g(Vki}*-!W!D-*5=xZQs`BiZg|qPY^*;Et!nHqwM$NLcu$>T
zud2^Umpdy4c`qg(62d(6!141cTb1-Gw)q)Fk9h*!LFRbazzU0`Src1T8o5&cX3$XT
zNnX#1TRrlQ=ZVVw&*_D}q{^f&8J0I0Uh1C;$ZJx=|5Na~Ca9p~;P%%P3Vy#BDzY%c
z@_K%HQ0z)l*O2SAk2afw(nDwITwki|$h+cu5Gt|5
zY5B_H?_Y$B+OnBHE$=8IK(eyZCM`ZGk)yM!RGwdWgfGc2ZYi}X0+Tw2SxX+tzy?=c
z!~TaMJS6s{0bN;LY;h*es3a=WNjcdgY<@R77dzj68}71fjxHRn8-(DRTnyOk;f$9M
zN<_PL#401AunWJ`Ie4KS
z!d-F-r&vX{R#7T;4M)hIsjz@Ecpst1C=W3UT>$6C+Bo3RRl9H$9ZZ;-uZW_rrPtFFNtmk4>d7rkZ+{trJFw@0I5|F)jTWP1%?Wx+*@V`o
zgzjxZoiZP;7oKqHZF^$=#QVIGFEPk9LO*2Z+7hP?N1nYytT)O##2~dA0y3?<9Gm!M
zx`gA0+0S{Ez!DmWs5V^|KA%m)0-*}NunSq-vYO>~>9X&5|MS&@ywe<#fVZp!?lH>V
zPYM&=Ja4Lb_OL6FGl(Y7Gu+UK40BxA1_CBFZM3LQvi~>R);KkPQ)r7dnFc-%1
z%Catqu`4MhCr8gQeZM^JryeRL^&%xVi=(H`dIU)!&ax{hBUg%Kfhe2@en@u8TPgo3
zE3QfjsB7U90M?!it=3Xp+x37f1dpEY;u2_L2yZbeJDZAqaHlHlBd~@)J}E1=n#tnv
zz-sk$M1~@wD(C~WH#svViy((%rxc|fKzfgiB37R)REJ@d^#+NVrTM$)GIMef+Sog`
zw=L$+r(|alR$K&Is`({mWaY@c9ItFS`SL(|jgQF8$f41MZ8b6A#%+oD_$BqD{%ZY&
zvi1@1euLb1_9tnHYT=ckF*kq?e#Ho+*e%q1c{sOwZ^`jmbKH4ak^qRdq7_Q3}WTWo09#7l#{aL
zyZhEtvUXN0Cx9ok5nZ(-12&VN|C9f}R4smeFL2UfQgJ4Kf`D$D4l{(_KOom$g)kJ^
zlSQX4=<}nv0G)5({85a~qK`JP$r17iNG>wP9%B#w1UXGy^?QK61sVU1>D0ZzMl)GT
z4g%9HWN1%zww&<`TM=0)D+A4Av89Zx96I#naY}M_FXD-psSD79Lp^e9Vg)2m`O$UD
z=2u|bM`CEe$l7`}Z=U4{{-VfMN)#TbBOhwCZnxbt={2+zFFM2u!UDsb71f{)p|x&7
zVXuq-%JkW;
zxA%NtZ21+XS(e!+RAQ5j;n;E0ixTw7Aq6aTU4F;XGipsLRX$KtPTcd{^N!{W!KD(E
zTY?RymHPLzcPOIi%FhJbom#-}SIvuL)^fxa4g$y_)AKIV`G$R(Lr_tzz)rk$kJ4sGj4nLDKeep)$s-q0)4znpZ
z_#O{JxxQ^|e8%5x+umr{dXA1;Hb0XybP3q_oNrxhJFH8N4SQCu4EC8YK>{`mMGK3L
zTNXc)({~geG%b82r)%&0zZK_J*ptpw!rqR$VsHbZx1~vhZxz2hPkzB4or+ebXgI9ODx-K(5$2(>p42a
zn;v_a!4PIwq|ZjkVG|u!{rwR})gy3sDLVl!2g6_ib6z^yh#EkbkXobXpaD23V6^Ui
zaaIAxo>thFpb&4-n=&=EBIiC3zK-osszU_BIO)?w&S~
z-Tasf7tlR;s5pYH2nzER&z~qUm$KU0w!Snmw{ps@=+qSZ_|@t04pbiT+hd|&>7P%*
z$6(5iJ})|>a@t%~QJq;x32oILEnJdXR7EJeLn!-K22ai%B%YTfSD^GY0GKkoq$<~`
z++1~+`>8VeE&+voW16nf>@#KM{noB!(Fw#$)82iZ_1lX|t%0}mK6LLc18oZl^4851
zvfKdmx-~)nKq4Cn=59=`-%)th9RFsMT`T!-Q8AKObM3I93+LFHT647%QlBBEG3`0J
zY{~peZrE{nt~k7;LW@DSqO>NvN=O~>rH=N{Udda8KS*xeiGS9d_mNz;75|_y?;*Kb
zky?M5!NFqK@H#n8Rr^5d9B4a(Gk9zC=DTkPeEyW#jIa+8M!d0O%f~V3NZe>N9XMLZ
zy)rd!lSGsWXrbdus+#T;?2yF2R$aZkqkq{dy{OOKn9#qj`0faf9M4&fcpVJQ%DwbmcB(;m&o{trv5`VLoLhg6k&)^`#ltGITvYvYxGyNzg_p_VMwpKO%?s&u|pVBir<kbzaY(I98;xO3v0?
z)Z|bGT~HA$d9{a4+Y~UKR(CQFlA__~6qm)bUwoP_{DU;-ChtL{ZHf;VnFRNpD6)x_q|r$k6{go&
z%|uCQ|IPGA3ec^*`OSvEv?X4OM%bwSFKyZ6SOzK+ObhddT{x1f4c#0!$?vm*Vez)cXRiMBIDsyKTu7nJ|At)&Z8)FPvvfQArIdJCc6iL#-gc
zx_5jY6t~VI`4;B$U&r&M|5JXNFFk71@guf3VzvOdp*csoUgx9E5t%Z~xuxC1
z>F2nqoqgZ}gd2#)d277*{R^%AredBvw0io&jZBaTjjTLHuO4}rh_-seh+u)qV4n?o
zf)=iGlfe!`R1j;!NlD7sK1HA?P5BR3a6k*mT`5nbD?=HB;|h^PGzt}y+Vj~;(Y7`?
z6(p5GL~L>9oXR!e=t7tPU(cR~HGX#sO|6HaKAdj{Z-ehCH#kMb8U5D)XV^ltb1oAL!ye=|rzZLs2Wik_^C@N`3$)OAuU9-_qg#umY>-ZjoUS%c~H96&H8m
zw+AM7ju}@jWeT6Q7IBKPLDQU#2#=C-OG0*r3-X-Ol|$Db2S2H>BNh*o@3LVp1LNcJ
zF)wrM-LOJ1Hg;s#SZc!NR#3sjfwVqJJrGl#iMLw~@ENY+yvmc(2^qVJoZ@}=($QUL
zf-J<-_ct0Ey@d*i)t!22Yo}LB6BQ8`RA=)wTJD#O>rtsM`f#v+3>P{Y<(=kG8@KJs
zVf}2R8-VqX?*4CDfF*Am2I>E#1@xBuA(b=PAzh9nrtrgJEP>Z9VqOAH>yQYh0mU+E
zHabEB=9oocTed5kkKvGa#?j}hzL;f93Y=!VkqehH9(l#N=-2)0*o3-F=B~QVV)prc
z(fQn})gbGaDrt{@glwPWLa=`{i(R~J-^7&c2P7vJ`mAqOTrbawU+}*^R`!Tbhv2!}
zCbHWoSbB{iM8Vv8Q|2p5II=5@$rSzEz-eFAzgs+de8-y0rUor)A=*m$_N&~qTCBKN
zc1PfZUZJT6(!FTGfC=))){Z-r3MYv|_9dJ}t$uoR9EyvoE4Abn4(f>|6ceMiyn2bF
zaSV1h>5iTzTSlBE+v8OGP66ZCm#ZyJ)03)jX7n(MFcVPLS{m|*LB$XI8LKk1;$0l+_9t5objSzNg_LpsWV-p*F~l3oev`Jxxk1}JQ<8i*M8O6k(Q^sjvKw;@)OXdqp3$JtIz>3^hpa
z9-LTMN~=gNcG}sb$_>9!X@4Ad*~5xSX<5Qk7o~22*Y$fnK%;#M{^5Ol
z^pr)w{s9-d1$Vk}-8$XhQTIjo!VR#I-XFUOSby#Chkk~qn4r;@m4
z(0o$XcT-dzdoo=m5tT>%BHX{4y)m3YJ)v3&*r%a-v~#nInWTeHwWGKeReH?Hs3iM!
zw1sB@7lkj;)n2WGmygqv`36jCa#e|#936B|Ix?5T%nY5J3_3GOA0@KjG4>o4+$5i_
zTa|nznu7*waOu|27u~dz+#hCB7@cN+!tvrO*efV`(-1}m#lQ)eHQV^WY6y%IEnhOx
z1&!v9#_ii3IF+;hvFJZK*qBG{2tmJ;&TPq~QCE6SXP~;|A+5k=EF>L<$Zao_6KEdA
zf5!I7G%yJJNI-_f@RZx7AAP+hDLyN-N
zU%F87`apOKx@tY0-o}tyO}rO5;e!?eN(S>_PQt@uu$@$rf`
z`r#_&;E?DY2nQ&~MGrGR-1`ejPT`paBz7LQ8}e;?(rBXw8$Fj8f`Sp
z?jzX58Bg^pm|9pMj@Ep@sbP2lg4vBRX*3#H^IBt%4eJ(@@U9#!S#i1Fh|d3=upNG~
zcJrV`6qG_sj=6mvz8e7R30NZi=Tu{SRsu)xnv-0BN-jBW)WOly!F=vvvyvD1H@<9N
zY1mdBIbe*CRVu7u6WMH3)fhS4M;GrW&JPK-fiGw40`y%-#4_PiP{{Hcd$;r7Z=N4UTUU?>ecc@`>kezJeT)@=@Xw%;Y&e^
zGTImm;^wMhhTIsuF#@8ej~R99l)o)~S+!uZbR0>-D$EHFnO@uMU`Ywm>Z;Hm3ADHS
zQS7@{=WAHQlz#6>kwXfkvO*who2%OuL*jlxqHmhqeskzO{%nP8D!OOFIg6^Paf2sx
z=d_j}Em;>~o+!P9!k2XtTz5W5k6NShKiOB+~BG2SRRo0?Bav(-Tc6!C4_m+KiUxIJYqSqzcC`Vl)$f~P)80e>0xg_mgqU`
zNk`ZQZj2hIl?*@)C&SB%*0z#2hvNMJy#stRLa5mO`N69}7Ge_*oyD6YyPWF&X+e!X
z&`Ynzd}3x%PabXRepW8*>jA_809AR-C@b~0uw>Ff1%Z^VuT
zvkSL3LDEq6iJS}(Q^~j66=+IH2k>amjk7bBBa48TE`?=6m{W+C=jKo`vsg4{|2!2JI33*4R|TyT#{Hus9GHurTiB#y03tNT-V
zoB8K@?86ry8TG%|0IHp~wCGV52p~@hPQxRbBUo5Yn_|wy24YHlgqD)S0Dj
z7eI?{oo?W%}2ZfAJ_96FSi9Mf(%U5O2LuwA0Vfa<%#F(8RozJA@o&|e{b_Y2y
zpvPkQUihF8-`^HrIE2-nI<*61+-Kd@7%LgC_V09tRPz(Rhwrw*eE$!|-a4qwHjWl7?(SOL-6goYyA>}G
z+=3Q&*S0{4ySuv-cXxL!Rw%If?%lh)cV>5HXY$wkCU2fR^3!upimuPB0sjQLe5e4-
zvju&qX~5f#8Vj*cxVGK=E~)?$zua%Bx3*pJcf@ghIPvGn_a0#59?;wTI5Q{ud-j9G
zB!sfJ9Zc(UcYgk@^Zl@8IhK8U*zFYEag1IBSMlQ}c_R@^K5UO>|F3nt3nw9Y_eWA2
zi8MH2H&VNGk|XA`s3sP-28E?tDr!DGMjdsvREbQjfGKMGIb?YD-?YVU7n^X?tA?NV
z@;fnyzkK;9|!UsrHz_A-LP+GCWn}+r9ObbzUJhGCrd7>i{l+@dxY4I5?Uda}ln!9W*r_
z$iB2~+v5v`^KqxwA504W1>7X}#6u42?O-N~Glt9^{XDFLR_$f8D8Sw%@b5Y7pI_du
z({aPUf6o8qu(cFyquu}W*;-C`))c{~6K|6c`S+|C*BxuN{gx7#E~a{qq1%JYKp)%U
z*7f{P=QT>rx9Mn^`(|qT=HdExoAEhT!;D$~6G~-;xj=Vnkq~!-4No@1FYymF
z^fz38!0dq$9^2>XV?88+rh-!-;4@7ZiCgKT-g{5Mdt
zzt&;k8+cMeNCSX060pk7TKCPnURGe+AFEbtCr0@|=BPhITV
zvcGB={h*V<%R4lX_ca~6L40y7vp>rh**zYA^YqCow`lwq_jh>PLY&fZy!g{KK3d4S
z6D|OA+ULu!D*vL`hG;Ii7uU5>9X!e+W@aVEQDk|+htvbMOLlAq3i)BZ+&&H&8ndY*
z0v$MZlOfLk54NJtqKKlBbiUH53H$m_1mX~psPiC#?OkGva2tje4aR6-~{&RQ>YFG~5N!PF0
zJ5|B9PG34es*!jdqFq(d%dB4i8`s?o!|o&pLj$xe+)H=YXXZa4uHGV_M&}osX=(||
z88`iBpYo^o!c(U-9@y7E|et_`E#Dk?|YWx^&-t#TC_wwt){QWCR3bN
zD>gb!-F+Uu!%Lqitu&N$RvUaRZzSk+-PV7p%0LPihTe{r<#O!<9#S*z&|~Oe85X`k
zJ@1``1O}|s%2snb1l+;fn_INg6KC@Lp{2(&m2-{c4KnE%z_tK9)C&E{ax_Pu)>nso
zJ&*I}X;#W|Gi%b_0vDn~z6lz1+x_=@r>oOnMxqZt<_Abr%!qZV9P==RlD?U>m2uUDloBIDI39xeP
z&Aqnbh?%&_gp8ENQlPx-PA3lBBuK9LJTglE9kDOc
z^djHpdoIadj1F%_ce}b&k=Uo9B+~V#KYax)2hD(!uA73zh*BPm+^AnORh@G8w$MG&
zCVvOo);Z3nOfozgE_*ogp!y{4%?G?(!XX8##4tXCzN$Ma05~lOrGRl90)s0f(6#^g
zx4UobH-z~;tUPM;6WcL5;fv^AGrO_^R~+5as{AeI(URnMiUh>tb57dhZ1V%_BZP^l
zbN=BXT}V$NvmMftm@a}>wxk4>Xm&!@lD6vPk;VTy-1UFG6|s|Hqf9
zZ(BevA0W}i^+L=veCVTw;C=$T+UqegA(WY)e2lN|WqAmw_^H+Z!G1LVgZ)HQhbdKw
zs~clSX|^q3XJrbC1qwG4w=KxbF7_22fwM-6;7id#Y{UC4kU}%8LR1^w(pZu1iShnu
zy)Rpn^Z|a7-kY&K+-#A|62+l=87=ZJ5|naRwujvyrF~5$2GSZX%Kr+Mkm|LjOWZ^2
zp(g)Wk(V^FAnTrf4mMJh!U9=`-R1Nno_(;q@1ahc+sO^^mi2_CQqdzr?Lgs^!6f6J%u7&a_
zJ3_jU4c3z-G~HH_*T%q#Sr=?JArDUf#g#CfCR=ob*dbiDz-D<)NvqeT2-A>jmg(!ghX_My
zJ_N*?OXL0z-{>Qxaq=I&k?cQwqpmZ{#P0vXH(K+O{fBSF_@DU3p8th!^!Cr{^8NGLt8!-eOp^V5FJD8h*&?{R^z2g~#amcldB#G42f=
z@eX>>{&#yn^srZPk5yjaJVZY3S6BWr*NKrCT;TS
zjz2BkDg51kP7i+q{8t9VRk>B++vqa>4Qw3AU$-NWphq6>P9CrFxvSXO7#D*ou(&-3
zWjyg{EO&esQSu9Rx1X
zJ_SakY2CR0z>Rs9%(<#~Yn|V)?j=2dC&4>x#ODfR9>8!$Dcy~jGH9V@_}w(vd~KoT
z!6RFxPNyMVYO)T7cH)zjG(j(NGLqc(sMX;=e$*a7xHRI7{Cph-f-y0fkz^i?yK3zzq^)+cqKF)K32Cbd
zc};o%|F#2c0D-Ep2_}u+X!CVY)fmh?BM|V0ln`H(JZv`di35xW5Fxkk8>Hp3ggk=1
zsMPm5$h$ajSKzyV2GcXHABn|&R{Q-Ax;N3aI(hO>2}y$Qyv#&a)qqvWK~)Tb+{^r>bqnZ*cD2pbnzA_p
zt1mzy(T3Xx9#f3H2VXe2@$_nYycoO#7FVVBx*{+^#m5PE=#a5WY6%dke5U
z{)u|X)QIZS?D$pW%7}(P9do+4<5E9%f&4cf2ibw;A5Kqzt8wtA44+MeqJAJDzuVX4
zK9d^D296UB(tY$q$E9ebVyvsR=E%@g#C>}WY%NETaE9tLoX6O>-ht58b{(hg712Jz
z>T^$5`Oqz2RQ}8Ezaj5CnAP?vm|DNugAuEPPAFqk^xSE|E>f*6B0=W^_59N$=8wc9
zf*3a$6c|o)KXu6;$3pFh?H>mdnDU%ri*`G!X!X!eHp|zCZ`TFh`&|9ca@NuFiA2%q
zs<(GW4eKBF5x4Ab1@NM5KTcSK+^{?Wkfs@4_WaHpq-jRfqr<_CpaCIx$h)9ld)Mo(
zLD`TvT-`DvHJt0D1W2|bGjQ_#lFI;B`0h|1xz3X>U=5~!CtcSsPnUM(MKpwXnSoYh
zqsN7$sulaVeS44LnwkW0wxd9B3u~TRPf#&0<|tf}Xnn)$jgj~g@mTsvt%*26MZ%$?
zG%5j?9WR1A-rxlz_xjt|T|pamcvjIIo`i5^#O54S9@8LEJGS3j%?m&8;Zh
z>3IE7%$INEF1?InY?Vdyx>$lYr_%+2`Hx0ewu5uOVMAzu6i*zb%re?vu-3J;30y3~
zVxRZraF^0|43Zah8H0s4E8Fz^Vv>a~hP`G`+69w^H$NoX1HPW9HvJHRYMmH*->nl?
zQ74pMhOXpy9i-73M#SWye{gcyFly#Hk2)pNZ(EQJi_PvQKf;$Y9J|!MF
zGCsS-nTN_O+QTN2>dH3zfq~Em6H=meq>sb9>$zxguQZeCz`ly2l4iK=WV0pc
znbd*r+(^QLP-!R@1F~cSR|Ydn0sKZt;1~%0u5Lt4<|Z(vrG-p8!Dm2q4}uCpMwe~k
zxxV1X@Ly$dlnZ~UZW}3~0gR)RLu_#rzkTki^6T2-;HvNzgYOQtpQC#q1mXm_uFTSb
zyBSjU4`c}eImPia0l(w->6&$N%4C`-I7{ovbtcz!DiR?x4XmQAu!dBMZIw#cFfKyY
zn8;cCgfwMyV1=&Vem@>rqdDyZJyqAaQ$xyl{dxOLFN53}mqDQ4;dU6B;VhoNI0&Um
zw>+BPofXO@9Ta%+AzuDxm*1qUGw@`YBc}Zmd~)MM#HUa&^Yjb
zO*7ofAnBFBS)1x^a{H^)t!yw3=>rgX$timT(^-3G6KI}txr33&Up$HL+d@y^OjAu3
zA>t>p@!e}1l&me;s?nl=Qf^nZD;t~~Bxhb3Pa8oJ-Bqws5ox@4G%38-il185%&Nh$
zrrgR2=bVev(W^)9w4krj45u_;$YYlDci6IW!G+oYoj(Qgj5+02EcQqeSH@l0_HW8b
zSBU&a)(=FY#Mg?1JhA+98@8!UKL#nOq95Bo`1~LK-@N+WKS9H(r*}@Ah`4_GsIC80
zFLzYNBkZ!r`zof=ZJYB_oXqGLImK4!ifL7loj|ILYm!zrBRUz_r+;4D27CPF52fYDO*$(2^rX~g
z#5m+PemWy`{t=pc{BoJx*Y(G7TI`>Ul{P}8J?WQjw6OMov9--RI`454PvV@@`u9e@
zah+rTdB)D&E;l_=nqzjpaWDNuzgC^A819Q&O9)Z7NsGrSd1`t&U~F2Ea)C9xB>u(}VIkrQoP|laP_F8PFdZqAsyI02p+DW{+yef6dH^wlGxo
zHMGSS9Ci=zjl9zC`UMtQl-w>;|}@>U_ekGMTa
z7M(cCs~}ipg8D^zoF!F1Tj12scn6eLLZ1yzh+|~0WtEmrx+E~pULaq^7wAK@QoZ2r
z^+C;Zgxku4i<2a(yKFSrkIzj-b<&EE53(Dx-J-CT0S*H>8hyoFCl)H*zD
zSvL60N5575%;&khzYblW=x_1q?=$oUZAcBEKgWW%mZ&ML)ov>zgnERKo6zzH!UoX|G;d#T3#<0fD-}odlzWG`MXL2UapU-XEMbRLoRFk^jS9rbH$n+lyNK7f
z4r9W4T6)#qks~>Y{ig-F{t6Kc&6to&7H;VOj6!S
z23n6|b>fEGI=yDa?@U4ohwC!yNZ%Z(cTU_I6^GtsMeR%$^-j{~^Mx$y!>V<$C0qcT
z+Af=4q^Ur5*R_t7aVoMmG{y-3gh&2c9M+J`m?-mo9S}7ZARLEU89A=PGJ2~yTuH09v5><#`K|D!c}!p`J+VK`vlkQ&4&s~X3dLD=U`>b;B<
zn7#WDji6M=6{@!i@3@vbxhp|J#pKdTS21EK%vrB}gC`e9ppW)1F+w%&UV72!g6hbo
zf>OA8(->B*Igk_!KugYURM3ukd-1ssMt$$35a@XqpPRrWP|#;P&XNh$J%I=gJGEX$
zhpYnjPfFl6BKWM=Q1Bc_6Pw+y)D;5gSA$i9nsj1Zs-}ZOB|c9awWE;a
zltEVuXH^CH_!KLLYI(wr;IT9)ZTMwb99B(&hro~*3lJT`WhqyGiwK4XUMy%6_Gzi(
zv)}~8r0hZxJ}QtRa(CMskQxM;_k;7h`s4`6Vt7!2%Dq?LP9eNBfe-{2&N~7lgASJ8
zB5^yxQHcGmLC&+vuxfiOxju4ueW^PEPJpru+`joq{8|}$$V3Bc2qHy(;`GhGvDe-U
z07B^34`fEPy08Gf@>twv>lr@iSxVmEfuk2691OVM3tw;o#%0Cq81nP`NKijab}AA}
zzgEI$=@gl>l4`gv5^{e>S#xnBnGzAmR;ooUwTdNvVY6dHfSd7xw_^wFL~MS6oChJx^m1ARj0RF~lH9SRAZNDU
zFVrAp8tz}$4)HsT9;(g7Pr6vTBz-thH@@aOmvmKIh~S75LX@f$M6jep{SYWNx0F95
z6Pm5ju#7IGB#%Y4Q=Rul8R3v0yH86q_YquN7QeGd(x(M!+zkglD9GG+Tu)R>a;bsKYK;O{H-r!C&A(}#1oH92jU@X99@P)Z{Ng++37prL<#5MHI
zi#HrwL3aNuIJCrfhYGxTwY3pSOa&sw`H!}exMPR88h*L;-~1y1IUH;pmYs)m&0yJO
zYyo16Zs?{?=-`mC`teLhNO%n~fiAtf$u_E&ji8n9|XBRjFU*mt{FosFx|
zf%{0ZH~JSdGx2`skP9EfMhLXhHy&AV#pjUy0!=N!$99mG;fYReD?Ht|Z@M)&U~FYO
zojMij@2`W#3j*fi#Ov`Y*AcI*8kQ5Mbh5&!C2*z&6hI86>|c;$P}^+wrpPI+M^cTD9Tb!BGpjcSVsELO
zY|p;~dF?!9Z;mj@AfR4M$P(x$>n#IeouLGb;L4fm93j3U?`9E|cwgeLiu8>pBZrNX
z7$hsS!~#6Dlit|HjZ7oS+#GdL51;SRLC#urY&Jy2C=;&D8DfE{FjgIgioID>?Gttw
zvqjyqCCNuzArHABC2-k6PlWgc+F=q2dZNBRwfm3%Tv$W&96$b0gCLPB!bIkOk!wf^
zhugs{&~tW^P|HOuK9u8X68=9;K-h*IMV=#kmIlJ7&krg~(%a#c+ad2fXp5(0kFKaT
zE?hZ?q3JIne}e?MKUIG6nxjK8|6oJ`5m1!OWF*wt(9T6T5zgrFcKC@uh4dXD%6b&J
zZFA)3sr>pWgauIpTyto9VUDxj?z2Tq{h?pWUi<-31mrUjs^vpiwx!qv-7tQ^?+T9o
zO1zy=e5|`gGJ_#`j(K$X%V>Isw}LmZk$opANbk{wBcQdd2Z;NU^QhOR_i=(rMs3xzG>liUbo2RK}%q&Qg4IjDeFw-;@f8PDO+|GREQqY
zL%6I-06Khwc)SCrN|&-||2Q-cL{am4+a$WQQIqFZbr}zb)aJCOzx+Uzt!UuBO&9R3
zcH`UU*j_nX00~4M(1BS$26}81lP6dB^_jzSjNj8UaCmWXy``sfQ;>*mRQuYhDx56S
zizuT92hqL=;sO|K)2|s_!*~>CZBi={6j{?<39!b
zKsf*C*1Pn$-xp@1iW)%McmI1T6(7W4`|!z^qvw8J;79z-AZ*Tl$MDG@Mw0$FK*le4
zsEJbcFa4PI@x9L`aJ!SM|3dsbkE2R3LjRbn$4prN3KIce;C2|Lt|Zs8yPxKZa;d{EjBLkCpn2X$`3{|hUg8i)DI}=g2&W4
zf~pPf;3Arw?|Z3qc*{DP%dBO6{<2O-Wc@5ysc8^YHZgYgOK@BQL!Bf3Pr*QYMK9%z
zJN+N~<6roav%>zWcC64!|8J^+R-X(1{9810704R<^veY;!#|uXF)t;+`#fD3MrttgIITV~KPb-JJrsTg4)J6-1
z0@A#hS-D0U+g&p{J1K%T#iY8l_%@RB&V6R-QUA5jB8#lGrA;c9Dr5vu`tCV$!a04*
z-c6je*^oa^7zNPxQ&6$-{A+DRp?PTg+&7+e=1jma%_pLnXtV99v@n3&e$NSJtG+sm
zAL)wlbq~PlO~hY@yIKxj`M)#-Kf|_cGJtBS{vkY0p@YyoKLLNo?vB&^Ys8`SOpqB2
z$6dcg=lkuai2ubV?;2VuJ3`i+^T(Rgo7N3Xm&QgqdMK$S$`my!M`#-nj&3m5#HK_XR)R#qTNq5HiSe
zUPkHTTCDY%p7q~B@ucVu7P?RMv8Cw~ZpdG0O8Y)v{rO`A$iQQ9Bbf01XQPN*kBc`z
z6nTV`1$l}uu;ytj4E7#IcrTc&@2Kg25rTcwn>-Hd#=r7gY(+Bdlp0h^3!Iwf*?Y|-
zM$X429Bk&rg%2<#$J&-SlcTZZ
zhySr_@`pev4(o*~{L=!6WSJRmRczzY3FN+3tZDkzFmqh2FS~ZIbUG3Q|I)ejIJP~#
zo!M$?e-UTuXvLK4@sNqIwohzw{r#3sj=z;RkS|(l&*-s(sM-*I5LVDS4T}_F`~R*k
z80|qCtq`yQCz+%%qt@Sb7FmuqYs&QffnB>%9jWMNamOeq+kX~%
zLY81%?gYQRWb#$88*|?%yjM&6e0zMv9k0zK
z@ZXx!&)>hsB21rB(-HC*e46Jb*3ia!^2+gUSEf3-WFvzod&A1pgv&IU_4szN#5IS4
zACKA_TJQe{S2_-M>03(3K5b|yK8^by>y)@8wma7
z4}^zGDeAIb?9zXL+M6j(2RaEJ%72}!oyPEw^=H3X)L&Zt)551t9-kPgxknNkM$PF9DFw8QIxWx`
z4W(^@Q+0zHB8a)#VQ?p+$~J4-!zQ3pZ0#MDYA71Qf-^$%8lkz|zYg+$v-Dg{T!k@4
zJG3OcU79k=qJAhV^Q`RhjT`>Gq)M|LQrEo4iQ)n-JFRH;njpn2DGXw)sPmYB&bvKf
z=y8jK-=(m>SmH4hunEp2aP4L;CE=Fq&sJVU7}$MgO^g45(nmSWZE3_?TvpEc;uwr|
zd=xlQh8zFGdy4zfgrt(FVAf519Ia|Zgqf&-W)LV%)-z*RxD~@mTwI#0KR7KA6T<0!
zvB4Pf*6Yg|tJ|Q1IsWwlG&UqqM}Q!D6}Xbi0Wd-?lr$
z^WBK7HIPGI=)&g`rCIEX0e(lej#~xuYXp0oV&knDh&k-YaNMcf4hbBe3VO3XAFiv%
zsrGr0h*fQF^2?V9^;VpSn<)0jt64j;DANZE4L(0N#4HT1im4vQLbrX#6L{`;5zpz@
zK0v)hrt&0~Hjo?6BrZ=~`I?-Hejc~T=&=HttK6?d7znZ{*xxLwdalB}c))y;oJDFnr_cj@k=5d^!#T)e&IjEwD3Z;f0KB%iMAG
zbk_LThAY6^^2>3ddbBi$-Ts(BA2(ZfMfGv2Etn+P(H1>{hOMNqjSvicW3T{~fj0ir=tNZua!b0_)KVY81uOLZ
zSNP?ODEV@C(WwiGo1?uR!JLp3W+M0xeG$z@or6w_hy{rFs~1d%7w@Xrvg&=W6#A`-
zpSl#Pnx$JDf*BrXCxiz_G@!KtSO>W*6Av)QRc8=_e-RAes0X-+#@QCoSwJ$!+xX*G
zLrV}c*`zFCOHAz=Ay{&76S|<_iVz(1+niA`<~hA+UgdAB&*NQ2|?&%eQ)(;pdP`gS?
zf75#(B_KGNlAh!fqqCH+5h8|k19g}j=8;Fh(e9Zw@pF;mLUH^WDQQz4ZX>Gh0sKod
zZAx?&5>X~%_g#`Jj()6702iBucHnT?2x^BBx>ilQaxrA$B|(OOxc>wZq#(H?NmUmgExOz>5ZQFyk4MoM{aCUO6~xDTFqY$;OnQ^IaE
z+w<>fe4WjWaAL@E;5`J#!IR)_nvhkn8Fw
zZ=&na(5~{%V{D!_|GkYWME@II=rZkkmnVOI1N|w|4HQK6C$i(~OwL`h0DuJUsnz8d
z11XuQP-Mwxy=0BuWd4cYyQ^yo_qjsV1M{skIIjGeo<82mV#qo#
zZ8t&)B<&x&N7XI9r{3mlSM#(dpCe9#rULQVb;q4sDyEf8BF`%zpt?5;bEAf-?TNYH
z&IpxAZ`Hm>*S>Z(PoJy3Xy4w~ScSR8KD+}Quc|eXZH<^kR!j#h9=u9t`7R${R3j~J
z9m}K&ExLdERa9+%Ds~Z8h&FK$zWn>Pz{vk4UgzoKILBU(;Hd-I%!I}1x~J@nkC(cu
zxh+J=PHpl0Lz!1#aZ`uJYkxSJjoeh$UbM}C-PwsC9PRLUe9_hj46bKiG_xmt4=kJ0
zTLe$DPd^AWthC5K{N&DDJ|&nM-TU@YQ)HBJ;`3{S;m+6Hvtbe|G@b(c*9mzNdO&xF
zh@La9@Yj>LQo&!^fahqlPv9%m_=PETl%^OLI28FP9ayx!*~H&tZ}HtPH~%zS=2|`s
zovt#zL_CZ||FkN{FQB+D(&K2~050R4v4;X(ZMrknP0qFo11c`BO)9;6Rx0sK&UM-|
zm%Ysho|x`q4>6RMY&tb3Z{{~Yvp0VZZXE2`m@L``gS*8p%@l-|8*DCzzQOxFE26nS
zmBWZz$7e>AzZboIoBq}Ha<|A(mFah%d*Ww?2^E2!k`HZtz`WzE_RwIQaJ1`;~n8H
zQDqWO+Hd5&K=CGD|C9Er8LyvS!7
zct+=!5P0<>KWqa%ig^;6AQonSC1ty$pz6C*`ed{ex^gbn&Ffg<$i_zaQK}^`4DX}#
zJ~V9gwCClE6?n!^E)1bo8e#6}B+Xi)*rBi*rO5Z%2VawhdF0PriCizQ=&wjCY%P<3
zmozWdqSX>}txO&3+pBZ@A*5(?vlL`#n!r%2jw0#AZIg{5&Sct@#iGmPu;SUm;^7k=V*PgR+rHloNMYEg!prMteT
z*n-8WviXo{LdP70Erg*3L&TwfBfpI)Gbf?u?3~~-c8hCDb1`pp^marx4nmJoVE-#6
zk)t3&1{dIr&cda@$tL
z=2OwhuDdV1!ioDcq7?rMDu5BBeUGvK^Jk6)1Zh
zpT>7A)D(`aU3>U4GOjWSE)Q}>P5)4kjZ@6z%HJYu=L`fIcB(&JkCGGBj;WZ?YSbttZK2HB@&UJ9Gry{TaGpz(=i3G8!o!z;LRr#
zzMm!EaA3jo-qMxtt7s!^OBbz?Se}K4>SKT3QqhLmE!dW}HgJ%;AF;Y@kB(WwuZv0T
z6kwDd-k8o+3OJkkiawnt3KiLclGw3?O#^@-BNsn){>#L&;Bh~J4kp0b2^H*QE%sCL
zB2;FNq(>0!G=UTNG{wtR(5=7_2`A*XQ%h)RAb&Sq)aRKQIGQk%c}K*l(MYiaNARW_vz6{B0E21_KcXtpvWg%C9TGz!x|!e11z!>e@mF4Z?2zpSYK
zWuV#OL#7RU2c?1b6#yV(XdTh(4y*q(lu!)c%(rG^;A3>x8uG9x>xISo
zfYj7MYzzUP;mr=oSHY1?kkK>twxgtcXFwf!*%K-)c@HKY&Ov`V==H@(m@!Ex1Z)0}Xv;089SO+gHX5I`x?Nt2P398X89y-NL|N#o?{l>vQP
z9Qo;fAN_YB`t*!~H@&khBDFBUp0wUwLSs59V`UeL>OC2vEE*xX2Qe9BMZ1jf!yuKtsBF~yMT$SzWw5Id9a*3J#^
zt*d@PiVV!C)m|-lVD;e=SwbkI+x99sP$lo}I5-|#zr33s!qere559#?R#2PS4G&Gc
zzF}du=yL=_jwnxiVPrd7K!#Q@AiS~b+O6w^SiKk{)+8qnT>F3#Is9O!^1$GneYttb)SA(LD7aC6(qjpamfvl
zffDLCYI)%ShK-^nui?U}sov4-eHcQ6RoAyVQE%subJ8(v5@9KZ4U@MVA1jc#ErsG!
z2O&n(VE5FW#kzsCiLJaniA~bxZQY6xV#q60qa0>JJzHMoz75gnqCrmRy}vP;_EgtN
zZj&2zg;4cVdQ^boDz`5{Ld%v)+oQV&q#|E4x)Bn8Kmg#w%LSP_cjZ-f`2TE
zX#u~0b8{Om-bB9ni`iMcp4*~!
ziP%nX)5dHz(;>m5!e0WE>%cgCXwkxa809DA-xS~NNXfK&7q9-<(G)4BZLs(4@ug5^
zpo=@0(HA?>ExM?b*sELjH{t!a)lY+>TYqVIa>!tMLY(7Ip#j}?1q*s3Nu6V*Oshx}
znVDysNiynww8IKH43d#hcM(4x`o%PB-U$j>Wwp1*(r?G0Us>
z%B|#rnMhH0YU&qL5i%QvIGUUOz7c*9b*&d;XQ!P;UKlu@P(2a-`s4=P3lwhe<}=Lv
zlxAcQeM<^v48TTrCLwRtaww#-j=@J}W
zs-p)GFQA=UOmVazzt@Z43Bpe+h@6(6lt%RewZpS8Gqj7*xqvc|#AF9uK=}QWgYZ&e
z9-v-XlZS=TjHz9p`63q(RVLbLv+Q9YhG5qKjJ#(16Hb#Mag|F8o`Z)YB
z#MB6NhLVvpKFDGpbt))GjDq+#B~DXaKzx9yA8F?O+$+0`3}9R7+`QsKTb9m0j9&?#
zgU~TJ%G}X?2$eqz4xB(1f_bNMdb0e#!0_ybrPN)?^~I(iK^R~Xn(t+2D2IkE02n`@
zNzYN
zK0TKXYF|ND!znuj$pl0+Hlkx-3d&%xX^@hu%LkL&j(CCa2|wE7k8eH|O?$x%qU>gut@Sv^2~Jo(iJX<0oU-)%EZh6~>KAkZ-!yHL1
z0GKQlyL(bp91s9h(+LK=-Yi5-`n)Y_<#2#Up=ZCB9N(}2B$Pwsyg`<=FINNeapgZa
zq*1PHj75OUUPDZ;>vvhuCRch*xcg?yOy3ObWnY~MY;9By=2NzoO)Gf#rJSP);S*AB
z8Hg}4;ti#!sF?wL}8VfUbRg8*t{UlJkOPE?G&&6+tsGknFiSG
z%;x^lYI(FHyn3sN{bknmdU%;NwE8+U(x6vj
zDZwy$
z&+_eXsOv|^R;g2W&g#z^DJL;@XR{3!zT(VN+ozpzf(P}d=<-p?Z~o*l2!W~}Gn$j_
zIx)b&6$*hwnX`_*G5Tt
z8u3?hx5}gzF{_MyQ(Cpj07;K*sSQahxV%aFAY`i->~%kAG(L?u2a#Yn2VI*BfQroF
zl`OgoSY&l@79`6DPJa)~(L4^}(WMj3dPF!z3RfHOm5rNnxi;u)>A}Od*R*G*@|SkeIQT+4nxY0NV3PYIA$ToI5lC
zU%y1<(k;|tJ?YM?Hixk-WU_^$v69qe!fIb_$uHvl#`0$nZ`UL97N_IQk5ENSgraH2
zshTjwd3w3LqGYYZ^SlmddN>WG?pPr#V7@x-{zW|v{(yS0$ae?w`6A~$khkpAAg^>)!{TM1623}3^782NhYsvUjXdq_CLYG>`GfO&s!&!T28AoyoY
zfX-48&HqOM{d%x*8SB#d>eN&QS9^Y11AH?4B0HeiCGu61VP0^VTl>f5FpotYj$3g+
zqLAsz`e$DDTK3G6BNa-~E81cSxA2*x1p?k?VK^`st=bbH&KfU|oVnKhp+tRg^Bv))
zq|0Dj&RveSDnQFnQi#R5FwJ|Ier|WmE1GpsJK?Wj>ct*UP#y!M!WV69QC4UDOG26sQQUp6P_Z8CXcJX<~fvc
z4(hzgqMYjv@=6ZstW;9evYe&jyJOA}vkmWwlFbApJV|6mN=NZ#sKP!
zN`Uv24lVzz_XF!`ukotRmk)k%Ni{c<3-Tk0TgL9*=*GIS4o-=*5wULlQWL+Z2Wz$4
z3Ou^2_T@tR)6R@5n4{WHSd>_*3w8+{FZzV)#gac}6w0I<yI
zI)7Wj8|pR%f0xp^rS!?@(6fOX#fKKwc3$|6zIfM403~yHnjLLN{Lk388+}n%N7SRV
z%V&5tPu8ncTMYoZ?8jiz*Nl9*xzjXx;h`x#
zgiFKGoo*Q{^x;b6LrX`KLuo2%575#2VyZA}1e~TAn;L4XVC&?~#UUjwiG@h>CiUmg
zdWh4dmqw@_U4?^8DC1Z(@UX`9F9YwVAbVXJPC9|ycu!tiit={<;skpUx})W25ZP#X
zVKX=Fepe#vMD?#e4U=@9mwTNYZUQ!Mp0rM4tnCDS-Op6%@U`8N3~D9qaOV1y0=Xo5
z292`r*C_0JfD21>xxjek9U*)P4dj|~MBA?>?*W9Q(q{epxiuEr@`HR91|#06rl<$!
z^ip-3%eyBI>t-cwBNpFuD=>D`lYtzPc!hL0*OSt6Kuu-|ora3P!26Fl1`Q~@9#UeX
zd_(g4as}gP`>(JP^Aq~{Kg$)b9EwbZ|)m3)q)l2CFbX5Bh
zY+EI)ZJaADyVifu9S*YyH`m1tR;A4l2R07~sqsfTq
zyu)g$KTRt}J037DFjDA{#^d&7M_3~=ss7ly&3w(Jy)VW`Uw78}IxmU0m8*hQwzC2j
zj^X8v)BLiXYFES<8c;_o8kC&FINz~L=*vPb@q<`W)&K7I&G3SF8eDU10-JJh=JSLy
z)n82tbBxS_T1c9DqKOFYyXD$gRIsL5EcR|ag@m#R$x^M#sz@Kvce#ZDX1)M(dY#@h4DW;DiE%R>d~+*M~yQUNK$pC5KZ^Wz5~D&eUWE-qWTc
z@mC$0lR}>S(Xwnn@xyx4BEtDBM_#1e`%>PI_lG?(;w-9hH&YoyS6v|5NBB=ne4YY4
ztU
zf+f?U47B<8&djr#&ox)KGq!P$-Fm!={*M4v1giTG|GHK=i`JP7`)?O#X7S@YUw^4D
zpmMVigUF3K_+${iKT4IRH}IJkQGf5Z;~orxFAMur&AO2um#$X-Sl>SQZ&dHUy#b`%
zfACQ+!d!j*Enlqeu2mXyyZE1vf6D*-^1oE&Ki*!imtVI3^xX*NM|Ld=BU!Q3V`?qi3=zneYy{$c-Qzizhs
zL-m`l?rvlK>KpZN{`=;m>XBLQyu)n&Yxlxhv@}TZo1nCatw@>$9YJ8Q_Tr5`hlm2>P`&b0~psg-P|Rfh!1hh>ovcOD%@fxZ*LCCDyNo
zu%Ot%HjaKZ5X@Qj@_|UKUxC-zULGxIUHa9K@cf~E#dgQXqF*5h&h{6dARP5;Lj785
zLz$Q8r!_163YDv{$;Qa~wKV#5zhK)ldOSh>Y9ho+>_|VBel7LNaY1}BC!t>rJ16+@
zAc%gorTRo{cKWqr=VH9-x9V3YQpB6qAFf|ZbLI`lE&_(suZ;0t{hG_B7Y;3ITYsC7
zCum=RUG%>!$G5K*_3$tUv9F|g^*|v?**}SjZePpuZ?rxau3*UN=R4ZXquo5%Zu0zu
zsX38*T39Jr+FL{)oPcXepM*cO;c-@z!-QwBK-5qy6Ov=0rsRh#yn9$o5cq%!5iq3`
z5iouHkmLg$B2=Jc`FtBm>7Mx*xseR8h!)g6CN+IC8LSa?4MaxWL($r6kia8aCih(7
zE~fAzaSI^>L4-7kz{U%o0Hsrj-gGHkBB5o&Y(S%G^Mrntjv*5Pk`R0sO=%M?oqIe_
zX9(l!L?Ei%TOGQGw6s1^BbN1>;Jfq6;6f27DEG>4$25vtV02H2rxYzpwObm51IDnO
z@{u@2hyr8i7Ic(~V@gH+xT-AA(dp`}tfH-5fqt2fs}&V4FS6X()!Bjj^t>X3sCGDO
z-{d5@Sk#;(tK4fu`#Gmz7B##Y!F(nH~qV5)B*1t_ILYb6#
zWyXo^qGr_JHGAcFVe}%&WL5U)MHRk=-JQHR$yx32qDJTrt;EL>j9Yj_OYDP>ZWw{J
zz+^DNSi2Ns(+A4HNK3?wxSKJ6WBfwClJ5 consumerFactory() {
+        Map props = new HashMap<>();
+        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
+        props.put(ConsumerConfig.GROUP_ID_CONFIG, "booking-group");
+        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
+        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer.class); // 에러 처리 포함
+
+        // 실제 역직렬화할 클래스 지정
+        props.put(ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS, JsonDeserializer.class.getName());
+        props.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
+        props.put(JsonDeserializer.VALUE_DEFAULT_TYPE, userDto); // 패키지명 포함한 클래스 경로
+
+        return new DefaultKafkaConsumerFactory<>(props,
+                new StringDeserializer(),
+                new JsonDeserializer<>(UserEventListener.UserEventDTO.class, false));
+    }
+
+
+    @Bean
+    public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() {
+
+
+        ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
+        factory.setConsumerFactory(consumerFactory());
+        return factory;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java b/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
new file mode 100644
index 0000000..8ff4342
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
@@ -0,0 +1,31 @@
+package com.mnms.booking.config;
+
+import com.mnms.booking.dto.response.WaitingNumberDTO;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.StringSerializer;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+import org.springframework.kafka.support.serializer.JsonSerializer;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class KafkaProducerConfig {
+
+    public  ProducerFactory producerFactory(Class clazz) {
+        Map config = new HashMap<>();
+        config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
+        config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+        config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
+        return new DefaultKafkaProducerFactory<>(config);
+    }
+
+    @Bean
+    public KafkaTemplate bookingEventKafkaTemplate() {
+        return new KafkaTemplate<>(producerFactory(WaitingNumberDTO.class));
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/config/KafkaTopicConfig.java b/src/main/java/com/mnms/booking/config/KafkaTopicConfig.java
new file mode 100644
index 0000000..587e518
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/KafkaTopicConfig.java
@@ -0,0 +1,18 @@
+package com.mnms.booking.config;
+
+import org.apache.kafka.clients.admin.NewTopic;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.config.TopicBuilder;
+
+@Configuration
+public class KafkaTopicConfig {
+
+    @Bean
+    public NewTopic bookingEventTopic() {
+        return TopicBuilder.name("booking-event")
+                .partitions(1)
+                .replicas(1)
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index d49f7d7..54d3d08 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.response.WaitingNumberDto;
+import com.mnms.booking.dto.response.WaitingNumberDTO;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -8,7 +8,6 @@
 import org.springframework.http.ResponseEntity;
 import org.springframework.messaging.handler.annotation.DestinationVariable;
 import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.handler.annotation.Payload;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
@@ -32,15 +31,15 @@ public class BookingController {
      */
     @GetMapping("/enter")
     @ResponseBody // JSON 응답을 위해 추가
-    public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) {
+    public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) {
         long waitingNumber = waitingService.enterWaitingQueue(userId);
 
         if (waitingNumber == 0) {
             // 즉시 입장 가능한 경우
-            return ResponseEntity.ok(new WaitingNumberDto(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
+            return ResponseEntity.ok(new WaitingNumberDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
             // 대기열에 진입한 경우
-            return ResponseEntity.ok(new WaitingNumberDto(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
+            return ResponseEntity.ok(new WaitingNumberDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
 
diff --git a/src/main/java/com/mnms/booking/controller/KaptchaController.java b/src/main/java/com/mnms/booking/controller/KaptchaController.java
index acc63fc..3b7ad62 100644
--- a/src/main/java/com/mnms/booking/controller/KaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/KaptchaController.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.response.KaptchaDto;
+import com.mnms.booking.dto.response.KaptchaDTO;
 import com.mnms.booking.service.KaptchaService;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -26,11 +26,11 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
     }
 
     @PostMapping("/verify")
-    public ResponseEntity verifyCaptcha(
+    public ResponseEntity verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
 
-        KaptchaDto result = kaptchaService.verifyCaptchaResult(captcha, session);
+        KaptchaDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
         return result.isSuccess()
                 ? ResponseEntity.ok(result)
                 : ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalDTO.java
new file mode 100644
index 0000000..d938096
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalDTO.java
@@ -0,0 +1,32 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Data;
+
+@Data
+public class FestivalDTO {
+
+    private String mt20id;
+
+    // 공연명
+    private String prfnm;
+
+    // 공연 시작일
+    private String prfpdfrom;
+
+    // 공연 종료일
+    private String prfpdto;
+
+    // 공연 시설명
+    private String fcltynm;
+
+    // 포스터 이미지 경로
+    private String poster;
+
+    // 티켓 비용
+    private String pcseguidance;
+
+    // 수용 가능 인원
+    private int availableNOP;
+
+    // 택배 날짜 (지류티켓 선택 시, 페스티벌 날짜 2주일 전 배송 - 자동) - 추후
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/KaptchaDto.java b/src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java
similarity index 87%
rename from src/main/java/com/mnms/booking/dto/response/KaptchaDto.java
rename to src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java
index 4007908..61b1cdd 100644
--- a/src/main/java/com/mnms/booking/dto/response/KaptchaDto.java
+++ b/src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java
@@ -5,7 +5,7 @@
 
 @Data // Lombok 사용 시
 @Builder
-public class KaptchaDto {
+public class KaptchaDTO {
     private boolean success;
     private String message;
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java b/src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java
similarity index 93%
rename from src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java
rename to src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java
index 5e1bad8..ab2bf98 100644
--- a/src/main/java/com/mnms/booking/dto/response/WaitingNumberDto.java
+++ b/src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java
@@ -7,7 +7,7 @@
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class WaitingNumberDto {
+public class WaitingNumberDTO {
     private String userId;
     private long waitingNumber; // 대기 순번
     // 선택
diff --git a/src/main/java/com/mnms/booking/kafka/UserEventListener.java b/src/main/java/com/mnms/booking/kafka/UserEventListener.java
new file mode 100644
index 0000000..7fa5d9e
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/UserEventListener.java
@@ -0,0 +1,38 @@
+package com.mnms.booking.kafka;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class UserEventListener {
+
+    // Kafka로부터 받은 메시지를 처리할 DTO : user 정보로 test
+    @Data
+    static public class UserEventDTO {
+        private Long userId;
+        private String loginId;
+        private String name;
+        private String email;
+        private UserEventType eventType; // 예: REGISTERED, DELETED 등
+        private String accessToken;
+    }
+
+    static public enum UserEventType {
+        REGISTERED,
+        LOGGED_IN,
+        LOGGED_OUT,
+        UPDATED_PROFILE,
+        DELETED
+    }
+
+    // user-event topic 구독
+    @KafkaListener(topics = "${app.kafka.topic.user-event}", groupId = "booking-group", containerFactory = "kafkaListenerContainerFactory")
+    public void listenOrderEvents(UserEventDTO userEventDto) {
+        log.info("새로운 주문 이벤트 수신: " + userEventDto);
+
+        // 여기에 주문 처리 관련 비즈니스 로직을 추가 예정
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/KaptchaService.java b/src/main/java/com/mnms/booking/service/KaptchaService.java
index ac789e0..4a465a0 100644
--- a/src/main/java/com/mnms/booking/service/KaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/KaptchaService.java
@@ -1,7 +1,7 @@
 package com.mnms.booking.service;
 
 import com.google.code.kaptcha.impl.DefaultKaptcha;
-import com.mnms.booking.dto.response.KaptchaDto;
+import com.mnms.booking.dto.response.KaptchaDTO;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
@@ -45,13 +45,13 @@ private BufferedImage generateCaptchaImage(HttpSession session) {
         return captchaProducer.createImage(captchaText);
     }
 
-    public KaptchaDto verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
+    public KaptchaDTO verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
         String sessionCaptcha = (String) session.getAttribute(CAPTCHA_SESSION_KEY);
 
         boolean isValid = sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(userInputCaptcha);
         if (isValid) {session.removeAttribute(CAPTCHA_SESSION_KEY);}
 
-        return KaptchaDto.builder()
+        return KaptchaDTO.builder()
                 .success(isValid)
                 .message(isValid ? "인증 성공" : "보안문자 불일치")
                 .build();
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index a5c23a0..ea8e1cc 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.service;
 
-import com.mnms.booking.dto.response.WaitingNumberDto;
+import com.mnms.booking.dto.response.WaitingNumberDTO;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.RequiredArgsConstructor;
@@ -28,7 +28,7 @@ public void onMessage(Message message, byte[] pattern) {
             log.info("Received message from Redis channel: {}", receivedMessage);
 
             // 받은 JSON 문자열을 WaitingNumberDto 객체로 변환
-            WaitingNumberDto dto = objectMapper.readValue(receivedMessage, WaitingNumberDto.class);
+            WaitingNumberDTO dto = objectMapper.readValue(receivedMessage, WaitingNumberDTO.class);
 
             // WebSocket을 통해 해당 사용자 토픽으로 메시지 전송
             messagingTemplate.convertAndSend("/topic/waiting/" + dto.getUserId(), dto);
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index e5ddc3a..e39cbc7 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -2,7 +2,7 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.mnms.booking.dto.response.WaitingNumberDto;
+import com.mnms.booking.dto.response.WaitingNumberDTO;
 import jakarta.annotation.PostConstruct;
 import jakarta.annotation.PreDestroy;
 import lombok.extern.slf4j.Slf4j;
@@ -10,7 +10,6 @@
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
-import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 
@@ -173,7 +172,7 @@ public long getAndPublishWaitingNumber(String userId) {
     private void publishWaitingNumber(String userId, long waitingNumber) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberDto dto = new WaitingNumberDto(userId, waitingNumber, false, null);
+            WaitingNumberDTO dto = new WaitingNumberDTO(userId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(dto);
             // Redis 채널로 발행
             stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 7b260c9..fa633d9 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -21,3 +21,13 @@ spring.h2.console.path=/h2-console
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
 #spring.redis.password=your_password
+
+# kafka
+app.kafka.topic.booking-event=booking-events
+app.kafka.topic.user-event: user-events
+spring.kafka.bootstrap-servers=192.168.0.139:9094
+spring.kafka.consumer.auto-offset-reset=earliest
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
+spring.kafka.consumer.properties.spring.json.trusted.packages=*
+spring.kafka.consumer.properties.spring.json.use.type.headers=false

From 9e4058e6470c17ea31a5811b7904074e80b04ee9 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 7 Aug 2025 16:56:01 +0900
Subject: [PATCH 011/149] =?UTF-8?q?MNMS-256=20feat:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EC=A7=84=ED=96=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

예매 티켓 생성 및 QR 생성
추후 수정 사항 : reservationStatus null값, exception 처리 등
---
 build.gradle                                  |   6 ++
 .../booking/config/KafkaConsumerConfig.java   |  56 ----------
 .../booking/config/KafkaProducerConfig.java   |   6 +-
 .../booking/controller/BookingController.java | 102 +++---------------
 .../booking/controller/KaptchaController.java |   6 +-
 .../booking/controller/QrCodeController.java  |  36 +++++++
 .../booking/controller/WaitingController.java |  98 +++++++++++++++++
 .../booking/dto/request/QrRequestDTO.java     |  21 ++++
 .../booking/dto/request/TicketRequestDTO.java |  14 +++
 ...tivalDTO.java => FestivalResponseDTO.java} |   2 +-
 ...aptchaDTO.java => KaptchaResponseDTO.java} |   2 +-
 .../booking/dto/response/QrResponseDTO.java   |  55 ++++++++++
 .../dto/response/TicketResponseDTO.java       |  36 +++++++
 ...DTO.java => WaitingNumberResponseDTO.java} |   2 +-
 .../com/mnms/booking/entity/Festival.java     |  25 +++++
 .../java/com/mnms/booking/entity/QrCode.java  |  38 +++++++
 .../java/com/mnms/booking/entity/Ticket.java  |  42 ++++++++
 .../com/mnms/booking/entity/TicketType.java   |   6 ++
 .../mnms/booking/kafka/UserEventListener.java |  38 -------
 .../repository/FestivalRepository.java        |   8 ++
 .../booking/repository/QrCodeRepository.java  |  12 +++
 .../booking/repository/TicketRepository.java  |   9 ++
 .../mnms/booking/service/BookingService.java  |  77 +++++++++++++
 .../mnms/booking/service/KaptchaService.java  |   6 +-
 .../mnms/booking/service/QrCodeService.java   |  59 ++++++++++
 .../service/RedisMessageSubscriber.java       |   4 +-
 .../mnms/booking/service/WaitingService.java  |   4 +-
 .../resources/application-test.properties     |   4 +-
 28 files changed, 575 insertions(+), 199 deletions(-)
 delete mode 100644 src/main/java/com/mnms/booking/config/KafkaConsumerConfig.java
 create mode 100644 src/main/java/com/mnms/booking/controller/QrCodeController.java
 create mode 100644 src/main/java/com/mnms/booking/controller/WaitingController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
 rename src/main/java/com/mnms/booking/dto/response/{FestivalDTO.java => FestivalResponseDTO.java} (94%)
 rename src/main/java/com/mnms/booking/dto/response/{KaptchaDTO.java => KaptchaResponseDTO.java} (84%)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
 rename src/main/java/com/mnms/booking/dto/response/{WaitingNumberDTO.java => WaitingNumberResponseDTO.java} (91%)
 create mode 100644 src/main/java/com/mnms/booking/entity/Festival.java
 create mode 100644 src/main/java/com/mnms/booking/entity/QrCode.java
 create mode 100644 src/main/java/com/mnms/booking/entity/Ticket.java
 create mode 100644 src/main/java/com/mnms/booking/entity/TicketType.java
 delete mode 100644 src/main/java/com/mnms/booking/kafka/UserEventListener.java
 create mode 100644 src/main/java/com/mnms/booking/repository/FestivalRepository.java
 create mode 100644 src/main/java/com/mnms/booking/repository/QrCodeRepository.java
 create mode 100644 src/main/java/com/mnms/booking/repository/TicketRepository.java
 create mode 100644 src/main/java/com/mnms/booking/service/BookingService.java
 create mode 100644 src/main/java/com/mnms/booking/service/QrCodeService.java

diff --git a/build.gradle b/build.gradle
index 9077b47..18df127 100644
--- a/build.gradle
+++ b/build.gradle
@@ -65,6 +65,12 @@ dependencies {
 	implementation 'com.fasterxml.jackson.core:jackson-databind'
 	implementation 'org.springframework.boot:spring-boot-starter-json'
 	testImplementation 'org.springframework.kafka:spring-kafka-test'
+
+	// QR 생성
+	implementation 'com.google.zxing:core:3.5.2'
+	implementation 'com.google.zxing:javase:3.5.2'
+	implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
+
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/config/KafkaConsumerConfig.java b/src/main/java/com/mnms/booking/config/KafkaConsumerConfig.java
deleted file mode 100644
index c7331bd..0000000
--- a/src/main/java/com/mnms/booking/config/KafkaConsumerConfig.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package com.mnms.booking.config;
-
-import com.mnms.booking.kafka.UserEventListener;
-import org.apache.kafka.clients.consumer.ConsumerConfig;
-import org.apache.kafka.common.serialization.StringDeserializer;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.kafka.annotation.EnableKafka;
-import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
-import org.springframework.kafka.core.ConsumerFactory;
-import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
-import org.springframework.kafka.support.serializer.ErrorHandlingDeserializer;
-import org.springframework.kafka.support.serializer.JsonDeserializer;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@EnableKafka
-@Configuration
-public class KafkaConsumerConfig {
-
-    @Value("${spring.kafka.bootstrap-servers}")
-    private String bootstrapServers;
-
-    @Value("${spring.kafka.consumer.properties.spring.json.value.default.type}")
-    private String userDto;
-
-    @Bean
-    public ConsumerFactory consumerFactory() {
-        Map props = new HashMap<>();
-        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
-        props.put(ConsumerConfig.GROUP_ID_CONFIG, "booking-group");
-        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
-        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, ErrorHandlingDeserializer.class); // 에러 처리 포함
-
-        // 실제 역직렬화할 클래스 지정
-        props.put(ErrorHandlingDeserializer.VALUE_DESERIALIZER_CLASS, JsonDeserializer.class.getName());
-        props.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
-        props.put(JsonDeserializer.VALUE_DEFAULT_TYPE, userDto); // 패키지명 포함한 클래스 경로
-
-        return new DefaultKafkaConsumerFactory<>(props,
-                new StringDeserializer(),
-                new JsonDeserializer<>(UserEventListener.UserEventDTO.class, false));
-    }
-
-
-    @Bean
-    public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() {
-
-
-        ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>();
-        factory.setConsumerFactory(consumerFactory());
-        return factory;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java b/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
index 8ff4342..11fb66c 100644
--- a/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
+++ b/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.config;
 
-import com.mnms.booking.dto.response.WaitingNumberDTO;
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.serialization.StringSerializer;
 import org.springframework.context.annotation.Bean;
@@ -25,7 +25,7 @@ public  ProducerFactory producerFactory(Class clazz) {
     }
 
     @Bean
-    public KafkaTemplate bookingEventKafkaTemplate() {
-        return new KafkaTemplate<>(producerFactory(WaitingNumberDTO.class));
+    public KafkaTemplate bookingEventKafkaTemplate() {
+        return new KafkaTemplate<>(producerFactory(WaitingNumberResponseDTO.class));
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 54d3d08..68e6ee3 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,98 +1,26 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.response.WaitingNumberDTO;
+import com.mnms.booking.dto.request.TicketRequestDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.service.BookingService;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.messaging.handler.annotation.DestinationVariable;
-import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.*;
-import com.mnms.booking.service.WaitingService;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
-@Controller
+@RestController
 @RequiredArgsConstructor
-@Slf4j
-@RequestMapping("/api/booking")
+@RequestMapping("/api/tickets")
 public class BookingController {
 
-    private final WaitingService waitingService;
+    private final BookingService bookingService;
 
-    @Autowired
-    private SimpMessagingTemplate messagingTemplate;
-
-
-    /**
-     * 예매하기 버튼 클릭 시 호출되는 API
-     * userId는 수정할 예정 (추후)
-     */
-    @GetMapping("/enter")
-    @ResponseBody // JSON 응답을 위해 추가
-    public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) {
-        long waitingNumber = waitingService.enterWaitingQueue(userId);
-
-        if (waitingNumber == 0) {
-            // 즉시 입장 가능한 경우
-            return ResponseEntity.ok(new WaitingNumberDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
-        } else {
-            // 대기열에 진입한 경우
-            return ResponseEntity.ok(new WaitingNumberDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
-        }
-    }
-
-    /**
-     * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출
-     * (이 사용자는 대기열에서 제거됨)
-     * userId는 수정할 예정 (추후)
-     */
-    @GetMapping("/release/{userId}")
-    public ResponseEntity releaseUser(@PathVariable("userId") String userId) {
-        try {
-            boolean removed = waitingService.userExitBookingPage(userId);
-            if (removed) {
-                return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
-            } else {
-                return ResponseEntity.status(HttpStatus.NOT_FOUND)
-                        .body("해당 사용자는 예매 사용자 목록에 없습니다.");
-            }
-        } catch (Exception e) {
-            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
-                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
-        }
-    }
-
-    /**
-     * 대기열에 있는 사용자가 대기열을 나간다 (예매 입장 아님)
-     * (이 사용자는 대기열에서 제거됨)
-     * userId는 수정할 예정 (추후)
-     */
-    @GetMapping("/exit/{userId}")
-    public ResponseEntity exitWaitingUser(@PathVariable("userId") String userId) {
-        try {
-            boolean removed = waitingService.removeUserFromQueue(userId);
-            if (removed) {
-                return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
-            } else {
-                return ResponseEntity.status(HttpStatus.NOT_FOUND)
-                        .body("해당 사용자는 대기열 목록에 없습니다.");
-            }
-        } catch (Exception e) {
-            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
-                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
-        }
+    @PostMapping("/reserve")
+    public ResponseEntity reserveTicket(@RequestBody TicketRequestDTO request) {
+        TicketResponseDTO response = bookingService.reserveTicket(request);
+        return ResponseEntity.ok(response);
     }
 
-    /**
-     * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
-     * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
-     * userId는 수정할 예정 (추후)
-     */
-    @MessageMapping("/subscribe/waiting/{userId}")
-    public void subscribeWaitingQueue(@DestinationVariable("userId") String userId) {
-        log.info("User {} subscribed to waiting queue updates.", userId);
-        waitingService.getAndPublishWaitingNumber(userId);
-    }
-}
\ No newline at end of file
+}
diff --git a/src/main/java/com/mnms/booking/controller/KaptchaController.java b/src/main/java/com/mnms/booking/controller/KaptchaController.java
index 3b7ad62..b5e50fe 100644
--- a/src/main/java/com/mnms/booking/controller/KaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/KaptchaController.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.response.KaptchaDTO;
+import com.mnms.booking.dto.response.KaptchaResponseDTO;
 import com.mnms.booking.service.KaptchaService;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
@@ -26,11 +26,11 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
     }
 
     @PostMapping("/verify")
-    public ResponseEntity verifyCaptcha(
+    public ResponseEntity verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
 
-        KaptchaDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
+        KaptchaResponseDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
         return result.isSuccess()
                 ? ResponseEntity.ok(result)
                 : ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
new file mode 100644
index 0000000..c44dc3c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -0,0 +1,36 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.request.QrRequestDTO;
+import com.mnms.booking.service.QrCodeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDateTime;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/qr")
+public class QrCodeController {
+
+    private final QrCodeService qrCodeService;
+
+    // 수정 : qrcode 생성하고 이미지 띄우기
+/*    @GetMapping(value = "/generate", produces = MediaType.IMAGE_PNG_VALUE)
+    public ResponseEntity generateQr(@RequestParam String qrCodeId) throws Exception {
+        QrRequestDTO payload = new QrRequestDTO(
+                qrCodeId,
+                "user1",
+                "ticket4",
+                LocalDateTime.now(), // issuedAt
+                LocalDateTime.now().plusMinutes(30), // expiredAt
+                "9241"
+        );
+        byte[] qrImage = qrCodeService.generateQrImageAsBytes(payload, 300, 300);
+        return ResponseEntity.ok().body(qrImage);
+    }*/
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
new file mode 100644
index 0000000..7fc0303
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -0,0 +1,98 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import com.mnms.booking.service.WaitingService;
+
+@Controller
+@RequiredArgsConstructor
+@Slf4j
+@RequestMapping("/api/booking")
+public class WaitingController {
+
+    private final WaitingService waitingService;
+
+    @Autowired
+    private SimpMessagingTemplate messagingTemplate;
+
+
+    /**
+     * 예매하기 버튼 클릭 시 호출되는 API
+     * userId는 수정할 예정 (추후)
+     */
+    @GetMapping("/enter")
+    @ResponseBody // JSON 응답을 위해 추가
+    public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) {
+        long waitingNumber = waitingService.enterWaitingQueue(userId);
+
+        if (waitingNumber == 0) {
+            // 즉시 입장 가능한 경우
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
+        } else {
+            // 대기열에 진입한 경우
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
+        }
+    }
+
+    /**
+     * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출
+     * (이 사용자는 대기열에서 제거됨)
+     * userId는 수정할 예정 (추후)
+     */
+    @GetMapping("/release/{userId}")
+    public ResponseEntity releaseUser(@PathVariable("userId") String userId) {
+        try {
+            boolean removed = waitingService.userExitBookingPage(userId);
+            if (removed) {
+                return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
+            } else {
+                return ResponseEntity.status(HttpStatus.NOT_FOUND)
+                        .body("해당 사용자는 예매 사용자 목록에 없습니다.");
+            }
+        } catch (Exception e) {
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+        }
+    }
+
+    /**
+     * 대기열에 있는 사용자가 대기열을 나간다 (예매 입장 아님)
+     * (이 사용자는 대기열에서 제거됨)
+     * userId는 수정할 예정 (추후)
+     */
+    @GetMapping("/exit/{userId}")
+    public ResponseEntity exitWaitingUser(@PathVariable("userId") String userId) {
+        try {
+            boolean removed = waitingService.removeUserFromQueue(userId);
+            if (removed) {
+                return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
+            } else {
+                return ResponseEntity.status(HttpStatus.NOT_FOUND)
+                        .body("해당 사용자는 대기열 목록에 없습니다.");
+            }
+        } catch (Exception e) {
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+        }
+    }
+
+    /**
+     * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
+     * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
+     * userId는 수정할 예정 (추후)
+     */
+    @MessageMapping("/subscribe/waiting/{userId}")
+    public void subscribeWaitingQueue(@DestinationVariable("userId") String userId) {
+        log.info("User {} subscribed to waiting queue updates.", userId);
+        waitingService.getAndPublishWaitingNumber(userId);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
new file mode 100644
index 0000000..33e447f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
@@ -0,0 +1,21 @@
+package com.mnms.booking.dto.request;
+
+import com.mnms.booking.entity.Ticket;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class QrRequestDTO {
+    private Long id;
+    private String qrCodeId;
+    private String userId;
+    private Ticket ticket;
+    private LocalDateTime issuedAt;
+    private LocalDateTime expiredAt;
+    private String pinCode;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
new file mode 100644
index 0000000..ef0715c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.dto.request;
+
+import com.mnms.booking.entity.TicketType;
+import lombok.Data;
+
+@Data
+public class TicketRequestDTO {
+
+    private Long id;
+    private String userId;
+    private Long festivalId;
+    private TicketType deliveryMethod;
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java
similarity index 94%
rename from src/main/java/com/mnms/booking/dto/response/FestivalDTO.java
rename to src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java
index d938096..cfd4499 100644
--- a/src/main/java/com/mnms/booking/dto/response/FestivalDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java
@@ -3,7 +3,7 @@
 import lombok.Data;
 
 @Data
-public class FestivalDTO {
+public class FestivalResponseDTO {
 
     private String mt20id;
 
diff --git a/src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java b/src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java
similarity index 84%
rename from src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java
rename to src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java
index 61b1cdd..b15ad03 100644
--- a/src/main/java/com/mnms/booking/dto/response/KaptchaDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java
@@ -5,7 +5,7 @@
 
 @Data // Lombok 사용 시
 @Builder
-public class KaptchaDTO {
+public class KaptchaResponseDTO {
     private boolean success;
     private String message;
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
new file mode 100644
index 0000000..2526bd8
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -0,0 +1,55 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.QrCode;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
+public class QrResponseDTO {
+
+    private Long id;
+    private String qrCodeId;
+    private String userId;
+    private LocalDateTime issuedAt;
+    private LocalDateTime expiredAt;
+    private Boolean used;
+    private LocalDateTime usedAt;
+
+    public static QrResponseDTO fromEntity(QrCode qrCode) {
+        return QrResponseDTO.builder()
+                .id(qrCode.getId())
+                .qrCodeId(qrCode.getQrCodeId())
+                .userId(qrCode.getUserId())
+                .issuedAt(qrCode.getIssuedAt())
+                .expiredAt(qrCode.getExpiredAt())
+                .used(qrCode.getUsed())
+                .usedAt(qrCode.getUsedAt())
+                .build();
+    }
+
+    public QrCode toEntity() {
+        return QrCode.builder()
+                .id(this.id)
+                .qrCodeId(this.qrCodeId)
+                .userId(this.userId)
+                .issuedAt(this.issuedAt)
+                .expiredAt(this.expiredAt)
+                .used(this.used != null ? this.used : false) // 기본값 처리
+                .usedAt(this.usedAt)
+                .build();
+    }
+
+    public static QrResponseDTO create(String userId, String qrCodeId,Festival festival) {
+        QrResponseDTO dto = new QrResponseDTO();
+        dto.setQrCodeId(qrCodeId);
+        dto.setUserId(userId);
+        dto.setIssuedAt(LocalDateTime.now());
+        dto.setExpiredAt(festival.getPrfpdto().minusMinutes(30));
+        return dto;
+    }
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
new file mode 100644
index 0000000..cfe9e22
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -0,0 +1,36 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.TicketType;
+import lombok.*;
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class TicketResponseDTO {
+
+    private Long id;
+    private String reservationNumber;
+    private Boolean reservationStatus;
+    private TicketType deliveryMethod;
+    private LocalDateTime deliveryDate;
+    private String userId;
+    private LocalDateTime reservationDate;
+    private QrResponseDTO qrCode;
+    private Festival festival;
+
+    public static TicketResponseDTO fromEntity(Ticket ticket) {
+        return TicketResponseDTO.builder()
+                .id(ticket.getId())
+                .reservationNumber(ticket.getReservationNumber())
+                .deliveryMethod(ticket.getDeliveryMethod())
+                .deliveryDate(ticket.getDeliveryDate())
+                .reservationDate(ticket.getReservationDate())
+                .qrCode(QrResponseDTO.fromEntity(ticket.getQrCode()))
+                .userId(ticket.getUserId())
+                .festival(ticket.getFestival())
+                .build();
+    }
+}
+
diff --git a/src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java b/src/main/java/com/mnms/booking/dto/response/WaitingNumberResponseDTO.java
similarity index 91%
rename from src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java
rename to src/main/java/com/mnms/booking/dto/response/WaitingNumberResponseDTO.java
index ab2bf98..d06cbc1 100644
--- a/src/main/java/com/mnms/booking/dto/response/WaitingNumberDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/WaitingNumberResponseDTO.java
@@ -7,7 +7,7 @@
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class WaitingNumberDTO {
+public class WaitingNumberResponseDTO {
     private String userId;
     private long waitingNumber; // 대기 순번
     // 선택
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
new file mode 100644
index 0000000..5ff3ee7
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -0,0 +1,25 @@
+package com.mnms.booking.entity;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Getter
+@Table(name = "festival")
+public class Festival {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id; // festival_id
+    private String name; // 이름
+    private String frame; // frame
+    private LocalDateTime prfpdfrom; // 시작일
+    private LocalDateTime prfpdto; // 종료일
+    private String poster; // 포스터
+    private String ticketPrice; // 가격
+    private int availableNOp; // 수용 가능 인원
+    private String area; // 장소
+    private int paper; // 지류 여부
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
new file mode 100644
index 0000000..b2a4557
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -0,0 +1,38 @@
+package com.mnms.booking.entity;
+
+import jakarta.persistence.*;
+import lombok.Builder;
+import lombok.Getter;
+import java.time.LocalDateTime;
+
+@Entity
+@Getter
+@Builder
+@Table(name = "qr_code")
+public class QrCode {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id; // qr_id
+
+    @Column(name = "qr_code_id", nullable = false)
+    private String qrCodeId;
+
+    @Column(name = "issued_at", nullable = false)
+    private LocalDateTime issuedAt;
+
+    @Column(name = "expired_at", nullable = false)
+    private LocalDateTime expiredAt;
+
+    @Column(name = "used", nullable = false)
+    private Boolean used;
+
+    @Column(name = "used_at")
+    private LocalDateTime usedAt;
+
+    @Column(name = "user_id", nullable = false)
+    private String userId;
+
+    @OneToOne(fetch = FetchType.LAZY)
+    private Ticket ticket; // ticket_id
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
new file mode 100644
index 0000000..44d9cae
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -0,0 +1,42 @@
+package com.mnms.booking.entity;
+
+import jakarta.persistence.*;
+import lombok.Builder;
+import lombok.Getter;
+import jakarta.persistence.Id;
+import java.time.LocalDateTime;
+
+@Entity
+@Builder
+@Getter
+@Table(name = "ticket")
+public class Ticket {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id; // ticket_id
+
+    @Column(name = "reservation_number")
+    private String reservationNumber; // 예매번호
+
+    @Column(name = "reservation_status")
+    private Boolean reservationStatus; // 예매 상태
+
+    @Column(name = "delivery_method")
+    private TicketType deliveryMethod; // 수령방법
+
+    @Column(name = "user_id")
+    private String userId; // 예매자 id
+
+    @Column(name = "reservation_date")
+    private LocalDateTime reservationDate; // 예매 날짜
+
+    @Column(name = "delivery_date")
+    private LocalDateTime deliveryDate; // 택배 날짜
+
+    @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+    private QrCode qrCode;
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "festival_id")
+    private Festival festival;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/TicketType.java b/src/main/java/com/mnms/booking/entity/TicketType.java
new file mode 100644
index 0000000..906bf6f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/TicketType.java
@@ -0,0 +1,6 @@
+package com.mnms.booking.entity;
+
+public enum TicketType {
+    MOBILE,
+    PAPER
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/kafka/UserEventListener.java b/src/main/java/com/mnms/booking/kafka/UserEventListener.java
deleted file mode 100644
index 7fa5d9e..0000000
--- a/src/main/java/com/mnms/booking/kafka/UserEventListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.mnms.booking.kafka;
-
-import lombok.Data;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.stereotype.Component;
-
-@Component
-@Slf4j
-public class UserEventListener {
-
-    // Kafka로부터 받은 메시지를 처리할 DTO : user 정보로 test
-    @Data
-    static public class UserEventDTO {
-        private Long userId;
-        private String loginId;
-        private String name;
-        private String email;
-        private UserEventType eventType; // 예: REGISTERED, DELETED 등
-        private String accessToken;
-    }
-
-    static public enum UserEventType {
-        REGISTERED,
-        LOGGED_IN,
-        LOGGED_OUT,
-        UPDATED_PROFILE,
-        DELETED
-    }
-
-    // user-event topic 구독
-    @KafkaListener(topics = "${app.kafka.topic.user-event}", groupId = "booking-group", containerFactory = "kafkaListenerContainerFactory")
-    public void listenOrderEvents(UserEventDTO userEventDto) {
-        log.info("새로운 주문 이벤트 수신: " + userEventDto);
-
-        // 여기에 주문 처리 관련 비즈니스 로직을 추가 예정
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
new file mode 100644
index 0000000..8a6b823
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -0,0 +1,8 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.Festival;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface FestivalRepository extends JpaRepository {
+    // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
new file mode 100644
index 0000000..40e1581
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -0,0 +1,12 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.QrCode;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface QrCodeRepository extends JpaRepository {
+    // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
+}
+
+
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
new file mode 100644
index 0000000..2d58c45
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -0,0 +1,9 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.Ticket;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TicketRepository extends JpaRepository {
+}
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
new file mode 100644
index 0000000..2fa928c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -0,0 +1,77 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.request.TicketRequestDTO;
+import com.mnms.booking.dto.response.QrResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.TicketType;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import jakarta.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.UUID;
+
+@Service
+@RequiredArgsConstructor
+public class BookingService {
+
+    private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
+    private final FestivalRepository festivalRepository;
+    private final QrCodeService qrCodeService;
+
+    @Transactional
+    public TicketResponseDTO reserveTicket(TicketRequestDTO request) {
+        // 페스티벌 정보 조회
+        Festival festival = festivalRepository.findById(request.getFestivalId())
+                .orElseThrow(() -> new IllegalArgumentException("Festival not found"));
+
+        // 티켓 택배 날짜
+        LocalDateTime deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), festival);
+
+        // Qr정보 생성
+        String qrCodeId = qrCodeService.generateQrCodeId();
+        QrResponseDTO qrResponse = QrResponseDTO.create(request.getUserId(), qrCodeId, festival);
+        QrCode qrCode = qrResponse.toEntity();
+        qrCodeRepository.save(qrCode);
+
+        // Ticket 저장 (reservation number 자동 래덤 생성됨)
+        Ticket ticket = Ticket.builder()
+                .reservationNumber(generateReservationNumber())
+                .reservationStatus(true)
+                .deliveryMethod(request.getDeliveryMethod())
+                .reservationDate(LocalDateTime.now())
+                .deliveryDate(deliveryDate)
+                .festival(festival)
+                .qrCode(qrCode)
+                .userId(request.getUserId()) // 나중에 수정할 예정
+                .build();
+        ticketRepository.save(ticket);
+
+        // 응답
+        return TicketResponseDTO.fromEntity(ticket);
+    }
+
+    // reservation number 랜덤 생성
+    private String generateReservationNumber() {
+        // T + UUID를 앞 8자리
+        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
+        return "T" + uuidPart;
+    }
+
+    // deliverydate 생성
+    private LocalDateTime calculateDeliveryDate(TicketType deliveryMethod, Festival festival) {
+        // 지류 티켓일 경우
+        if (deliveryMethod == TicketType.PAPER && festival.getPrfpdto() != null) {
+            return festival.getPrfpdto().minusDays(14);
+        }
+        // mobile일 경우
+        return null;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/KaptchaService.java b/src/main/java/com/mnms/booking/service/KaptchaService.java
index 4a465a0..8213436 100644
--- a/src/main/java/com/mnms/booking/service/KaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/KaptchaService.java
@@ -1,7 +1,7 @@
 package com.mnms.booking.service;
 
 import com.google.code.kaptcha.impl.DefaultKaptcha;
-import com.mnms.booking.dto.response.KaptchaDTO;
+import com.mnms.booking.dto.response.KaptchaResponseDTO;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
@@ -45,13 +45,13 @@ private BufferedImage generateCaptchaImage(HttpSession session) {
         return captchaProducer.createImage(captchaText);
     }
 
-    public KaptchaDTO verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
+    public KaptchaResponseDTO verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
         String sessionCaptcha = (String) session.getAttribute(CAPTCHA_SESSION_KEY);
 
         boolean isValid = sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(userInputCaptcha);
         if (isValid) {session.removeAttribute(CAPTCHA_SESSION_KEY);}
 
-        return KaptchaDTO.builder()
+        return KaptchaResponseDTO.builder()
                 .success(isValid)
                 .message(isValid ? "인증 성공" : "보안문자 불일치")
                 .build();
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
new file mode 100644
index 0000000..e02fd4b
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -0,0 +1,59 @@
+package com.mnms.booking.service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.mnms.booking.dto.request.QrRequestDTO;
+import com.mnms.booking.repository.QrCodeRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
+import java.security.SecureRandom;
+import java.util.Base64;
+
+@Service
+@RequiredArgsConstructor
+public class QrCodeService {
+
+    private final ObjectMapper objectMapper;
+    private final QrCodeRepository qrCodeRepository;
+
+    // QrCodeId 생성
+    private static final SecureRandom secureRandom = new SecureRandom();
+    private static final String HEX_CHARS = "0123456789abcdef";
+
+    // QrCodeId : 32자리의 UUID-like 문자열 생성
+    public String generateQrCodeId() {
+        StringBuilder sb = new StringBuilder(32);
+        for (int i = 0; i < 32; i++) {
+            int index = secureRandom.nextInt(HEX_CHARS.length());
+            sb.append(HEX_CHARS.charAt(index));
+        }
+        return sb.toString();
+    }
+
+    //
+    public BufferedImage generateQrImage(QrRequestDTO payload, int width, int height) throws Exception {
+        String json = objectMapper.writeValueAsString(payload);
+        QRCodeWriter qrCodeWriter = new QRCodeWriter();
+        BitMatrix bitMatrix = qrCodeWriter.encode(json, BarcodeFormat.QR_CODE, width, height);
+        return MatrixToImageWriter.toBufferedImage(bitMatrix);
+    }
+
+    public byte[] generateQrImageAsBytes(QrRequestDTO payload, int width, int height) throws Exception {
+        BufferedImage image = generateQrImage(payload, width, height);
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ImageIO.write(image, "PNG", outputStream);
+        return outputStream.toByteArray();
+    }
+
+    public String generateQrBase64(QrRequestDTO payload, int width, int height) throws Exception {
+        byte[] bytes = generateQrImageAsBytes(payload, width, height);
+        return Base64.getEncoder().encodeToString(bytes);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index ea8e1cc..23c6059 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.service;
 
-import com.mnms.booking.dto.response.WaitingNumberDTO;
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.RequiredArgsConstructor;
@@ -28,7 +28,7 @@ public void onMessage(Message message, byte[] pattern) {
             log.info("Received message from Redis channel: {}", receivedMessage);
 
             // 받은 JSON 문자열을 WaitingNumberDto 객체로 변환
-            WaitingNumberDTO dto = objectMapper.readValue(receivedMessage, WaitingNumberDTO.class);
+            WaitingNumberResponseDTO dto = objectMapper.readValue(receivedMessage, WaitingNumberResponseDTO.class);
 
             // WebSocket을 통해 해당 사용자 토픽으로 메시지 전송
             messagingTemplate.convertAndSend("/topic/waiting/" + dto.getUserId(), dto);
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index e39cbc7..c8c4dd1 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -2,7 +2,7 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.mnms.booking.dto.response.WaitingNumberDTO;
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import jakarta.annotation.PostConstruct;
 import jakarta.annotation.PreDestroy;
 import lombok.extern.slf4j.Slf4j;
@@ -172,7 +172,7 @@ public long getAndPublishWaitingNumber(String userId) {
     private void publishWaitingNumber(String userId, long waitingNumber) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberDTO dto = new WaitingNumberDTO(userId, waitingNumber, false, null);
+            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(dto);
             // Redis 채널로 발행
             stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index fa633d9..35638aa 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -25,9 +25,9 @@ spring.redis.port=6379
 # kafka
 app.kafka.topic.booking-event=booking-events
 app.kafka.topic.user-event: user-events
-spring.kafka.bootstrap-servers=192.168.0.139:9094
+spring.kafka.bootstrap-servers=192.168.0.141:9094
 spring.kafka.consumer.auto-offset-reset=earliest
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
-spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
+#spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
 spring.kafka.consumer.properties.spring.json.use.type.headers=false

From ebfe5fd3194b7fabaf6db13ce04fa419d62524e9 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 8 Aug 2025 16:46:55 +0900
Subject: [PATCH 012/149] =?UTF-8?q?MNMS-282=20fix:=20JwtPrincipal=EB=A1=9C?=
 =?UTF-8?q?=20user=20=EC=A0=95=EB=B3=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4?=
 =?UTF-8?q?=EA=B8=B0=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 build.gradle                                  |  8 +-
 .../mnms/booking/config/SecurityConfig.java   | 35 ++++++++
 .../booking/controller/BookingController.java | 10 ++-
 .../mnms/booking/controller/MeController.java | 23 ++++++
 .../booking/dto/request/TicketRequestDTO.java |  4 +-
 .../booking/dto/response/QrResponseDTO.java   | 10 +--
 .../dto/response/TicketResponseDTO.java       |  2 +-
 .../java/com/mnms/booking/entity/QrCode.java  |  2 +-
 .../java/com/mnms/booking/entity/Ticket.java  |  2 +-
 .../mnms/booking/service/BookingService.java  |  6 +-
 .../com/mnms/booking/util/JwtAuthFilter.java  | 50 ++++++++++++
 .../com/mnms/booking/util/JwtPrincipal.java   |  5 ++
 .../com/mnms/booking/util/RsaJwtVerifier.java | 79 +++++++++++++++++++
 .../resources/application-test.properties     |  4 +
 src/main/resources/application.properties     |  6 +-
 src/main/resources/keys/public.pem            |  9 +++
 16 files changed, 235 insertions(+), 20 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/SecurityConfig.java
 create mode 100644 src/main/java/com/mnms/booking/controller/MeController.java
 create mode 100644 src/main/java/com/mnms/booking/util/JwtAuthFilter.java
 create mode 100644 src/main/java/com/mnms/booking/util/JwtPrincipal.java
 create mode 100644 src/main/java/com/mnms/booking/util/RsaJwtVerifier.java
 create mode 100644 src/main/resources/keys/public.pem

diff --git a/build.gradle b/build.gradle
index 18df127..16f1079 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,7 +36,13 @@ dependencies {
 	annotationProcessor 'org.projectlombok:lombok'
 
 	// security
-	//implementation 'org.springframework.boot:spring-boot-starter-security'
+	implementation 'org.springframework.boot:spring-boot-starter-security'
+
+	// JWT
+	implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
+	runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
+	runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
+
 
 	// h2
 	runtimeOnly 'com.h2database:h2'
diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
new file mode 100644
index 0000000..cf3d313
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -0,0 +1,35 @@
+package com.mnms.booking.config;
+
+import com.mnms.booking.util.JwtAuthFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@Configuration
+@EnableWebSecurity
+public class SecurityConfig {
+    private final JwtAuthFilter jwtAuthFilter;
+    public SecurityConfig(JwtAuthFilter jwtAuthFilter) { this.jwtAuthFilter = jwtAuthFilter; }
+
+    @Bean
+    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+        http.csrf(AbstractHttpConfigurer::disable)
+                .headers(headers -> headers
+                        .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) // iframe 허용
+                )
+                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+                .authorizeHttpRequests(auth -> auth
+                        .requestMatchers("/public/**", "/h2-console/**").permitAll() // 하위 경로 포함 허용
+                        .anyRequest().authenticated()
+                )
+                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
+
+        return http.build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 68e6ee3..cc54db2 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -3,8 +3,11 @@
 import com.mnms.booking.dto.request.TicketRequestDTO;
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.service.BookingService;
+import com.mnms.booking.util.JwtPrincipal;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,15 +15,16 @@
 
 @RestController
 @RequiredArgsConstructor
+@Slf4j
 @RequestMapping("/api/tickets")
 public class BookingController {
 
     private final BookingService bookingService;
 
     @PostMapping("/reserve")
-    public ResponseEntity reserveTicket(@RequestBody TicketRequestDTO request) {
-        TicketResponseDTO response = bookingService.reserveTicket(request);
+    public ResponseEntity reserveTicket(@RequestBody TicketRequestDTO request, @AuthenticationPrincipal JwtPrincipal principal){
+        TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
+        log.info("id : " + principal.userId());
         return ResponseEntity.ok(response);
     }
-
 }
diff --git a/src/main/java/com/mnms/booking/controller/MeController.java b/src/main/java/com/mnms/booking/controller/MeController.java
new file mode 100644
index 0000000..9936433
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/MeController.java
@@ -0,0 +1,23 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.util.JwtPrincipal;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/me")
+public class MeController {
+
+    @GetMapping
+    public Map me(@AuthenticationPrincipal JwtPrincipal principal) {
+        return Map.of(
+            "userId", principal.userId(),
+            "loginId", principal.loginId(),
+            "roles", principal.roles()
+        );
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
index ef0715c..eaf9927 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -6,8 +6,8 @@
 @Data
 public class TicketRequestDTO {
 
-    private Long id;
-    private String userId;
+    //private Long id;
+    //private String userId;
     private Long festivalId;
     private TicketType deliveryMethod;
 
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
index 2526bd8..5d217cb 100644
--- a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -14,7 +14,7 @@ public class QrResponseDTO {
 
     private Long id;
     private String qrCodeId;
-    private String userId;
+    private Long userId;
     private LocalDateTime issuedAt;
     private LocalDateTime expiredAt;
     private Boolean used;
@@ -24,11 +24,11 @@ public static QrResponseDTO fromEntity(QrCode qrCode) {
         return QrResponseDTO.builder()
                 .id(qrCode.getId())
                 .qrCodeId(qrCode.getQrCodeId())
-                .userId(qrCode.getUserId())
                 .issuedAt(qrCode.getIssuedAt())
                 .expiredAt(qrCode.getExpiredAt())
                 .used(qrCode.getUsed())
                 .usedAt(qrCode.getUsedAt())
+                .userId(qrCode.getUserId())
                 .build();
     }
 
@@ -36,18 +36,18 @@ public QrCode toEntity() {
         return QrCode.builder()
                 .id(this.id)
                 .qrCodeId(this.qrCodeId)
-                .userId(this.userId)
                 .issuedAt(this.issuedAt)
                 .expiredAt(this.expiredAt)
                 .used(this.used != null ? this.used : false) // 기본값 처리
                 .usedAt(this.usedAt)
+                .userId(this.userId)
                 .build();
     }
 
-    public static QrResponseDTO create(String userId, String qrCodeId,Festival festival) {
+    public static QrResponseDTO create(Long userId, String qrCodeId,Festival festival) {
         QrResponseDTO dto = new QrResponseDTO();
-        dto.setQrCodeId(qrCodeId);
         dto.setUserId(userId);
+        dto.setQrCodeId(qrCodeId);
         dto.setIssuedAt(LocalDateTime.now());
         dto.setExpiredAt(festival.getPrfpdto().minusMinutes(30));
         return dto;
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index cfe9e22..fd2f490 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -15,7 +15,7 @@ public class TicketResponseDTO {
     private Boolean reservationStatus;
     private TicketType deliveryMethod;
     private LocalDateTime deliveryDate;
-    private String userId;
+    private Long userId;
     private LocalDateTime reservationDate;
     private QrResponseDTO qrCode;
     private Festival festival;
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index b2a4557..65f0da9 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -31,7 +31,7 @@ public class QrCode {
     private LocalDateTime usedAt;
 
     @Column(name = "user_id", nullable = false)
-    private String userId;
+    private Long userId;
 
     @OneToOne(fetch = FetchType.LAZY)
     private Ticket ticket; // ticket_id
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 44d9cae..524fe06 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -25,7 +25,7 @@ public class Ticket {
     private TicketType deliveryMethod; // 수령방법
 
     @Column(name = "user_id")
-    private String userId; // 예매자 id
+    private Long userId; // 예매자 id
 
     @Column(name = "reservation_date")
     private LocalDateTime reservationDate; // 예매 날짜
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index 2fa928c..138c24d 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -27,7 +27,7 @@ public class BookingService {
     private final QrCodeService qrCodeService;
 
     @Transactional
-    public TicketResponseDTO reserveTicket(TicketRequestDTO request) {
+    public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
         // 페스티벌 정보 조회
         Festival festival = festivalRepository.findById(request.getFestivalId())
                 .orElseThrow(() -> new IllegalArgumentException("Festival not found"));
@@ -37,7 +37,7 @@ public TicketResponseDTO reserveTicket(TicketRequestDTO request) {
 
         // Qr정보 생성
         String qrCodeId = qrCodeService.generateQrCodeId();
-        QrResponseDTO qrResponse = QrResponseDTO.create(request.getUserId(), qrCodeId, festival);
+        QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival);
         QrCode qrCode = qrResponse.toEntity();
         qrCodeRepository.save(qrCode);
 
@@ -50,7 +50,7 @@ public TicketResponseDTO reserveTicket(TicketRequestDTO request) {
                 .deliveryDate(deliveryDate)
                 .festival(festival)
                 .qrCode(qrCode)
-                .userId(request.getUserId()) // 나중에 수정할 예정
+                .userId(userId)
                 .build();
         ticketRepository.save(ticket);
 
diff --git a/src/main/java/com/mnms/booking/util/JwtAuthFilter.java b/src/main/java/com/mnms/booking/util/JwtAuthFilter.java
new file mode 100644
index 0000000..701026b
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/JwtAuthFilter.java
@@ -0,0 +1,50 @@
+package com.mnms.booking.util;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtException;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.List;
+
+@Component
+public class JwtAuthFilter extends OncePerRequestFilter {
+    private final RsaJwtVerifier jwt;
+
+    public JwtAuthFilter(RsaJwtVerifier jwt) { this.jwt = jwt; }
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
+            throws ServletException, IOException {
+
+        String header = req.getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION);
+        if (header != null && header.startsWith("Bearer ")) {
+            String token = header.substring(7);
+            try {
+                Claims c = jwt.parse(token);
+                Long userId = c.get("userId", Long.class);
+                String loginId = c.getSubject();
+                // B 서비스는 "role": "USER" 형태니까 이렇게 권한 만들기
+                String role = c.get("role", String.class);
+                List auths = (role == null) ? List.of() : List.of(new SimpleGrantedAuthority("ROLE_" + role));
+                JwtPrincipal principal = new JwtPrincipal(userId, loginId, role == null ? List.of() : List.of(role));
+
+                var authentication = new UsernamePasswordAuthenticationToken(principal, null, auths);
+                SecurityContextHolder.getContext().setAuthentication(authentication);
+            } catch (JwtException e) {
+                res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+                return;
+            }
+        }
+        chain.doFilter(req, res);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/JwtPrincipal.java b/src/main/java/com/mnms/booking/util/JwtPrincipal.java
new file mode 100644
index 0000000..2cc7df0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/JwtPrincipal.java
@@ -0,0 +1,5 @@
+package com.mnms.booking.util;
+
+import java.util.List;
+
+public record JwtPrincipal(Long userId, String loginId, List roles) {}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java b/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java
new file mode 100644
index 0000000..4cca3f4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java
@@ -0,0 +1,79 @@
+package com.mnms.booking.util;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.JwtParserBuilder;
+import io.jsonwebtoken.Jwts;
+import jakarta.annotation.PostConstruct;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import java.security.PublicKey;
+import org.springframework.core.io.Resource;
+
+@Component
+public class RsaJwtVerifier {
+    @Value("${jwt.public-pem-path}")
+    private Resource publicPemPath;
+
+    @Value("${jwt.issuer:festival-user-service}")
+    private String issuer;
+
+    private PublicKey publicKey;
+
+//    @PostConstruct
+//    public void init() {
+//        try {
+//            String pem = new String(publicPemPath.getInputStream().readAllBytes(), java.nio.charset.StandardCharsets.UTF_8);
+//            this.publicKey = loadPublicKeyFromPem(pem);
+//        } catch (IOException e) {
+//            throw new IllegalStateException("Failed to read public PEM", e);
+//        }
+//    }
+    @PostConstruct
+    public void init() {
+        try {
+            System.out.println("[DEBUG] resource = " + publicPemPath);
+            System.out.println("[DEBUG] exists   = " + publicPemPath.exists());
+            byte[] bytes = publicPemPath.getInputStream().readAllBytes();
+            System.out.println("[DEBUG] size     = " + bytes.length);
+
+            String peek = new String(bytes, java.nio.charset.StandardCharsets.UTF_8);
+            System.out.println("[DEBUG] first line = " + peek.lines().findFirst().orElse("(empty)"));
+            // ↓ 여기서 바로 던지지 말고, 현재 로더로 시도
+            this.publicKey = loadPublicKeyFromPem(peek);
+            System.out.println("[DEBUG] loaded PublicKey: " + publicKey.getAlgorithm());
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new IllegalStateException("Failed to init RsaJwtVerifier", e);
+        }
+    }
+
+    public Claims parse(String token) {
+        JwtParserBuilder builder = Jwts.parserBuilder()
+                .setSigningKey(publicKey)
+                .setAllowedClockSkewSeconds(30); // 시계 오차 허용
+        if (!issuer.isBlank()) builder.requireIssuer(issuer); // 발급자 강제(옵션)
+        return builder.build().parseClaimsJws(token).getBody();
+    }
+
+    public Long getUserId(String token) {
+        return parse(token).get("userId", Long.class);
+    }
+
+    public String getLoginId(String token) {
+        return parse(token).getSubject(); // sub = loginId
+    }
+
+    // --- PEM 로더
+    private static PublicKey loadPublicKeyFromPem(String pem) {
+        try {
+            String content = pem.replace("-----BEGIN PUBLIC KEY-----","")
+                    .replace("-----END PUBLIC KEY-----","")
+                    .replaceAll("\\s","");
+            byte[] der = java.util.Base64.getDecoder().decode(content);
+            var spec = new java.security.spec.X509EncodedKeySpec(der);
+            return java.security.KeyFactory.getInstance("RSA").generatePublic(spec);
+        } catch (Exception e) {
+            throw new IllegalStateException("Failed to load RSA public key", e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 35638aa..aaab099 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -31,3 +31,7 @@ spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.S
 #spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
 spring.kafka.consumer.properties.spring.json.use.type.headers=false
+
+# jwt
+jwt.public-pem-path=classpath:keys/public.pem
+jwt.issuer=festival-user-service
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 0362d09..65fb4dc 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -3,8 +3,8 @@ spring.application.name=booking
 # 기본 true
 spring.devtools.restart.enabled=true
 
-# 애플리케이션 포트 설정, 기본은 8080
-server.port=8080
+# 포트 설정
+server.port=8082
 
 # 모든 IP 주소에서 접근 허용
 server.address=0.0.0.0
@@ -13,4 +13,4 @@ server.address=0.0.0.0
 spring.profiles.active=test
 
 # log file
-logging.file.path=logs
\ No newline at end of file
+logging.file.path=logs
diff --git a/src/main/resources/keys/public.pem b/src/main/resources/keys/public.pem
new file mode 100644
index 0000000..441e127
--- /dev/null
+++ b/src/main/resources/keys/public.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA312ubekF6tOrMRzgwkvE
+w8Fq2MSJI6gzaBIyKarFMiahThLhivj2pId8FnoOSHGD0bVDP/cOQ4DnIFPpVGjO
+gHHIPb28k5+U37Y/8bRzvkjBHK9VTjHls1Ck+lr5NxhET9rtv3NVWN0hdTcF8EL9
+l7xYun00hNg8S0nUUMlwkrgumio+9bntlnE8GRJ3zuMu9WCRtbV+PuRrgjD/CuOv
+xtRUtrmlVmmYg2UX2JaY2nx2O6aW3HzWg3pR+2YdTW3vzQGOrXhYO4LUQSWkZQPV
+OjfGTzpJj4DkFgGXhymyErtzLrIBwjM2Nt84F5gE/sVg4Hv6ub8v56BqX11IYJxV
+uQIDAQAB
+-----END PUBLIC KEY-----

From db3bc2ee35a4bb12546c24171502ee5e4f322d5e Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 8 Aug 2025 17:20:48 +0900
Subject: [PATCH 013/149] =?UTF-8?q?MNMS-282=20fix:=20user=20JwtPrincipal?=
 =?UTF-8?q?=20=EC=A0=84=EC=B2=B4=20=EC=A0=81=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java |  1 -
 .../booking/controller/WaitingController.java | 35 ++++++-----
 .../mnms/booking/service/WaitingService.java  | 58 +++++++++----------
 3 files changed, 49 insertions(+), 45 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index cc54db2..b8526fd 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -24,7 +24,6 @@ public class BookingController {
     @PostMapping("/reserve")
     public ResponseEntity reserveTicket(@RequestBody TicketRequestDTO request, @AuthenticationPrincipal JwtPrincipal principal){
         TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
-        log.info("id : " + principal.userId());
         return ResponseEntity.ok(response);
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 7fc0303..2065690 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -1,14 +1,15 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import com.mnms.booking.util.JwtPrincipal;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.messaging.handler.annotation.DestinationVariable;
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
@@ -31,15 +32,16 @@ public class WaitingController {
      */
     @GetMapping("/enter")
     @ResponseBody // JSON 응답을 위해 추가
-    public ResponseEntity enterBookingPage(@RequestParam("userId") String userId) {
-        long waitingNumber = waitingService.enterWaitingQueue(userId);
+    public ResponseEntity enterBookingPage(@AuthenticationPrincipal JwtPrincipal principal) {
+        String loginId = principal.loginId();
+        long waitingNumber = waitingService.enterWaitingQueue(loginId);
 
         if (waitingNumber == 0) {
             // 즉시 입장 가능한 경우
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
             // 대기열에 진입한 경우
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
 
@@ -48,10 +50,11 @@ public ResponseEntity enterBookingPage(@RequestParam("
      * (이 사용자는 대기열에서 제거됨)
      * userId는 수정할 예정 (추후)
      */
-    @GetMapping("/release/{userId}")
-    public ResponseEntity releaseUser(@PathVariable("userId") String userId) {
+    @GetMapping("/release")
+    public ResponseEntity releaseUser(@AuthenticationPrincipal JwtPrincipal principal) {
+        String loginId = principal.loginId();
         try {
-            boolean removed = waitingService.userExitBookingPage(userId);
+            boolean removed = waitingService.userExitBookingPage(loginId);
             if (removed) {
                 return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
@@ -69,10 +72,11 @@ public ResponseEntity releaseUser(@PathVariable("userId") String userId)
      * (이 사용자는 대기열에서 제거됨)
      * userId는 수정할 예정 (추후)
      */
-    @GetMapping("/exit/{userId}")
-    public ResponseEntity exitWaitingUser(@PathVariable("userId") String userId) {
+    @GetMapping("/exit")
+    public ResponseEntity exitWaitingUser(@AuthenticationPrincipal JwtPrincipal principal) {
+        String loginId = principal.loginId();
         try {
-            boolean removed = waitingService.removeUserFromQueue(userId);
+            boolean removed = waitingService.removeUserFromQueue(loginId);
             if (removed) {
                 return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
             } else {
@@ -90,9 +94,10 @@ public ResponseEntity exitWaitingUser(@PathVariable("userId") String use
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
      * userId는 수정할 예정 (추후)
      */
-    @MessageMapping("/subscribe/waiting/{userId}")
-    public void subscribeWaitingQueue(@DestinationVariable("userId") String userId) {
-        log.info("User {} subscribed to waiting queue updates.", userId);
-        waitingService.getAndPublishWaitingNumber(userId);
+    @MessageMapping("/subscribe/waiting")
+    public void subscribeWaitingQueue(@AuthenticationPrincipal JwtPrincipal principal) {
+        String loginId = principal.loginId();
+        log.info("User {} subscribed to waiting queue updates.", loginId);
+        waitingService.getAndPublishWaitingNumber(loginId);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index c8c4dd1..050d4a7 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -72,10 +72,10 @@ public WaitingService(
 
     /**
      * 사용자 대기열 진입 처리
-     * @param userId 사용자 ID
+     * @param loginId 사용자 ID
      * @return 대기 순번 (즉시 입장 가능한 경우 0)
      */
-    public long enterWaitingQueue(String userId) {
+    public long enterWaitingQueue(String loginId) {
 
         // 현재 입장한 사용자 수
         Long currentUserCount = redisTemplate.opsForSet().size(BOOKING_USERS_SET_KEY);
@@ -83,21 +83,21 @@ public long enterWaitingQueue(String userId) {
 
         // 입장한 사용자가 제한보다 작을 때
         if(currentUserCount < IMMEDIATE_ENTRY_COUNT){
-            log.info("User {} can enter booking page immediately ({} < {}).", userId, currentUserCount, IMMEDIATE_ENTRY_COUNT);
+            log.info("User {} can enter booking page immediately ({} < {}).", loginId, currentUserCount, IMMEDIATE_ENTRY_COUNT);
 
-            redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, userId); // 사용자 등록
+            redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, loginId); // 사용자 등록
             return 0L;
         } else{
             // 대기열로 보냄 (ZSet)
             long timestamp = System.currentTimeMillis();
-            zSetOperations.add(WAITING_QUEUE_KEY, userId, timestamp);
+            zSetOperations.add(WAITING_QUEUE_KEY, loginId, timestamp);
 
-            log.info("User {} added to waiting queue with timestamp {}.", userId, timestamp);
+            log.info("User {} added to waiting queue with timestamp {}.", loginId, timestamp);
 
             // 조건부 스케줄러 시작
             startScheduler();
 
-            return getAndPublishWaitingNumber(userId);
+            return getAndPublishWaitingNumber(loginId);
         }
     }
 
@@ -131,8 +131,8 @@ public void runSchedulerLogic() {
             return;
         }
 
-        for (String userId : waitingUsers) {
-            getAndPublishWaitingNumber(userId);
+        for (String loginId : waitingUsers) {
+            getAndPublishWaitingNumber(loginId);
         }
         log.info("대기열 사용자 {}명에게 대기번호 발행 완료.", waitingUsers.size());
     }
@@ -145,19 +145,19 @@ public List getWaitingUsers() {
 
     /**
      * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
-     * @param userId 사용자 ID
+     * @param loginId 사용자 ID
      * @return 대기 순번
      */
-    public long getAndPublishWaitingNumber(String userId) {
-        // 해당 userId의 대기열 순번을 조회
-        Long rank = zSetOperations.rank(WAITING_QUEUE_KEY, userId);
+    public long getAndPublishWaitingNumber(String loginId) {
+        // 해당 loginId의 대기열 순번을 조회
+        Long rank = zSetOperations.rank(WAITING_QUEUE_KEY, loginId);
 
         if (rank != null) {
             long waitingNumber = rank + 1;
-            //log.info("User {}'s waiting number: {}", userId, waitingNumber);
+            //log.info("User {}'s waiting number: {}", loginId, waitingNumber);
 
             // Redis Pub/Sub 채널로 메시지 발행
-            publishWaitingNumber(userId, waitingNumber);
+            publishWaitingNumber(loginId, waitingNumber);
 
             return waitingNumber;
         }
@@ -166,13 +166,13 @@ public long getAndPublishWaitingNumber(String userId) {
 
     /**
      * Redis Pub/Sub 채널로 대기 순번 정보 발행
-     * @param userId 사용자 ID
+     * @param loginId 사용자 ID
      * @param waitingNumber 대기 순번
      */
-    private void publishWaitingNumber(String userId, long waitingNumber) {
+    private void publishWaitingNumber(String loginId, long waitingNumber) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
+            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(loginId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(dto);
             // Redis 채널로 발행
             stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
@@ -185,17 +185,17 @@ private void publishWaitingNumber(String userId, long waitingNumber) {
      * 대기열에서 다음 사용자 진입 처리
      * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출)
      */
-    public boolean userExitBookingPage(String userId){
+    public boolean userExitBookingPage(String loginId){
         // 예매 완료된 Set에서 제거
-        Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, userId);
+        Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, loginId);
 
         if(removed != null && removed > 0){
-            log.info("User {} exited booking page and removed from booking user set.", userId);
+            log.info("User {} exited booking page and removed from booking user set.", loginId);
             // 대기열에서 다음 사용자 진입 처리
             releaseWaitingUser();
             return true;
         }else{
-            log.warn("User {} was not found in booking user set on exit.", userId);
+            log.warn("User {} was not found in booking user set on exit.", loginId);
             return false;
         }
     }
@@ -233,27 +233,27 @@ public void notifyAllWaitingUsers() {
         Set allUsersInQueue = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1);
 
         if (allUsersInQueue != null) {
-            for (String userId : allUsersInQueue) {
+            for (String loginId : allUsersInQueue) {
                 // 각 사용자에게 순번 알림을 Redis Pub/Sub으로 발행
-                getAndPublishWaitingNumber(userId);
+                getAndPublishWaitingNumber(loginId);
             }
         }
     }
 
     /**
      * 특정 사용자가 대기열에서 이탈했음을 처리
-     * @param userId
+     * @param loginId
      * @return boolean - 사용자가 대기열에서 성공적으로 제거되었으면 true, 아니면 false
      */
-    public boolean removeUserFromQueue(String userId) {
-        Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, userId);
+    public boolean removeUserFromQueue(String loginId) {
+        Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, loginId);
         if (removedCount != null && removedCount > 0) {
-            log.info("User {} removed from waiting queue (manual removal).", userId);
+            log.info("User {} removed from waiting queue (manual removal).", loginId);
             notifyAllWaitingUsers(); // 순번 업데이트 알림
             return true;
         } else {
             // 사용자가 대기열에 없었거나, 제거 과정에서 문제가 발생한 경우
-            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", userId, removedCount);
+            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", loginId, removedCount);
             return false;
         }
     }

From 4b34515974ff079c60171d41f50b78929dfcb8c4 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 9 Aug 2025 14:54:52 +0900
Subject: [PATCH 014/149] =?UTF-8?q?MNMS-282=20fix:=20=EC=98=88=EB=A7=A4=20?=
 =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EC=A0=84?=
 =?UTF-8?q?=EB=B0=98=EC=A0=81=EC=9D=B8=20=EC=98=88=EC=99=B8=EC=B2=98?=
 =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

status 수정 및 날짜 type, 배송날짜 조건 변경
보안문자 3분 유효시간 조건 추가
exception 처리
---
 .gitignore                                    |  9 +-
 .../mnms/booking/config/SecurityConfig.java   |  2 +-
 ...Controller.java => CaptchaController.java} | 12 +--
 .../mnms/booking/controller/MeController.java | 23 -----
 .../booking/controller/QrCodeController.java  | 36 --------
 .../booking/controller/WaitingController.java |  4 -
 .../dto/request/CaptchaRequestDTO.java        | 24 +++++
 .../FestivalRequestDTO.java}                  | 12 +--
 .../booking/dto/request/QrRequestDTO.java     |  3 +-
 ...sponseDTO.java => CaptchaResponseDTO.java} |  2 +-
 .../booking/dto/response/QrResponseDTO.java   |  9 +-
 .../dto/response/TicketResponseDTO.java       |  8 +-
 .../com/mnms/booking/entity/Festival.java     |  7 +-
 .../java/com/mnms/booking/entity/QrCode.java  |  6 +-
 .../java/com/mnms/booking/entity/Ticket.java  |  6 +-
 .../com/mnms/booking/exception/ErrorCode.java | 14 ++-
 .../booking/repository/TicketRepository.java  |  1 +
 .../mnms/booking/service/BookingService.java  | 90 ++++++++++++++-----
 ...aptchaService.java => CaptchaService.java} | 26 ++++--
 .../mnms/booking/service/QrCodeService.java   | 20 ++++-
 .../resources/application-test.properties     | 10 ++-
 21 files changed, 193 insertions(+), 131 deletions(-)
 rename src/main/java/com/mnms/booking/controller/{KaptchaController.java => CaptchaController.java} (75%)
 delete mode 100644 src/main/java/com/mnms/booking/controller/MeController.java
 delete mode 100644 src/main/java/com/mnms/booking/controller/QrCodeController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/CaptchaRequestDTO.java
 rename src/main/java/com/mnms/booking/dto/{response/FestivalResponseDTO.java => request/FestivalRequestDTO.java} (69%)
 rename src/main/java/com/mnms/booking/dto/response/{KaptchaResponseDTO.java => CaptchaResponseDTO.java} (84%)
 rename src/main/java/com/mnms/booking/service/{KaptchaService.java => CaptchaService.java} (64%)

diff --git a/.gitignore b/.gitignore
index 224b9b0..dd7c0db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,4 +44,11 @@ logs/
 *.gz
 
 # 힙 덤프 파일
-*.hprof
\ No newline at end of file
+*.hprof
+
+# env
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index cf3d313..8a52b8f 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -25,7 +25,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                 )
                 .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                 .authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/public/**", "/h2-console/**").permitAll() // 하위 경로 포함 허용
+                        .requestMatchers("/public/**", "/h2-console/**", "/api/captcha/**").permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
                 .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
diff --git a/src/main/java/com/mnms/booking/controller/KaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
similarity index 75%
rename from src/main/java/com/mnms/booking/controller/KaptchaController.java
rename to src/main/java/com/mnms/booking/controller/CaptchaController.java
index b5e50fe..16a05cd 100644
--- a/src/main/java/com/mnms/booking/controller/KaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -1,7 +1,7 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.response.KaptchaResponseDTO;
-import com.mnms.booking.service.KaptchaService;
+import com.mnms.booking.dto.response.CaptchaResponseDTO;
+import com.mnms.booking.service.CaptchaService;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
@@ -16,9 +16,9 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/captcha")
-public class KaptchaController {
+public class CaptchaController {
 
-    private final KaptchaService kaptchaService;
+    private final CaptchaService kaptchaService;
 
     @GetMapping("/image")
     public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
@@ -26,11 +26,11 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
     }
 
     @PostMapping("/verify")
-    public ResponseEntity verifyCaptcha(
+    public ResponseEntity verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
 
-        KaptchaResponseDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
+        CaptchaResponseDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
         return result.isSuccess()
                 ? ResponseEntity.ok(result)
                 : ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
diff --git a/src/main/java/com/mnms/booking/controller/MeController.java b/src/main/java/com/mnms/booking/controller/MeController.java
deleted file mode 100644
index 9936433..0000000
--- a/src/main/java/com/mnms/booking/controller/MeController.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.mnms.booking.controller;
-
-import com.mnms.booking.util.JwtPrincipal;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.Map;
-
-@RestController
-@RequestMapping("/me")
-public class MeController {
-
-    @GetMapping
-    public Map me(@AuthenticationPrincipal JwtPrincipal principal) {
-        return Map.of(
-            "userId", principal.userId(),
-            "loginId", principal.loginId(),
-            "roles", principal.roles()
-        );
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
deleted file mode 100644
index c44dc3c..0000000
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.mnms.booking.controller;
-
-import com.mnms.booking.dto.request.QrRequestDTO;
-import com.mnms.booking.service.QrCodeService;
-import lombok.RequiredArgsConstructor;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.time.LocalDateTime;
-
-@RestController
-@RequiredArgsConstructor
-@RequestMapping("/api/qr")
-public class QrCodeController {
-
-    private final QrCodeService qrCodeService;
-
-    // 수정 : qrcode 생성하고 이미지 띄우기
-/*    @GetMapping(value = "/generate", produces = MediaType.IMAGE_PNG_VALUE)
-    public ResponseEntity generateQr(@RequestParam String qrCodeId) throws Exception {
-        QrRequestDTO payload = new QrRequestDTO(
-                qrCodeId,
-                "user1",
-                "ticket4",
-                LocalDateTime.now(), // issuedAt
-                LocalDateTime.now().plusMinutes(30), // expiredAt
-                "9241"
-        );
-        byte[] qrImage = qrCodeService.generateQrImageAsBytes(payload, 300, 300);
-        return ResponseEntity.ok().body(qrImage);
-    }*/
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 2065690..55ee066 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -28,7 +28,6 @@ public class WaitingController {
 
     /**
      * 예매하기 버튼 클릭 시 호출되는 API
-     * userId는 수정할 예정 (추후)
      */
     @GetMapping("/enter")
     @ResponseBody // JSON 응답을 위해 추가
@@ -48,7 +47,6 @@ public ResponseEntity enterBookingPage(@Authentication
     /**
      * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출
      * (이 사용자는 대기열에서 제거됨)
-     * userId는 수정할 예정 (추후)
      */
     @GetMapping("/release")
     public ResponseEntity releaseUser(@AuthenticationPrincipal JwtPrincipal principal) {
@@ -70,7 +68,6 @@ public ResponseEntity releaseUser(@AuthenticationPrincipal JwtPrincipal
     /**
      * 대기열에 있는 사용자가 대기열을 나간다 (예매 입장 아님)
      * (이 사용자는 대기열에서 제거됨)
-     * userId는 수정할 예정 (추후)
      */
     @GetMapping("/exit")
     public ResponseEntity exitWaitingUser(@AuthenticationPrincipal JwtPrincipal principal) {
@@ -92,7 +89,6 @@ public ResponseEntity exitWaitingUser(@AuthenticationPrincipal JwtPrinci
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
-     * userId는 수정할 예정 (추후)
      */
     @MessageMapping("/subscribe/waiting")
     public void subscribeWaitingQueue(@AuthenticationPrincipal JwtPrincipal principal) {
diff --git a/src/main/java/com/mnms/booking/dto/request/CaptchaRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/CaptchaRequestDTO.java
new file mode 100644
index 0000000..da696b0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/CaptchaRequestDTO.java
@@ -0,0 +1,24 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Getter;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+
+// 캡차 정보 DTO
+@Getter
+public class CaptchaRequestDTO {
+    private final String code;
+    private final LocalDateTime creationTime;
+
+    public CaptchaRequestDTO(String code) {
+        this.code = code;
+        this.creationTime = LocalDateTime.now();
+    }
+
+    // 캡차 만료 여부 확인
+    public boolean isExpired(long expirationMillis) {
+        Duration duration = Duration.between(creationTime, LocalDateTime.now());
+        return duration.toMillis() > expirationMillis;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
similarity index 69%
rename from src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java
rename to src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
index cfd4499..d5dd966 100644
--- a/src/main/java/com/mnms/booking/dto/response/FestivalResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
@@ -1,9 +1,11 @@
-package com.mnms.booking.dto.response;
+package com.mnms.booking.dto.request;
 
 import lombok.Data;
 
+import java.time.LocalDate;
+
 @Data
-public class FestivalResponseDTO {
+public class FestivalRequestDTO {
 
     private String mt20id;
 
@@ -11,10 +13,10 @@ public class FestivalResponseDTO {
     private String prfnm;
 
     // 공연 시작일
-    private String prfpdfrom;
+    private LocalDate prfpdfrom;
 
     // 공연 종료일
-    private String prfpdto;
+    private LocalDate prfpdto;
 
     // 공연 시설명
     private String fcltynm;
@@ -23,7 +25,7 @@ public class FestivalResponseDTO {
     private String poster;
 
     // 티켓 비용
-    private String pcseguidance;
+    private int pcseguidance;
 
     // 수용 가능 인원
     private int availableNOP;
diff --git a/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
index 33e447f..a8e8d19 100644
--- a/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/QrRequestDTO.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Data
@@ -15,7 +16,7 @@ public class QrRequestDTO {
     private String qrCodeId;
     private String userId;
     private Ticket ticket;
-    private LocalDateTime issuedAt;
+    private LocalDate issuedAt;
     private LocalDateTime expiredAt;
     private String pinCode;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/CaptchaResponseDTO.java
similarity index 84%
rename from src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java
rename to src/main/java/com/mnms/booking/dto/response/CaptchaResponseDTO.java
index b15ad03..9b948a3 100644
--- a/src/main/java/com/mnms/booking/dto/response/KaptchaResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/CaptchaResponseDTO.java
@@ -5,7 +5,7 @@
 
 @Data // Lombok 사용 시
 @Builder
-public class KaptchaResponseDTO {
+public class CaptchaResponseDTO {
     private boolean success;
     private String message;
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
index 5d217cb..478892a 100644
--- a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -4,6 +4,7 @@
 import com.mnms.booking.entity.QrCode;
 import lombok.*;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Data
@@ -15,8 +16,8 @@ public class QrResponseDTO {
     private Long id;
     private String qrCodeId;
     private Long userId;
-    private LocalDateTime issuedAt;
-    private LocalDateTime expiredAt;
+    private LocalDate issuedAt;
+    private LocalDate expiredAt;
     private Boolean used;
     private LocalDateTime usedAt;
 
@@ -48,8 +49,8 @@ public static QrResponseDTO create(Long userId, String qrCodeId,Festival festiva
         QrResponseDTO dto = new QrResponseDTO();
         dto.setUserId(userId);
         dto.setQrCodeId(qrCodeId);
-        dto.setIssuedAt(LocalDateTime.now());
-        dto.setExpiredAt(festival.getPrfpdto().minusMinutes(30));
+        dto.setIssuedAt(LocalDate.now());
+        dto.setExpiredAt(festival.getPrfpdto());
         return dto;
     }
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index fd2f490..3050e65 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -4,7 +4,8 @@
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.TicketType;
 import lombok.*;
-import java.time.LocalDateTime;
+
+import java.time.LocalDate;
 
 @Data
 @Builder
@@ -14,9 +15,9 @@ public class TicketResponseDTO {
     private String reservationNumber;
     private Boolean reservationStatus;
     private TicketType deliveryMethod;
-    private LocalDateTime deliveryDate;
+    private LocalDate deliveryDate;
     private Long userId;
-    private LocalDateTime reservationDate;
+    private LocalDate reservationDate;
     private QrResponseDTO qrCode;
     private Festival festival;
 
@@ -24,6 +25,7 @@ public static TicketResponseDTO fromEntity(Ticket ticket) {
         return TicketResponseDTO.builder()
                 .id(ticket.getId())
                 .reservationNumber(ticket.getReservationNumber())
+                .reservationStatus(ticket.getReservationStatus())
                 .deliveryMethod(ticket.getDeliveryMethod())
                 .deliveryDate(ticket.getDeliveryDate())
                 .reservationDate(ticket.getReservationDate())
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 5ff3ee7..b536a2d 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -3,6 +3,7 @@
 import jakarta.persistence.*;
 import lombok.Getter;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Entity
@@ -14,10 +15,10 @@ public class Festival {
     private Long id; // festival_id
     private String name; // 이름
     private String frame; // frame
-    private LocalDateTime prfpdfrom; // 시작일
-    private LocalDateTime prfpdto; // 종료일
+    private LocalDate prfpdfrom; // 시작일
+    private LocalDate prfpdto; // 종료일
     private String poster; // 포스터
-    private String ticketPrice; // 가격
+    private int ticketPrice; // 가격
     private int availableNOp; // 수용 가능 인원
     private String area; // 장소
     private int paper; // 지류 여부
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index 65f0da9..ff30545 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -3,6 +3,8 @@
 import jakarta.persistence.*;
 import lombok.Builder;
 import lombok.Getter;
+
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Entity
@@ -19,10 +21,10 @@ public class QrCode {
     private String qrCodeId;
 
     @Column(name = "issued_at", nullable = false)
-    private LocalDateTime issuedAt;
+    private LocalDate issuedAt;
 
     @Column(name = "expired_at", nullable = false)
-    private LocalDateTime expiredAt;
+    private LocalDate expiredAt;
 
     @Column(name = "used", nullable = false)
     private Boolean used;
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 524fe06..617eb87 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -4,6 +4,8 @@
 import lombok.Builder;
 import lombok.Getter;
 import jakarta.persistence.Id;
+
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Entity
@@ -28,10 +30,10 @@ public class Ticket {
     private Long userId; // 예매자 id
 
     @Column(name = "reservation_date")
-    private LocalDateTime reservationDate; // 예매 날짜
+    private LocalDate reservationDate; // 예매 날짜
 
     @Column(name = "delivery_date")
-    private LocalDateTime deliveryDate; // 택배 날짜
+    private LocalDate deliveryDate; // 택배 날짜
 
     @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private QrCode qrCode;
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index b56fb95..4188178 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -6,8 +6,20 @@
 @Getter
 public enum ErrorCode {
 
-    FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND);
+    // FESTIVAL
+    FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
+    FESTIVAL_INVALID_DATE("F002", "공연 시작일을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    FESTIVAL_DELIVERY_INVALID("F003", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
 
+    // TICKET
+    TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
+
+    // QR
+    QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    QR_CODE_ID_GENERATION_FAILED("Q002", "QR 코드 ID 생성을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    QR_IMAGE_GENERATION_FAILED("Q003", "QR 이미지 생성 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    QR_IMAGE_CONVERSION_FAILED("Q004", "QR 이미지 데이터를 변환하는 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    QR_PAYLOAD_SERIALIZATION_FAILED("Q005", "QR 코드 데이터를 직렬화하는 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 2d58c45..c6b5267 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -6,4 +6,5 @@
 
 @Repository
 public interface TicketRepository extends JpaRepository {
+    boolean existsByUserIdAndFestivalId(Long userId, Long festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index 138c24d..cf0245a 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -7,6 +7,8 @@
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.TicketType;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
@@ -14,7 +16,7 @@
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
-import java.time.LocalDateTime;
+import java.time.LocalDate;
 import java.util.UUID;
 
 @Service
@@ -30,32 +32,82 @@ public class BookingService {
     public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
         // 페스티벌 정보 조회
         Festival festival = festivalRepository.findById(request.getFestivalId())
-                .orElseThrow(() -> new IllegalArgumentException("Festival not found"));
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
-        // 티켓 택배 날짜
-        LocalDateTime deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), festival);
+        // 해당 사용자가 이미 같은 페스티벌에 티켓을 예약했는지 확인
+        validateReservation(userId, request);
+        LocalDate deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), festival);
 
         // Qr정보 생성
-        String qrCodeId = qrCodeService.generateQrCodeId();
-        QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival);
-        QrCode qrCode = qrResponse.toEntity();
-        qrCodeRepository.save(qrCode);
+        QrCode qrCode = createAndSaveQrCode(userId, festival);
 
         // Ticket 저장 (reservation number 자동 래덤 생성됨)
-        Ticket ticket = Ticket.builder()
+        Ticket ticket = buildTicket(request, userId, festival, deliveryDate, qrCode);
+        ticketRepository.save(ticket);
+
+        // 응답
+        return TicketResponseDTO.fromEntity(ticket);
+    }
+
+    private void validateReservation(Long userId,TicketRequestDTO request) {
+
+        if (ticketRepository.existsByUserIdAndFestivalId(userId, request.getFestivalId())) {
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+        if (request.getDeliveryMethod() == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
+        }
+    }
+
+    // deliveryDate 생성
+    private LocalDate calculateDeliveryDate(TicketType deliveryMethod, Festival festival) {
+        // 지류 티켓일 경우
+        if (festival.getPrfpdfrom() == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+
+        if (deliveryMethod == TicketType.PAPER && festival.getPrfpdto() != null) {
+            LocalDate deliveryDate = festival.getPrfpdfrom().minusDays(14);
+            return deliveryDate.isAfter(LocalDate.now())
+                    ? deliveryDate
+                    : LocalDate.now().plusDays(1);
+        }
+
+        // 모바일 티켓일 경우
+        return null;
+    }
+
+    // Qr정보 생성
+    private QrCode createAndSaveQrCode(Long userId, Festival festival) {
+        try {
+            String qrCodeId = qrCodeService.generateQrCodeId();
+            if (qrCodeId == null || qrCodeId.isEmpty()) {
+                throw new BusinessException(ErrorCode.QR_CODE_ID_GENERATION_FAILED);
+            }
+            QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival);
+            QrCode qrCode = qrResponse.toEntity();
+            qrCodeRepository.save(qrCode);
+            return qrCode;
+        } catch (BusinessException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new BusinessException(ErrorCode.QR_CODE_SAVE_FAILED);
+        }
+    }
+
+    // Ticket 저장
+    private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festival,
+                               LocalDate deliveryDate, QrCode qrCode) {
+        return Ticket.builder()
                 .reservationNumber(generateReservationNumber())
                 .reservationStatus(true)
                 .deliveryMethod(request.getDeliveryMethod())
-                .reservationDate(LocalDateTime.now())
+                .reservationDate(LocalDate.now())
                 .deliveryDate(deliveryDate)
                 .festival(festival)
                 .qrCode(qrCode)
                 .userId(userId)
                 .build();
-        ticketRepository.save(ticket);
-
-        // 응답
-        return TicketResponseDTO.fromEntity(ticket);
     }
 
     // reservation number 랜덤 생성
@@ -64,14 +116,4 @@ private String generateReservationNumber() {
         String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
         return "T" + uuidPart;
     }
-
-    // deliverydate 생성
-    private LocalDateTime calculateDeliveryDate(TicketType deliveryMethod, Festival festival) {
-        // 지류 티켓일 경우
-        if (deliveryMethod == TicketType.PAPER && festival.getPrfpdto() != null) {
-            return festival.getPrfpdto().minusDays(14);
-        }
-        // mobile일 경우
-        return null;
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/KaptchaService.java b/src/main/java/com/mnms/booking/service/CaptchaService.java
similarity index 64%
rename from src/main/java/com/mnms/booking/service/KaptchaService.java
rename to src/main/java/com/mnms/booking/service/CaptchaService.java
index 8213436..7ca0407 100644
--- a/src/main/java/com/mnms/booking/service/KaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/CaptchaService.java
@@ -1,7 +1,8 @@
 package com.mnms.booking.service;
 
 import com.google.code.kaptcha.impl.DefaultKaptcha;
-import com.mnms.booking.dto.response.KaptchaResponseDTO;
+import com.mnms.booking.dto.request.CaptchaRequestDTO;
+import com.mnms.booking.dto.response.CaptchaResponseDTO;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
@@ -15,10 +16,12 @@
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class KaptchaService {
+public class CaptchaService {
 
     private final DefaultKaptcha captchaProducer;
     private static final String CAPTCHA_SESSION_KEY = "captchaCode";
+    private static final long CAPTCHA_EXPIRATION_MILLIS = 3 * 60 * 1000L;
+
 
     // 캡차 이미지 생성
     public void writeCaptchaImage(HttpSession session, HttpServletResponse response) throws IOException {
@@ -39,19 +42,26 @@ public void writeCaptchaImage(HttpSession session, HttpServletResponse response)
 
     private BufferedImage generateCaptchaImage(HttpSession session) {
         String captchaText = captchaProducer.createText();
-        session.setAttribute(CAPTCHA_SESSION_KEY, captchaText);
+        session.setAttribute(CAPTCHA_SESSION_KEY, new CaptchaRequestDTO(captchaText));
         log.info("Generated Kaptcha Text: {}", captchaText);
-
         return captchaProducer.createImage(captchaText);
     }
 
-    public KaptchaResponseDTO verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
-        String sessionCaptcha = (String) session.getAttribute(CAPTCHA_SESSION_KEY);
+    public CaptchaResponseDTO verifyCaptchaResult(String userInputCaptcha, HttpSession session) {
+        CaptchaRequestDTO captchaRequest = (CaptchaRequestDTO) session.getAttribute(CAPTCHA_SESSION_KEY);
+
+        if (captchaRequest == null || captchaRequest.isExpired(CAPTCHA_EXPIRATION_MILLIS)) { // 3분 만료
+            session.removeAttribute(CAPTCHA_SESSION_KEY);
+            return CaptchaResponseDTO.builder()
+                    .success(false)
+                    .message("보안문자가 만료되었습니다.")
+                    .build();
+        }
 
-        boolean isValid = sessionCaptcha != null && sessionCaptcha.equalsIgnoreCase(userInputCaptcha);
+        boolean isValid = captchaRequest.getCode().equalsIgnoreCase(userInputCaptcha);
         if (isValid) {session.removeAttribute(CAPTCHA_SESSION_KEY);}
 
-        return KaptchaResponseDTO.builder()
+        return CaptchaResponseDTO.builder()
                 .success(isValid)
                 .message(isValid ? "인증 성공" : "보안문자 불일치")
                 .build();
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index e02fd4b..e421952 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -1,11 +1,15 @@
 package com.mnms.booking.service;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
 import com.google.zxing.client.j2se.MatrixToImageWriter;
 import com.google.zxing.common.BitMatrix;
 import com.google.zxing.qrcode.QRCodeWriter;
 import com.mnms.booking.dto.request.QrRequestDTO;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.QrCodeRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
@@ -39,10 +43,18 @@ public String generateQrCodeId() {
 
     //
     public BufferedImage generateQrImage(QrRequestDTO payload, int width, int height) throws Exception {
-        String json = objectMapper.writeValueAsString(payload);
-        QRCodeWriter qrCodeWriter = new QRCodeWriter();
-        BitMatrix bitMatrix = qrCodeWriter.encode(json, BarcodeFormat.QR_CODE, width, height);
-        return MatrixToImageWriter.toBufferedImage(bitMatrix);
+        try {
+            String json = objectMapper.writeValueAsString(payload);
+            QRCodeWriter qrCodeWriter = new QRCodeWriter();
+            BitMatrix bitMatrix = qrCodeWriter.encode(json, BarcodeFormat.QR_CODE, width, height);
+            return MatrixToImageWriter.toBufferedImage(bitMatrix);
+        } catch (JsonProcessingException e) {
+            throw new BusinessException(ErrorCode.QR_PAYLOAD_SERIALIZATION_FAILED);
+        } catch (WriterException e) {
+            throw new BusinessException(ErrorCode.QR_IMAGE_GENERATION_FAILED);
+        } catch (Exception e) {
+            throw new BusinessException(ErrorCode.QR_IMAGE_CONVERSION_FAILED);
+        }
     }
 
     public byte[] generateQrImageAsBytes(QrRequestDTO payload, int width, int height) throws Exception {
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index aaab099..b484185 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -25,13 +25,19 @@ spring.redis.port=6379
 # kafka
 app.kafka.topic.booking-event=booking-events
 app.kafka.topic.user-event: user-events
-spring.kafka.bootstrap-servers=192.168.0.141:9094
+
+spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 #spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
 spring.kafka.consumer.properties.spring.json.use.type.headers=false
 
+# kafka 사용 X
+#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
+
 # jwt
 jwt.public-pem-path=classpath:keys/public.pem
-jwt.issuer=festival-user-service
\ No newline at end of file
+jwt.issuer=festival-user-service
+
+spring.config.import=optional:file:.env[.properties]
\ No newline at end of file

From 69f68af987ac8573288d4088082c69aff147194e Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 9 Aug 2025 16:06:49 +0900
Subject: [PATCH 015/149] =?UTF-8?q?MNMS-282=20feat:=20Swagger=20=EC=A0=81?=
 =?UTF-8?q?=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

http://localhost:8082/swagger-ui/index.html
---
 build.gradle                                  |  2 +
 .../mnms/booking/config/SecurityConfig.java   |  7 ++-
 .../booking/controller/BookingController.java | 18 +++++-
 .../booking/controller/CaptchaController.java | 12 ++++
 .../booking/controller/WaitingController.java | 55 ++++++++++++-------
 .../booking/dto/request/TicketRequestDTO.java |  2 -
 .../mnms/booking/service/CaptchaService.java  |  2 +-
 .../resources/application-test.properties     |  8 ++-
 8 files changed, 79 insertions(+), 27 deletions(-)

diff --git a/build.gradle b/build.gradle
index 16f1079..ae1dec7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -77,6 +77,8 @@ dependencies {
 	implementation 'com.google.zxing:javase:3.5.2'
 	implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
 
+	// swagger
+	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 8a52b8f..c52cd05 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -25,7 +25,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                 )
                 .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                 .authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/public/**", "/h2-console/**", "/api/captcha/**").permitAll() // 하위 경로 포함 허용
+                        .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
+                        .requestMatchers(
+                                "/public/**",
+                                "/h2-console/**",
+                                "/api/captcha/**"
+                                ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
                 .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index b8526fd..e2db8af 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -4,8 +4,14 @@
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.service.BookingService;
 import com.mnms.booking.util.JwtPrincipal;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -15,14 +21,20 @@
 
 @RestController
 @RequiredArgsConstructor
-@Slf4j
 @RequestMapping("/api/tickets")
+@Tag(name = "예매 API", description = "예매 티켓 생성")
 public class BookingController {
 
     private final BookingService bookingService;
 
     @PostMapping("/reserve")
-    public ResponseEntity reserveTicket(@RequestBody TicketRequestDTO request, @AuthenticationPrincipal JwtPrincipal principal){
+    @Operation(summary = "페스티벌 예매 티켓 생성",
+            description = "사용자가 특정 페스티벌 티켓 예매를 완료합니다."
+    )
+    public ResponseEntity reserveTicket(
+            @Valid @RequestBody TicketRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
         TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
         return ResponseEntity.ok(response);
     }
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
index 16a05cd..85df93c 100644
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -2,6 +2,8 @@
 
 import com.mnms.booking.dto.response.CaptchaResponseDTO;
 import com.mnms.booking.service.CaptchaService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
@@ -16,16 +18,26 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/captcha")
+@Tag(name = "보안문자 API", description = "보안문자 생성 및 인증")
 public class CaptchaController {
 
     private final CaptchaService kaptchaService;
 
     @GetMapping("/image")
+    @Operation(
+            summary = "보안문자 이미지 요청",
+            description = "새로운 보안문자 이미지를 생성하여 반환합니다."
+    )
     public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
         kaptchaService.writeCaptchaImage(request.getSession(), response);
     }
 
     @PostMapping("/verify")
+    @Operation(
+            summary = "보안문자 검증",
+            description = "사용자가 입력한 보안문자 값이 올바른지 검증합니다. " +
+                    "보안문자는 다섯 글자이며 대소문자 구분하지 않습니다. 만료시간은 3분이고, 불일치로 실패해도 만료시간 내에 입력하면 인증 가능합니다."
+    )
     public ResponseEntity verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 55ee066..b9fed52 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -2,6 +2,10 @@
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import com.mnms.booking.util.JwtPrincipal;
+import io.swagger.v3.oas.annotations.Hidden;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -15,9 +19,10 @@
 import com.mnms.booking.service.WaitingService;
 
 @Controller
-@RequiredArgsConstructor
 @Slf4j
+@RequiredArgsConstructor
 @RequestMapping("/api/booking")
+@Tag(name = "대기열 API", description = "대기열 입장, 예매 화면 입장, 대기번호 조회(websocket), 대기열 퇴장")
 public class WaitingController {
 
     private final WaitingService waitingService;
@@ -26,30 +31,36 @@ public class WaitingController {
     private SimpMessagingTemplate messagingTemplate;
 
 
-    /**
-     * 예매하기 버튼 클릭 시 호출되는 API
-     */
+    // 예매하기 버튼 클릭 시 호출되는 API
     @GetMapping("/enter")
-    @ResponseBody // JSON 응답을 위해 추가
-    public ResponseEntity enterBookingPage(@AuthenticationPrincipal JwtPrincipal principal) {
-        String loginId = principal.loginId();
+    @ResponseBody
+    @Operation(summary = "대기열/예매 페이지 진입",
+            description = "페스티벌 수용 인원만큼 예매 페이지 진입하며," +
+                    "나머지 사용자는 대기열에 들어가 대기하게 됩니다.")
+    public ResponseEntity enterBookingPage(
+            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
+
+        String loginId = (principal != null) ? principal.loginId() : "swagger-test-user";
         long waitingNumber = waitingService.enterWaitingQueue(loginId);
 
         if (waitingNumber == 0) {
-            // 즉시 입장 가능한 경우
             return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
-            // 대기열에 진입한 경우
             return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
 
-    /**
-     * 대기열에 있는 사용자가 예매 페이지로 진입 완료 후 호출
-     * (이 사용자는 대기열에서 제거됨)
-     */
+
+    // 예매 페이지 퇴장 - 대기열 대기자 예매 페이지 진입 (추후 수정 가능)
     @GetMapping("/release")
-    public ResponseEntity releaseUser(@AuthenticationPrincipal JwtPrincipal principal) {
+    @Operation(
+            summary = "예매 페이지 진입 완료 처리",
+            description = "예매 페이지에 있던 사용자가 예매 페이지에서 나가면, " +
+                    "대기열에 있던 사용자가 예매 페이지로 입장 하게 됩니다. " +
+                    "대기열에 있던 모든 대기자의 대기번호가 변경됩니다."
+    )
+    public ResponseEntity releaseUser(
+            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         try {
             boolean removed = waitingService.userExitBookingPage(loginId);
@@ -65,12 +76,16 @@ public ResponseEntity releaseUser(@AuthenticationPrincipal JwtPrincipal
         }
     }
 
-    /**
-     * 대기열에 있는 사용자가 대기열을 나간다 (예매 입장 아님)
-     * (이 사용자는 대기열에서 제거됨)
-     */
+
+    // 대기열에서 퇴장
+    @Operation(
+            summary = "대기열 퇴장",
+            description = "대기 중인 사용자가 스스로 대기열에서 나갈 때 호출됩니다. " +
+                    "호출 시 해당 사용자는 대기열에서 제거됩니다."
+    )
     @GetMapping("/exit")
-    public ResponseEntity exitWaitingUser(@AuthenticationPrincipal JwtPrincipal principal) {
+    public ResponseEntity exitWaitingUser(
+            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         try {
             boolean removed = waitingService.removeUserFromQueue(loginId);
@@ -86,10 +101,12 @@ public ResponseEntity exitWaitingUser(@AuthenticationPrincipal JwtPrinci
         }
     }
 
+
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
      */
+    @Hidden
     @MessageMapping("/subscribe/waiting")
     public void subscribeWaitingQueue(@AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
index eaf9927..7fb3375 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -6,8 +6,6 @@
 @Data
 public class TicketRequestDTO {
 
-    //private Long id;
-    //private String userId;
     private Long festivalId;
     private TicketType deliveryMethod;
 
diff --git a/src/main/java/com/mnms/booking/service/CaptchaService.java b/src/main/java/com/mnms/booking/service/CaptchaService.java
index 7ca0407..83f611b 100644
--- a/src/main/java/com/mnms/booking/service/CaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/CaptchaService.java
@@ -63,7 +63,7 @@ public CaptchaResponseDTO verifyCaptchaResult(String userInputCaptcha, HttpSessi
 
         return CaptchaResponseDTO.builder()
                 .success(isValid)
-                .message(isValid ? "인증 성공" : "보안문자 불일치")
+                .message(isValid ? "보안문자 인증되었습니다." : "보안문자 불일치로 인증이 실패하였습니다.")
                 .build();
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index b484185..f535e96 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -40,4 +40,10 @@ spring.kafka.consumer.properties.spring.json.use.type.headers=false
 jwt.public-pem-path=classpath:keys/public.pem
 jwt.issuer=festival-user-service
 
-spring.config.import=optional:file:.env[.properties]
\ No newline at end of file
+spring.config.import=optional:file:.env[.properties]
+
+# swagger
+springdoc.api-docs.enabled=true
+springdoc.swagger-ui.enabled=true
+springdoc.swagger-ui.path=/swagger-ui.html
+springdoc.override-with-generic-response=false
\ No newline at end of file

From 12b1ca972082217df68ab5a58bc73da60d47f9f1 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 9 Aug 2025 23:11:11 +0900
Subject: [PATCH 016/149] =?UTF-8?q?MNMS-282=20feat:=20QR=20=EA=B8=B0?=
 =?UTF-8?q?=EB=8A=A5=20=EB=B0=8F=20ticket=20entity=20=EC=88=98=EC=A0=95=20?=
 =?UTF-8?q?=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

QR : QR 이미지 조회, 주최측 QR 스캔
TICKET : 티켓 performanceDate, performanceTime, selectedTicketCount 추가
TICKET : 티켓 개수 제한
추후 : kafka로 결제 완료 메시지 발행했을 때, Consumer로 받아서 하나씩 순차 처리 수행
---
 ...{KaptchaConfig.java => CaptchaConfig.java} |  2 +-
 .../mnms/booking/config/SecurityConfig.java   |  3 +-
 .../booking/controller/QrCodeController.java  | 58 ++++++++++++++
 .../booking/dto/request/TicketRequestDTO.java |  7 ++
 .../booking/dto/response/QrResponseDTO.java   |  6 +-
 .../com/mnms/booking/entity/Festival.java     |  2 +-
 .../java/com/mnms/booking/entity/QrCode.java  | 21 ++++-
 .../java/com/mnms/booking/entity/Ticket.java  | 25 ++++--
 .../com/mnms/booking/exception/ErrorCode.java | 11 ++-
 .../booking/repository/QrCodeRepository.java  |  3 +
 .../booking/repository/TicketRepository.java  |  2 +-
 .../mnms/booking/service/BookingService.java  | 49 +++++++-----
 .../mnms/booking/service/QrCodeService.java   | 80 +++++++++++++------
 13 files changed, 210 insertions(+), 59 deletions(-)
 rename src/main/java/com/mnms/booking/config/{KaptchaConfig.java => CaptchaConfig.java} (97%)
 create mode 100644 src/main/java/com/mnms/booking/controller/QrCodeController.java

diff --git a/src/main/java/com/mnms/booking/config/KaptchaConfig.java b/src/main/java/com/mnms/booking/config/CaptchaConfig.java
similarity index 97%
rename from src/main/java/com/mnms/booking/config/KaptchaConfig.java
rename to src/main/java/com/mnms/booking/config/CaptchaConfig.java
index 9427c09..4718b8d 100644
--- a/src/main/java/com/mnms/booking/config/KaptchaConfig.java
+++ b/src/main/java/com/mnms/booking/config/CaptchaConfig.java
@@ -8,7 +8,7 @@
 import java.util.Properties;
 
 @Configuration
-public class KaptchaConfig {
+public class CaptchaConfig {
 
     @Bean
     public DefaultKaptcha captchaProducer() {
diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index c52cd05..0ec33fe 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -29,7 +29,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                         .requestMatchers(
                                 "/public/**",
                                 "/h2-console/**",
-                                "/api/captcha/**"
+                                "/api/captcha/**",
+                                "/api/qr/**"
                                 ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
new file mode 100644
index 0000000..62a0c67
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -0,0 +1,58 @@
+package com.mnms.booking.controller;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.QRCodeWriter;
+import com.mnms.booking.dto.request.QrRequestDTO;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.service.QrCodeService;
+import com.mnms.booking.util.JwtPrincipal;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+
+import java.time.LocalDateTime;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/qr")
+@Tag(name = "QR API", description = "QR 이미지 조회, 스캔, ")
+public class QrCodeController {
+
+    private final QrCodeService qrCodeService;
+
+    /// Qrcode 이미지 조회
+    @GetMapping(value = "/image/{qrCodeId}", produces = MediaType.IMAGE_PNG_VALUE)
+    @Operation(summary = "QR 코드 이미지 조회",
+            description = "qrCodeId로 QR 코드 이미지를 PNG 형식으로 반환합니다.")
+    public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
+        QrCode qrCode = qrCodeService.getQrCodeByCode(qrCodeId);
+        String qrCodeText = qrCode.getQrCodeId();
+
+        try {
+            byte[] imageBytes = qrCodeService.generateQrCodeImage(qrCodeText, 250, 250);
+            return ResponseEntity.ok().contentType(MediaType.IMAGE_PNG).body(imageBytes);
+        } catch (Exception e) {
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
+        }
+    }
+
+    /// 페스티벌 주최자 QR 스캔
+    @PostMapping(value = "/validate/{qrCodeId}")
+    @Operation(summary = "QR 코드 스캔 및 유효성 검사",
+            description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
+    public ResponseEntity validateAndUseQrCode(
+            @PathVariable String qrCodeId,
+            @AuthenticationPrincipal JwtPrincipal principal) {
+
+        qrCodeService.validateAndUseQrCode(principal.userId(), qrCodeId);
+        return ResponseEntity.ok().build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
index 7fb3375..03f9846 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -1,12 +1,19 @@
 package com.mnms.booking.dto.request;
 
 import com.mnms.booking.entity.TicketType;
+import jakarta.persistence.Column;
 import lombok.Data;
 
+import java.time.LocalDate;
+import java.time.LocalTime;
+
 @Data
 public class TicketRequestDTO {
 
     private Long festivalId;
+    private int selectedTicketCount; // <= Festival.maxTicketsPerUser
+    private LocalDate performanceDate;
+    private LocalTime performanceTime;
     private TicketType deliveryMethod;
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
index 478892a..a281930 100644
--- a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
 import lombok.*;
 
 import java.time.LocalDate;
@@ -20,6 +21,7 @@ public class QrResponseDTO {
     private LocalDate expiredAt;
     private Boolean used;
     private LocalDateTime usedAt;
+    private Ticket ticket;
 
     public static QrResponseDTO fromEntity(QrCode qrCode) {
         return QrResponseDTO.builder()
@@ -42,15 +44,17 @@ public QrCode toEntity() {
                 .used(this.used != null ? this.used : false) // 기본값 처리
                 .usedAt(this.usedAt)
                 .userId(this.userId)
+                .ticket(this.ticket)
                 .build();
     }
 
-    public static QrResponseDTO create(Long userId, String qrCodeId,Festival festival) {
+    public static QrResponseDTO create(Long userId, String qrCodeId,Festival festival, Ticket ticket) {
         QrResponseDTO dto = new QrResponseDTO();
         dto.setUserId(userId);
         dto.setQrCodeId(qrCodeId);
         dto.setIssuedAt(LocalDate.now());
         dto.setExpiredAt(festival.getPrfpdto());
+        dto.setTicket(ticket);
         return dto;
     }
 }
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index b536a2d..a3f04c4 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -22,5 +22,5 @@ public class Festival {
     private int availableNOp; // 수용 가능 인원
     private String area; // 장소
     private int paper; // 지류 여부
-
+    private int maxTicketsPerUser; // 한 사람당 최대 예매 티켓 수
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index ff30545..d203ae5 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -1,8 +1,7 @@
 package com.mnms.booking.entity;
 
 import jakarta.persistence.*;
-import lombok.Builder;
-import lombok.Getter;
+import lombok.*;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -10,6 +9,8 @@
 @Entity
 @Getter
 @Builder
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
 @Table(name = "qr_code")
 public class QrCode {
 
@@ -37,4 +38,20 @@ public class QrCode {
 
     @OneToOne(fetch = FetchType.LAZY)
     private Ticket ticket; // ticket_id
+
+    // 비지니스 로직
+    public void markAsUsed() {
+        if (this.used) {
+            throw new IllegalStateException("이미 사용된 QR 코드입니다.");
+        }
+        if (isExpired()) {
+            throw new IllegalStateException("QR 코드의 유효기간이 지났습니다.");
+        }
+        this.used = true;
+        this.usedAt = LocalDateTime.now();
+    }
+
+    private boolean isExpired() {
+        return LocalDate.now().isAfter(this.expiredAt);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 617eb87..89a286f 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -1,17 +1,18 @@
 package com.mnms.booking.entity;
 
 import jakarta.persistence.*;
-import lombok.Builder;
-import lombok.Getter;
+import lombok.*;
 import jakarta.persistence.Id;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
 
 @Entity
-@Builder
-@Getter
+@Builder @Getter
 @Table(name = "ticket")
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+@AllArgsConstructor
 public class Ticket {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
@@ -30,15 +31,29 @@ public class Ticket {
     private Long userId; // 예매자 id
 
     @Column(name = "reservation_date")
-    private LocalDate reservationDate; // 예매 날짜
+    private LocalDate reservationDate; // 예매한 날짜
 
     @Column(name = "delivery_date")
     private LocalDate deliveryDate; // 택배 날짜
 
+    @Column(name = "performance_date")
+    private LocalDate performanceDate; // 선택한 공연 날짜
+
+    @Column(name = "performance_time")
+    private LocalTime performanceTime; // 선택한 공연 시간
+
+    @Column(name = "selected_ticket_count")
+    private int selectedTicketCount;
+
     @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private QrCode qrCode;
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "festival_id")
     private Festival festival;
+
+    // setter
+    public void setQrCode(QrCode qrCode){
+        this.qrCode= qrCode;
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 4188178..8877663 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -8,8 +8,9 @@ public enum ErrorCode {
 
     // FESTIVAL
     FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
-    FESTIVAL_INVALID_DATE("F002", "공연 시작일을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     FESTIVAL_DELIVERY_INVALID("F003", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
+    FESTIVAL_MISMATCH("F004", "해당하는 FESTIVAL QR 코드가 아닙니다.", HttpStatus.FORBIDDEN),
 
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
@@ -17,9 +18,11 @@ public enum ErrorCode {
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
     QR_CODE_ID_GENERATION_FAILED("Q002", "QR 코드 ID 생성을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
-    QR_IMAGE_GENERATION_FAILED("Q003", "QR 이미지 생성 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
-    QR_IMAGE_CONVERSION_FAILED("Q004", "QR 이미지 데이터를 변환하는 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
-    QR_PAYLOAD_SERIALIZATION_FAILED("Q005", "QR 코드 데이터를 직렬화하는 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
+    QR_CODE_NOT_FOUND("Q003", "QR 코드를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    QR_CODE_INVALID("Q004", "QR 코드가 유효하지 않습니다.", HttpStatus.BAD_REQUEST),
+    QR_CODE_EXPIRED("Q005", "QR 코드의 만료일이 지났습니다.", HttpStatus.GONE),
+    QR_CODE_ALREADY_USED("Q006", "QR 코드가 이미 사용되었습니다.", HttpStatus.CONFLICT);
+
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index 40e1581..5dd5a88 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -4,9 +4,12 @@
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.Optional;
+
 @Repository
 public interface QrCodeRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
+    Optional findByQrCodeId(String qrCodeId);
 }
 
 
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index c6b5267..ffb2aba 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -6,5 +6,5 @@
 
 @Repository
 public interface TicketRepository extends JpaRepository {
-    boolean existsByUserIdAndFestivalId(Long userId, Long festivalId);
+    int countByUserIdAndFestivalId(Long userId, Long festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index cf0245a..947da77 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -34,57 +34,64 @@ public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
         Festival festival = festivalRepository.findById(request.getFestivalId())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
-        // 해당 사용자가 이미 같은 페스티벌에 티켓을 예약했는지 확인
-        validateReservation(userId, request);
-        LocalDate deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), festival);
-
-        // Qr정보 생성
-        QrCode qrCode = createAndSaveQrCode(userId, festival);
+        // 사용자 예약 티켓 매수, 지류티켓 확인
+        validateReservation(userId, request, festival);
+        LocalDate deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), request);
 
         // Ticket 저장 (reservation number 자동 래덤 생성됨)
-        Ticket ticket = buildTicket(request, userId, festival, deliveryDate, qrCode);
+        Ticket ticket = buildTicket(request, userId, festival, deliveryDate);
+
+        // QR 생성 (Ticket 포함)
+        QrCode qrCode = createAndSaveQrCode(userId, festival, ticket);
+
+        // Ticket에 QR 세팅 후 저장
+        ticket.setQrCode(qrCode);
         ticketRepository.save(ticket);
 
         // 응답
         return TicketResponseDTO.fromEntity(ticket);
     }
 
-    private void validateReservation(Long userId,TicketRequestDTO request) {
+    private void validateReservation(Long userId, TicketRequestDTO request, Festival festival) {
+
+        int alreadyReservedCount = ticketRepository.countByUserIdAndFestivalId(userId, festival.getId());
+        int reservedCount = request.getSelectedTicketCount() + alreadyReservedCount;
 
-        if (ticketRepository.existsByUserIdAndFestivalId(userId, request.getFestivalId())) {
+        // 티켓 개수 초과
+        if ( reservedCount > festival.getMaxTicketsPerUser()) {
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
+
+        // 배송 방법 유효성 검사
         if (request.getDeliveryMethod() == null) {
             throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
         }
     }
 
     // deliveryDate 생성
-    private LocalDate calculateDeliveryDate(TicketType deliveryMethod, Festival festival) {
+    private LocalDate calculateDeliveryDate(TicketType deliveryMethod, TicketRequestDTO request) {
         // 지류 티켓일 경우
-        if (festival.getPrfpdfrom() == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        if (request.getPerformanceDate() == null || request.getPerformanceTime() == null) {
+                throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
         }
-
-        if (deliveryMethod == TicketType.PAPER && festival.getPrfpdto() != null) {
-            LocalDate deliveryDate = festival.getPrfpdfrom().minusDays(14);
+        if (deliveryMethod == TicketType.PAPER) {
+            LocalDate deliveryDate = request.getPerformanceDate().minusDays(14);
             return deliveryDate.isAfter(LocalDate.now())
                     ? deliveryDate
                     : LocalDate.now().plusDays(1);
         }
-
         // 모바일 티켓일 경우
         return null;
     }
 
     // Qr정보 생성
-    private QrCode createAndSaveQrCode(Long userId, Festival festival) {
+    private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
         try {
             String qrCodeId = qrCodeService.generateQrCodeId();
             if (qrCodeId == null || qrCodeId.isEmpty()) {
                 throw new BusinessException(ErrorCode.QR_CODE_ID_GENERATION_FAILED);
             }
-            QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival);
+            QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival, ticket);
             QrCode qrCode = qrResponse.toEntity();
             qrCodeRepository.save(qrCode);
             return qrCode;
@@ -97,15 +104,17 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival) {
 
     // Ticket 저장
     private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festival,
-                               LocalDate deliveryDate, QrCode qrCode) {
+                               LocalDate deliveryDate) { // , QrCode qrCode
         return Ticket.builder()
                 .reservationNumber(generateReservationNumber())
                 .reservationStatus(true)
                 .deliveryMethod(request.getDeliveryMethod())
                 .reservationDate(LocalDate.now())
                 .deliveryDate(deliveryDate)
+                .performanceDate(request.getPerformanceDate())
+                .performanceTime(request.getPerformanceTime())
+                .selectedTicketCount(request.getSelectedTicketCount())
                 .festival(festival)
-                .qrCode(qrCode)
                 .userId(userId)
                 .build();
     }
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index e421952..5000732 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -8,16 +8,22 @@
 import com.google.zxing.common.BitMatrix;
 import com.google.zxing.qrcode.QRCodeWriter;
 import com.mnms.booking.dto.request.QrRequestDTO;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.QrCodeRepository;
+import jakarta.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.security.SecureRandom;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.Base64;
 
 @Service
@@ -27,11 +33,11 @@ public class QrCodeService {
     private final ObjectMapper objectMapper;
     private final QrCodeRepository qrCodeRepository;
 
-    // QrCodeId 생성
+    /// QrCodeId 생성
     private static final SecureRandom secureRandom = new SecureRandom();
     private static final String HEX_CHARS = "0123456789abcdef";
 
-    // QrCodeId : 32자리의 UUID-like 문자열 생성
+    /// QrCodeId : 32자리의 UUID-like 문자열 생성
     public String generateQrCodeId() {
         StringBuilder sb = new StringBuilder(32);
         for (int i = 0; i < 32; i++) {
@@ -41,31 +47,59 @@ public String generateQrCodeId() {
         return sb.toString();
     }
 
-    //
-    public BufferedImage generateQrImage(QrRequestDTO payload, int width, int height) throws Exception {
-        try {
-            String json = objectMapper.writeValueAsString(payload);
-            QRCodeWriter qrCodeWriter = new QRCodeWriter();
-            BitMatrix bitMatrix = qrCodeWriter.encode(json, BarcodeFormat.QR_CODE, width, height);
-            return MatrixToImageWriter.toBufferedImage(bitMatrix);
-        } catch (JsonProcessingException e) {
-            throw new BusinessException(ErrorCode.QR_PAYLOAD_SERIALIZATION_FAILED);
-        } catch (WriterException e) {
-            throw new BusinessException(ErrorCode.QR_IMAGE_GENERATION_FAILED);
-        } catch (Exception e) {
-            throw new BusinessException(ErrorCode.QR_IMAGE_CONVERSION_FAILED);
+    /**
+     * QR IMG 조회
+     * @param qrCodeText = qrCodeId
+     */
+    public byte[] generateQrCodeImage(String qrCodeText, int width, int height) throws WriterException, IOException {
+        QRCodeWriter qrCodeWriter = new QRCodeWriter();
+        BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, width, height);
+
+        try (ByteArrayOutputStream pngOutputStream = new ByteArrayOutputStream()) {
+            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", pngOutputStream);
+            return pngOutputStream.toByteArray();
         }
     }
 
-    public byte[] generateQrImageAsBytes(QrRequestDTO payload, int width, int height) throws Exception {
-        BufferedImage image = generateQrImage(payload, width, height);
-        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        ImageIO.write(image, "PNG", outputStream);
-        return outputStream.toByteArray();
+    public QrCode getQrCodeByCode(String qrCodeId) {
+        return qrCodeRepository.findByQrCodeId(qrCodeId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
     }
 
-    public String generateQrBase64(QrRequestDTO payload, int width, int height) throws Exception {
-        byte[] bytes = generateQrImageAsBytes(payload, width, height);
-        return Base64.getEncoder().encodeToString(bytes);
+
+    /**
+     * 해당 Festival 주최자 QR 스캔
+     * @param qrCodeId, festivalId
+     */
+    @Transactional
+    public void validateAndUseQrCode(Long userId, String qrCodeId) {
+
+        // QR 코드 조회
+        QrCode qrCode = qrCodeRepository.findByQrCodeId(qrCodeId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
+
+        // QR 코드에 연결된 티켓과 페스티벌 확인
+        Ticket ticket = qrCode.getTicket();
+        if (ticket == null || ticket.getFestival() == null) {
+            throw new BusinessException(ErrorCode.QR_CODE_INVALID);
+        }
+
+        /// 주최자 확인 -> 추후 수정
+//        if (!ticket.getFestival().getId().equals(/*여기에 userId를 통해 festivalId 조회*/)) {
+//            throw new BusinessException(ErrorCode.FESTIVAL_MISMATCH);
+//        }
+
+        // 만료 여부 확인
+        if (qrCode.getExpiredAt().isBefore(LocalDate.now())) {
+            throw new BusinessException(ErrorCode.QR_CODE_EXPIRED);
+        }
+
+        // 이미 사용된 QR 코드인지 확인
+        if (Boolean.TRUE.equals(qrCode.getUsed())) {
+            throw new BusinessException(ErrorCode.QR_CODE_ALREADY_USED);
+        }
+
+        // QR 코드 사용 처리
+        qrCode.markAsUsed();
     }
 }
\ No newline at end of file

From 3ca0784f86506ca1b253b1a9a7bb553dbe073c9d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 11 Aug 2025 10:05:06 +0900
Subject: [PATCH 017/149] =?UTF-8?q?MNMS-282=20feat:=20=EC=99=B8=EB=B6=80?=
 =?UTF-8?q?=20User=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=97=B0=EB=8F=99=20-?=
 =?UTF-8?q?=20userId=20=EA=B8=B0=EB=B0=98=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?=
 =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

아직 테스트 미수행
---
 .../booking/config/RestTemplateConfig.java    | 13 ++++++++++
 .../booking/controller/BookingController.java | 26 +++++++++++++------
 .../dto/response/UserInfoResponseDTO.java     | 13 ++++++++++
 .../com/mnms/booking/service/UserService.java | 24 +++++++++++++++++
 .../resources/application-test.properties     |  5 +++-
 5 files changed, 72 insertions(+), 9 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/RestTemplateConfig.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/service/UserService.java

diff --git a/src/main/java/com/mnms/booking/config/RestTemplateConfig.java b/src/main/java/com/mnms/booking/config/RestTemplateConfig.java
new file mode 100644
index 0000000..a5ae2f4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/RestTemplateConfig.java
@@ -0,0 +1,13 @@
+package com.mnms.booking.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index e2db8af..84489e3 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,23 +1,18 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.request.TicketRequestDTO;
+import com.mnms.booking.dto.response.UserInfoResponseDTO;
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.service.BookingService;
+import com.mnms.booking.service.UserService;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 @RestController
 @RequiredArgsConstructor
@@ -26,6 +21,21 @@
 public class BookingController {
 
     private final BookingService bookingService;
+    private final UserService userService;
+
+    ///  GET : 페스티벌 예매 정보 조회
+    ///  POST : 페스티벌 예매 정보 선택
+
+
+    /// GET : userId로 예매자 정보 조회 - phone, email, address, birth
+    @GetMapping("/user/info")
+    @Operation(summary = "예매자 정보 조회",
+            description = "예매 과정에서 예매자 정보를 조회합니다."
+    )
+    public ResponseEntity getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
+        UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
+        return ResponseEntity.ok(userInfo);
+    }
 
     @PostMapping("/reserve")
     @Operation(summary = "페스티벌 예매 티켓 생성",
diff --git a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
new file mode 100644
index 0000000..226aba4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
@@ -0,0 +1,13 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Data;
+
+@Data
+@Builder
+public class UserInfoResponseDTO {
+    private String phone;
+    private String email;
+    private String address;
+    private String birth;
+}
diff --git a/src/main/java/com/mnms/booking/service/UserService.java b/src/main/java/com/mnms/booking/service/UserService.java
new file mode 100644
index 0000000..6d6c200
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/UserService.java
@@ -0,0 +1,24 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.NoSuchElementException;
+
+@Service
+@RequiredArgsConstructor
+public class UserService {
+
+    private final RestTemplate restTemplate;
+
+    @Value("${user.service.url}")
+    private String userServiceUrl;
+
+    public UserInfoResponseDTO getUserInfoById(Long userId) {
+        String url = String.format("%s/%d", userServiceUrl, userId);
+        return restTemplate.getForObject(url, UserInfoResponseDTO.class);
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index f535e96..1d55e53 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -46,4 +46,7 @@ spring.config.import=optional:file:.env[.properties]
 springdoc.api-docs.enabled=true
 springdoc.swagger-ui.enabled=true
 springdoc.swagger-ui.path=/swagger-ui.html
-springdoc.override-with-generic-response=false
\ No newline at end of file
+springdoc.override-with-generic-response=false
+
+# user api
+user.service.url=${USER_INFO_API}
\ No newline at end of file

From 6cd1037e7c7147427c5557ab61d8cedf6762a39d Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Mon, 11 Aug 2025 10:20:28 +0900
Subject: [PATCH 018/149] =?UTF-8?q?MNMS-318=20:whale:=20feat(ci):=20bookin?=
 =?UTF-8?q?g=20Dockerfile=20=EB=B0=8F=20Docker=20=EB=B9=8C=EB=93=9C/?=
 =?UTF-8?q?=EB=B0=B0=ED=8F=AC=20=EC=9B=8C=ED=81=AC=ED=94=8C=EB=A1=9C=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- booking 서비스용 Dockerfile 추가 (multi-stage build 적용)
- GitHub Actions 워크플로(booking-docker-publish.yml) 추가
  - feature/MNMS-318 브랜치 push 시 실행
  - Docker 이미지 빌드 및 Docker Hub 푸시
  - gitops-repo로 repository_dispatch 이벤트 전송
    → ArgoCD 자동 반영
---
 .github/workflows/booking-docker-publish.yml | 55 ++++++++++++++++++++
 Dockerfile                                   | 16 ++++++
 2 files changed, 71 insertions(+)
 create mode 100644 .github/workflows/booking-docker-publish.yml
 create mode 100644 Dockerfile

diff --git a/.github/workflows/booking-docker-publish.yml b/.github/workflows/booking-docker-publish.yml
new file mode 100644
index 0000000..5fdeec6
--- /dev/null
+++ b/.github/workflows/booking-docker-publish.yml
@@ -0,0 +1,55 @@
+name: "💰 booking Docker & Dispatch"
+
+on:
+  push:
+    branches: [ 'feature/MNMS-318' ]
+  workflow_dispatch: {}
+
+env:
+  IMAGE: ${{ secrets.DOCKER_USERNAME }}/api-booking
+  SERVICE: booking
+  DEVOPS_REPO: 3-mnms/gitops-repo
+
+jobs:
+  build-push:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: actions/setup-java@v3
+        with:
+          distribution: temurin
+          java-version: '17'
+
+      - run: chmod +x ./gradlew
+      - run: ./gradlew bootJar --no-daemon
+
+      - name: ⏱️ Tag
+        run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> "$GITHUB_ENV"
+
+      - uses: docker/login-action@v3
+        with:
+          username: ${{ secrets.DOCKER_USERNAME }}
+          password: ${{ secrets.DOCKER_TOKEN }}
+
+      - uses: docker/build-push-action@v5
+        with:
+          context: .
+          file: ./Dockerfile
+          push: true
+          tags: |
+            ${{ env.IMAGE }}:${{ env.TAG }}
+
+      - name: Dispatch to gitops-repo
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "targetBranch": "feature/MNMS-299"
+            }
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..da18336
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,16 @@
+# -------- build stage --------
+FROM eclipse-temurin:17-jdk AS build
+WORKDIR /app
+COPY gradlew gradlew
+COPY gradle gradle
+COPY build.gradle settings.gradle ./
+COPY src src
+RUN chmod +x gradlew && ./gradlew bootJar --no-daemon
+
+# -------- run stage --------
+FROM eclipse-temurin:17-jre
+WORKDIR /app
+# 빌드 산출물 복사 (이름 모르면 * 로)
+COPY --from=build /app/build/libs/*.jar app.jar
+EXPOSE 8080
+ENTRYPOINT ["java","-jar","/app/app.jar"]
\ No newline at end of file

From 87ea3dd70e40675fd383f2fd518fff7283227700 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 11 Aug 2025 10:27:21 +0900
Subject: [PATCH 019/149] =?UTF-8?q?MNMS-282=20fix:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=EC=9E=90=20dto=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dto/response/AddressResponseDTO.java      | 23 +++++++++++++++++++
 .../dto/response/UserInfoResponseDTO.java     |  4 +++-
 2 files changed, 26 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/AddressResponseDTO.java

diff --git a/src/main/java/com/mnms/booking/dto/response/AddressResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/AddressResponseDTO.java
new file mode 100644
index 0000000..8735211
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/AddressResponseDTO.java
@@ -0,0 +1,23 @@
+package com.mnms.booking.dto.response;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Schema(description = "사용자 주소 응답 DTO", name = "AddressDTO")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Builder
+public class AddressResponseDTO {
+    @Schema(description = "사용자 주소")
+    private String address;
+
+    @Schema(description = "사용자 주소 우편번호")
+    private String zipCode;
+
+    @Schema(description = "사용자 주소 기본 배송지 여부")
+    private boolean isDefault;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
index 226aba4..ab8b36f 100644
--- a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
@@ -3,11 +3,13 @@
 import lombok.Builder;
 import lombok.Data;
 
+import java.util.List;
+
 @Data
 @Builder
 public class UserInfoResponseDTO {
     private String phone;
     private String email;
-    private String address;
+    private List address;
     private String birth;
 }

From 0caecac12069250fc91f54e8c8f683b5656c7f73 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 11 Aug 2025 17:35:04 +0900
Subject: [PATCH 020/149] =?UTF-8?q?MNMS-282=20fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

festivalId, date, time 추가
Error : 대기열 release, exit 안됨
---
 .../booking/controller/BookingController.java |   1 -
 .../booking/controller/WaitingController.java |  38 ++--
 .../dto/request/FestivalRequestDTO.java       |  39 ++--
 .../booking/dto/request/TicketRequestDTO.java |   7 +-
 .../booking/dto/response/QrResponseDTO.java   |   2 +-
 .../dto/response/TicketResponseDTO.java       |   3 +-
 .../com/mnms/booking/entity/Festival.java     |  51 +++--
 .../com/mnms/booking/entity/Schedule.java     |  24 +++
 .../java/com/mnms/booking/entity/Ticket.java  |   7 +-
 .../repository/FestivalRepository.java        |   3 +
 .../mnms/booking/service/BookingService.java  |  18 +-
 .../mnms/booking/service/FestivalService.java |  25 +++
 .../com/mnms/booking/service/UserService.java |   1 -
 .../mnms/booking/service/WaitingService.java  | 189 ++++++++++--------
 14 files changed, 263 insertions(+), 145 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/entity/Schedule.java
 create mode 100644 src/main/java/com/mnms/booking/service/FestivalService.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 84489e3..fb5f650 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -26,7 +26,6 @@ public class BookingController {
     ///  GET : 페스티벌 예매 정보 조회
     ///  POST : 페스티벌 예매 정보 선택
 
-
     /// GET : userId로 예매자 정보 조회 - phone, email, address, birth
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index b9fed52..acf0ee1 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -1,6 +1,7 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import com.mnms.booking.service.FestivalService;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -18,6 +19,8 @@
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
 
+import java.time.LocalDateTime;
+
 @Controller
 @Slf4j
 @RequiredArgsConstructor
@@ -26,22 +29,22 @@
 public class WaitingController {
 
     private final WaitingService waitingService;
+    private final FestivalService festivalService;
 
     @Autowired
     private SimpMessagingTemplate messagingTemplate;
 
-
-    // 예매하기 버튼 클릭 시 호출되는 API
+    // front - 예매하기 버튼 클릭 시 호출되는 API
     @GetMapping("/enter")
-    @ResponseBody
-    @Operation(summary = "대기열/예매 페이지 진입",
-            description = "페스티벌 수용 인원만큼 예매 페이지 진입하며," +
-                    "나머지 사용자는 대기열에 들어가 대기하게 됩니다.")
     public ResponseEntity enterBookingPage(
-            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
+            @RequestParam String festivalId,
+            @RequestParam LocalDateTime reservationDate,
+            @AuthenticationPrincipal JwtPrincipal principal) {
 
-        String loginId = (principal != null) ? principal.loginId() : "swagger-test-user";
-        long waitingNumber = waitingService.enterWaitingQueue(loginId);
+        String loginId = principal != null ? principal.loginId() : "swagger-test-user";
+
+        int availableNOP = festivalService.getCapacity(festivalId); // 수용 인원 가져오기
+        long waitingNumber = waitingService.enterWaitingQueue(festivalId, reservationDate, loginId, availableNOP);
 
         if (waitingNumber == 0) {
             return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
@@ -50,7 +53,6 @@ public ResponseEntity enterBookingPage(
         }
     }
 
-
     // 예매 페이지 퇴장 - 대기열 대기자 예매 페이지 진입 (추후 수정 가능)
     @GetMapping("/release")
     @Operation(
@@ -60,10 +62,12 @@ public ResponseEntity enterBookingPage(
                     "대기열에 있던 모든 대기자의 대기번호가 변경됩니다."
     )
     public ResponseEntity releaseUser(
+            @RequestParam String festivalId,
+            @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         try {
-            boolean removed = waitingService.userExitBookingPage(loginId);
+            boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, loginId);
             if (removed) {
                 return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
@@ -85,10 +89,12 @@ public ResponseEntity releaseUser(
     )
     @GetMapping("/exit")
     public ResponseEntity exitWaitingUser(
+            @RequestParam String festivalId,
+            @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         try {
-            boolean removed = waitingService.removeUserFromQueue(loginId);
+            boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, loginId);
             if (removed) {
                 return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
             } else {
@@ -108,9 +114,13 @@ public ResponseEntity exitWaitingUser(
      */
     @Hidden
     @MessageMapping("/subscribe/waiting")
-    public void subscribeWaitingQueue(@AuthenticationPrincipal JwtPrincipal principal) {
+    public void subscribeWaitingQueue(
+            @RequestParam String festivalId,
+            @RequestParam LocalDateTime reservationDate,
+            @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         log.info("User {} subscribed to waiting queue updates.", loginId);
-        waitingService.getAndPublishWaitingNumber(loginId);
+        String waitingQueueKey = waitingService.getWaitingQueueKey(festivalId, reservationDate);
+        waitingService.getAndPublishWaitingNumber(waitingQueueKey, loginId);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
index d5dd966..8036279 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
@@ -3,32 +3,37 @@
 import lombok.Data;
 
 import java.time.LocalDate;
+import java.util.List;
 
 @Data
 public class FestivalRequestDTO {
 
-    private String mt20id;
+    private String id; // 공연 고유 ID (PF000001)
 
-    // 공연명
-    private String prfnm;
+    private String fname; // 공연명
 
-    // 공연 시작일
-    private LocalDate prfpdfrom;
+    private LocalDate fdfrom; // 공연 시작일
 
-    // 공연 종료일
-    private LocalDate prfpdto;
+    private LocalDate fdto; // 공연 종료일
 
-    // 공연 시설명
-    private String fcltynm;
+    private String posterFile; // 공연 대표 이미지 URL
 
-    // 포스터 이미지 경로
-    private String poster;
+    private String fcltynm; // 공연장 장소
 
-    // 티켓 비용
-    private int pcseguidance;
+    private int ticketPick; // 티켓 배송 방법
 
-    // 수용 가능 인원
-    private int availableNOP;
+    private int maxPurchase; // 1회 최대 구매 가능 수량
 
-    // 택배 날짜 (지류티켓 선택 시, 페스티벌 날짜 2주일 전 배송 - 자동) - 추후
-}
+    private int ticketPrice; // 티켓 가격
+
+    private int availableNOP; // 수용인원
+
+    private List schedules;
+
+    @Data
+    public static class ScheduleDTO {
+        private Long scheduleId;
+        private String dayOfWeek;
+        private String time;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
index 03f9846..019c18d 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -1,19 +1,16 @@
 package com.mnms.booking.dto.request;
 
 import com.mnms.booking.entity.TicketType;
-import jakarta.persistence.Column;
 import lombok.Data;
 
-import java.time.LocalDate;
-import java.time.LocalTime;
+import java.time.LocalDateTime;
 
 @Data
 public class TicketRequestDTO {
 
     private Long festivalId;
     private int selectedTicketCount; // <= Festival.maxTicketsPerUser
-    private LocalDate performanceDate;
-    private LocalTime performanceTime;
+    private LocalDateTime performanceDate;
     private TicketType deliveryMethod;
 
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
index a281930..9f2c2ab 100644
--- a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -53,7 +53,7 @@ public static QrResponseDTO create(Long userId, String qrCodeId,Festival festiva
         dto.setUserId(userId);
         dto.setQrCodeId(qrCodeId);
         dto.setIssuedAt(LocalDate.now());
-        dto.setExpiredAt(festival.getPrfpdto());
+        dto.setExpiredAt(festival.getFdto());
         dto.setTicket(ticket);
         return dto;
     }
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index 3050e65..ddee0b5 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -6,6 +6,7 @@
 import lombok.*;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 
 @Data
 @Builder
@@ -15,7 +16,7 @@ public class TicketResponseDTO {
     private String reservationNumber;
     private Boolean reservationStatus;
     private TicketType deliveryMethod;
-    private LocalDate deliveryDate;
+    private LocalDateTime deliveryDate;
     private Long userId;
     private LocalDate reservationDate;
     private QrResponseDTO qrCode;
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index a3f04c4..09ab10b 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -2,25 +2,52 @@
 
 import jakarta.persistence.*;
 import lombok.Getter;
+import lombok.Setter;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
 
 @Entity
 @Getter
-@Table(name = "festival")
 public class Festival {
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id; // festival_id
-    private String name; // 이름
-    private String frame; // frame
-    private LocalDate prfpdfrom; // 시작일
-    private LocalDate prfpdto; // 종료일
-    private String poster; // 포스터
-    private int ticketPrice; // 가격
-    private int availableNOp; // 수용 가능 인원
-    private String area; // 장소
-    private int paper; // 지류 여부
-    private int maxTicketsPerUser; // 한 사람당 최대 예매 티켓 수
+    private Long id; // DB PK (자동증가)
+
+    @Column(name = "festival_id", unique = true, nullable = false, length = 20)
+    private String festivalId; // 공연 고유 ID (PF000001)
+
+    @Column(name = "fname", nullable = false)
+    private String fname; // 공연명
+
+    @Column(name = "fdfrom", nullable = false)
+    private LocalDate fdfrom; // 공연 시작일 (YYYY-MM-DD)
+
+    @Column(name = "fdto", nullable = false)
+    private LocalDate fdto; // 공연 종료일 (YYYY-MM-DD)
+
+    @Column(name = "poster_file")
+    private String posterFile; // 공연 대표 이미지 URL
+
+    @Column(name = "fcltynm")
+    private String fcltynm; // 공연장 장소
+
+    @Column(name = "ticket_pick")
+    private int ticketPick; // 티켓 배송 방법 (1=배송만, 2=qr만, 3=둘다)
+
+    @Column(name = "max_purchase")
+    private int maxPurchase; // 1회 최대 구매 가능 수량 (1~4)
+
+    @Column(name = "ticket_price")
+    private int ticketPrice; // 티켓 가격 (원 단위)
+
+    @Column(name = "available_nop")
+    private int availableNOP; // 수용인원
+
+    @OneToMany(mappedBy = "festival", cascade = CascadeType.ALL, orphanRemoval = true)
+    private List schedules = new ArrayList<>();
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Schedule.java b/src/main/java/com/mnms/booking/entity/Schedule.java
new file mode 100644
index 0000000..4ca8590
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/Schedule.java
@@ -0,0 +1,24 @@
+package com.mnms.booking.entity;
+
+import jakarta.persistence.*;
+import lombok.Getter;
+import lombok.Setter;
+
+@Entity
+@Getter @Setter
+public class Schedule {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long scheduleId; // 공연 일정 PK
+
+    @Column(name = "dayOfWeek", length = 3)
+    private String dayOfWeek; // 요일 코드 (MON, TUE...)
+
+    @Column(name = "time", length = 5)
+    private String time; // 공연 시작 시간 (HH:mm)
+
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "festival_id", nullable = false)
+    private Festival festival;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 89a286f..2e0eda1 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -34,13 +34,10 @@ public class Ticket {
     private LocalDate reservationDate; // 예매한 날짜
 
     @Column(name = "delivery_date")
-    private LocalDate deliveryDate; // 택배 날짜
+    private LocalDateTime deliveryDate; // 택배 날짜
 
     @Column(name = "performance_date")
-    private LocalDate performanceDate; // 선택한 공연 날짜
-
-    @Column(name = "performance_time")
-    private LocalTime performanceTime; // 선택한 공연 시간
+    private LocalDateTime performanceDate; // 선택한 공연 날짜 시간
 
     @Column(name = "selected_ticket_count")
     private int selectedTicketCount;
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index 8a6b823..58c6cb4 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -3,6 +3,9 @@
 import com.mnms.booking.entity.Festival;
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.Optional;
+
 public interface FestivalRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
+    Optional findByFestivalId(String festivalId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index 947da77..03e4082 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -17,6 +17,7 @@
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.UUID;
 
 @Service
@@ -36,7 +37,7 @@ public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
 
         // 사용자 예약 티켓 매수, 지류티켓 확인
         validateReservation(userId, request, festival);
-        LocalDate deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), request);
+        LocalDateTime deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), request);
 
         // Ticket 저장 (reservation number 자동 래덤 생성됨)
         Ticket ticket = buildTicket(request, userId, festival, deliveryDate);
@@ -58,7 +59,7 @@ private void validateReservation(Long userId, TicketRequestDTO request, Festival
         int reservedCount = request.getSelectedTicketCount() + alreadyReservedCount;
 
         // 티켓 개수 초과
-        if ( reservedCount > festival.getMaxTicketsPerUser()) {
+        if ( reservedCount > festival.getMaxPurchase()) {
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
 
@@ -69,16 +70,16 @@ private void validateReservation(Long userId, TicketRequestDTO request, Festival
     }
 
     // deliveryDate 생성
-    private LocalDate calculateDeliveryDate(TicketType deliveryMethod, TicketRequestDTO request) {
+    private LocalDateTime calculateDeliveryDate(TicketType deliveryMethod, TicketRequestDTO request) {
         // 지류 티켓일 경우
-        if (request.getPerformanceDate() == null || request.getPerformanceTime() == null) {
+        if (request.getPerformanceDate() == null) {
                 throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
         }
         if (deliveryMethod == TicketType.PAPER) {
-            LocalDate deliveryDate = request.getPerformanceDate().minusDays(14);
-            return deliveryDate.isAfter(LocalDate.now())
+            LocalDateTime deliveryDate = request.getPerformanceDate().minusDays(14);
+            return deliveryDate.isAfter(LocalDateTime.now())
                     ? deliveryDate
-                    : LocalDate.now().plusDays(1);
+                    : LocalDateTime.now().plusDays(1);
         }
         // 모바일 티켓일 경우
         return null;
@@ -104,7 +105,7 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket
 
     // Ticket 저장
     private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festival,
-                               LocalDate deliveryDate) { // , QrCode qrCode
+                               LocalDateTime deliveryDate) { // , QrCode qrCode
         return Ticket.builder()
                 .reservationNumber(generateReservationNumber())
                 .reservationStatus(true)
@@ -112,7 +113,6 @@ private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festi
                 .reservationDate(LocalDate.now())
                 .deliveryDate(deliveryDate)
                 .performanceDate(request.getPerformanceDate())
-                .performanceTime(request.getPerformanceTime())
                 .selectedTicketCount(request.getSelectedTicketCount())
                 .festival(festival)
                 .userId(userId)
diff --git a/src/main/java/com/mnms/booking/service/FestivalService.java b/src/main/java/com/mnms/booking/service/FestivalService.java
new file mode 100644
index 0000000..c07fd48
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/FestivalService.java
@@ -0,0 +1,25 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class FestivalService {
+
+    private final FestivalRepository festivalRepository;
+
+    /**
+     * 특정 festivalId에 해당하는 공연의 수용 인원을 조회
+     * @return 수용 인원
+     */
+    public int getCapacity(String festivalId) {
+        Festival festival = festivalRepository.findByFestivalId(festivalId)
+            .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+        return festival.getAvailableNOP();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/UserService.java b/src/main/java/com/mnms/booking/service/UserService.java
index 6d6c200..49c4f17 100644
--- a/src/main/java/com/mnms/booking/service/UserService.java
+++ b/src/main/java/com/mnms/booking/service/UserService.java
@@ -6,7 +6,6 @@
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
 
-import java.util.NoSuchElementException;
 
 @Service
 @RequiredArgsConstructor
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 050d4a7..135fae5 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -3,7 +3,6 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
-import jakarta.annotation.PostConstruct;
 import jakarta.annotation.PreDestroy;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Qualifier;
@@ -14,10 +13,10 @@
 import org.springframework.stereotype.Service;
 
 import java.time.Duration;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledFuture;
 
 @Service
@@ -39,23 +38,14 @@ public class WaitingService {
     // Redis Pub/Sub 채널 이름
     private static final String NOTIFICATION_CHANNEL = "waiting_notification";
 
-    // 예매 페이지 수용인원
-    private static final long PERFORMANCE_CAPACITY = 2; // 공연 수용 인원
-    private static final double IMMEDIATE_ENTRY_RATIO = 1; // 기준 : 즉시 입장 비율 (1.5배), 테스트 (1배)
-    private static final long IMMEDIATE_ENTRY_COUNT = (long) (PERFORMANCE_CAPACITY * IMMEDIATE_ENTRY_RATIO);
-
     // scheduled
     private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
     private ScheduledFuture scheduledTask;
+    private final Map> scheduledTasks = new ConcurrentHashMap<>();
 
-
-    @PostConstruct
     public void init() {
         zSetOperations = redisTemplate.opsForZSet();
-        List waitingUsers = getWaitingUsers();
-        if (!waitingUsers.isEmpty()) {
-            startScheduler();
-        }
+        // startScheduler() 호출 코드를 제거합니다.
     }
 
     public WaitingService(
@@ -70,71 +60,101 @@ public WaitingService(
         scheduler.initialize();
     }
 
+
     /**
-     * 사용자 대기열 진입 처리
-     * @param loginId 사용자 ID
-     * @return 대기 순번 (즉시 입장 가능한 경우 0)
+     * 사용자 대기열 진입 처리 (공연별·시간별 분리)
+     * @param festivalId, reservationDate, loginId, availableNOP
+     * @return 대기 순번 (즉시 입장 가능 시 0)
      */
-    public long enterWaitingQueue(String loginId) {
+    public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String loginId, long availableNOP) {
+        String bookingUsersKey = getBookingUsersKey(festivalId, reservationDate);
+        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
 
-        // 현재 입장한 사용자 수
-        Long currentUserCount = redisTemplate.opsForSet().size(BOOKING_USERS_SET_KEY);
-        if (currentUserCount == null) currentUserCount = 0L;
+        zSetOperations = redisTemplate.opsForZSet(); // Redis ZSet ops 재설정 필요
 
-        // 입장한 사용자가 제한보다 작을 때
-        if(currentUserCount < IMMEDIATE_ENTRY_COUNT){
-            log.info("User {} can enter booking page immediately ({} < {}).", loginId, currentUserCount, IMMEDIATE_ENTRY_COUNT);
+        Long currentUserCount = redisTemplate.opsForSet().size(bookingUsersKey);
+        if (currentUserCount == null) currentUserCount = 0L;
 
-            redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, loginId); // 사용자 등록
+        if (currentUserCount < availableNOP) {
+            log.info("User {} can enter booking page immediately ({} < {}).", loginId, currentUserCount, availableNOP);
+            redisTemplate.opsForSet().add(bookingUsersKey, loginId);
             return 0L;
-        } else{
-            // 대기열로 보냄 (ZSet)
+        } else {
             long timestamp = System.currentTimeMillis();
-            zSetOperations.add(WAITING_QUEUE_KEY, loginId, timestamp);
+            zSetOperations.add(waitingQueueKey, loginId, timestamp);
+            log.info("User {} added to waiting queue {} with timestamp {}.", loginId, waitingQueueKey, timestamp);
 
-            log.info("User {} added to waiting queue with timestamp {}.", loginId, timestamp);
+            startScheduler(waitingQueueKey, bookingUsersKey, availableNOP);
 
-            // 조건부 스케줄러 시작
-            startScheduler();
-
-            return getAndPublishWaitingNumber(loginId);
+            return getAndPublishWaitingNumber(waitingQueueKey, loginId);
         }
     }
 
     /**
      * 스케줄러 시작 (중복 시작 방지)
      */
-    public synchronized void startScheduler() {
-        if (scheduledTask == null || scheduledTask.isCancelled() || scheduledTask.isDone()) {
-            log.info("대기열 감시 스케줄러 시작됨.");
-            scheduledTask = scheduler.scheduleWithFixedDelay(this::runSchedulerLogic, Duration.ofSeconds(5));
+    public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, long availableNOP) {
+        if (scheduledTasks.containsKey(waitingQueueKey) && !scheduledTasks.get(waitingQueueKey).isDone()) {
+            // 이미 스케줄러 실행 중
+            return;
         }
+        log.info("Starting scheduler for queue: {}", waitingQueueKey);
+        ScheduledFuture task = scheduler.scheduleWithFixedDelay(() -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, availableNOP), Duration.ofSeconds(5));
+        scheduledTasks.put(waitingQueueKey, task);
     }
 
     /**
      * 스케줄러 중지
      */
-    public synchronized void stopScheduler() {
-        if (scheduledTask != null && !scheduledTask.isCancelled()) {
-            log.info("대기열이 비어 스케줄러 중지됨.");
-            scheduledTask.cancel(false);
+    public synchronized void stopScheduler(String waitingQueueKey) {
+        ScheduledFuture task = scheduledTasks.get(waitingQueueKey);
+        if (task != null && !task.isCancelled()) {
+            task.cancel(false);
+            scheduledTasks.remove(waitingQueueKey);
+            log.info("Stopped scheduler for queue: {}", waitingQueueKey);
         }
     }
 
     /**
      * 주기적으로 대기열 순번 발행
      */
-    public void runSchedulerLogic() {
-        List waitingUsers = getWaitingUsers();
-        if (waitingUsers.isEmpty()) {
-            stopScheduler(); // 비었으면 중지
+    public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, long availableNOP) {
+        zSetOperations = redisTemplate.opsForZSet();
+        Set waitingUsers = zSetOperations.range(waitingQueueKey, 0, -1);
+        if (waitingUsers == null || waitingUsers.isEmpty()) {
+            stopScheduler(waitingQueueKey);
             return;
         }
 
         for (String loginId : waitingUsers) {
-            getAndPublishWaitingNumber(loginId);
+            getAndPublishWaitingNumber(waitingQueueKey, loginId);
+        }
+        log.info("Published waiting numbers to {} users for queue {}", waitingUsers.size(), waitingQueueKey);
+
+        // 빈자리 생겼을 때 대기열에서 사용자 입장 처리
+        Long currentBookingCount = redisTemplate.opsForSet().size(bookingUsersKey);
+        if (currentBookingCount == null) currentBookingCount = 0L;
+
+        // 빈자리가 생겼을 때
+        while (currentBookingCount < availableNOP) {
+            Set nextUsers = zSetOperations.range(waitingQueueKey, 0, 0);
+            if (nextUsers == null || nextUsers.isEmpty()) {
+                break;
+            }
+            // 대기열에서 대기자 지우고, 예메 페이지에 입장
+            String nextUser = nextUsers.iterator().next();
+            Long removed = zSetOperations.remove(waitingQueueKey, nextUser);
+
+            // 대기열에 removed 된 사람이 있으면
+            if (removed != null && removed > 0) {
+                redisTemplate.opsForSet().add(bookingUsersKey, nextUser);
+                log.info("User {} moved from waiting queue to booking users for queue {}", nextUser, waitingQueueKey);
+                notifyAllWaitingUsers(waitingQueueKey);
+                currentBookingCount++;
+            } else {
+                break;
+            }
         }
-        log.info("대기열 사용자 {}명에게 대기번호 발행 완료.", waitingUsers.size());
     }
 
     public List getWaitingUsers() {
@@ -145,34 +165,29 @@ public List getWaitingUsers() {
 
     /**
      * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
-     * @param loginId 사용자 ID
+     * @param waitingQueueKey, userId
      * @return 대기 순번
      */
-    public long getAndPublishWaitingNumber(String loginId) {
-        // 해당 loginId의 대기열 순번을 조회
-        Long rank = zSetOperations.rank(WAITING_QUEUE_KEY, loginId);
-
+    public long getAndPublishWaitingNumber(String waitingQueueKey, String loginId) {
+        zSetOperations = redisTemplate.opsForZSet();
+        Long rank = zSetOperations.rank(waitingQueueKey, loginId);
         if (rank != null) {
             long waitingNumber = rank + 1;
-            //log.info("User {}'s waiting number: {}", loginId, waitingNumber);
-
-            // Redis Pub/Sub 채널로 메시지 발행
             publishWaitingNumber(loginId, waitingNumber);
-
             return waitingNumber;
         }
-        return -1; // 대기열에 없는 경우
+        return -1;
     }
 
     /**
      * Redis Pub/Sub 채널로 대기 순번 정보 발행
-     * @param loginId 사용자 ID
+     * @param userId 사용자 ID
      * @param waitingNumber 대기 순번
      */
-    private void publishWaitingNumber(String loginId, long waitingNumber) {
+    private void publishWaitingNumber(String userId, long waitingNumber) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(loginId, waitingNumber, false, null);
+            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(dto);
             // Redis 채널로 발행
             stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
@@ -185,22 +200,25 @@ private void publishWaitingNumber(String loginId, long waitingNumber) {
      * 대기열에서 다음 사용자 진입 처리
      * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출)
      */
-    public boolean userExitBookingPage(String loginId){
+    public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId){
         // 예매 완료된 Set에서 제거
-        Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, loginId);
+        Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, userId);
 
         if(removed != null && removed > 0){
-            log.info("User {} exited booking page and removed from booking user set.", loginId);
+            log.info("User {} exited booking page and removed from booking user set.", userId);
             // 대기열에서 다음 사용자 진입 처리
-            releaseWaitingUser();
+            releaseWaitingUser(festivalId, reservationDate);
             return true;
         }else{
-            log.warn("User {} was not found in booking user set on exit.", loginId);
+            log.warn("User {} was not found in booking user set on exit.", userId);
             return false;
         }
     }
 
-    public void releaseWaitingUser() {
+    public void releaseWaitingUser(String festivalId, LocalDateTime reservationDate) {
+
+        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
+
         // 대기열 큐 가장 앞에 있는 사람
         Set releasedUsers = zSetOperations.range(WAITING_QUEUE_KEY, 0, 0);
 
@@ -217,7 +235,7 @@ public void releaseWaitingUser() {
                 log.info("User {} added to booking user set.", releasedUser);
 
                 // 남은 대기열 사용자에게 순번 알림
-                notifyAllWaitingUsers();
+                notifyAllWaitingUsers(waitingQueueKey);
 
             } else {
                 log.warn("Failed to remove user {} from waiting queue. Removed count: {}", releasedUser, removedCount);
@@ -228,32 +246,33 @@ public void releaseWaitingUser() {
     /**
      * 모든 대기열 사용자에게 순번 업데이트 알림
      */
-    public void notifyAllWaitingUsers() {
+    public void notifyAllWaitingUsers(String waitingQueueKey) {
         // 대기열 사용자 수 전체 범위 조회
-        Set allUsersInQueue = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1);
+        Set allUsersInQueue = zSetOperations.range(waitingQueueKey, 0, -1);
 
         if (allUsersInQueue != null) {
-            for (String loginId : allUsersInQueue) {
+            for (String userId : allUsersInQueue) {
                 // 각 사용자에게 순번 알림을 Redis Pub/Sub으로 발행
-                getAndPublishWaitingNumber(loginId);
+                getAndPublishWaitingNumber(waitingQueueKey, userId);
             }
         }
     }
 
     /**
      * 특정 사용자가 대기열에서 이탈했음을 처리
-     * @param loginId
+     * @param festivalId, reservationDate, userId
      * @return boolean - 사용자가 대기열에서 성공적으로 제거되었으면 true, 아니면 false
      */
-    public boolean removeUserFromQueue(String loginId) {
-        Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, loginId);
+    public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationDate, String userId) {
+        Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, userId);
+        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
         if (removedCount != null && removedCount > 0) {
-            log.info("User {} removed from waiting queue (manual removal).", loginId);
-            notifyAllWaitingUsers(); // 순번 업데이트 알림
+            log.info("User {} removed from waiting queue (manual removal).", userId);
+            notifyAllWaitingUsers(waitingQueueKey); // 순번 업데이트 알림
             return true;
         } else {
             // 사용자가 대기열에 없었거나, 제거 과정에서 문제가 발생한 경우
-            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", loginId, removedCount);
+            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", userId, removedCount);
             return false;
         }
     }
@@ -262,4 +281,16 @@ public boolean removeUserFromQueue(String loginId) {
     public void cleanup() {
         scheduler.shutdown();
     }
+
+    /// util
+    public String getWaitingQueueKey(String festivalId, LocalDateTime reservationDate) {
+        // reservationDate는 yyyyMMddHHmm 형태로 저장 (ex: 202509011930)
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return "waiting_queue:" + festivalId + ":" + dateStr;
+    }
+
+    private String getBookingUsersKey(String festivalId, LocalDateTime reservationDate) {
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return "booking_users:" + festivalId + ":" + dateStr;
+    }
 }
\ No newline at end of file

From a348bfb8d74ae4d1f2336d5468e264116c29513d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 12 Aug 2025 15:43:51 +0900
Subject: [PATCH 021/149] =?UTF-8?q?MNMS-282=20fix:=20festivalId,=20selecte?=
 =?UTF-8?q?dDate=EC=B6=94=EA=B0=80=ED=95=9C=20=EB=8C=80=EA=B8=B0=EC=97=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/config/RedisConfig.java  | 32 +++++++----
 .../mnms/booking/config/WebSocketConfig.java  |  3 +-
 .../booking/controller/WaitingController.java |  9 +--
 .../service/RedisMessageSubscriber.java       | 28 ++++-----
 .../service/WaitingNotificationService.java   |  4 ++
 .../service/WaitingQueueRedisService.java     |  4 ++
 .../WaitingQueueSchedulingService.java        |  4 ++
 .../mnms/booking/service/WaitingService.java  | 57 ++++++++++++-------
 .../resources/application-test.properties     |  6 +-
 9 files changed, 91 insertions(+), 56 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/WaitingNotificationService.java
 create mode 100644 src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
 create mode 100644 src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index e60c71a..bcd391b 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -1,11 +1,13 @@
 package com.mnms.booking.config;
 
 import com.mnms.booking.service.RedisMessageSubscriber;
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.listener.ChannelTopic;
+import org.springframework.data.redis.listener.PatternTopic;
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
@@ -13,22 +15,33 @@
 
 
 @Configuration
+@Slf4j
 public class RedisConfig {
 
-    // Redis Pub/Sub 메시지를 구독하고 처리할 컨테이너
+
+    @PostConstruct
+    public void init() {
+        log.info("RedisConfig bean initialized");
+    }
+
+    /// Redis Pub/Sub 메시지를 구독하고 처리할 컨테이너
     @Bean
     public RedisMessageListenerContainer redisMessageListenerContainer(
             RedisConnectionFactory connectionFactory,
-            MessageListenerAdapter listenerAdapter // 아래에서 정의할 리스너 어댑터
+            MessageListenerAdapter listenerAdapter
     ) {
         RedisMessageListenerContainer container = new RedisMessageListenerContainer();
         container.setConnectionFactory(connectionFactory);
-        // "waiting_notification" 채널을 구독하도록 설정
-        container.addMessageListener(listenerAdapter, new ChannelTopic("waiting_notification"));
+
+        PatternTopic patternTopic = new PatternTopic("waiting_notification:*");
+        container.addMessageListener(listenerAdapter, patternTopic);
+
+        // 구독 시작 시 로그 출력
+        log.info("Subscribed to Redis channels with pattern: {}", patternTopic.getTopic());
         return container;
     }
 
-    // Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결)
+    /// Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결)
     @Bean
     public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
         // RedisMessageSubscriber의 "onMessage" 메서드를 호출하도록 설정
@@ -36,7 +49,6 @@ public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber)
     }
 
     // Redis Pub/Sub 메시지를 발행하는 데 사용될 템플릿
-    // String, String 형태로 메시지를 발행할 것이므로 StringRedisTemplate을 사용
     @Bean
     public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
         return new StringRedisTemplate(connectionFactory);
@@ -48,18 +60,14 @@ public RedisTemplate redisTemplate(RedisConnectionFactory connec
         RedisTemplate template = new RedisTemplate<>();
         template.setConnectionFactory(connectionFactory);
 
-        // Key 직렬화 설정: StringRedisSerializer 사용 (필수)
+        // 직렬화 설정
         template.setKeySerializer(new StringRedisSerializer());
-        // Value 직렬화 설정
         template.setValueSerializer(new StringRedisSerializer());
-
-        // Hash Key/Value 직렬화 설정 (ZSet에서는 직접 사용되지 않지만, 다른 Redis 자료구조 사용 시 일관성을 위해 설정)
         template.setHashKeySerializer(new StringRedisSerializer());
         template.setHashValueSerializer(new StringRedisSerializer());
 
         // 초기화 메서드 호출 (설정 적용)
         template.afterPropertiesSet();
-
         return template;
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index 1d57f23..7331acd 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -13,9 +13,10 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
     @Override
     public void configureMessageBroker(MessageBrokerRegistry config) {
         // 구독경로
-        config.enableSimpleBroker("/topic");
+        config.enableSimpleBroker("/topic", "/queue");
         // 클라이언트 → 서버 메시지 경로
         config.setApplicationDestinationPrefixes("/app");
+        config.setUserDestinationPrefix("/user");
     }
 
     @Override
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index acf0ee1..5e8070b 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -34,7 +34,7 @@ public class WaitingController {
     @Autowired
     private SimpMessagingTemplate messagingTemplate;
 
-    // front - 예매하기 버튼 클릭 시 호출되는 API
+    /// 예매하기 버튼(front) 클릭 시 호출되는 API
     @GetMapping("/enter")
     public ResponseEntity enterBookingPage(
             @RequestParam String festivalId,
@@ -53,7 +53,7 @@ public ResponseEntity enterBookingPage(
         }
     }
 
-    // 예매 페이지 퇴장 - 대기열 대기자 예매 페이지 진입 (추후 수정 가능)
+    /// 예매 페이지 퇴장 - 대기열 대기자 예매 페이지 진입 (추후 수정 가능)
     @GetMapping("/release")
     @Operation(
             summary = "예매 페이지 진입 완료 처리",
@@ -64,7 +64,7 @@ public ResponseEntity enterBookingPage(
     public ResponseEntity releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
-            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
+            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) { ///  예매칸에 있는 예매자 accessToken
         String loginId = principal.loginId();
         try {
             boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, loginId);
@@ -121,6 +121,7 @@ public void subscribeWaitingQueue(
         String loginId = principal.loginId();
         log.info("User {} subscribed to waiting queue updates.", loginId);
         String waitingQueueKey = waitingService.getWaitingQueueKey(festivalId, reservationDate);
-        waitingService.getAndPublishWaitingNumber(waitingQueueKey, loginId);
+        String notificationChannelKey = waitingService.getNotificationChannelKey(festivalId, reservationDate);
+        waitingService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 23c6059..5499182 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -1,12 +1,9 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.data.redis.connection.Message;
-import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Service;
 
@@ -14,30 +11,29 @@
 @Service
 @RequiredArgsConstructor
 @Slf4j
-public class RedisMessageSubscriber implements MessageListener {
+public class RedisMessageSubscriber {
 
     private final SimpMessagingTemplate messagingTemplate; // WebSocket 메시지 전송
     private final ObjectMapper objectMapper; // JSON 파싱을 위한 ObjectMapper
 
     // Redis로부터 메시지를 수신할 때 호출되는 메서드
-    @Override
-    public void onMessage(Message message, byte[] pattern) {
+    public void onMessage(String message, String channel) {
+        // 채널 이름
+        log.info("channel name : {}", channel);
+
+        // message는 JSON 문자열 -> DTO로 변환
         try {
-            // Redis에서 받은 메시지 바디를 문자열로 변환
-            String receivedMessage = new String(message.getBody());
-            log.info("Received message from Redis channel: {}", receivedMessage);
+            // 여기에 로그 추가
+            log.info("Received message from Redis channel: {}", message);
 
-            // 받은 JSON 문자열을 WaitingNumberDto 객체로 변환
-            WaitingNumberResponseDTO dto = objectMapper.readValue(receivedMessage, WaitingNumberResponseDTO.class);
+            WaitingNumberResponseDTO dto = new ObjectMapper().readValue(message, WaitingNumberResponseDTO.class);
 
-            // WebSocket을 통해 해당 사용자 토픽으로 메시지 전송
-            messagingTemplate.convertAndSend("/topic/waiting/" + dto.getUserId(), dto);
+            // userId 기준으로 메시지 전송
+            messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
             log.info("Sent WebSocket message to user {}: {}", dto.getUserId(), dto.getWaitingNumber());
 
-        } catch (JsonProcessingException e) {
-            log.error("Error parsing Redis message to WaitingNumberDto: {}", e.getMessage());
         } catch (Exception e) {
-            log.error("Error processing Redis message: {}", e.getMessage());
+            log.error("예외 발생: {}", e.getMessage(), e);
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
new file mode 100644
index 0000000..d1308e8
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -0,0 +1,4 @@
+package com.mnms.booking.service;
+
+public class WaitingNotificationService {
+}
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
new file mode 100644
index 0000000..9fa2f48
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -0,0 +1,4 @@
+package com.mnms.booking.service;
+
+public class WaitingQueueRedisService {
+}
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
new file mode 100644
index 0000000..d2fc1dc
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -0,0 +1,4 @@
+package com.mnms.booking.service;
+
+public class WaitingQueueSchedulingService {
+}
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 135fae5..84d1066 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -69,6 +69,7 @@ public WaitingService(
     public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String loginId, long availableNOP) {
         String bookingUsersKey = getBookingUsersKey(festivalId, reservationDate);
         String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
+        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
 
         zSetOperations = redisTemplate.opsForZSet(); // Redis ZSet ops 재설정 필요
 
@@ -84,22 +85,22 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
             zSetOperations.add(waitingQueueKey, loginId, timestamp);
             log.info("User {} added to waiting queue {} with timestamp {}.", loginId, waitingQueueKey, timestamp);
 
-            startScheduler(waitingQueueKey, bookingUsersKey, availableNOP);
+            startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
 
-            return getAndPublishWaitingNumber(waitingQueueKey, loginId);
+            return getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
         }
     }
 
     /**
      * 스케줄러 시작 (중복 시작 방지)
      */
-    public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, long availableNOP) {
+    public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
         if (scheduledTasks.containsKey(waitingQueueKey) && !scheduledTasks.get(waitingQueueKey).isDone()) {
             // 이미 스케줄러 실행 중
             return;
         }
         log.info("Starting scheduler for queue: {}", waitingQueueKey);
-        ScheduledFuture task = scheduler.scheduleWithFixedDelay(() -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, availableNOP), Duration.ofSeconds(5));
+        ScheduledFuture task = scheduler.scheduleWithFixedDelay(() -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP), Duration.ofSeconds(5));
         scheduledTasks.put(waitingQueueKey, task);
     }
 
@@ -118,7 +119,7 @@ public synchronized void stopScheduler(String waitingQueueKey) {
     /**
      * 주기적으로 대기열 순번 발행
      */
-    public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, long availableNOP) {
+    public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
         zSetOperations = redisTemplate.opsForZSet();
         Set waitingUsers = zSetOperations.range(waitingQueueKey, 0, -1);
         if (waitingUsers == null || waitingUsers.isEmpty()) {
@@ -127,7 +128,7 @@ public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, lo
         }
 
         for (String loginId : waitingUsers) {
-            getAndPublishWaitingNumber(waitingQueueKey, loginId);
+            getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
         }
         log.info("Published waiting numbers to {} users for queue {}", waitingUsers.size(), waitingQueueKey);
 
@@ -149,7 +150,7 @@ public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, lo
             if (removed != null && removed > 0) {
                 redisTemplate.opsForSet().add(bookingUsersKey, nextUser);
                 log.info("User {} moved from waiting queue to booking users for queue {}", nextUser, waitingQueueKey);
-                notifyAllWaitingUsers(waitingQueueKey);
+                notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
                 currentBookingCount++;
             } else {
                 break;
@@ -167,13 +168,14 @@ public List getWaitingUsers() {
      * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
      * @param waitingQueueKey, userId
      * @return 대기 순번
+     * getNotificationChannelKey(festivalId, reservationDate);
      */
-    public long getAndPublishWaitingNumber(String waitingQueueKey, String loginId) {
+    public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
         zSetOperations = redisTemplate.opsForZSet();
         Long rank = zSetOperations.rank(waitingQueueKey, loginId);
         if (rank != null) {
             long waitingNumber = rank + 1;
-            publishWaitingNumber(loginId, waitingNumber);
+            publishWaitingNumber(loginId, waitingNumber, notificationChannelKey);
             return waitingNumber;
         }
         return -1;
@@ -184,13 +186,14 @@ public long getAndPublishWaitingNumber(String waitingQueueKey, String loginId) {
      * @param userId 사용자 ID
      * @param waitingNumber 대기 순번
      */
-    private void publishWaitingNumber(String userId, long waitingNumber) {
+    private void publishWaitingNumber(String userId, long waitingNumber, String notificationChannelKey) {
         try {
             // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberResponseDTO dto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
-            String message = objectMapper.writeValueAsString(dto);
+            WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
+            //WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber);
+            String message = objectMapper.writeValueAsString(waitingNumberDto);
             // Redis 채널로 발행
-            stringRedisTemplate.convertAndSend(NOTIFICATION_CHANNEL, message);
+            stringRedisTemplate.convertAndSend(notificationChannelKey, message);
         } catch (JsonProcessingException e) {
             log.error("Error converting DTO to JSON: {}", e.getMessage());
         }
@@ -218,24 +221,27 @@ public boolean userExitBookingPage(String festivalId, LocalDateTime reservationD
     public void releaseWaitingUser(String festivalId, LocalDateTime reservationDate) {
 
         String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
+        String bookingUserSetKey = getBookingUsersKey(festivalId, reservationDate);
+        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
 
         // 대기열 큐 가장 앞에 있는 사람
-        Set releasedUsers = zSetOperations.range(WAITING_QUEUE_KEY, 0, 0);
+        Set releasedUsers = zSetOperations.range(waitingQueueKey, 0, 0);
 
         if (releasedUsers != null && !releasedUsers.isEmpty()) {
             String releasedUser = releasedUsers.iterator().next();
 
             // 대기열에서 삭제
-            Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, releasedUser);
+            Long removedCount = zSetOperations.remove(waitingQueueKey, releasedUser);
 
             if (removedCount != null && removedCount > 0) {
                 log.info("User {} removed from waiting queue.", releasedUser);
+
                 // 예매 중 사용자 set에 추가
-                redisTemplate.opsForSet().add(BOOKING_USERS_SET_KEY, releasedUser);
+                redisTemplate.opsForSet().add(bookingUserSetKey, releasedUser);
                 log.info("User {} added to booking user set.", releasedUser);
 
                 // 남은 대기열 사용자에게 순번 알림
-                notifyAllWaitingUsers(waitingQueueKey);
+                notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
 
             } else {
                 log.warn("Failed to remove user {} from waiting queue. Removed count: {}", releasedUser, removedCount);
@@ -246,14 +252,14 @@ public void releaseWaitingUser(String festivalId, LocalDateTime reservationDate)
     /**
      * 모든 대기열 사용자에게 순번 업데이트 알림
      */
-    public void notifyAllWaitingUsers(String waitingQueueKey) {
+    public void notifyAllWaitingUsers(String waitingQueueKey, String notificationChannelKey) {
         // 대기열 사용자 수 전체 범위 조회
         Set allUsersInQueue = zSetOperations.range(waitingQueueKey, 0, -1);
 
         if (allUsersInQueue != null) {
             for (String userId : allUsersInQueue) {
                 // 각 사용자에게 순번 알림을 Redis Pub/Sub으로 발행
-                getAndPublishWaitingNumber(waitingQueueKey, userId);
+                getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
             }
         }
     }
@@ -266,9 +272,11 @@ public void notifyAllWaitingUsers(String waitingQueueKey) {
     public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationDate, String userId) {
         Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, userId);
         String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
+        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
+
         if (removedCount != null && removedCount > 0) {
             log.info("User {} removed from waiting queue (manual removal).", userId);
-            notifyAllWaitingUsers(waitingQueueKey); // 순번 업데이트 알림
+            notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey); // 순번 업데이트 알림
             return true;
         } else {
             // 사용자가 대기열에 없었거나, 제거 과정에서 문제가 발생한 경우
@@ -286,11 +294,16 @@ public void cleanup() {
     public String getWaitingQueueKey(String festivalId, LocalDateTime reservationDate) {
         // reservationDate는 yyyyMMddHHmm 형태로 저장 (ex: 202509011930)
         String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return "waiting_queue:" + festivalId + ":" + dateStr;
+        return WAITING_QUEUE_KEY + festivalId + ":" + dateStr;
     }
 
     private String getBookingUsersKey(String festivalId, LocalDateTime reservationDate) {
         String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return "booking_users:" + festivalId + ":" + dateStr;
+        return BOOKING_USERS_SET_KEY + festivalId + ":" + dateStr;
+    }
+
+    public String getNotificationChannelKey(String festivalId, LocalDateTime reservationDate) {
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return NOTIFICATION_CHANNEL + festivalId + ":" + dateStr;
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 1d55e53..b02476c 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,7 +1,11 @@
 myboot.name=Test Env
 
 #log level
-logging.level.com.basic.myspringboot=debug
+logging.level.root=INFO
+logging.level.c.mnms.booking.config.RedisConfig=INFO
+#logging.level.com.basic.myspringboot=debug
+
+
 
 # H2 Database 설정
 spring.datasource.url=jdbc:h2:mem:testdb

From 6710ab201a298066ec7278b1e392b87f99203f42 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 12 Aug 2025 17:05:46 +0900
Subject: [PATCH 022/149] =?UTF-8?q?MNMS-282=20Refactor:=20=EB=8C=80?=
 =?UTF-8?q?=EA=B8=B0=EC=97=B4=20=EB=A1=9C=EC=A7=81=20=EB=A6=AC=ED=8C=A9?=
 =?UTF-8?q?=ED=86=A0=EB=A7=81=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EA=B0=80?=
 =?UTF-8?q?=EB=8F=85=EC=84=B1=20=EA=B0=9C=EC=84=A0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/WaitingController.java |  10 +-
 .../service/WaitingNotificationService.java   |  57 +++-
 .../service/WaitingQueueKeyGenerator.java     |  29 ++
 .../service/WaitingQueueRedisService.java     |  55 ++++
 .../WaitingQueueSchedulingService.java        |  93 ++++++
 .../mnms/booking/service/WaitingService.java  | 286 +++---------------
 6 files changed, 282 insertions(+), 248 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 5e8070b..b53fdbd 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -2,6 +2,8 @@
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import com.mnms.booking.service.FestivalService;
+import com.mnms.booking.service.WaitingNotificationService;
+import com.mnms.booking.service.WaitingQueueKeyGenerator;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -30,6 +32,8 @@ public class WaitingController {
 
     private final WaitingService waitingService;
     private final FestivalService festivalService;
+    private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
+    private final WaitingNotificationService waitingNotificationService;
 
     @Autowired
     private SimpMessagingTemplate messagingTemplate;
@@ -120,8 +124,8 @@ public void subscribeWaitingQueue(
             @AuthenticationPrincipal JwtPrincipal principal) {
         String loginId = principal.loginId();
         log.info("User {} subscribed to waiting queue updates.", loginId);
-        String waitingQueueKey = waitingService.getWaitingQueueKey(festivalId, reservationDate);
-        String notificationChannelKey = waitingService.getNotificationChannelKey(festivalId, reservationDate);
-        waitingService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
+        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
+        waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index d1308e8..2f6ac90 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -1,4 +1,59 @@
 package com.mnms.booking.service;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.Set;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
 public class WaitingNotificationService {
-}
+
+    private final StringRedisTemplate stringRedisTemplate;
+    private final ObjectMapper objectMapper;
+    private final WaitingQueueRedisService waitingQueueRedisService;
+
+    /**
+     * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
+     */
+    public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
+        long waitingNumber = waitingQueueRedisService.getWaitingNumber(waitingQueueKey, loginId);
+        if (waitingNumber != -1) {
+            publishWaitingNumber(loginId, waitingNumber, notificationChannelKey);
+            return waitingNumber;
+        }
+        return -1;
+    }
+
+    /**
+     * Redis Pub/Sub 채널로 대기 순번 정보 발행
+     */
+    private void publishWaitingNumber(String userId, long waitingNumber, String notificationChannelKey) {
+        try {
+            WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
+            String message = objectMapper.writeValueAsString(waitingNumberDto);
+            stringRedisTemplate.convertAndSend(notificationChannelKey, message);
+        } catch (JsonProcessingException e) {
+            log.error("Error converting DTO to JSON: {}", e.getMessage());
+        }
+    }
+
+    /**
+     * 모든 대기열 사용자에게 순번 업데이트 알림
+     */
+    public void notifyAllWaitingUsers(String waitingQueueKey, String notificationChannelKey) {
+        Set allUsersInQueue = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
+
+        if (allUsersInQueue != null) {
+            for (String userId : allUsersInQueue) {
+                getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java b/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java
new file mode 100644
index 0000000..8459b47
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java
@@ -0,0 +1,29 @@
+package com.mnms.booking.service;
+
+import org.springframework.stereotype.Component;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+@Component
+public class WaitingQueueKeyGenerator {
+
+    private static final String WAITING_QUEUE_KEY = "waiting_queue";
+    private static final String BOOKING_USERS_SET_KEY = "booking_users";
+    private static final String NOTIFICATION_CHANNEL = "waiting_notification";
+
+    public String getWaitingQueueKey(String festivalId, LocalDateTime reservationDate) {
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return WAITING_QUEUE_KEY + ":" + festivalId + ":" + dateStr;
+    }
+
+    public String getBookingUsersKey(String festivalId, LocalDateTime reservationDate) {
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return BOOKING_USERS_SET_KEY + ":" + festivalId + ":" + dateStr;
+    }
+
+    public String getNotificationChannelKey(String festivalId, LocalDateTime reservationDate) {
+        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
+        return NOTIFICATION_CHANNEL + ":" + festivalId + ":" + dateStr;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index 9fa2f48..dcd9eda 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -1,4 +1,59 @@
 package com.mnms.booking.service;
 
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ZSetOperations;
+import org.springframework.stereotype.Service;
+
+import java.util.Set;
+
+@Service
 public class WaitingQueueRedisService {
+
+    private final RedisTemplate redisTemplate;
+    private final ZSetOperations zSetOperations;
+
+    public WaitingQueueRedisService(RedisTemplate redisTemplate) {
+        this.redisTemplate = redisTemplate;
+        this.zSetOperations = redisTemplate.opsForZSet();
+    }
+
+    public void addUserToQueue(String waitingQueueKey, String loginId) {
+        long timestamp = System.currentTimeMillis();
+        zSetOperations.add(waitingQueueKey, loginId, timestamp);
+    }
+
+    public boolean removeUserFromQueue(String waitingQueueKey, String userId) {
+        Long removedCount = zSetOperations.remove(waitingQueueKey, userId);
+        return removedCount != null && removedCount > 0;
+    }
+
+    public Set getAllUsersInQueue(String waitingQueueKey) {
+        return zSetOperations.range(waitingQueueKey, 0, -1);
+    }
+
+    public String getFirstUserInQueue(String waitingQueueKey) {
+        Set users = zSetOperations.range(waitingQueueKey, 0, 0);
+        return (users != null && !users.isEmpty()) ? users.iterator().next() : null;
+    }
+
+    public long getWaitingNumber(String waitingQueueKey, String userId) {
+        Long rank = zSetOperations.rank(waitingQueueKey, userId);
+        return (rank != null) ? rank + 1 : -1;
+    }
+
+    public long getBookingUserCount(String bookingUsersKey) {
+        Long count = redisTemplate.opsForSet().size(bookingUsersKey);
+        return (count != null) ? count : 0L;
+    }
+
+    public void addBookingUser(String bookingUsersKey, String userId) {
+        redisTemplate.opsForSet().add(bookingUsersKey, userId);
+    }
+
+    public boolean removeBookingUser(String bookingUsersKey, String userId) {
+        Long removed = redisTemplate.opsForSet().remove(bookingUsersKey, userId);
+        return removed != null && removed > 0;
+    }
 }
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index d2fc1dc..e54b840 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -1,4 +1,97 @@
 package com.mnms.booking.service;
 
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.stereotype.Service;
+
+import java.time.Duration;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledFuture;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
 public class WaitingQueueSchedulingService {
+    private final WaitingQueueRedisService waitingQueueRedisService;
+    private final WaitingNotificationService waitingNotificationService;
+    private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+    private final Map> scheduledTasks = new ConcurrentHashMap<>();
+
+    @PostConstruct
+    public void init() {
+        scheduler.initialize();
+    }
+
+    /**
+     * 스케줄러 시작 (중복 시작 방지)
+     */
+    public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
+        if (scheduledTasks.containsKey(waitingQueueKey) && !scheduledTasks.get(waitingQueueKey).isDone()) {
+            return;
+        }
+        log.info("Starting scheduler for queue: {}", waitingQueueKey);
+        ScheduledFuture task = scheduler.scheduleWithFixedDelay(
+                () -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP),
+                Duration.ofSeconds(5)
+        );
+        scheduledTasks.put(waitingQueueKey, task);
+    }
+
+    /**
+     * 스케줄러 중지
+     */
+    public synchronized void stopScheduler(String waitingQueueKey) {
+        ScheduledFuture task = scheduledTasks.get(waitingQueueKey);
+        if (task != null && !task.isCancelled()) {
+            task.cancel(false);
+            scheduledTasks.remove(waitingQueueKey);
+            log.info("Stopped scheduler for queue: {}", waitingQueueKey);
+        }
+    }
+
+    /**
+     * 주기적으로 대기열 순번 발행 및 입장 처리
+     */
+    private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
+        Set waitingUsers = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
+
+        if (waitingUsers == null || waitingUsers.isEmpty()) {
+            stopScheduler(waitingQueueKey);
+            return;
+        }
+
+        for (String loginId : waitingUsers) {
+            waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+        }
+
+        long currentBookingCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
+
+        while (currentBookingCount < availableNOP) {
+            String nextUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
+            if (nextUser == null) {
+                break;
+            }
+
+            boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, nextUser);
+
+            if (removed) {
+                waitingQueueRedisService.addBookingUser(bookingUsersKey, nextUser);
+                log.info("User {} moved from waiting queue to booking users for queue {}", nextUser, waitingQueueKey);
+                waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
+                currentBookingCount++;
+            } else {
+                break;
+            }
+        }
+    }
+
+    @PreDestroy
+    public void cleanup() {
+        scheduler.shutdown();
+    }
 }
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 84d1066..5cab408 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -1,215 +1,56 @@
 package com.mnms.booking.service;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
-import jakarta.annotation.PreDestroy;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.StringRedisTemplate;
-import org.springframework.data.redis.core.ZSetOperations;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 
-import java.time.Duration;
 import java.time.LocalDateTime;
-import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledFuture;
 
 @Service
 @Slf4j
+@RequiredArgsConstructor
 public class WaitingService {
 
-    private final RedisTemplate redisTemplate; // ZSet 관리용
-    private final StringRedisTemplate stringRedisTemplate; // Pub/Sub 발행용
-    private final ObjectMapper objectMapper; // DTO를 JSON으로 변환용
-    private ZSetOperations zSetOperations;
-
-    // redis message
-    // 대기열큐에 진입한 사용자 ZSet
-    private static final String WAITING_QUEUE_KEY = "waiting_queue";
-
-    // 예매 페이지에 진입한 사용자 Set
-    private static final String BOOKING_USERS_SET_KEY = "booking_users";
-
-    // Redis Pub/Sub 채널 이름
-    private static final String NOTIFICATION_CHANNEL = "waiting_notification";
-
-    // scheduled
-    private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
-    private ScheduledFuture scheduledTask;
-    private final Map> scheduledTasks = new ConcurrentHashMap<>();
-
-    public void init() {
-        zSetOperations = redisTemplate.opsForZSet();
-        // startScheduler() 호출 코드를 제거합니다.
-    }
-
-    public WaitingService(
-            @Qualifier("redisTemplate") RedisTemplate redisTemplate, // <-- redisTemplate 빈 주입
-            @Qualifier("stringRedisTemplate") StringRedisTemplate stringRedisTemplate, // <-- stringRedisTemplate 빈 주입
-            ObjectMapper objectMapper) {
-        this.redisTemplate = redisTemplate;
-        this.stringRedisTemplate = stringRedisTemplate;
-        this.objectMapper = objectMapper;
-
-        // scheduler 초기화
-        scheduler.initialize();
-    }
-
+    private final WaitingQueueRedisService waitingQueueRedisService;
+    private final WaitingQueueSchedulingService waitingQueueSchedulingService;
+    private final WaitingNotificationService waitingNotificationService;
+    private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
 
     /**
-     * 사용자 대기열 진입 처리 (공연별·시간별 분리)
-     * @param festivalId, reservationDate, loginId, availableNOP
+     * 사용자 대기열 진입 처리
      * @return 대기 순번 (즉시 입장 가능 시 0)
      */
     public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String loginId, long availableNOP) {
-        String bookingUsersKey = getBookingUsersKey(festivalId, reservationDate);
-        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
-        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
-
-        zSetOperations = redisTemplate.opsForZSet(); // Redis ZSet ops 재설정 필요
+        String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
+        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
+        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
 
-        Long currentUserCount = redisTemplate.opsForSet().size(bookingUsersKey);
-        if (currentUserCount == null) currentUserCount = 0L;
+        long currentUserCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
 
         if (currentUserCount < availableNOP) {
             log.info("User {} can enter booking page immediately ({} < {}).", loginId, currentUserCount, availableNOP);
-            redisTemplate.opsForSet().add(bookingUsersKey, loginId);
+            waitingQueueRedisService.addBookingUser(bookingUsersKey, loginId);
             return 0L;
         } else {
-            long timestamp = System.currentTimeMillis();
-            zSetOperations.add(waitingQueueKey, loginId, timestamp);
-            log.info("User {} added to waiting queue {} with timestamp {}.", loginId, waitingQueueKey, timestamp);
+            waitingQueueRedisService.addUserToQueue(waitingQueueKey, loginId);
+            log.info("User {} added to waiting queue {}.", loginId, waitingQueueKey);
 
-            startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
+            waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
 
-            return getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+            return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
         }
     }
 
     /**
-     * 스케줄러 시작 (중복 시작 방지)
-     */
-    public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
-        if (scheduledTasks.containsKey(waitingQueueKey) && !scheduledTasks.get(waitingQueueKey).isDone()) {
-            // 이미 스케줄러 실행 중
-            return;
-        }
-        log.info("Starting scheduler for queue: {}", waitingQueueKey);
-        ScheduledFuture task = scheduler.scheduleWithFixedDelay(() -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP), Duration.ofSeconds(5));
-        scheduledTasks.put(waitingQueueKey, task);
-    }
-
-    /**
-     * 스케줄러 중지
-     */
-    public synchronized void stopScheduler(String waitingQueueKey) {
-        ScheduledFuture task = scheduledTasks.get(waitingQueueKey);
-        if (task != null && !task.isCancelled()) {
-            task.cancel(false);
-            scheduledTasks.remove(waitingQueueKey);
-            log.info("Stopped scheduler for queue: {}", waitingQueueKey);
-        }
-    }
-
-    /**
-     * 주기적으로 대기열 순번 발행
-     */
-    public void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
-        zSetOperations = redisTemplate.opsForZSet();
-        Set waitingUsers = zSetOperations.range(waitingQueueKey, 0, -1);
-        if (waitingUsers == null || waitingUsers.isEmpty()) {
-            stopScheduler(waitingQueueKey);
-            return;
-        }
-
-        for (String loginId : waitingUsers) {
-            getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
-        }
-        log.info("Published waiting numbers to {} users for queue {}", waitingUsers.size(), waitingQueueKey);
-
-        // 빈자리 생겼을 때 대기열에서 사용자 입장 처리
-        Long currentBookingCount = redisTemplate.opsForSet().size(bookingUsersKey);
-        if (currentBookingCount == null) currentBookingCount = 0L;
-
-        // 빈자리가 생겼을 때
-        while (currentBookingCount < availableNOP) {
-            Set nextUsers = zSetOperations.range(waitingQueueKey, 0, 0);
-            if (nextUsers == null || nextUsers.isEmpty()) {
-                break;
-            }
-            // 대기열에서 대기자 지우고, 예메 페이지에 입장
-            String nextUser = nextUsers.iterator().next();
-            Long removed = zSetOperations.remove(waitingQueueKey, nextUser);
-
-            // 대기열에 removed 된 사람이 있으면
-            if (removed != null && removed > 0) {
-                redisTemplate.opsForSet().add(bookingUsersKey, nextUser);
-                log.info("User {} moved from waiting queue to booking users for queue {}", nextUser, waitingQueueKey);
-                notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
-                currentBookingCount++;
-            } else {
-                break;
-            }
-        }
-    }
-
-    public List getWaitingUsers() {
-        Set userSet = zSetOperations.range(WAITING_QUEUE_KEY, 0, -1);
-        return (userSet == null) ? Collections.emptyList() : new ArrayList<>(userSet);
-    }
-
-
-    /**
-     * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
-     * @param waitingQueueKey, userId
-     * @return 대기 순번
-     * getNotificationChannelKey(festivalId, reservationDate);
-     */
-    public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
-        zSetOperations = redisTemplate.opsForZSet();
-        Long rank = zSetOperations.rank(waitingQueueKey, loginId);
-        if (rank != null) {
-            long waitingNumber = rank + 1;
-            publishWaitingNumber(loginId, waitingNumber, notificationChannelKey);
-            return waitingNumber;
-        }
-        return -1;
-    }
-
-    /**
-     * Redis Pub/Sub 채널로 대기 순번 정보 발행
-     * @param userId 사용자 ID
-     * @param waitingNumber 대기 순번
-     */
-    private void publishWaitingNumber(String userId, long waitingNumber, String notificationChannelKey) {
-        try {
-            // immediateEntry는 false (이 메서드는 대기 순번 알림용), message는 null
-            WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
-            //WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber);
-            String message = objectMapper.writeValueAsString(waitingNumberDto);
-            // Redis 채널로 발행
-            stringRedisTemplate.convertAndSend(notificationChannelKey, message);
-        } catch (JsonProcessingException e) {
-            log.error("Error converting DTO to JSON: {}", e.getMessage());
-        }
-    }
-
-    /**
-     * 대기열에서 다음 사용자 진입 처리
-     * (예매 완료 또는 타임아웃 등으로 인해 예매 페이지에서 나간 경우 호출)
+     * 예매 페이지에서 사용자 이탈 처리 (예매 완료 또는 타임아웃)
      */
     public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId){
-        // 예매 완료된 Set에서 제거
-        Long removed = redisTemplate.opsForSet().remove(BOOKING_USERS_SET_KEY, userId);
+        String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
+        boolean removed = waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
 
-        if(removed != null && removed > 0){
+        if(removed){
             log.info("User {} exited booking page and removed from booking user set.", userId);
-            // 대기열에서 다음 사용자 진입 처리
+            // 대기열에서 다음 사용자 입장 처리
             releaseWaitingUser(festivalId, reservationDate);
             return true;
         }else{
@@ -218,92 +59,49 @@ public boolean userExitBookingPage(String festivalId, LocalDateTime reservationD
         }
     }
 
-    public void releaseWaitingUser(String festivalId, LocalDateTime reservationDate) {
-
-        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
-        String bookingUserSetKey = getBookingUsersKey(festivalId, reservationDate);
-        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
+    /**
+     * 대기열에서 다음 사용자 입장 처리
+     */
+    private void releaseWaitingUser(String festivalId, LocalDateTime reservationDate) {
+        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
+        String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
+        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
 
         // 대기열 큐 가장 앞에 있는 사람
-        Set releasedUsers = zSetOperations.range(waitingQueueKey, 0, 0);
-
-        if (releasedUsers != null && !releasedUsers.isEmpty()) {
-            String releasedUser = releasedUsers.iterator().next();
+        String releasedUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
 
-            // 대기열에서 삭제
-            Long removedCount = zSetOperations.remove(waitingQueueKey, releasedUser);
+        if (releasedUser != null) {
+            boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, releasedUser);
 
-            if (removedCount != null && removedCount > 0) {
+            if (removed) {
                 log.info("User {} removed from waiting queue.", releasedUser);
 
-                // 예매 중 사용자 set에 추가
-                redisTemplate.opsForSet().add(bookingUserSetKey, releasedUser);
+                waitingQueueRedisService.addBookingUser(bookingUsersKey, releasedUser);
                 log.info("User {} added to booking user set.", releasedUser);
 
-                // 남은 대기열 사용자에게 순번 알림
-                notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
-
+                waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
             } else {
-                log.warn("Failed to remove user {} from waiting queue. Removed count: {}", releasedUser, removedCount);
-            }
-        }
-    }
-
-    /**
-     * 모든 대기열 사용자에게 순번 업데이트 알림
-     */
-    public void notifyAllWaitingUsers(String waitingQueueKey, String notificationChannelKey) {
-        // 대기열 사용자 수 전체 범위 조회
-        Set allUsersInQueue = zSetOperations.range(waitingQueueKey, 0, -1);
-
-        if (allUsersInQueue != null) {
-            for (String userId : allUsersInQueue) {
-                // 각 사용자에게 순번 알림을 Redis Pub/Sub으로 발행
-                getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
+                log.warn("Failed to remove user {} from waiting queue.", releasedUser);
             }
         }
     }
 
     /**
      * 특정 사용자가 대기열에서 이탈했음을 처리
-     * @param festivalId, reservationDate, userId
-     * @return boolean - 사용자가 대기열에서 성공적으로 제거되었으면 true, 아니면 false
      */
     public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationDate, String userId) {
-        Long removedCount = zSetOperations.remove(WAITING_QUEUE_KEY, userId);
-        String waitingQueueKey = getWaitingQueueKey(festivalId, reservationDate);
-        String notificationChannelKey = getNotificationChannelKey(festivalId, reservationDate);
+        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
+        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
+
+        boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, userId);
 
-        if (removedCount != null && removedCount > 0) {
+        if (removed) {
             log.info("User {} removed from waiting queue (manual removal).", userId);
-            notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey); // 순번 업데이트 알림
+            waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
             return true;
         } else {
-            // 사용자가 대기열에 없었거나, 제거 과정에서 문제가 발생한 경우
-            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed. Removed count: {}", userId, removedCount);
+            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed.", userId);
             return false;
         }
     }
-
-    @PreDestroy
-    public void cleanup() {
-        scheduler.shutdown();
-    }
-
-    /// util
-    public String getWaitingQueueKey(String festivalId, LocalDateTime reservationDate) {
-        // reservationDate는 yyyyMMddHHmm 형태로 저장 (ex: 202509011930)
-        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return WAITING_QUEUE_KEY + festivalId + ":" + dateStr;
-    }
-
-    private String getBookingUsersKey(String festivalId, LocalDateTime reservationDate) {
-        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return BOOKING_USERS_SET_KEY + festivalId + ":" + dateStr;
-    }
-
-    public String getNotificationChannelKey(String festivalId, LocalDateTime reservationDate) {
-        String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return NOTIFICATION_CHANNEL + festivalId + ":" + dateStr;
-    }
 }
\ No newline at end of file

From 9397a5db795f409210e76fc9d45e6d08262ae258 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 13 Aug 2025 16:38:57 +0900
Subject: [PATCH 023/149] =?UTF-8?q?MNMS-282=20Feat:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=20=EB=8B=A8=EA=B3=84=20=EC=A1=B0=ED=9A=8C=20=EB=B0=8F=20?=
 =?UTF-8?q?=EC=A0=80=EC=9E=A5&=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java |  54 +++++-
 .../FestivalSelectDeliveryRequestDTO.java     |  16 ++
 .../dto/request/FestivalSelectRequestDTO.java |  14 ++
 .../booking/dto/request/TicketRequestDTO.java |   2 +-
 .../FestivalBookingDetailResponseDTO.java     |  21 +++
 .../response/FestivalDetailResponseDTO.java   |  22 +++
 .../booking/dto/response/QrResponseDTO.java   |   4 +-
 .../dto/response/ScheduleResponseDTO.java     |  14 ++
 .../dto/response/TicketResponseDTO.java       |   3 +-
 .../com/mnms/booking/entity/EventType.java    |   7 +
 .../com/mnms/booking/entity/Festival.java     |   3 +
 .../java/com/mnms/booking/entity/QrCode.java  |   4 +-
 .../booking/entity/ReservationStatus.java     |   7 +
 .../java/com/mnms/booking/entity/Ticket.java  |   8 +-
 .../com/mnms/booking/exception/ErrorCode.java |   7 +-
 .../repository/ScheduleRepository.java        |  10 ++
 .../booking/repository/TicketRepository.java  |   4 +
 .../mnms/booking/service/BookingService.java  | 159 ++++++++++++++++--
 .../mnms/booking/service/QrCodeService.java   |   8 +-
 19 files changed, 338 insertions(+), 29 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/entity/EventType.java
 create mode 100644 src/main/java/com/mnms/booking/entity/ReservationStatus.java
 create mode 100644 src/main/java/com/mnms/booking/repository/ScheduleRepository.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index fb5f650..79d7410 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,6 +1,10 @@
 package com.mnms.booking.controller;
 
+import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
+import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
 import com.mnms.booking.dto.request.TicketRequestDTO;
+import com.mnms.booking.dto.response.FestivalBookingDetailResponseDTO;
+import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.service.BookingService;
@@ -10,10 +14,13 @@
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
+import java.time.LocalDateTime;
+
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/tickets")
@@ -24,7 +31,50 @@ public class BookingController {
     private final UserService userService;
 
     ///  GET : 페스티벌 예매 정보 조회
-    ///  POST : 페스티벌 예매 정보 선택
+    /// 조회 : festival 이름, 선택 날자, 선택 시간, 가격 전체 날짜, poster url, 제한 매수 (festivalId, 선택날짜시간 전달하면 조회 가능)
+    @GetMapping("/detail")
+    @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId와 performanceDate(사용자가 선택한 날짜,시간)으로 공연 상세 정보를 조회합니다.")
+    public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody FestivalSelectRequestDTO request) {
+        return bookingService.getFestivalDetail(request);
+    }
+
+    /// 조회 : festival 이름, 날짜, 시간, poster url, 매수, 가격, 예매자 이름, 전화번호, email, 티켓 수령 방법, 주소
+    @GetMapping("/booking/detail")
+    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId, userId, performanceDate로 공연 및 예매자 상세 정보를 조회합니다.")
+    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(
+            @Valid @RequestBody FestivalSelectRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
+        return bookingService.getFestivalBookingDetail(request, principal.userId());
+    }
+
+
+    /// POST : 페스티벌 예매 정보 선택
+    ///  수정 : 매수, 선택날짜, 선택시간
+    @PostMapping("/selectDate")
+    @Operation(summary = "페스티벌 날짜, 시간 선택",
+            description = "사용자가 특정 페스티벌 날짜, 시간을 선택합니다."
+    )
+    public void selectFestivalDate(
+            @Valid @RequestBody FestivalSelectRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
+        bookingService.selectFestivalDate(request, principal.userId());
+    }
+
+    ///  POST : 티켓수령방법
+    @PostMapping("/selectDeliveryMethod")
+    @Operation(summary = "페스티벌 티켓 수령 방법 선택",
+            description = "사용자가 특정 페스티벌 티켓 수령 방법을 선택합니다."
+    )
+    public void selectFestivalDelivery(
+            @Valid @RequestBody FestivalSelectDeliveryRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
+        bookingService.selectFestivalDelivery(request, principal.userId());
+    }
 
     /// GET : userId로 예매자 정보 조회 - phone, email, address, birth
     @GetMapping("/user/info")
@@ -36,7 +86,7 @@ public ResponseEntity getUserInfo(@AuthenticationPrincipal
         return ResponseEntity.ok(userInfo);
     }
 
-    @PostMapping("/reserve")
+    @PostMapping
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓 예매를 완료합니다."
     )
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
new file mode 100644
index 0000000..5fba816
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
@@ -0,0 +1,16 @@
+package com.mnms.booking.dto.request;
+
+import com.mnms.booking.entity.TicketType;
+import lombok.Data;
+import lombok.Getter;
+
+import java.time.LocalDateTime;
+
+@Data
+@Getter
+public class FestivalSelectDeliveryRequestDTO {
+    private String festivalId;
+    private LocalDateTime performanceDate;
+    private int selectedTicketCount;
+    private String deliveryMethod;
+}
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java
new file mode 100644
index 0000000..b04ef1f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.dto.request;
+
+
+import lombok.Data;
+import lombok.Getter;
+import java.time.LocalDateTime;
+
+@Data
+@Getter
+public class FestivalSelectRequestDTO {
+    private String festivalId;
+    private LocalDateTime performanceDate;
+    private int selectedTicketCount;
+}
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
index 019c18d..e071bc7 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -8,7 +8,7 @@
 @Data
 public class TicketRequestDTO {
 
-    private Long festivalId;
+    private String festivalId;
     private int selectedTicketCount; // <= Festival.maxTicketsPerUser
     private LocalDateTime performanceDate;
     private TicketType deliveryMethod;
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
new file mode 100644
index 0000000..4dd791e
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
@@ -0,0 +1,21 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Getter
+@Setter
+@Builder
+public class FestivalBookingDetailResponseDTO {
+
+    private String festivalName;
+    private LocalDate performanceDate;
+    private LocalTime performanceTime;
+    private String posterFile;
+    private int ticketCount;
+    private int ticketPrice;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
new file mode 100644
index 0000000..f656476
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
@@ -0,0 +1,22 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+@Builder
+public class FestivalDetailResponseDTO {
+    /// festival 정보
+    private String fname; // festival 이름
+    private int ticketPrice;
+    private String posterFile;
+    private int maxPurchase; // 최대 구매 가능 매수
+    private List schedules; // 공연 스케줄 목록
+
+    ///  ticket 정보
+    private LocalDateTime performanceDate; // 선택 날짜,시간
+
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
index 9f2c2ab..34e18b3 100644
--- a/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/QrResponseDTO.java
@@ -18,7 +18,7 @@ public class QrResponseDTO {
     private String qrCodeId;
     private Long userId;
     private LocalDate issuedAt;
-    private LocalDate expiredAt;
+    private LocalDateTime expiredAt;
     private Boolean used;
     private LocalDateTime usedAt;
     private Ticket ticket;
@@ -53,7 +53,7 @@ public static QrResponseDTO create(Long userId, String qrCodeId,Festival festiva
         dto.setUserId(userId);
         dto.setQrCodeId(qrCodeId);
         dto.setIssuedAt(LocalDate.now());
-        dto.setExpiredAt(festival.getFdto());
+        dto.setExpiredAt(ticket.getPerformanceDate().plusMinutes(30));
         dto.setTicket(ticket);
         return dto;
     }
diff --git a/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
new file mode 100644
index 0000000..caecbb4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@Builder
+public class ScheduleResponseDTO {
+    private Long scheduleId; // 공연 일정 PK
+    private String dayOfWeek; // 요일 코드
+    private String time;      // 공연 시작 시간 (HH:mm)
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index ddee0b5..1a22ed9 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -1,6 +1,7 @@
 package com.mnms.booking.dto.response;
 
 import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.ReservationStatus;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.TicketType;
 import lombok.*;
@@ -14,7 +15,7 @@ public class TicketResponseDTO {
 
     private Long id;
     private String reservationNumber;
-    private Boolean reservationStatus;
+    private ReservationStatus reservationStatus;
     private TicketType deliveryMethod;
     private LocalDateTime deliveryDate;
     private Long userId;
diff --git a/src/main/java/com/mnms/booking/entity/EventType.java b/src/main/java/com/mnms/booking/entity/EventType.java
new file mode 100644
index 0000000..6995c99
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/EventType.java
@@ -0,0 +1,7 @@
+package com.mnms.booking.entity;
+
+public enum EventType {
+    FESTIVAL_CREATED,
+    FESTIVAL_UPDATED,
+    FESTIVAL_DELETED,
+}
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 09ab10b..4a099c8 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -18,6 +18,9 @@ public class Festival {
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id; // DB PK (자동증가)
 
+    @Column(name = "event_type")
+    private EventType eventType;
+
     @Column(name = "festival_id", unique = true, nullable = false, length = 20)
     private String festivalId; // 공연 고유 ID (PF000001)
 
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index d203ae5..4626792 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -25,7 +25,7 @@ public class QrCode {
     private LocalDate issuedAt;
 
     @Column(name = "expired_at", nullable = false)
-    private LocalDate expiredAt;
+    private LocalDateTime expiredAt;
 
     @Column(name = "used", nullable = false)
     private Boolean used;
@@ -52,6 +52,6 @@ public void markAsUsed() {
     }
 
     private boolean isExpired() {
-        return LocalDate.now().isAfter(this.expiredAt);
+        return LocalDateTime.now().isAfter(this.expiredAt);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/ReservationStatus.java b/src/main/java/com/mnms/booking/entity/ReservationStatus.java
new file mode 100644
index 0000000..7e087bf
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/ReservationStatus.java
@@ -0,0 +1,7 @@
+package com.mnms.booking.entity;
+
+public enum ReservationStatus {
+    TEMP_RESERVED,     // 가예매 (결제 전)
+    CONFIRMED,         // 결제 완료, 확정
+    CANCELED,          // 결제 실패 or 취소
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 2e0eda1..dca9e59 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -22,7 +22,7 @@ public class Ticket {
     private String reservationNumber; // 예매번호
 
     @Column(name = "reservation_status")
-    private Boolean reservationStatus; // 예매 상태
+    private ReservationStatus reservationStatus; // 예매상태
 
     @Column(name = "delivery_method")
     private TicketType deliveryMethod; // 수령방법
@@ -40,7 +40,9 @@ public class Ticket {
     private LocalDateTime performanceDate; // 선택한 공연 날짜 시간
 
     @Column(name = "selected_ticket_count")
-    private int selectedTicketCount;
+    private int selectedTicketCount; // 선택 매수
+
+
 
     @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private QrCode qrCode;
@@ -53,4 +55,6 @@ public class Ticket {
     public void setQrCode(QrCode qrCode){
         this.qrCode= qrCode;
     }
+
+    public void setDeliveryMethod(TicketType deliveryMethod){this.deliveryMethod = deliveryMethod;}
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 8877663..f6fddde 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -9,11 +9,14 @@ public enum ErrorCode {
     // FESTIVAL
     FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
     FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
-    FESTIVAL_DELIVERY_INVALID("F003", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
-    FESTIVAL_MISMATCH("F004", "해당하는 FESTIVAL QR 코드가 아닙니다.", HttpStatus.FORBIDDEN),
+    FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    FESTIVAL_DELIVERY_INVALID("F004", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
+    FESTIVAL_MISMATCH("F005", "해당하는 FESTIVAL QR 코드가 아닙니다.", HttpStatus.FORBIDDEN),
 
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
+    TICKET_NOT_FOUND("T002", "해당하는 티켓을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    TICKET_INVALID_DELIVERY_METHOD("T003", "수령 방법이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
diff --git a/src/main/java/com/mnms/booking/repository/ScheduleRepository.java b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
new file mode 100644
index 0000000..c75ed05
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
@@ -0,0 +1,10 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.Schedule;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface ScheduleRepository  extends JpaRepository {
+    List findByFestivalId(String festivalId);
+}
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index ffb2aba..8730ec7 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -4,7 +4,11 @@
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.time.LocalDateTime;
+import java.util.Optional;
+
 @Repository
 public interface TicketRepository extends JpaRepository {
     int countByUserIdAndFestivalId(Long userId, Long festivalId);
+    Optional findByFestivalIdAndUserIdAndPerformanceDate(String festivalId, Long userId, LocalDateTime performanceDate);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index 03e4082..62702b0 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -1,23 +1,26 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
+import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
 import com.mnms.booking.dto.request.TicketRequestDTO;
-import com.mnms.booking.dto.response.QrResponseDTO;
-import com.mnms.booking.dto.response.TicketResponseDTO;
-import com.mnms.booking.entity.Festival;
-import com.mnms.booking.entity.QrCode;
-import com.mnms.booking.entity.Ticket;
-import com.mnms.booking.entity.TicketType;
+import com.mnms.booking.dto.response.*;
+import com.mnms.booking.entity.*;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.ScheduleRepository;
 import com.mnms.booking.repository.TicketRepository;
-import jakarta.transaction.Transactional;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
 import java.util.UUID;
 
 @Service
@@ -28,11 +31,147 @@ public class BookingService {
     private final QrCodeRepository qrCodeRepository;
     private final FestivalRepository festivalRepository;
     private final QrCodeService qrCodeService;
+    private final ScheduleRepository scheduleRepository;
+
+    @Transactional(readOnly = true)
+    public FestivalDetailResponseDTO getFestivalDetail(@Valid FestivalSelectRequestDTO request) {
+        // 페스티벌 조회
+        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+
+        LocalDateTime performanceDate = request.getPerformanceDate();
+        LocalDate selectDate = performanceDate.toLocalDate();
+        LocalTime selectTime = performanceDate.toLocalTime();
+
+        // 날짜 범위 검증
+        if (selectDate.isBefore(festival.getFdfrom()) || selectDate.isAfter(festival.getFdto())) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+
+        // 3. 스케줄 찾기
+        String dayOfWeek = selectDate.getDayOfWeek().name();
+        Schedule matchedSchedule = festival.getSchedules().stream()
+                .filter(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&
+                        LocalTime.parse(s.getTime(), DateTimeFormatter.ofPattern("HH:mm")).equals(selectTime))
+                .findFirst()
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME));
+
+
+        List schedules = scheduleRepository.findByFestivalId(festival.getFestivalId());
+        List scheduleDTOs = schedules.stream()
+                .map(s -> ScheduleResponseDTO.builder()
+                        .scheduleId(s.getScheduleId())
+                        .dayOfWeek(s.getDayOfWeek())
+                        .time(s.getTime())
+                        .build())
+                .toList();
+
+        // 4. DTO 반환
+        return FestivalDetailResponseDTO.builder()
+                .fname(festival.getFname())
+                .ticketPrice(festival.getTicketPrice())
+                .posterFile(festival.getPosterFile())
+                .maxPurchase(festival.getMaxPurchase())
+                .performanceDate(request.getPerformanceDate())
+                .schedules(scheduleDTOs)
+                .build();
+    }
+
+    // 가예매 상황 : 1차 저장
+    @Transactional
+    public void selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
+        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+
+        // 요청한 날짜가 해당 페스티벌의 공연 일정에 포함되어 있는지 확인
+        LocalDateTime performanceDate = request.getPerformanceDate();
+        LocalDate selectDate = performanceDate.toLocalDate();
+        LocalTime selectTime = performanceDate.toLocalTime();
+
+        if(selectDate.isBefore(festival.getFdfrom()) || selectDate.isAfter(festival.getFdto())){
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+
+        String dayOfWeek = performanceDate.getDayOfWeek().name(); // MON, TUE, 형태임
+        boolean isValidSchedule = festival.getSchedules().stream()
+                .anyMatch(s ->
+                        s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&
+                                LocalTime.parse(s.getTime()).equals(selectTime)
+                );
+
+        if (!isValidSchedule) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
+        }
+
+        if(festival.getAvailableNOP() < request.getSelectedTicketCount()){
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+
+        // 페스티벌, 유저, 선택 날짜, 시간 저장
+        Ticket ticket = Ticket.builder()
+                .festival(festival)
+                .userId(userId)
+                .selectedTicketCount(request.getSelectedTicketCount())
+                .performanceDate(performanceDate)
+                .reservationStatus(ReservationStatus.TEMP_RESERVED)
+                .build();
+        ticketRepository.save(ticket);
+    }
+
+    // 가예매 상황 : 2차 조회
+    @Transactional(readOnly = true)
+    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(@Valid FestivalSelectRequestDTO request, Long userId) {
+        // 공연 정보 조회
+        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+
+        LocalDateTime performanceDate = request.getPerformanceDate();
+        LocalDate date = performanceDate.toLocalDate();
+        LocalTime time = performanceDate.toLocalTime();
+
+        // 2. 예매 티켓 조회 (해당 유저, 해당 공연 시간)
+        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndPerformanceDate(request.getFestivalId(), userId, performanceDate)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        // 4. DTO 생성
+        return FestivalBookingDetailResponseDTO.builder()
+                .festivalName(festival.getFname())
+                .performanceDate(date)
+                .performanceTime(time)
+                .posterFile(festival.getPosterFile())
+                .ticketCount(ticket.getSelectedTicketCount())
+                .ticketPrice(festival.getTicketPrice())
+                .build();
+    }
+
+    // 가예매 상황 : 2차 저장
+    @Transactional
+    public void selectFestivalDelivery(FestivalSelectDeliveryRequestDTO request, Long userId) {
+        // 1. 해당 티켓 조회
+        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndPerformanceDate(
+                request.getFestivalId(),
+                userId,
+                request.getPerformanceDate()
+        ).orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        TicketType type;
+        try {
+            type = TicketType.valueOf(request.getDeliveryMethod().toUpperCase());
+        } catch (IllegalArgumentException e) {
+            throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
+        }
+
+        // 티켓 엔티티에 수령 방법 설정
+        ticket.setDeliveryMethod(type);
+
+        // 저장
+        ticketRepository.save(ticket);
+    }
+
 
     @Transactional
     public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
-        // 페스티벌 정보 조회
-        Festival festival = festivalRepository.findById(request.getFestivalId())
+        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
         // 사용자 예약 티켓 매수, 지류티켓 확인
@@ -108,7 +247,7 @@ private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festi
                                LocalDateTime deliveryDate) { // , QrCode qrCode
         return Ticket.builder()
                 .reservationNumber(generateReservationNumber())
-                .reservationStatus(true)
+                .reservationStatus(ReservationStatus.CONFIRMED)
                 .deliveryMethod(request.getDeliveryMethod())
                 .reservationDate(LocalDate.now())
                 .deliveryDate(deliveryDate)
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index 5000732..d6e43ce 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -1,13 +1,11 @@
 package com.mnms.booking.service;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.WriterException;
 import com.google.zxing.client.j2se.MatrixToImageWriter;
 import com.google.zxing.common.BitMatrix;
 import com.google.zxing.qrcode.QRCodeWriter;
-import com.mnms.booking.dto.request.QrRequestDTO;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.exception.BusinessException;
@@ -16,15 +14,11 @@
 import jakarta.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.security.SecureRandom;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.Base64;
 
 @Service
 @RequiredArgsConstructor
@@ -90,7 +84,7 @@ public void validateAndUseQrCode(Long userId, String qrCodeId) {
 //        }
 
         // 만료 여부 확인
-        if (qrCode.getExpiredAt().isBefore(LocalDate.now())) {
+        if (qrCode.getExpiredAt().isBefore(LocalDateTime.now())) {
             throw new BusinessException(ErrorCode.QR_CODE_EXPIRED);
         }
 

From 948d8d30578e63cf9e0b91816f97f63511268d76 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 13 Aug 2025 17:35:58 +0900
Subject: [PATCH 024/149] =?UTF-8?q?MNMS-282=20Fix:=20db=20h2=EC=97=90?=
 =?UTF-8?q?=EC=84=9C=20mariaDB=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/config/SecurityConfig.java   |  3 +-
 .../java/com/mnms/booking/entity/Ticket.java  |  2 -
 .../repository/FestivalRepository.java        |  2 +
 .../repository/ScheduleRepository.java        |  7 ++-
 .../booking/repository/TicketRepository.java  | 11 +++-
 src/main/resources/application-dev.properties | 51 +++++++++++++++++++
 .../resources/application-test.properties     |  2 -
 src/main/resources/application.properties     |  2 +-
 8 files changed, 72 insertions(+), 8 deletions(-)
 create mode 100644 src/main/resources/application-dev.properties

diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 0ec33fe..730aeaf 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -30,7 +30,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                                 "/public/**",
                                 "/h2-console/**",
                                 "/api/captcha/**",
-                                "/api/qr/**"
+                                "/api/qr/**",
+                                "/api/tickets/detail"
                                 ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index dca9e59..e830d62 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -42,8 +42,6 @@ public class Ticket {
     @Column(name = "selected_ticket_count")
     private int selectedTicketCount; // 선택 매수
 
-
-
     @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
     private QrCode qrCode;
 
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index 58c6cb4..25ce591 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -2,9 +2,11 @@
 
 import com.mnms.booking.entity.Festival;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
 
 import java.util.Optional;
 
+@Repository
 public interface FestivalRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByFestivalId(String festivalId);
diff --git a/src/main/java/com/mnms/booking/repository/ScheduleRepository.java b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
index c75ed05..2458020 100644
--- a/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
+++ b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
@@ -2,9 +2,14 @@
 
 import com.mnms.booking.entity.Schedule;
 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;
 
+@Repository
 public interface ScheduleRepository  extends JpaRepository {
-    List findByFestivalId(String festivalId);
+    @Query("SELECT s FROM Schedule s WHERE s.festival.id = :festivalId")
+    List findByFestivalId(@Param("festivalId") String festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 8730ec7..e7f625a 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -1,7 +1,10 @@
 package com.mnms.booking.repository;
 
+import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 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.time.LocalDateTime;
@@ -10,5 +13,11 @@
 @Repository
 public interface TicketRepository extends JpaRepository {
     int countByUserIdAndFestivalId(Long userId, Long festivalId);
-    Optional findByFestivalIdAndUserIdAndPerformanceDate(String festivalId, Long userId, LocalDateTime performanceDate);
+
+    @Query("SELECT t FROM Ticket t WHERE t.festival.id = :festivalId AND t.userId = :userId AND t.performanceDate = :performanceDate")
+    Optional findByFestivalIdAndUserIdAndPerformanceDate(
+            @Param("festivalId") String festivalId,
+            @Param("userId") Long userId,
+            @Param("performanceDate") LocalDateTime performanceDate
+    );
 }
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
new file mode 100644
index 0000000..427a99e
--- /dev/null
+++ b/src/main/resources/application-dev.properties
@@ -0,0 +1,51 @@
+myboot.name=Dev Env
+
+#log level
+logging.level.root=INFO
+logging.level.c.mnms.booking.config.RedisConfig=INFO
+#logging.level.com.basic.myspringboot=debug
+
+#maria db info
+spring.datasource.url=${DB_URL}
+spring.datasource.username=${DB_USERNAME}
+spring.datasource.password=${DB_PASSWORD}
+spring.datasource.driverClassName=org.mariadb.jdbc.Driver
+
+# hibernate info
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
+
+# redis 설정 - 로컬 설정
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+#spring.redis.password=your_password
+
+# kafka
+app.kafka.topic.booking-event=booking-events
+app.kafka.topic.user-event: user-events
+
+spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
+spring.kafka.consumer.auto-offset-reset=earliest
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+#spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
+spring.kafka.consumer.properties.spring.json.trusted.packages=*
+spring.kafka.consumer.properties.spring.json.use.type.headers=false
+
+# kafka 사용 X
+#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
+
+# jwt
+jwt.public-pem-path=classpath:keys/public.pem
+jwt.issuer=festival-user-service
+
+spring.config.import=optional:file:.env[.properties]
+
+# swagger
+springdoc.api-docs.enabled=true
+springdoc.swagger-ui.enabled=true
+springdoc.swagger-ui.path=/swagger-ui.html
+springdoc.override-with-generic-response=false
+
+# user api
+user.service.url=${USER_INFO_API}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index b02476c..affea0f 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -5,8 +5,6 @@ logging.level.root=INFO
 logging.level.c.mnms.booking.config.RedisConfig=INFO
 #logging.level.com.basic.myspringboot=debug
 
-
-
 # H2 Database 설정
 spring.datasource.url=jdbc:h2:mem:testdb
 spring.datasource.driver-class-name=org.h2.Driver
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 65fb4dc..3633a4e 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -10,7 +10,7 @@ server.port=8082
 server.address=0.0.0.0
 
 # 현재 활성화된 환경 - 개발 환경에 따라 수정하세요
-spring.profiles.active=test
+spring.profiles.active=dev
 
 # log file
 logging.file.path=logs

From f8edb6ef0ac562a5d9e012b96d7e2afb145da6c2 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 14 Aug 2025 14:05:21 +0900
Subject: [PATCH 025/149] =?UTF-8?q?MNMS-282=20Fix:=20=EC=98=88=EC=95=BD=20?=
 =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/config/SecurityConfig.java   |  2 +-
 .../booking/controller/BookingController.java | 57 ++++++++++---------
 .../repository/ScheduleRepository.java        |  2 +-
 .../booking/repository/TicketRepository.java  |  2 +-
 .../mnms/booking/service/BookingService.java  | 16 ++++--
 5 files changed, 45 insertions(+), 34 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 730aeaf..7f23cf3 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -31,7 +31,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                                 "/h2-console/**",
                                 "/api/captcha/**",
                                 "/api/qr/**",
-                                "/api/tickets/detail"
+                                "/api/booking/detail/phases/1"
                                 ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 79d7410..a916bbb 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -23,51 +23,49 @@
 
 @RestController
 @RequiredArgsConstructor
-@RequestMapping("/api/tickets")
-@Tag(name = "예매 API", description = "예매 티켓 생성")
+@RequestMapping("/api/booking")
+@Tag(name = "예매 API", description = "예매 티켓 조회, 티켓 선택, 생성")
 public class BookingController {
 
     private final BookingService bookingService;
     private final UserService userService;
 
-    ///  GET : 페스티벌 예매 정보 조회
-    /// 조회 : festival 이름, 선택 날자, 선택 시간, 가격 전체 날짜, poster url, 제한 매수 (festivalId, 선택날짜시간 전달하면 조회 가능)
-    @GetMapping("/detail")
+    /// GET : 페스티벌 예매 정보 조회
+    @GetMapping("/detail/phases/1")
     @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId와 performanceDate(사용자가 선택한 날짜,시간)으로 공연 상세 정보를 조회합니다.")
+            description = "festivalId와 performanceDate(사용자가 선택한 날짜 시간) 으로 공연 상세 정보를 조회합니다." +
+                    "selectedTicketCount는 0으로 넣을 것!")
     public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody FestivalSelectRequestDTO request) {
         return bookingService.getFestivalDetail(request);
     }
 
-    /// 조회 : festival 이름, 날짜, 시간, poster url, 매수, 가격, 예매자 이름, 전화번호, email, 티켓 수령 방법, 주소
-    @GetMapping("/booking/detail")
-    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId, userId, performanceDate로 공연 및 예매자 상세 정보를 조회합니다.")
-    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(
+    /// POST : 페스티벌 예매 정보 0차, 1차 선택
+    @PostMapping("/selectDate")
+    @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
+            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)"
+    )
+    public void selectFestivalDate(
             @Valid @RequestBody FestivalSelectRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        return bookingService.getFestivalBookingDetail(request, principal.userId());
+        bookingService.selectFestivalDate(request, principal.userId());
     }
 
-
-    /// POST : 페스티벌 예매 정보 선택
-    ///  수정 : 매수, 선택날짜, 선택시간
-    @PostMapping("/selectDate")
-    @Operation(summary = "페스티벌 날짜, 시간 선택",
-            description = "사용자가 특정 페스티벌 날짜, 시간을 선택합니다."
-    )
-    public void selectFestivalDate(
+    /// GET : festival 이름, 날짜, 시간, poster url, 매수, 가격, 예매자 이름, 전화번호, email, 티켓 수령 방법, 주소
+    @GetMapping("/detail/phases/2")
+    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId, userId, performanceDate로 공연 및 예매자 상세 정보를 조회합니다.")
+    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(
             @Valid @RequestBody FestivalSelectRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        bookingService.selectFestivalDate(request, principal.userId());
+        return bookingService.getFestivalBookingDetail(request, principal.userId());
     }
 
-    ///  POST : 티켓수령방법
+    ///  POST : 페스티벌 예매 정보 2차 선택 - 티켓수령방법
     @PostMapping("/selectDeliveryMethod")
-    @Operation(summary = "페스티벌 티켓 수령 방법 선택",
-            description = "사용자가 특정 페스티벌 티켓 수령 방법을 선택합니다."
+    @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법 선택",
+            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER)"
     )
     public void selectFestivalDelivery(
             @Valid @RequestBody FestivalSelectDeliveryRequestDTO request,
@@ -76,19 +74,21 @@ public void selectFestivalDelivery(
         bookingService.selectFestivalDelivery(request, principal.userId());
     }
 
-    /// GET : userId로 예매자 정보 조회 - phone, email, address, birth
+    /// GET : userId로 예매자 정보 조회
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
-            description = "예매 과정에서 예매자 정보를 조회합니다."
+            description = "예매 과정에서 예매자 정보를 조회합니다." +
+                    "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
     )
     public ResponseEntity getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
         UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
         return ResponseEntity.ok(userInfo);
     }
 
+    /// POST : 3차 예매 완료 (결제 직전)
     @PostMapping
     @Operation(summary = "페스티벌 예매 티켓 생성",
-            description = "사용자가 특정 페스티벌 티켓 예매를 완료합니다."
+            description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
     )
     public ResponseEntity reserveTicket(
             @Valid @RequestBody TicketRequestDTO request,
@@ -97,4 +97,7 @@ public ResponseEntity reserveTicket(
         TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
         return ResponseEntity.ok(response);
     }
+
+    ///  POST : 가예매 -> 진예매 (결제 완료 확인 상태)
+
 }
diff --git a/src/main/java/com/mnms/booking/repository/ScheduleRepository.java b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
index 2458020..adf2faf 100644
--- a/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
+++ b/src/main/java/com/mnms/booking/repository/ScheduleRepository.java
@@ -10,6 +10,6 @@
 
 @Repository
 public interface ScheduleRepository  extends JpaRepository {
-    @Query("SELECT s FROM Schedule s WHERE s.festival.id = :festivalId")
+    @Query("SELECT s FROM Schedule s WHERE s.festival.festivalId = :festivalId")
     List findByFestivalId(@Param("festivalId") String festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index e7f625a..c1d8d09 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -14,7 +14,7 @@
 public interface TicketRepository extends JpaRepository {
     int countByUserIdAndFestivalId(Long userId, Long festivalId);
 
-    @Query("SELECT t FROM Ticket t WHERE t.festival.id = :festivalId AND t.userId = :userId AND t.performanceDate = :performanceDate")
+    @Query("SELECT t FROM Ticket t WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.performanceDate = :performanceDate")
     Optional findByFestivalIdAndUserIdAndPerformanceDate(
             @Param("festivalId") String festivalId,
             @Param("userId") Long userId,
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index 62702b0..add6131 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -13,6 +13,7 @@
 import com.mnms.booking.repository.TicketRepository;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -20,11 +21,14 @@
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
 import java.util.List;
+import java.util.Locale;
 import java.util.UUID;
 
 @Service
 @RequiredArgsConstructor
+@Slf4j
 public class BookingService {
 
     private final TicketRepository ticketRepository;
@@ -48,15 +52,17 @@ public FestivalDetailResponseDTO getFestivalDetail(@Valid FestivalSelectRequestD
             throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
         }
 
-        // 3. 스케줄 찾기
-        String dayOfWeek = selectDate.getDayOfWeek().name();
+        // 스케줄 찾기
+        String dayOfWeek = selectDate.getDayOfWeek()
+                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
+                .toUpperCase();
+
         Schedule matchedSchedule = festival.getSchedules().stream()
                 .filter(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&
                         LocalTime.parse(s.getTime(), DateTimeFormatter.ofPattern("HH:mm")).equals(selectTime))
                 .findFirst()
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME));
 
-
         List schedules = scheduleRepository.findByFestivalId(festival.getFestivalId());
         List scheduleDTOs = schedules.stream()
                 .map(s -> ScheduleResponseDTO.builder()
@@ -92,7 +98,9 @@ public void selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
             throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
         }
 
-        String dayOfWeek = performanceDate.getDayOfWeek().name(); // MON, TUE, 형태임
+        String dayOfWeek = selectDate.getDayOfWeek()
+                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
+                .toUpperCase();
         boolean isValidSchedule = festival.getSchedules().stream()
                 .anyMatch(s ->
                         s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&

From 171fb71e2a986b5145b54f74d005e9c32e57ad32 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 14 Aug 2025 16:37:52 +0900
Subject: [PATCH 026/149] =?UTF-8?q?MNMS-282=20Chore:=203=EC=B0=A8=20?=
 =?UTF-8?q?=EA=B0=80=EC=98=88=EB=A7=A4=20=EC=88=98=EC=A0=95=20=EC=99=84?=
 =?UTF-8?q?=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

calculateDeliveryDate -> deliveryDate 수정
최대 예매 티켓 확인 로직 수정
---
 .../booking/controller/BookingController.java | 20 ++---
 .../dto/request/FestivalRequestDTO.java       | 39 ++-------
 .../FestivalSelectDeliveryRequestDTO.java     |  3 +-
 .../FestivalBookingDetailResponseDTO.java     |  7 +-
 .../com/mnms/booking/entity/Festival.java     |  2 +
 .../com/mnms/booking/entity/Schedule.java     |  2 +
 .../java/com/mnms/booking/entity/Ticket.java  |  4 +-
 .../com/mnms/booking/exception/ErrorCode.java |  1 +
 .../booking/repository/TicketRepository.java  | 12 +--
 .../mnms/booking/service/BookingService.java  | 87 ++++++++-----------
 10 files changed, 69 insertions(+), 108 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index a916bbb..69d62d1 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.controller;
 
+import com.mnms.booking.dto.request.FestivalRequestDTO;
 import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
 import com.mnms.booking.dto.request.TicketRequestDTO;
@@ -14,13 +15,10 @@
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
-import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
-import java.time.LocalDateTime;
-
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
@@ -39,24 +37,24 @@ public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody FestivalS
         return bookingService.getFestivalDetail(request);
     }
 
-    /// POST : 페스티벌 예매 정보 0차, 1차 선택
+    /// POST : 페스티벌 예매 정보 1차 선택
     @PostMapping("/selectDate")
     @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
-            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)"
+            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)를 입력하고 reservationNumber를 반환합니다."
     )
-    public void selectFestivalDate(
+    public String selectFestivalDate(
             @Valid @RequestBody FestivalSelectRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        bookingService.selectFestivalDate(request, principal.userId());
+        return bookingService.selectFestivalDate(request, principal.userId());
     }
 
     /// GET : festival 이름, 날짜, 시간, poster url, 매수, 가격, 예매자 이름, 전화번호, email, 티켓 수령 방법, 주소
     @GetMapping("/detail/phases/2")
     @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId, userId, performanceDate로 공연 및 예매자 상세 정보를 조회합니다.")
+            description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
     public FestivalBookingDetailResponseDTO getFestivalBookingDetail(
-            @Valid @RequestBody FestivalSelectRequestDTO request,
+            @Valid @RequestBody FestivalRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
         return bookingService.getFestivalBookingDetail(request, principal.userId());
@@ -86,12 +84,12 @@ public ResponseEntity getUserInfo(@AuthenticationPrincipal
     }
 
     /// POST : 3차 예매 완료 (결제 직전)
-    @PostMapping
+    @PostMapping("/qr")
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
     )
     public ResponseEntity reserveTicket(
-            @Valid @RequestBody TicketRequestDTO request,
+            @Valid @RequestBody FestivalRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
         TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
index 8036279..d69b9e5 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
@@ -1,39 +1,10 @@
 package com.mnms.booking.dto.request;
 
 import lombok.Data;
+import lombok.Getter;
 
-import java.time.LocalDate;
-import java.util.List;
-
-@Data
+@Data @Getter
 public class FestivalRequestDTO {
-
-    private String id; // 공연 고유 ID (PF000001)
-
-    private String fname; // 공연명
-
-    private LocalDate fdfrom; // 공연 시작일
-
-    private LocalDate fdto; // 공연 종료일
-
-    private String posterFile; // 공연 대표 이미지 URL
-
-    private String fcltynm; // 공연장 장소
-
-    private int ticketPick; // 티켓 배송 방법
-
-    private int maxPurchase; // 1회 최대 구매 가능 수량
-
-    private int ticketPrice; // 티켓 가격
-
-    private int availableNOP; // 수용인원
-
-    private List schedules;
-
-    @Data
-    public static class ScheduleDTO {
-        private Long scheduleId;
-        private String dayOfWeek;
-        private String time;
-    }
-}
\ No newline at end of file
+    private String festivalId;
+    private String reservationNumber;
+}
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
index 5fba816..d85b2e3 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
@@ -10,7 +10,6 @@
 @Getter
 public class FestivalSelectDeliveryRequestDTO {
     private String festivalId;
-    private LocalDateTime performanceDate;
-    private int selectedTicketCount;
+    private String reservationNumber;
     private String deliveryMethod;
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
index 4dd791e..aa91e2c 100644
--- a/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
@@ -5,6 +5,7 @@
 import lombok.Setter;
 
 import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.LocalTime;
 
 @Getter
@@ -13,9 +14,9 @@
 public class FestivalBookingDetailResponseDTO {
 
     private String festivalName;
-    private LocalDate performanceDate;
-    private LocalTime performanceTime;
     private String posterFile;
-    private int ticketCount;
     private int ticketPrice;
+
+    private LocalDateTime performanceDate;
+    private int ticketCount;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 4a099c8..967f041 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.entity;
 
+import com.fasterxml.jackson.annotation.JsonManagedReference;
 import jakarta.persistence.*;
 import lombok.Getter;
 import lombok.Setter;
@@ -52,5 +53,6 @@ public class Festival {
     private int availableNOP; // 수용인원
 
     @OneToMany(mappedBy = "festival", cascade = CascadeType.ALL, orphanRemoval = true)
+    @JsonManagedReference
     private List schedules = new ArrayList<>();
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Schedule.java b/src/main/java/com/mnms/booking/entity/Schedule.java
index 4ca8590..b17a425 100644
--- a/src/main/java/com/mnms/booking/entity/Schedule.java
+++ b/src/main/java/com/mnms/booking/entity/Schedule.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.entity;
 
+import com.fasterxml.jackson.annotation.JsonBackReference;
 import jakarta.persistence.*;
 import lombok.Getter;
 import lombok.Setter;
@@ -20,5 +21,6 @@ public class Schedule {
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "festival_id", nullable = false)
+    @JsonBackReference
     private Festival festival;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index e830d62..31773cc 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -31,7 +31,7 @@ public class Ticket {
     private Long userId; // 예매자 id
 
     @Column(name = "reservation_date")
-    private LocalDate reservationDate; // 예매한 날짜
+    private LocalDate reservationDate; // 예매를 수행한 날짜
 
     @Column(name = "delivery_date")
     private LocalDateTime deliveryDate; // 택배 날짜
@@ -53,6 +53,6 @@ public class Ticket {
     public void setQrCode(QrCode qrCode){
         this.qrCode= qrCode;
     }
-
     public void setDeliveryMethod(TicketType deliveryMethod){this.deliveryMethod = deliveryMethod;}
+    public void setDeliveryDate(LocalDateTime deliveryDate){ this.deliveryDate = deliveryDate;}
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index f6fddde..5a09acc 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -17,6 +17,7 @@ public enum ErrorCode {
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
     TICKET_NOT_FOUND("T002", "해당하는 티켓을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     TICKET_INVALID_DELIVERY_METHOD("T003", "수령 방법이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
+    FESTIVAL_DELIVERY_NOT_COMPLETED("T004", "티켓 수령 방법이 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index c1d8d09..0895845 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -1,6 +1,5 @@
 package com.mnms.booking.repository;
 
-import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
@@ -12,12 +11,15 @@
 
 @Repository
 public interface TicketRepository extends JpaRepository {
-    int countByUserIdAndFestivalId(Long userId, Long festivalId);
+    int countByUserIdAndFestivalIdAndPerformanceDate(Long userId, Long festivalId, LocalDateTime performanceDate);
 
-    @Query("SELECT t FROM Ticket t WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.performanceDate = :performanceDate")
-    Optional findByFestivalIdAndUserIdAndPerformanceDate(
+
+    @Query("SELECT t FROM Ticket t WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.reservationNumber = :reservationNumber")
+    Optional findByFestivalIdAndUserIdAndReservationNumber(
             @Param("festivalId") String festivalId,
             @Param("userId") Long userId,
-            @Param("performanceDate") LocalDateTime performanceDate
+            @Param("reservationNumber") String reservationNumber
     );
+
+    Optional findByReservationNumber(String reservationNumber);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
index add6131..934d8a7 100644
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ b/src/main/java/com/mnms/booking/service/BookingService.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.request.FestivalRequestDTO;
 import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
 import com.mnms.booking.dto.request.TicketRequestDTO;
@@ -27,8 +28,9 @@
 import java.util.UUID;
 
 @Service
-@RequiredArgsConstructor
 @Slf4j
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
 public class BookingService {
 
     private final TicketRepository ticketRepository;
@@ -37,7 +39,6 @@ public class BookingService {
     private final QrCodeService qrCodeService;
     private final ScheduleRepository scheduleRepository;
 
-    @Transactional(readOnly = true)
     public FestivalDetailResponseDTO getFestivalDetail(@Valid FestivalSelectRequestDTO request) {
         // 페스티벌 조회
         Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
@@ -85,7 +86,7 @@ public FestivalDetailResponseDTO getFestivalDetail(@Valid FestivalSelectRequestD
 
     // 가예매 상황 : 1차 저장
     @Transactional
-    public void selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
+    public String selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
         Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
@@ -115,79 +116,85 @@ public void selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
 
+        // 사용자 예약 티켓 매수, 지류티켓 확인
+        validateReservation(userId, request, festival);
+
         // 페스티벌, 유저, 선택 날짜, 시간 저장
         Ticket ticket = Ticket.builder()
                 .festival(festival)
                 .userId(userId)
+                .reservationNumber(generateReservationNumber())
                 .selectedTicketCount(request.getSelectedTicketCount())
                 .performanceDate(performanceDate)
                 .reservationStatus(ReservationStatus.TEMP_RESERVED)
+                .reservationDate(LocalDate.now())
                 .build();
         ticketRepository.save(ticket);
+        return ticket.getReservationNumber();
     }
 
     // 가예매 상황 : 2차 조회
-    @Transactional(readOnly = true)
-    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(@Valid FestivalSelectRequestDTO request, Long userId) {
+    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(@Valid FestivalRequestDTO request, Long userId) {
         // 공연 정보 조회
         Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
-        LocalDateTime performanceDate = request.getPerformanceDate();
-        LocalDate date = performanceDate.toLocalDate();
-        LocalTime time = performanceDate.toLocalTime();
-
-        // 2. 예매 티켓 조회 (해당 유저, 해당 공연 시간)
-        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndPerformanceDate(request.getFestivalId(), userId, performanceDate)
+        Ticket ticket = ticketRepository.findByReservationNumber(request.getReservationNumber())
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
         // 4. DTO 생성
         return FestivalBookingDetailResponseDTO.builder()
                 .festivalName(festival.getFname())
-                .performanceDate(date)
-                .performanceTime(time)
                 .posterFile(festival.getPosterFile())
-                .ticketCount(ticket.getSelectedTicketCount())
                 .ticketPrice(festival.getTicketPrice())
+                .performanceDate(ticket.getPerformanceDate()) // 선택한 페스티벌 날짜 시간
+                .ticketCount(ticket.getSelectedTicketCount())
                 .build();
     }
 
     // 가예매 상황 : 2차 저장
     @Transactional
     public void selectFestivalDelivery(FestivalSelectDeliveryRequestDTO request, Long userId) {
+
         // 1. 해당 티켓 조회
-        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndPerformanceDate(
+        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(
                 request.getFestivalId(),
                 userId,
-                request.getPerformanceDate()
+                request.getReservationNumber()
         ).orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
         TicketType type;
+        // 배송 방법 유효성 검사
+        if (request.getDeliveryMethod() == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
+        }
         try {
             type = TicketType.valueOf(request.getDeliveryMethod().toUpperCase());
         } catch (IllegalArgumentException e) {
             throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
         }
-
         // 티켓 엔티티에 수령 방법 설정
         ticket.setDeliveryMethod(type);
 
-        // 저장
+        // 배송 날짜 설정
+        ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
         ticketRepository.save(ticket);
     }
 
 
+    // 가예매 상황 : 3차
     @Transactional
-    public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
+    public TicketResponseDTO reserveTicket(FestivalRequestDTO request, Long userId) {
         Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
-        // 사용자 예약 티켓 매수, 지류티켓 확인
-        validateReservation(userId, request, festival);
-        LocalDateTime deliveryDate = calculateDeliveryDate(request.getDeliveryMethod(), request);
+        Ticket ticket = ticketRepository.findByReservationNumber(request.getReservationNumber())
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        // Ticket 저장 (reservation number 자동 래덤 생성됨)
-        Ticket ticket = buildTicket(request, userId, festival, deliveryDate);
+        // 2차 완료 여부 검증
+        if (ticket.getDeliveryMethod() == null || ticket.getDeliveryDate() == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_NOT_COMPLETED);
+        }
 
         // QR 생성 (Ticket 포함)
         QrCode qrCode = createAndSaveQrCode(userId, festival, ticket);
@@ -200,30 +207,24 @@ public TicketResponseDTO reserveTicket(TicketRequestDTO request, Long userId) {
         return TicketResponseDTO.fromEntity(ticket);
     }
 
-    private void validateReservation(Long userId, TicketRequestDTO request, Festival festival) {
-
-        int alreadyReservedCount = ticketRepository.countByUserIdAndFestivalId(userId, festival.getId());
+    private void validateReservation(Long userId, FestivalSelectRequestDTO request, Festival festival) {
+        int alreadyReservedCount = ticketRepository.countByUserIdAndFestivalIdAndPerformanceDate(userId, festival.getId(), request.getPerformanceDate());
         int reservedCount = request.getSelectedTicketCount() + alreadyReservedCount;
 
         // 티켓 개수 초과
         if ( reservedCount > festival.getMaxPurchase()) {
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
-
-        // 배송 방법 유효성 검사
-        if (request.getDeliveryMethod() == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
-        }
     }
 
     // deliveryDate 생성
-    private LocalDateTime calculateDeliveryDate(TicketType deliveryMethod, TicketRequestDTO request) {
+    private LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMethod) {
         // 지류 티켓일 경우
-        if (request.getPerformanceDate() == null) {
+        if (ticket.getPerformanceDate() == null) {
                 throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
         }
         if (deliveryMethod == TicketType.PAPER) {
-            LocalDateTime deliveryDate = request.getPerformanceDate().minusDays(14);
+            LocalDateTime deliveryDate = ticket.getPerformanceDate().minusDays(14);
             return deliveryDate.isAfter(LocalDateTime.now())
                     ? deliveryDate
                     : LocalDateTime.now().plusDays(1);
@@ -250,22 +251,6 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket
         }
     }
 
-    // Ticket 저장
-    private Ticket buildTicket(TicketRequestDTO request, Long userId, Festival festival,
-                               LocalDateTime deliveryDate) { // , QrCode qrCode
-        return Ticket.builder()
-                .reservationNumber(generateReservationNumber())
-                .reservationStatus(ReservationStatus.CONFIRMED)
-                .deliveryMethod(request.getDeliveryMethod())
-                .reservationDate(LocalDate.now())
-                .deliveryDate(deliveryDate)
-                .performanceDate(request.getPerformanceDate())
-                .selectedTicketCount(request.getSelectedTicketCount())
-                .festival(festival)
-                .userId(userId)
-                .build();
-    }
-
     // reservation number 랜덤 생성
     private String generateReservationNumber() {
         // T + UUID를 앞 8자리

From eb3fb6256ab9a4ef94b941a9f9a65ebe146f60d1 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 14 Aug 2025 17:08:48 +0900
Subject: [PATCH 027/149] =?UTF-8?q?MNMS-282=20Refactor:=20=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81=20=EC=99=84?=
 =?UTF-8?q?=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

bookService -> BookingCommandService, BookingQueryService
조회, 생성용 코드 분리
---
 .../booking/controller/BookingController.java |  84 +++---
 ...RequestDTO.java => BookingRequestDTO.java} |   2 +-
 ...a => BookingSelectDeliveryRequestDTO.java} |   5 +-
 ...tDTO.java => BookingSelectRequestDTO.java} |   2 +-
 .../booking/dto/request/TicketRequestDTO.java |  16 --
 .../response/BookingDetailResponseDTO.java    |  30 ++
 ...sponseDTO.java => BookingResponseDTO.java} |   6 +-
 .../FestivalBookingDetailResponseDTO.java     |  22 --
 .../response/FestivalDetailResponseDTO.java   |  12 +
 .../service/BookingCommandService.java        | 183 ++++++++++++
 .../booking/service/BookingQueryService.java  |  98 +++++++
 .../mnms/booking/service/BookingService.java  | 260 ------------------
 12 files changed, 372 insertions(+), 348 deletions(-)
 rename src/main/java/com/mnms/booking/dto/request/{FestivalRequestDTO.java => BookingRequestDTO.java} (83%)
 rename src/main/java/com/mnms/booking/dto/request/{FestivalSelectDeliveryRequestDTO.java => BookingSelectDeliveryRequestDTO.java} (61%)
 rename src/main/java/com/mnms/booking/dto/request/{FestivalSelectRequestDTO.java => BookingSelectRequestDTO.java} (85%)
 delete mode 100644 src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
 rename src/main/java/com/mnms/booking/dto/response/{TicketResponseDTO.java => BookingResponseDTO.java} (89%)
 delete mode 100644 src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/service/BookingCommandService.java
 create mode 100644 src/main/java/com/mnms/booking/service/BookingQueryService.java
 delete mode 100644 src/main/java/com/mnms/booking/service/BookingService.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 69d62d1..d39a99a 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,14 +1,14 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.request.FestivalRequestDTO;
-import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
-import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
-import com.mnms.booking.dto.request.TicketRequestDTO;
-import com.mnms.booking.dto.response.FestivalBookingDetailResponseDTO;
+import com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectRequestDTO;
+import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
-import com.mnms.booking.dto.response.TicketResponseDTO;
-import com.mnms.booking.service.BookingService;
+import com.mnms.booking.dto.response.BookingResponseDTO;
+import com.mnms.booking.service.BookingQueryService;
+import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.service.UserService;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Operation;
@@ -25,7 +25,8 @@
 @Tag(name = "예매 API", description = "예매 티켓 조회, 티켓 선택, 생성")
 public class BookingController {
 
-    private final BookingService bookingService;
+    private final BookingCommandService bookingCommandService;
+    private final BookingQueryService bookingQueryService;
     private final UserService userService;
 
     /// GET : 페스티벌 예매 정보 조회
@@ -33,54 +34,42 @@ public class BookingController {
     @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId와 performanceDate(사용자가 선택한 날짜 시간) 으로 공연 상세 정보를 조회합니다." +
                     "selectedTicketCount는 0으로 넣을 것!")
-    public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody FestivalSelectRequestDTO request) {
-        return bookingService.getFestivalDetail(request);
+    public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
+        return bookingQueryService.getFestivalDetail(request);
     }
 
-    /// POST : 페스티벌 예매 정보 1차 선택
+    @GetMapping("/detail/phases/2")
+    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
+    public BookingDetailResponseDTO getFestivalBookingDetail(
+            @Valid @RequestBody BookingRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
+        return bookingQueryService.getFestivalBookingDetail(request, principal.userId());
+    }
+
+
+    /// POST
     @PostMapping("/selectDate")
     @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
             description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)를 입력하고 reservationNumber를 반환합니다."
     )
     public String selectFestivalDate(
-            @Valid @RequestBody FestivalSelectRequestDTO request,
+            @Valid @RequestBody BookingSelectRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        return bookingService.selectFestivalDate(request, principal.userId());
+        return bookingCommandService.selectFestivalDate(request, principal.userId());
     }
 
-    /// GET : festival 이름, 날짜, 시간, poster url, 매수, 가격, 예매자 이름, 전화번호, email, 티켓 수령 방법, 주소
-    @GetMapping("/detail/phases/2")
-    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
-    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(
-            @Valid @RequestBody FestivalRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
-    ) {
-        return bookingService.getFestivalBookingDetail(request, principal.userId());
-    }
-
-    ///  POST : 페스티벌 예매 정보 2차 선택 - 티켓수령방법
     @PostMapping("/selectDeliveryMethod")
     @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법 선택",
             description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER)"
     )
     public void selectFestivalDelivery(
-            @Valid @RequestBody FestivalSelectDeliveryRequestDTO request,
+            @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        bookingService.selectFestivalDelivery(request, principal.userId());
-    }
-
-    /// GET : userId로 예매자 정보 조회
-    @GetMapping("/user/info")
-    @Operation(summary = "예매자 정보 조회",
-            description = "예매 과정에서 예매자 정보를 조회합니다." +
-                    "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
-    )
-    public ResponseEntity getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
-        UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
-        return ResponseEntity.ok(userInfo);
+        bookingCommandService.selectFestivalDelivery(request, principal.userId());
     }
 
     /// POST : 3차 예매 완료 (결제 직전)
@@ -88,14 +77,27 @@ public ResponseEntity getUserInfo(@AuthenticationPrincipal
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
     )
-    public ResponseEntity reserveTicket(
-            @Valid @RequestBody FestivalRequestDTO request,
+    public ResponseEntity reserveTicket(
+            @Valid @RequestBody BookingRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        TicketResponseDTO response = bookingService.reserveTicket(request, principal.userId());
+        BookingResponseDTO response = bookingCommandService.reserveTicket(request, principal.userId());
         return ResponseEntity.ok(response);
     }
 
     ///  POST : 가예매 -> 진예매 (결제 완료 확인 상태)
 
+
+    ///  GET
+    @GetMapping("/user/info")
+    @Operation(summary = "예매자 정보 조회",
+            description = "예매 과정에서 예매자 정보를 조회합니다." +
+                    "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
+    )
+    public ResponseEntity getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
+        UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
+        return ResponseEntity.ok(userInfo);
+    }
+
+
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
similarity index 83%
rename from src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
rename to src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
index d69b9e5..966fb77 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
@@ -4,7 +4,7 @@
 import lombok.Getter;
 
 @Data @Getter
-public class FestivalRequestDTO {
+public class BookingRequestDTO {
     private String festivalId;
     private String reservationNumber;
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
similarity index 61%
rename from src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
rename to src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
index d85b2e3..ba7b63d 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalSelectDeliveryRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
@@ -1,14 +1,11 @@
 package com.mnms.booking.dto.request;
 
-import com.mnms.booking.entity.TicketType;
 import lombok.Data;
 import lombok.Getter;
 
-import java.time.LocalDateTime;
-
 @Data
 @Getter
-public class FestivalSelectDeliveryRequestDTO {
+public class BookingSelectDeliveryRequestDTO {
     private String festivalId;
     private String reservationNumber;
     private String deliveryMethod;
diff --git a/src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingSelectRequestDTO.java
similarity index 85%
rename from src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java
rename to src/main/java/com/mnms/booking/dto/request/BookingSelectRequestDTO.java
index b04ef1f..f8f11e8 100644
--- a/src/main/java/com/mnms/booking/dto/request/FestivalSelectRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/BookingSelectRequestDTO.java
@@ -7,7 +7,7 @@
 
 @Data
 @Getter
-public class FestivalSelectRequestDTO {
+public class BookingSelectRequestDTO {
     private String festivalId;
     private LocalDateTime performanceDate;
     private int selectedTicketCount;
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
deleted file mode 100644
index e071bc7..0000000
--- a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.mnms.booking.dto.request;
-
-import com.mnms.booking.entity.TicketType;
-import lombok.Data;
-
-import java.time.LocalDateTime;
-
-@Data
-public class TicketRequestDTO {
-
-    private String festivalId;
-    private int selectedTicketCount; // <= Festival.maxTicketsPerUser
-    private LocalDateTime performanceDate;
-    private TicketType deliveryMethod;
-
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
new file mode 100644
index 0000000..3dff1b1
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
@@ -0,0 +1,30 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.Setter;
+import java.time.LocalDateTime;
+
+
+@Getter @Setter
+@Builder
+public class BookingDetailResponseDTO {
+
+    private String festivalName;
+    private int ticketPrice;
+    private String posterFile;
+    private LocalDateTime performanceDate;
+    private int ticketCount;
+
+    public static BookingDetailResponseDTO fromEntities(Festival festival, Ticket ticket) {
+        return BookingDetailResponseDTO.builder()
+                .festivalName(festival.getFname())
+                .posterFile(festival.getPosterFile())
+                .ticketPrice(festival.getTicketPrice())
+                .performanceDate(ticket.getPerformanceDate())
+                .ticketCount(ticket.getSelectedTicketCount())
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
similarity index 89%
rename from src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
rename to src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
index 1a22ed9..5203685 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
@@ -11,7 +11,7 @@
 
 @Data
 @Builder
-public class TicketResponseDTO {
+public class BookingResponseDTO {
 
     private Long id;
     private String reservationNumber;
@@ -23,8 +23,8 @@ public class TicketResponseDTO {
     private QrResponseDTO qrCode;
     private Festival festival;
 
-    public static TicketResponseDTO fromEntity(Ticket ticket) {
-        return TicketResponseDTO.builder()
+    public static BookingResponseDTO fromEntity(Ticket ticket) {
+        return BookingResponseDTO.builder()
                 .id(ticket.getId())
                 .reservationNumber(ticket.getReservationNumber())
                 .reservationStatus(ticket.getReservationStatus())
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
deleted file mode 100644
index aa91e2c..0000000
--- a/src/main/java/com/mnms/booking/dto/response/FestivalBookingDetailResponseDTO.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.mnms.booking.dto.response;
-
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-
-@Getter
-@Setter
-@Builder
-public class FestivalBookingDetailResponseDTO {
-
-    private String festivalName;
-    private String posterFile;
-    private int ticketPrice;
-
-    private LocalDateTime performanceDate;
-    private int ticketCount;
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
index f656476..ca5238e 100644
--- a/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/FestivalDetailResponseDTO.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.dto.response;
 
+import com.mnms.booking.entity.Festival;
 import lombok.Builder;
 import lombok.Data;
 
@@ -19,4 +20,15 @@ public class FestivalDetailResponseDTO {
     ///  ticket 정보
     private LocalDateTime performanceDate; // 선택 날짜,시간
 
+    public static FestivalDetailResponseDTO fromEntity(Festival festival, LocalDateTime performanceDate, List schedules) {
+        return FestivalDetailResponseDTO.builder()
+                .fname(festival.getFname())
+                .ticketPrice(festival.getTicketPrice())
+                .posterFile(festival.getPosterFile())
+                .maxPurchase(festival.getMaxPurchase())
+                .performanceDate(performanceDate)
+                .schedules(schedules)
+                .build();
+    }
+
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
new file mode 100644
index 0000000..5689d17
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -0,0 +1,183 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectRequestDTO;
+import com.mnms.booking.dto.response.*;
+import com.mnms.booking.entity.*;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.Locale;
+import java.util.UUID;
+
+
+@Service
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+public class BookingCommandService {
+
+    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
+
+    private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
+    private final FestivalRepository festivalRepository;
+    private final QrCodeService qrCodeService;
+
+    /// 1차: 임시 예약
+    @Transactional
+    public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
+        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        LocalDateTime performanceDate = request.getPerformanceDate();
+
+        validatePerformanceDate(festival, performanceDate);
+        validateScheduleExists(festival, performanceDate);
+        validateTicketAvailability(festival, request.getSelectedTicketCount());
+        validateUserReservationLimit(userId, request, festival);
+
+        Ticket ticket = Ticket.builder()
+                .festival(festival)
+                .userId(userId)
+                .reservationNumber(generateReservationNumber())
+                .selectedTicketCount(request.getSelectedTicketCount())
+                .performanceDate(performanceDate)
+                .reservationStatus(ReservationStatus.TEMP_RESERVED)
+                .reservationDate(LocalDate.now())
+                .build();
+
+        ticketRepository.save(ticket);
+        return ticket.getReservationNumber();
+    }
+
+    /// 2차: 배송 방법 선택
+    @Transactional
+    public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long userId) {
+        Ticket ticket = getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
+        TicketType type = parseDeliveryMethod(request.getDeliveryMethod());
+
+        ticket.setDeliveryMethod(type);
+        ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
+        ticketRepository.save(ticket);
+    }
+
+    /// 3차: 최종 예약 - QR생성
+    @Transactional
+    public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId) {
+        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
+
+        ensureDeliveryStepCompleted(ticket);
+
+        QrCode qrCode = createAndSaveQrCode(userId, festival, ticket);
+
+        ticket.setQrCode(qrCode);
+        ticketRepository.save(ticket);
+        return BookingResponseDTO.fromEntity(ticket);
+    }
+
+    /// 검증
+    private void validatePerformanceDate(Festival festival, LocalDateTime performanceDate) {
+        LocalDate date = performanceDate.toLocalDate();
+        if (date.isBefore(festival.getFdfrom()) || date.isAfter(festival.getFdto())) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+    }
+
+    private void validateScheduleExists(Festival festival, LocalDateTime performanceDate) {
+        String dayOfWeek = performanceDate.getDayOfWeek()
+                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
+                .toUpperCase();
+
+        boolean exists = festival.getSchedules().stream()
+                .anyMatch(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek)
+                        && LocalTime.parse(s.getTime(), TIME_FORMATTER).equals(performanceDate.toLocalTime()));
+
+        if (!exists) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
+    }
+
+    private void validateTicketAvailability(Festival festival, int selectedTicketCount) {
+        if (festival.getAvailableNOP() < selectedTicketCount) {
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+    }
+
+    private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO request, Festival festival) {
+        int alreadyReserved = ticketRepository.countByUserIdAndFestivalIdAndPerformanceDate(
+                userId, festival.getId(), request.getPerformanceDate());
+        if (alreadyReserved + request.getSelectedTicketCount() > festival.getMaxPurchase()) {
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+    }
+
+    private void ensureDeliveryStepCompleted(Ticket ticket) {
+        if (ticket.getDeliveryMethod() == null || ticket.getDeliveryDate() == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_NOT_COMPLETED);
+        }
+    }
+
+    /// 기타
+    private Festival getFestivalOrThrow(String festivalId) {
+        return festivalRepository.findByFestivalId(festivalId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+    }
+
+    private Ticket getTicketOrThrow(String festivalId, Long userId, String reservationNumber) {
+        return ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(festivalId, userId, reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    private Ticket getTicketByReservationNumberOrThrow(String reservationNumber) {
+        return ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    private TicketType parseDeliveryMethod(String method) {
+        if (method == null) throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
+        try {
+            return TicketType.valueOf(method.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
+        }
+    }
+
+    /// deliveryDate 생성
+    private LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMethod) {
+        if (ticket.getPerformanceDate() == null) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+
+        if (deliveryMethod == TicketType.PAPER) {
+            LocalDateTime deliveryDate = ticket.getPerformanceDate().minusDays(14);
+            return deliveryDate.isAfter(LocalDateTime.now())
+                    ? deliveryDate
+                    : LocalDateTime.now().plusDays(1);
+        }
+        return null; // 모바일 티켓
+    }
+
+    /// Qr정보 생성
+    private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
+        String qrCodeId = qrCodeService.generateQrCodeId();
+        if (qrCodeId == null || qrCodeId.isEmpty()) {
+            throw new BusinessException(ErrorCode.QR_CODE_ID_GENERATION_FAILED);
+        }
+        QrCode qrCode = QrResponseDTO.create(userId, qrCodeId, festival, ticket).toEntity();
+        qrCodeRepository.save(qrCode);
+        return qrCode;
+    }
+
+    ///  reservation number 랜덤 생성
+    private String generateReservationNumber() {
+        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
+        return "T" + uuidPart;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingQueryService.java b/src/main/java/com/mnms/booking/service/BookingQueryService.java
new file mode 100644
index 0000000..e7bd834
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/BookingQueryService.java
@@ -0,0 +1,98 @@
+package com.mnms.booking.service;
+
+
+import com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectRequestDTO;
+import com.mnms.booking.dto.response.BookingDetailResponseDTO;
+import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
+import com.mnms.booking.dto.response.ScheduleResponseDTO;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.booking.repository.ScheduleRepository;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.util.List;
+import java.util.Locale;
+
+
+@Service
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+public class BookingQueryService {
+
+    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
+    private final TicketRepository ticketRepository;
+    private final FestivalRepository festivalRepository;
+    private final ScheduleRepository scheduleRepository;
+
+    /// 1차 : 조회
+    public FestivalDetailResponseDTO getFestivalDetail(BookingSelectRequestDTO request) {
+        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        LocalDateTime performanceDate = request.getPerformanceDate();
+
+        validatePerformanceDate(festival, performanceDate);
+        validateScheduleExists(festival, performanceDate);
+        List scheduleDTOs = getSchedules(festival);
+        return FestivalDetailResponseDTO.fromEntity(festival, performanceDate, scheduleDTOs);
+    }
+
+    ///  2차 : 조회
+    public BookingDetailResponseDTO getFestivalBookingDetail(BookingRequestDTO request, Long userId) {
+        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
+
+        return BookingDetailResponseDTO.fromEntities(festival, ticket);
+    }
+
+    ///  기타
+    private void validatePerformanceDate(Festival festival, LocalDateTime performanceDate) {
+        LocalDate date = performanceDate.toLocalDate();
+        if (date.isBefore(festival.getFdfrom()) || date.isAfter(festival.getFdto())) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+    }
+
+    private void validateScheduleExists(Festival festival, LocalDateTime performanceDate) {
+        String dayOfWeek = performanceDate.getDayOfWeek()
+                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
+                .toUpperCase();
+
+        boolean exists = festival.getSchedules().stream()
+                .anyMatch(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek)
+                        && LocalTime.parse(s.getTime(), TIME_FORMATTER).equals(performanceDate.toLocalTime()));
+
+        if (!exists) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
+    }
+
+    private Festival getFestivalOrThrow(String festivalId) {
+        return festivalRepository.findByFestivalId(festivalId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+    }
+
+    private Ticket getTicketByReservationNumberOrThrow(String reservationNumber) {
+        return ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    private List getSchedules(Festival festival) {
+        return scheduleRepository.findByFestivalId(festival.getFestivalId())
+                .stream()
+                .map(s -> ScheduleResponseDTO.builder()
+                        .scheduleId(s.getScheduleId())
+                        .dayOfWeek(s.getDayOfWeek())
+                        .time(s.getTime())
+                        .build())
+                .toList();
+    }
+}
diff --git a/src/main/java/com/mnms/booking/service/BookingService.java b/src/main/java/com/mnms/booking/service/BookingService.java
deleted file mode 100644
index 934d8a7..0000000
--- a/src/main/java/com/mnms/booking/service/BookingService.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package com.mnms.booking.service;
-
-import com.mnms.booking.dto.request.FestivalRequestDTO;
-import com.mnms.booking.dto.request.FestivalSelectDeliveryRequestDTO;
-import com.mnms.booking.dto.request.FestivalSelectRequestDTO;
-import com.mnms.booking.dto.request.TicketRequestDTO;
-import com.mnms.booking.dto.response.*;
-import com.mnms.booking.entity.*;
-import com.mnms.booking.exception.BusinessException;
-import com.mnms.booking.exception.ErrorCode;
-import com.mnms.booking.repository.FestivalRepository;
-import com.mnms.booking.repository.QrCodeRepository;
-import com.mnms.booking.repository.ScheduleRepository;
-import com.mnms.booking.repository.TicketRepository;
-import jakarta.validation.Valid;
-import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.TextStyle;
-import java.util.List;
-import java.util.Locale;
-import java.util.UUID;
-
-@Service
-@Slf4j
-@RequiredArgsConstructor
-@Transactional(readOnly = true)
-public class BookingService {
-
-    private final TicketRepository ticketRepository;
-    private final QrCodeRepository qrCodeRepository;
-    private final FestivalRepository festivalRepository;
-    private final QrCodeService qrCodeService;
-    private final ScheduleRepository scheduleRepository;
-
-    public FestivalDetailResponseDTO getFestivalDetail(@Valid FestivalSelectRequestDTO request) {
-        // 페스티벌 조회
-        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
-
-        LocalDateTime performanceDate = request.getPerformanceDate();
-        LocalDate selectDate = performanceDate.toLocalDate();
-        LocalTime selectTime = performanceDate.toLocalTime();
-
-        // 날짜 범위 검증
-        if (selectDate.isBefore(festival.getFdfrom()) || selectDate.isAfter(festival.getFdto())) {
-            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
-        }
-
-        // 스케줄 찾기
-        String dayOfWeek = selectDate.getDayOfWeek()
-                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
-                .toUpperCase();
-
-        Schedule matchedSchedule = festival.getSchedules().stream()
-                .filter(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&
-                        LocalTime.parse(s.getTime(), DateTimeFormatter.ofPattern("HH:mm")).equals(selectTime))
-                .findFirst()
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME));
-
-        List schedules = scheduleRepository.findByFestivalId(festival.getFestivalId());
-        List scheduleDTOs = schedules.stream()
-                .map(s -> ScheduleResponseDTO.builder()
-                        .scheduleId(s.getScheduleId())
-                        .dayOfWeek(s.getDayOfWeek())
-                        .time(s.getTime())
-                        .build())
-                .toList();
-
-        // 4. DTO 반환
-        return FestivalDetailResponseDTO.builder()
-                .fname(festival.getFname())
-                .ticketPrice(festival.getTicketPrice())
-                .posterFile(festival.getPosterFile())
-                .maxPurchase(festival.getMaxPurchase())
-                .performanceDate(request.getPerformanceDate())
-                .schedules(scheduleDTOs)
-                .build();
-    }
-
-    // 가예매 상황 : 1차 저장
-    @Transactional
-    public String selectFestivalDate(FestivalSelectRequestDTO request, Long userId) {
-        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
-
-        // 요청한 날짜가 해당 페스티벌의 공연 일정에 포함되어 있는지 확인
-        LocalDateTime performanceDate = request.getPerformanceDate();
-        LocalDate selectDate = performanceDate.toLocalDate();
-        LocalTime selectTime = performanceDate.toLocalTime();
-
-        if(selectDate.isBefore(festival.getFdfrom()) || selectDate.isAfter(festival.getFdto())){
-            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
-        }
-
-        String dayOfWeek = selectDate.getDayOfWeek()
-                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
-                .toUpperCase();
-        boolean isValidSchedule = festival.getSchedules().stream()
-                .anyMatch(s ->
-                        s.getDayOfWeek().equalsIgnoreCase(dayOfWeek) &&
-                                LocalTime.parse(s.getTime()).equals(selectTime)
-                );
-
-        if (!isValidSchedule) {
-            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
-        }
-
-        if(festival.getAvailableNOP() < request.getSelectedTicketCount()){
-            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
-        }
-
-        // 사용자 예약 티켓 매수, 지류티켓 확인
-        validateReservation(userId, request, festival);
-
-        // 페스티벌, 유저, 선택 날짜, 시간 저장
-        Ticket ticket = Ticket.builder()
-                .festival(festival)
-                .userId(userId)
-                .reservationNumber(generateReservationNumber())
-                .selectedTicketCount(request.getSelectedTicketCount())
-                .performanceDate(performanceDate)
-                .reservationStatus(ReservationStatus.TEMP_RESERVED)
-                .reservationDate(LocalDate.now())
-                .build();
-        ticketRepository.save(ticket);
-        return ticket.getReservationNumber();
-    }
-
-    // 가예매 상황 : 2차 조회
-    public FestivalBookingDetailResponseDTO getFestivalBookingDetail(@Valid FestivalRequestDTO request, Long userId) {
-        // 공연 정보 조회
-        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
-
-        Ticket ticket = ticketRepository.findByReservationNumber(request.getReservationNumber())
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
-        // 4. DTO 생성
-        return FestivalBookingDetailResponseDTO.builder()
-                .festivalName(festival.getFname())
-                .posterFile(festival.getPosterFile())
-                .ticketPrice(festival.getTicketPrice())
-                .performanceDate(ticket.getPerformanceDate()) // 선택한 페스티벌 날짜 시간
-                .ticketCount(ticket.getSelectedTicketCount())
-                .build();
-    }
-
-    // 가예매 상황 : 2차 저장
-    @Transactional
-    public void selectFestivalDelivery(FestivalSelectDeliveryRequestDTO request, Long userId) {
-
-        // 1. 해당 티켓 조회
-        Ticket ticket = ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(
-                request.getFestivalId(),
-                userId,
-                request.getReservationNumber()
-        ).orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
-        TicketType type;
-        // 배송 방법 유효성 검사
-        if (request.getDeliveryMethod() == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
-        }
-        try {
-            type = TicketType.valueOf(request.getDeliveryMethod().toUpperCase());
-        } catch (IllegalArgumentException e) {
-            throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
-        }
-        // 티켓 엔티티에 수령 방법 설정
-        ticket.setDeliveryMethod(type);
-
-        // 배송 날짜 설정
-        ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
-        ticketRepository.save(ticket);
-    }
-
-
-    // 가예매 상황 : 3차
-    @Transactional
-    public TicketResponseDTO reserveTicket(FestivalRequestDTO request, Long userId) {
-        Festival festival = festivalRepository.findByFestivalId(request.getFestivalId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
-
-        Ticket ticket = ticketRepository.findByReservationNumber(request.getReservationNumber())
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
-        // 2차 완료 여부 검증
-        if (ticket.getDeliveryMethod() == null || ticket.getDeliveryDate() == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_NOT_COMPLETED);
-        }
-
-        // QR 생성 (Ticket 포함)
-        QrCode qrCode = createAndSaveQrCode(userId, festival, ticket);
-
-        // Ticket에 QR 세팅 후 저장
-        ticket.setQrCode(qrCode);
-        ticketRepository.save(ticket);
-
-        // 응답
-        return TicketResponseDTO.fromEntity(ticket);
-    }
-
-    private void validateReservation(Long userId, FestivalSelectRequestDTO request, Festival festival) {
-        int alreadyReservedCount = ticketRepository.countByUserIdAndFestivalIdAndPerformanceDate(userId, festival.getId(), request.getPerformanceDate());
-        int reservedCount = request.getSelectedTicketCount() + alreadyReservedCount;
-
-        // 티켓 개수 초과
-        if ( reservedCount > festival.getMaxPurchase()) {
-            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
-        }
-    }
-
-    // deliveryDate 생성
-    private LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMethod) {
-        // 지류 티켓일 경우
-        if (ticket.getPerformanceDate() == null) {
-                throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
-        }
-        if (deliveryMethod == TicketType.PAPER) {
-            LocalDateTime deliveryDate = ticket.getPerformanceDate().minusDays(14);
-            return deliveryDate.isAfter(LocalDateTime.now())
-                    ? deliveryDate
-                    : LocalDateTime.now().plusDays(1);
-        }
-        // 모바일 티켓일 경우
-        return null;
-    }
-
-    // Qr정보 생성
-    private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
-        try {
-            String qrCodeId = qrCodeService.generateQrCodeId();
-            if (qrCodeId == null || qrCodeId.isEmpty()) {
-                throw new BusinessException(ErrorCode.QR_CODE_ID_GENERATION_FAILED);
-            }
-            QrResponseDTO qrResponse = QrResponseDTO.create(userId, qrCodeId, festival, ticket);
-            QrCode qrCode = qrResponse.toEntity();
-            qrCodeRepository.save(qrCode);
-            return qrCode;
-        } catch (BusinessException e) {
-            throw e;
-        } catch (Exception e) {
-            throw new BusinessException(ErrorCode.QR_CODE_SAVE_FAILED);
-        }
-    }
-
-    // reservation number 랜덤 생성
-    private String generateReservationNumber() {
-        // T + UUID를 앞 8자리
-        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
-        return "T" + uuidPart;
-    }
-}
\ No newline at end of file

From 7d512be5b950d408052b374dc1e88f6bea2639f7 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 14 Aug 2025 22:16:34 +0900
Subject: [PATCH 028/149] =?UTF-8?q?MNMS-282=20Feat:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=20Scheduler=20=EC=A0=81=EC=9A=A9,=20kafka,=20enum=20=ED=8F=B4?=
 =?UTF-8?q?=EB=8D=94=20=EA=B5=AC=EC=A1=B0=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Scheduler: Ticket reservationStatus - TEMP_RESERVED scheduler db 자동 삭제 처리 (현재 : 1분)
Scheduler: CONFIRMED 상태 되면 삭제 X
enum 분리
payment-topic kafka 구독 코드 작성 (추후 테스트 할 예정)
---
 .../mnms/booking/config/SchedulerConfig.java  | 17 +++++++++
 .../booking/controller/BookingController.java |  3 --
 .../dto/response/BookingResponseDTO.java      |  4 +-
 .../com/mnms/booking/entity/Festival.java     |  3 +-
 .../java/com/mnms/booking/entity/Ticket.java  |  5 ++-
 .../booking/{entity => enums}/EventType.java  |  2 +-
 .../{entity => enums}/ReservationStatus.java  |  2 +-
 .../booking/{entity => enums}/TicketType.java |  2 +-
 .../service/BookingCommandService.java        | 37 +++++++++++++++++--
 .../WaitingQueueSchedulingService.java        |  5 ---
 .../booking/config/KafkaProducerConfig.java   |  2 +-
 .../booking/config/KafkaTopicConfig.java      |  4 +-
 .../booking/dto/PaymentSuccessEvent.java      | 14 +++++++
 .../listener/KafkaPaymentListener.java        | 22 +++++++++++
 src/main/resources/application-dev.properties |  8 ++--
 15 files changed, 104 insertions(+), 26 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/SchedulerConfig.java
 rename src/main/java/com/mnms/booking/{entity => enums}/EventType.java (73%)
 rename src/main/java/com/mnms/booking/{entity => enums}/ReservationStatus.java (84%)
 rename src/main/java/com/mnms/booking/{entity => enums}/TicketType.java (59%)
 rename src/main/java/com/mnms/{ => kafka}/booking/config/KafkaProducerConfig.java (97%)
 rename src/main/java/com/mnms/{ => kafka}/booking/config/KafkaTopicConfig.java (82%)
 create mode 100644 src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java
 create mode 100644 src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java

diff --git a/src/main/java/com/mnms/booking/config/SchedulerConfig.java b/src/main/java/com/mnms/booking/config/SchedulerConfig.java
new file mode 100644
index 0000000..3b40a42
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/SchedulerConfig.java
@@ -0,0 +1,17 @@
+package com.mnms.booking.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+public class SchedulerConfig {
+    @Bean
+    public ThreadPoolTaskScheduler taskScheduler() {
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        scheduler.setPoolSize(5);
+        scheduler.setThreadNamePrefix("booking-scheduler-");
+        scheduler.initialize();
+        return scheduler;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index d39a99a..59f9160 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -85,9 +85,6 @@ public ResponseEntity reserveTicket(
         return ResponseEntity.ok(response);
     }
 
-    ///  POST : 가예매 -> 진예매 (결제 완료 확인 상태)
-
-
     ///  GET
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
index 5203685..4447e7c 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
@@ -1,9 +1,9 @@
 package com.mnms.booking.dto.response;
 
 import com.mnms.booking.entity.Festival;
-import com.mnms.booking.entity.ReservationStatus;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.entity.Ticket;
-import com.mnms.booking.entity.TicketType;
+import com.mnms.booking.enums.TicketType;
 import lombok.*;
 
 import java.time.LocalDate;
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 967f041..def26f2 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -1,12 +1,11 @@
 package com.mnms.booking.entity;
 
 import com.fasterxml.jackson.annotation.JsonManagedReference;
+import com.mnms.booking.enums.EventType;
 import jakarta.persistence.*;
 import lombok.Getter;
-import lombok.Setter;
 
 import java.time.LocalDate;
-import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 31773cc..6eae700 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -1,12 +1,12 @@
 package com.mnms.booking.entity;
 
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.enums.TicketType;
 import jakarta.persistence.*;
 import lombok.*;
 import jakarta.persistence.Id;
-
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
 
 @Entity
 @Builder @Getter
@@ -55,4 +55,5 @@ public void setQrCode(QrCode qrCode){
     }
     public void setDeliveryMethod(TicketType deliveryMethod){this.deliveryMethod = deliveryMethod;}
     public void setDeliveryDate(LocalDateTime deliveryDate){ this.deliveryDate = deliveryDate;}
+    public void setReservationStatus(ReservationStatus reservationStatus){ this.reservationStatus = reservationStatus; }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/EventType.java b/src/main/java/com/mnms/booking/enums/EventType.java
similarity index 73%
rename from src/main/java/com/mnms/booking/entity/EventType.java
rename to src/main/java/com/mnms/booking/enums/EventType.java
index 6995c99..617170b 100644
--- a/src/main/java/com/mnms/booking/entity/EventType.java
+++ b/src/main/java/com/mnms/booking/enums/EventType.java
@@ -1,4 +1,4 @@
-package com.mnms.booking.entity;
+package com.mnms.booking.enums;
 
 public enum EventType {
     FESTIVAL_CREATED,
diff --git a/src/main/java/com/mnms/booking/entity/ReservationStatus.java b/src/main/java/com/mnms/booking/enums/ReservationStatus.java
similarity index 84%
rename from src/main/java/com/mnms/booking/entity/ReservationStatus.java
rename to src/main/java/com/mnms/booking/enums/ReservationStatus.java
index 7e087bf..606e70a 100644
--- a/src/main/java/com/mnms/booking/entity/ReservationStatus.java
+++ b/src/main/java/com/mnms/booking/enums/ReservationStatus.java
@@ -1,4 +1,4 @@
-package com.mnms.booking.entity;
+package com.mnms.booking.enums;
 
 public enum ReservationStatus {
     TEMP_RESERVED,     // 가예매 (결제 전)
diff --git a/src/main/java/com/mnms/booking/entity/TicketType.java b/src/main/java/com/mnms/booking/enums/TicketType.java
similarity index 59%
rename from src/main/java/com/mnms/booking/entity/TicketType.java
rename to src/main/java/com/mnms/booking/enums/TicketType.java
index 906bf6f..556d80b 100644
--- a/src/main/java/com/mnms/booking/entity/TicketType.java
+++ b/src/main/java/com/mnms/booking/enums/TicketType.java
@@ -1,4 +1,4 @@
-package com.mnms.booking.entity;
+package com.mnms.booking.enums;
 
 public enum TicketType {
     MOBILE,
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 5689d17..afa1205 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -5,20 +5,27 @@
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
 import com.mnms.booking.dto.response.*;
 import com.mnms.booking.entity.*;
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
+import com.mnms.kafka.booking.dto.PaymentSuccessEvent;
 import lombok.RequiredArgsConstructor;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
+import java.time.temporal.ChronoUnit;
 import java.util.Locale;
 import java.util.UUID;
 
@@ -29,13 +36,15 @@
 public class BookingCommandService {
 
     private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
+    private static final int TEMP_RESERVATION_TTL_MINUTES = 1; // 임시 예약 유지 시간
 
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
     private final FestivalRepository festivalRepository;
     private final QrCodeService qrCodeService;
+    private final ThreadPoolTaskScheduler scheduler;
 
-    /// 1차: 임시 예약
+    /// 1차: 가예매 - 임시 예약
     @Transactional
     public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
         Festival festival = getFestivalOrThrow(request.getFestivalId());
@@ -57,10 +66,14 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .build();
 
         ticketRepository.save(ticket);
+
+        // TTL 스케줄링: 일정 시간 지나면 자동 삭제
+        scheduleTempReservationExpiration(ticket.getReservationNumber());
+
         return ticket.getReservationNumber();
     }
 
-    /// 2차: 배송 방법 선택
+    /// 2차: 가예매 - 배송 방법 선택
     @Transactional
     public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long userId) {
         Ticket ticket = getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
@@ -71,7 +84,7 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
         ticketRepository.save(ticket);
     }
 
-    /// 3차: 최종 예약 - QR생성
+    /// 3차: 가예매 - 최종 예약 - QR생성
     @Transactional
     public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = getFestivalOrThrow(request.getFestivalId());
@@ -86,6 +99,24 @@ public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId)
         return BookingResponseDTO.fromEntity(ticket);
     }
 
+    ///  최종 예약 완료
+    public void confirmTicket(String reservationNumber) {
+        ticketRepository.findByReservationNumber(reservationNumber)
+                .ifPresent(ticket -> {
+                    ticket.setReservationStatus(ReservationStatus.CONFIRMED);
+                    ticketRepository.save(ticket);
+                });
+    }
+
+    /// schedule 점검
+    private void scheduleTempReservationExpiration(String reservationNumber) {
+        scheduler.schedule(() -> {
+            ticketRepository.findByReservationNumber(reservationNumber)
+                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
+                    .ifPresent(ticketRepository::delete);
+        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
+    }
+
     /// 검증
     private void validatePerformanceDate(Festival festival, LocalDateTime performanceDate) {
         LocalDate date = performanceDate.toLocalDate();
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index e54b840..4233960 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -22,11 +22,6 @@ public class WaitingQueueSchedulingService {
     private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
     private final Map> scheduledTasks = new ConcurrentHashMap<>();
 
-    @PostConstruct
-    public void init() {
-        scheduler.initialize();
-    }
-
     /**
      * 스케줄러 시작 (중복 시작 방지)
      */
diff --git a/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java b/src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java
similarity index 97%
rename from src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
rename to src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java
index 11fb66c..375cf02 100644
--- a/src/main/java/com/mnms/booking/config/KafkaProducerConfig.java
+++ b/src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java
@@ -1,4 +1,4 @@
-package com.mnms.booking.config;
+package com.mnms.kafka.booking.config;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import org.apache.kafka.clients.producer.ProducerConfig;
diff --git a/src/main/java/com/mnms/booking/config/KafkaTopicConfig.java b/src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java
similarity index 82%
rename from src/main/java/com/mnms/booking/config/KafkaTopicConfig.java
rename to src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java
index 587e518..4c26c2d 100644
--- a/src/main/java/com/mnms/booking/config/KafkaTopicConfig.java
+++ b/src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java
@@ -1,4 +1,4 @@
-package com.mnms.booking.config;
+package com.mnms.kafka.booking.config;
 
 import org.apache.kafka.clients.admin.NewTopic;
 import org.springframework.context.annotation.Bean;
@@ -10,7 +10,7 @@ public class KafkaTopicConfig {
 
     @Bean
     public NewTopic bookingEventTopic() {
-        return TopicBuilder.name("booking-event")
+        return TopicBuilder.name("booking-topic")
                 .partitions(1)
                 .replicas(1)
                 .build();
diff --git a/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java b/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java
new file mode 100644
index 0000000..ea1abd9
--- /dev/null
+++ b/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java
@@ -0,0 +1,14 @@
+package com.mnms.kafka.booking.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PaymentSuccessEvent {
+    private String reservationNumber;
+    private Long userId;
+    private int amount; // 필요시 추가
+}
diff --git a/src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java b/src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java
new file mode 100644
index 0000000..2ec9f28
--- /dev/null
+++ b/src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java
@@ -0,0 +1,22 @@
+package com.mnms.kafka.booking.listener;
+
+import com.mnms.booking.service.BookingCommandService;
+import com.mnms.kafka.booking.dto.PaymentSuccessEvent;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class KafkaPaymentListener {
+
+    private final BookingCommandService bookingCommandService;
+
+    @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group",  containerFactory = "kafkaListenerContainerFactory")
+    public void consumePaymentSuccess(PaymentSuccessEvent event) {
+        log.info("Received payment success event: {}", event);
+        bookingCommandService.confirmTicket(event.getReservationNumber());
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 427a99e..a64f507 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -22,15 +22,17 @@ spring.redis.port=6379
 #spring.redis.password=your_password
 
 # kafka
-app.kafka.topic.booking-event=booking-events
-app.kafka.topic.user-event: user-events
+app.kafka.topic.payment-event=payment-topic
+#app.kafka.topic.booking-event=booking-events
+#app.kafka.topic.user-event: user-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
-#spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
 spring.kafka.consumer.properties.spring.json.use.type.headers=false
+#spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
+
 
 # kafka 사용 X
 #spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration

From a2c6677aa1d339211d24c83c9d41bcb37ed8ba81 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 15 Aug 2025 00:13:31 +0900
Subject: [PATCH 029/149] =?UTF-8?q?MNMS-282=20Chore:=20SelectedTicketCount?=
 =?UTF-8?q?=EB=A7=8C=ED=81=BC=20QrCode=20=EC=83=9D=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

예매한 매수만큼 QR 생성하기 (Ticket은 1개, QR은 선택한 매수만큼 생성)
추후 : 최대 매수만큼 나눠서 예매 가능한지 확인하기
---
 .../dto/response/BookingResponseDTO.java      |  8 ++++--
 .../java/com/mnms/booking/entity/QrCode.java  |  3 ++-
 .../java/com/mnms/booking/entity/Ticket.java  | 22 +++++++++-------
 .../booking/repository/QrCodeRepository.java  |  1 +
 .../service/BookingCommandService.java        | 26 +++++++++++++------
 .../booking/service/BookingQueryService.java  |  1 -
 6 files changed, 39 insertions(+), 22 deletions(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
index 4447e7c..d45494b 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
@@ -8,6 +8,8 @@
 
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
 
 @Data
 @Builder
@@ -20,7 +22,7 @@ public class BookingResponseDTO {
     private LocalDateTime deliveryDate;
     private Long userId;
     private LocalDate reservationDate;
-    private QrResponseDTO qrCode;
+    private List qrCodes;
     private Festival festival;
 
     public static BookingResponseDTO fromEntity(Ticket ticket) {
@@ -31,7 +33,9 @@ public static BookingResponseDTO fromEntity(Ticket ticket) {
                 .deliveryMethod(ticket.getDeliveryMethod())
                 .deliveryDate(ticket.getDeliveryDate())
                 .reservationDate(ticket.getReservationDate())
-                .qrCode(QrResponseDTO.fromEntity(ticket.getQrCode()))
+                .qrCodes(ticket.getQrCodes().stream()
+                        .map(QrResponseDTO::fromEntity)
+                        .collect(Collectors.toList()))
                 .userId(ticket.getUserId())
                 .festival(ticket.getFestival())
                 .build();
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index 4626792..ac1b7a1 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -36,7 +36,8 @@ public class QrCode {
     @Column(name = "user_id", nullable = false)
     private Long userId;
 
-    @OneToOne(fetch = FetchType.LAZY)
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "ticket_id")
     private Ticket ticket; // ticket_id
 
     // 비지니스 로직
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 6eae700..792d0e5 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -7,13 +7,16 @@
 import jakarta.persistence.Id;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.List;
 
 @Entity
 @Builder @Getter
 @Table(name = "ticket")
-@NoArgsConstructor(access = AccessLevel.PROTECTED)
 @AllArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Ticket {
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id; // ticket_id
@@ -21,9 +24,11 @@ public class Ticket {
     @Column(name = "reservation_number")
     private String reservationNumber; // 예매번호
 
+    @Setter
     @Column(name = "reservation_status")
     private ReservationStatus reservationStatus; // 예매상태
 
+    @Setter
     @Column(name = "delivery_method")
     private TicketType deliveryMethod; // 수령방법
 
@@ -33,6 +38,7 @@ public class Ticket {
     @Column(name = "reservation_date")
     private LocalDate reservationDate; // 예매를 수행한 날짜
 
+    @Setter
     @Column(name = "delivery_date")
     private LocalDateTime deliveryDate; // 택배 날짜
 
@@ -42,18 +48,14 @@ public class Ticket {
     @Column(name = "selected_ticket_count")
     private int selectedTicketCount; // 선택 매수
 
-    @OneToOne(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
-    private QrCode qrCode;
+    @Setter
+    @Builder.Default
+    @OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
+    private List qrCodes = new ArrayList<>();
+
 
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "festival_id")
     private Festival festival;
 
-    // setter
-    public void setQrCode(QrCode qrCode){
-        this.qrCode= qrCode;
-    }
-    public void setDeliveryMethod(TicketType deliveryMethod){this.deliveryMethod = deliveryMethod;}
-    public void setDeliveryDate(LocalDateTime deliveryDate){ this.deliveryDate = deliveryDate;}
-    public void setReservationStatus(ReservationStatus reservationStatus){ this.reservationStatus = reservationStatus; }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index 5dd5a88..cbcd3b8 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -10,6 +10,7 @@
 public interface QrCodeRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByQrCodeId(String qrCodeId);
+    Boolean existsByQrCodeId(String qrCodeId);
 }
 
 
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index afa1205..e07662b 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -12,9 +12,7 @@
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
-import com.mnms.kafka.booking.dto.PaymentSuccessEvent;
 import lombok.RequiredArgsConstructor;
-import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -26,8 +24,12 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 
 @Service
@@ -92,10 +94,16 @@ public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId)
 
         ensureDeliveryStepCompleted(ticket);
 
-        QrCode qrCode = createAndSaveQrCode(userId, festival, ticket);
+        // 기존 QR 코드 초기화
+        ticket.getQrCodes().clear();
+        ticket.getQrCodes().addAll(
+                IntStream.range(0, ticket.getSelectedTicketCount())
+                        .mapToObj(i -> createAndSaveQrCode(userId, festival, ticket))
+                        .toList()
+        );
 
-        ticket.setQrCode(qrCode);
         ticketRepository.save(ticket);
+
         return BookingResponseDTO.fromEntity(ticket);
     }
 
@@ -197,10 +205,12 @@ private LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMe
 
     /// Qr정보 생성
     private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
-        String qrCodeId = qrCodeService.generateQrCodeId();
-        if (qrCodeId == null || qrCodeId.isEmpty()) {
-            throw new BusinessException(ErrorCode.QR_CODE_ID_GENERATION_FAILED);
-        }
+        // 중복 없는 QR 코드 ID 생성
+        String qrCodeId;
+        do {
+            qrCodeId = qrCodeService.generateQrCodeId();
+        } while (qrCodeRepository.existsByQrCodeId(qrCodeId));
+
         QrCode qrCode = QrResponseDTO.create(userId, qrCodeId, festival, ticket).toEntity();
         qrCodeRepository.save(qrCode);
         return qrCode;
diff --git a/src/main/java/com/mnms/booking/service/BookingQueryService.java b/src/main/java/com/mnms/booking/service/BookingQueryService.java
index e7bd834..fbc14c1 100644
--- a/src/main/java/com/mnms/booking/service/BookingQueryService.java
+++ b/src/main/java/com/mnms/booking/service/BookingQueryService.java
@@ -1,6 +1,5 @@
 package com.mnms.booking.service;
 
-
 import com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;

From 2ba4b2b68b8cf16aba4cba1bd7b0e62cc4c15b8a Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 17 Aug 2025 15:41:38 +0900
Subject: [PATCH 030/149] =?UTF-8?q?MNMS-282=20Chore:=20=EC=B5=9C=EB=8C=80?=
 =?UTF-8?q?=20=EB=A7=A4=EC=88=98=20=EB=82=98=EB=88=A0=EC=84=9C=20=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EC=A1=B0=EA=B1=B4=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

최대 매수 나눠서 예매 테스트 후 조건문
3차 가예매 응답 변경 - BookingResponseDTO 삭제 가능
---
 .../booking/controller/BookingController.java |  7 ++---
 .../dto/response/BookingResponseDTO.java      |  2 ++
 .../booking/repository/TicketRepository.java  | 12 ++++++++
 .../service/BookingCommandService.java        | 28 +++++++++----------
 4 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 59f9160..9b84001 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -6,7 +6,6 @@
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
-import com.mnms.booking.dto.response.BookingResponseDTO;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.service.UserService;
@@ -77,12 +76,12 @@ public void selectFestivalDelivery(
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
     )
-    public ResponseEntity reserveTicket(
+    public void reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        BookingResponseDTO response = bookingCommandService.reserveTicket(request, principal.userId());
-        return ResponseEntity.ok(response);
+        bookingCommandService.reserveTicket(request, principal.userId());
+        //return ResponseEntity.ok(response);
     }
 
     ///  GET
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
index d45494b..f62c899 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
@@ -11,6 +11,8 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
+
+// 추후에 지울 수 있음. - 가예매 3차에서 반환값으로 사용했었음.
 @Data
 @Builder
 public class BookingResponseDTO {
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 0895845..4b53965 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -13,6 +13,18 @@
 public interface TicketRepository extends JpaRepository {
     int countByUserIdAndFestivalIdAndPerformanceDate(Long userId, Long festivalId, LocalDateTime performanceDate);
 
+    @Query("SELECT COALESCE(SUM(t.selectedTicketCount), 0) " +
+            "FROM Ticket t " +
+            "WHERE t.userId = :userId " +
+            "AND t.festival.festivalId = :festivalId " +
+            "AND t.performanceDate >= :startDate " +
+            "AND t.performanceDate < :endDate")
+    Long sumSelectedTicketCount(
+            @Param("userId") Long userId,
+            @Param("festivalId") String festivalId,
+            @Param("startDate") LocalDateTime startDate,
+            @Param("endDate") LocalDateTime endDate);
+
 
     @Query("SELECT t FROM Ticket t WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.reservationNumber = :reservationNumber")
     Optional findByFestivalIdAndUserIdAndReservationNumber(
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index e07662b..17f2015 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -13,6 +13,7 @@
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -24,21 +25,19 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoUnit;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Locale;
 import java.util.UUID;
-import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
 
 @Service
 @RequiredArgsConstructor
+@Slf4j
 @Transactional(readOnly = true)
 public class BookingCommandService {
 
     private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
-    private static final int TEMP_RESERVATION_TTL_MINUTES = 1; // 임시 예약 유지 시간
+    private static final int TEMP_RESERVATION_TTL_MINUTES = 5; // 가예매 유지 시간
 
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
@@ -54,7 +53,6 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
 
         validatePerformanceDate(festival, performanceDate);
         validateScheduleExists(festival, performanceDate);
-        validateTicketAvailability(festival, request.getSelectedTicketCount());
         validateUserReservationLimit(userId, request, festival);
 
         Ticket ticket = Ticket.builder()
@@ -88,7 +86,7 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
 
     /// 3차: 가예매 - 최종 예약 - QR생성
     @Transactional
-    public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId) {
+    public void reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = getFestivalOrThrow(request.getFestivalId());
         Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
 
@@ -104,7 +102,7 @@ public BookingResponseDTO reserveTicket(BookingRequestDTO request, Long userId)
 
         ticketRepository.save(ticket);
 
-        return BookingResponseDTO.fromEntity(ticket);
+        //return BookingResponseDTO.fromEntity(ticket);
     }
 
     ///  최종 예약 완료
@@ -145,16 +143,18 @@ private void validateScheduleExists(Festival festival, LocalDateTime performance
         if (!exists) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
     }
 
-    private void validateTicketAvailability(Festival festival, int selectedTicketCount) {
-        if (festival.getAvailableNOP() < selectedTicketCount) {
+    private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO request, Festival festival) {
+        int selectTicketCount = request.getSelectedTicketCount();
+        if (festival.getMaxPurchase() < selectTicketCount){
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
-    }
 
-    private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO request, Festival festival) {
-        int alreadyReserved = ticketRepository.countByUserIdAndFestivalIdAndPerformanceDate(
-                userId, festival.getId(), request.getPerformanceDate());
-        if (alreadyReserved + request.getSelectedTicketCount() > festival.getMaxPurchase()) {
+        LocalDateTime startDate = request.getPerformanceDate();
+        LocalDateTime endDate = startDate.plusSeconds(1);
+
+        Long alreadyReserved = ticketRepository.sumSelectedTicketCount(
+                userId, festival.getFestivalId(), startDate, endDate);
+        if (alreadyReserved + selectTicketCount > festival.getMaxPurchase()) {
             throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
         }
     }

From 96d443164411f19b510433476045a7f994444d80 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 17 Aug 2025 15:49:08 +0900
Subject: [PATCH 031/149] =?UTF-8?q?MNMS-282=20Chore:=20JwtPrincipal=20logi?=
 =?UTF-8?q?nId=20->=20userId=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/WaitingController.java | 22 +++++++++----------
 .../mnms/booking/service/WaitingService.java  | 12 +++++-----
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index b53fdbd..7d04875 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -45,15 +45,15 @@ public ResponseEntity enterBookingPage(
             @RequestParam LocalDateTime reservationDate,
             @AuthenticationPrincipal JwtPrincipal principal) {
 
-        String loginId = principal != null ? principal.loginId() : "swagger-test-user";
+        String userId = principal != null ? String.valueOf(principal.userId()) : "swagger-test-user";
 
         int availableNOP = festivalService.getCapacity(festivalId); // 수용 인원 가져오기
-        long waitingNumber = waitingService.enterWaitingQueue(festivalId, reservationDate, loginId, availableNOP);
+        long waitingNumber = waitingService.enterWaitingQueue(festivalId, reservationDate, userId, availableNOP);
 
         if (waitingNumber == 0) {
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(loginId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
+            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
 
@@ -69,9 +69,9 @@ public ResponseEntity releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) { ///  예매칸에 있는 예매자 accessToken
-        String loginId = principal.loginId();
+        String userId = String.valueOf(principal.userId());
         try {
-            boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, loginId);
+            boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, userId);
             if (removed) {
                 return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
@@ -96,9 +96,9 @@ public ResponseEntity exitWaitingUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
-        String loginId = principal.loginId();
+        String userId = String.valueOf(principal.userId());
         try {
-            boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, loginId);
+            boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, userId);
             if (removed) {
                 return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
             } else {
@@ -122,10 +122,10 @@ public void subscribeWaitingQueue(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @AuthenticationPrincipal JwtPrincipal principal) {
-        String loginId = principal.loginId();
-        log.info("User {} subscribed to waiting queue updates.", loginId);
+        String userId = String.valueOf(principal.userId());
+        log.info("User {} subscribed to waiting queue updates.", userId);
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
-        waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+        waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 5cab408..64b06db 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -20,7 +20,7 @@ public class WaitingService {
      * 사용자 대기열 진입 처리
      * @return 대기 순번 (즉시 입장 가능 시 0)
      */
-    public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String loginId, long availableNOP) {
+    public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String userId, long availableNOP) {
         String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
@@ -28,16 +28,16 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
         long currentUserCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
 
         if (currentUserCount < availableNOP) {
-            log.info("User {} can enter booking page immediately ({} < {}).", loginId, currentUserCount, availableNOP);
-            waitingQueueRedisService.addBookingUser(bookingUsersKey, loginId);
+            log.info("User {} can enter booking page immediately ({} < {}).", userId, currentUserCount, availableNOP);
+            waitingQueueRedisService.addBookingUser(bookingUsersKey, userId);
             return 0L;
         } else {
-            waitingQueueRedisService.addUserToQueue(waitingQueueKey, loginId);
-            log.info("User {} added to waiting queue {}.", loginId, waitingQueueKey);
+            waitingQueueRedisService.addUserToQueue(waitingQueueKey, userId);
+            log.info("User {} added to waiting queue {}.", userId, waitingQueueKey);
 
             waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
 
-            return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+            return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
         }
     }
 

From 68b9e9ed707afea5d2fc3845948b33975f037e1a Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 17 Aug 2025 16:41:43 +0900
Subject: [PATCH 032/149] =?UTF-8?q?MNMS-282=20Feat:=20QR=20=ED=99=95?=
 =?UTF-8?q?=EC=9D=B8=20=EC=8B=9C=20=EC=A3=BC=EC=B5=9C=EC=9E=90=20=ED=99=95?=
 =?UTF-8?q?=EC=9D=B8=20=EC=A1=B0=EA=B1=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

+ festival에 주최자 추가
---
 .../java/com/mnms/booking/entity/Festival.java     |  3 +++
 .../java/com/mnms/booking/exception/ErrorCode.java |  2 +-
 .../com/mnms/booking/service/QrCodeService.java    | 14 +++++---------
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index def26f2..4dbefa1 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -21,6 +21,9 @@ public class Festival {
     @Column(name = "event_type")
     private EventType eventType;
 
+    @Column(name = "organizer")
+    private Long organizer;
+
     @Column(name = "festival_id", unique = true, nullable = false, length = 20)
     private String festivalId; // 공연 고유 ID (PF000001)
 
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 5a09acc..5064317 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -11,7 +11,7 @@ public enum ErrorCode {
     FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     FESTIVAL_DELIVERY_INVALID("F004", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
-    FESTIVAL_MISMATCH("F005", "해당하는 FESTIVAL QR 코드가 아닙니다.", HttpStatus.FORBIDDEN),
+    FESTIVAL_MISMATCH("F005", "해당하는 QR의 페스티벌 주최자가 아닙니다.", HttpStatus.FORBIDDEN),
 
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index d6e43ce..c4fb983 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -17,7 +17,6 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.security.SecureRandom;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Service
@@ -61,10 +60,7 @@ public QrCode getQrCodeByCode(String qrCodeId) {
     }
 
 
-    /**
-     * 해당 Festival 주최자 QR 스캔
-     * @param qrCodeId, festivalId
-     */
+    /// 해당 Festival 주최자 QR 스캔
     @Transactional
     public void validateAndUseQrCode(Long userId, String qrCodeId) {
 
@@ -78,10 +74,10 @@ public void validateAndUseQrCode(Long userId, String qrCodeId) {
             throw new BusinessException(ErrorCode.QR_CODE_INVALID);
         }
 
-        /// 주최자 확인 -> 추후 수정
-//        if (!ticket.getFestival().getId().equals(/*여기에 userId를 통해 festivalId 조회*/)) {
-//            throw new BusinessException(ErrorCode.FESTIVAL_MISMATCH);
-//        }
+        // 주최자 확인
+        if (!ticket.getFestival().getOrganizer().equals(userId)) {
+            throw new BusinessException(ErrorCode.FESTIVAL_MISMATCH);
+        }
 
         // 만료 여부 확인
         if (qrCode.getExpiredAt().isBefore(LocalDateTime.now())) {

From c6684f520b4dce7c115cf81d51c215365ac1a7f6 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 17 Aug 2025 17:17:55 +0900
Subject: [PATCH 033/149] =?UTF-8?q?MNMS-352=20Feat:=20=ED=8B=B0=EC=BC=93?=
 =?UTF-8?q?=20=EC=98=88=EB=A7=A4=20=EC=B7=A8=EC=86=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

티켓 예매 상태(reservationStatus) CANCELED로 변경
QR은 삭제
---
 .../booking/controller/BookingController.java | 14 +++++++++--
 .../dto/request/BookingCancelRequestDTO.java  | 10 ++++++++
 .../com/mnms/booking/exception/ErrorCode.java |  4 +++-
 .../service/BookingCommandService.java        | 23 ++++++++++++++++++-
 4 files changed, 47 insertions(+), 4 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 9b84001..56a51c1 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.controller;
 
+import com.mnms.booking.dto.request.BookingCancelRequestDTO;
 import com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
@@ -84,6 +85,17 @@ public void reserveTicket(
         //return ResponseEntity.ok(response);
     }
 
+    ///  예매 취소
+    @PostMapping("/cancel")
+    @Operation(summary = "예매 취소",
+            description = "사용자가 예약한 티켓을 취소합니다. reservationNumber 필요")
+    public void cancelBooking(
+            @RequestBody BookingCancelRequestDTO request,
+            @AuthenticationPrincipal JwtPrincipal principal
+    ) {
+        bookingCommandService.cancelBooking(request.getReservationNumber(), principal.userId());
+    }
+
     ///  GET
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
@@ -94,6 +106,4 @@ public ResponseEntity getUserInfo(@AuthenticationPrincipal
         UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
         return ResponseEntity.ok(userInfo);
     }
-
-
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java
new file mode 100644
index 0000000..5121889
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java
@@ -0,0 +1,10 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+public class BookingCancelRequestDTO {
+    private String reservationNumber;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 5064317..212e73e 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -17,7 +17,9 @@ public enum ErrorCode {
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
     TICKET_NOT_FOUND("T002", "해당하는 티켓을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     TICKET_INVALID_DELIVERY_METHOD("T003", "수령 방법이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
-    FESTIVAL_DELIVERY_NOT_COMPLETED("T004", "티켓 수령 방법이 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
+    TICKET_DELIVERY_NOT_COMPLETED("T004", "티켓 수령 방법이 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
+    TICKET_USER_NOT_SAME("T005", "사용자가 티켓 소유자가 아닙니다.", HttpStatus.FORBIDDEN),
+    TICKET_ALREADY_CANCELED("T006", "티켓이 이미 예매 취소되었습니다.", HttpStatus.CONFLICT),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 17f2015..a2501ec 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -105,6 +105,7 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
         //return BookingResponseDTO.fromEntity(ticket);
     }
 
+
     ///  최종 예약 완료
     public void confirmTicket(String reservationNumber) {
         ticketRepository.findByReservationNumber(reservationNumber)
@@ -114,6 +115,26 @@ public void confirmTicket(String reservationNumber) {
                 });
     }
 
+    ///  예매 취소
+    @Transactional
+    public void cancelBooking(String reservationNumber, Long userId) {
+        Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        if(!ticket.getUserId().equals(userId)){
+            throw new BusinessException(ErrorCode.TICKET_USER_NOT_SAME);
+        }
+
+        if (ticket.getReservationStatus() == ReservationStatus.CANCELED) {
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_CANCELED);
+        }
+
+        // qr 삭제 + ticket 상태 변경
+        ticket.getQrCodes().clear();
+        ticket.setReservationStatus(ReservationStatus.CANCELED);
+        ticketRepository.save(ticket);
+    }
+
     /// schedule 점검
     private void scheduleTempReservationExpiration(String reservationNumber) {
         scheduler.schedule(() -> {
@@ -161,7 +182,7 @@ private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO r
 
     private void ensureDeliveryStepCompleted(Ticket ticket) {
         if (ticket.getDeliveryMethod() == null || ticket.getDeliveryDate() == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_NOT_COMPLETED);
+            throw new BusinessException(ErrorCode.TICKET_DELIVERY_NOT_COMPLETED);
         }
     }
 

From 466ec45ad5d92f46cedb523c6cbfed33739f5c50 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 18 Aug 2025 13:11:23 +0900
Subject: [PATCH 034/149] =?UTF-8?q?MNMS-352=20Feat:=20=ED=8E=98=EC=8A=A4?=
 =?UTF-8?q?=ED=8B=B0=EB=B2=8C=20kafka=20=EA=B5=AC=EB=8F=85(Listener?=
 =?UTF-8?q?=EA=B5=AC=EC=84=B1)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dto/response/ScheduleResponseDTO.java     |  1 +
 .../com/mnms/booking/entity/Festival.java     | 34 ++++++++++++++---
 .../com/mnms/booking/entity/Schedule.java     | 13 +++++++
 .../kafka/booking/dto/FestivalEventDTO.java   | 26 +++++++++++++
 ...Event.java => PaymentSuccessEventDTO.java} |  2 +-
 .../kafka/booking/dto/ScheduleEventDTO.java   | 27 +++++++++++++
 .../booking/listener/FestivalListener.java    | 38 +++++++++++++++++++
 ...mentListener.java => PaymentListener.java} |  6 +--
 src/main/resources/application-dev.properties |  1 +
 9 files changed, 138 insertions(+), 10 deletions(-)
 create mode 100644 src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java
 rename src/main/java/com/mnms/kafka/booking/dto/{PaymentSuccessEvent.java => PaymentSuccessEventDTO.java} (88%)
 create mode 100644 src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java
 create mode 100644 src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java
 rename src/main/java/com/mnms/kafka/booking/listener/{KafkaPaymentListener.java => PaymentListener.java} (81%)

diff --git a/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
index caecbb4..600df73 100644
--- a/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.dto.response;
 
+import com.mnms.booking.entity.Schedule;
 import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 4dbefa1..76f51e4 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -2,8 +2,11 @@
 
 import com.fasterxml.jackson.annotation.JsonManagedReference;
 import com.mnms.booking.enums.EventType;
+import com.mnms.kafka.booking.dto.FestivalEventDTO;
 import jakarta.persistence.*;
+import lombok.Builder;
 import lombok.Getter;
+import lombok.Setter;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -12,18 +15,13 @@
 
 @Entity
 @Getter
+@Builder
 public class Festival {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id; // DB PK (자동증가)
 
-    @Column(name = "event_type")
-    private EventType eventType;
-
-    @Column(name = "organizer")
-    private Long organizer;
-
     @Column(name = "festival_id", unique = true, nullable = false, length = 20)
     private String festivalId; // 공연 고유 ID (PF000001)
 
@@ -54,7 +52,31 @@ public class Festival {
     @Column(name = "available_nop")
     private int availableNOP; // 수용인원
 
+    @Column(name = "event_type")
+    private EventType eventType;
+
+    @Column(name = "organizer")
+    private Long organizer;
+
     @OneToMany(mappedBy = "festival", cascade = CascadeType.ALL, orphanRemoval = true)
     @JsonManagedReference
+    @Setter
     private List schedules = new ArrayList<>();
+
+    public static Festival fromDto(FestivalEventDTO dto) {
+        return Festival.builder()
+                .festivalId(dto.getFestivalId())
+                .fname(dto.getFname())
+                .fdfrom(dto.getFdfrom())
+                .fdto(dto.getFdto())
+                .posterFile(dto.getPosterFile())
+                .fcltynm(dto.getFcltynm())
+                .ticketPick(dto.getTicketPick())
+                .maxPurchase(dto.getMaxPurchase())
+                .ticketPrice(dto.getTicketPrice())
+                .availableNOP(dto.getAvailableNOP())
+                .eventType(dto.getEventType())
+                .organizer(dto.getOrganizer())
+                .build();
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Schedule.java b/src/main/java/com/mnms/booking/entity/Schedule.java
index b17a425..dd4c73e 100644
--- a/src/main/java/com/mnms/booking/entity/Schedule.java
+++ b/src/main/java/com/mnms/booking/entity/Schedule.java
@@ -1,12 +1,16 @@
 package com.mnms.booking.entity;
 
 import com.fasterxml.jackson.annotation.JsonBackReference;
+import com.mnms.booking.dto.response.ScheduleResponseDTO;
+import com.mnms.kafka.booking.dto.ScheduleEventDTO;
 import jakarta.persistence.*;
+import lombok.Builder;
 import lombok.Getter;
 import lombok.Setter;
 
 @Entity
 @Getter @Setter
+@Builder
 public class Schedule {
 
     @Id
@@ -23,4 +27,13 @@ public class Schedule {
     @JoinColumn(name = "festival_id", nullable = false)
     @JsonBackReference
     private Festival festival;
+
+    public static Schedule fromDto(
+            ScheduleEventDTO schedule, Festival festival){
+        return Schedule.builder()
+                .dayOfWeek(schedule.getDayOfWeek())
+                .time(schedule.getTime())
+                .festival(festival)
+                .build();
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java b/src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java
new file mode 100644
index 0000000..99a92ac
--- /dev/null
+++ b/src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java
@@ -0,0 +1,26 @@
+package com.mnms.kafka.booking.dto;
+
+import com.mnms.booking.dto.response.ScheduleResponseDTO;
+import com.mnms.booking.enums.EventType;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+public class FestivalEventDTO {
+    private String festivalId;
+    private String fname;
+    private LocalDate fdfrom;
+    private LocalDate fdto;
+    private String posterFile;
+    private String fcltynm;
+    private int ticketPick;
+    private int maxPurchase;
+    private int ticketPrice;
+    private int availableNOP;
+    private EventType eventType;
+    private Long organizer;
+
+    private List schedules; // 추가
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java b/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java
similarity index 88%
rename from src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java
rename to src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java
index ea1abd9..79521aa 100644
--- a/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEvent.java
+++ b/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java
@@ -7,7 +7,7 @@
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
-public class PaymentSuccessEvent {
+public class PaymentSuccessEventDTO {
     private String reservationNumber;
     private Long userId;
     private int amount; // 필요시 추가
diff --git a/src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java b/src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java
new file mode 100644
index 0000000..02a78b2
--- /dev/null
+++ b/src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java
@@ -0,0 +1,27 @@
+package com.mnms.kafka.booking.dto;
+
+import com.mnms.booking.entity.Schedule;
+import jakarta.persistence.Column;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+@Data
+@Builder
+public class ScheduleEventDTO {
+
+    private String dayOfWeek; // 요일 코드 (MON, TUE...)
+    private String time; // 공연 시작 시간 (HH:mm)
+
+    public static ScheduleEventDTO fromEntity(Schedule schedule) {
+        return ScheduleEventDTO.builder()
+                .dayOfWeek(schedule.getDayOfWeek())
+                .time(schedule.getTime())
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java b/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java
new file mode 100644
index 0000000..802c6fb
--- /dev/null
+++ b/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java
@@ -0,0 +1,38 @@
+package com.mnms.kafka.booking.listener;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Schedule;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.kafka.booking.dto.FestivalEventDTO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class FestivalListener {
+
+    private final FestivalRepository festivalRepository;
+
+    @KafkaListener(topics = "${app.kafka.topic.festival-event}", groupId = "festival-service-group")
+    public void consumeFestival(String message) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+        
+        FestivalEventDTO dto = objectMapper.readValue(message, FestivalEventDTO.class);
+
+        Festival festival = Festival.fromDto(dto);
+
+        List schedules = dto.getSchedules().stream()
+                .map(s -> Schedule.fromDto(s, festival))
+                .toList();
+
+        festival.setSchedules(schedules);
+        festivalRepository.save(festival);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java b/src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java
similarity index 81%
rename from src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java
rename to src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java
index 2ec9f28..464c43e 100644
--- a/src/main/java/com/mnms/kafka/booking/listener/KafkaPaymentListener.java
+++ b/src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java
@@ -1,7 +1,7 @@
 package com.mnms.kafka.booking.listener;
 
 import com.mnms.booking.service.BookingCommandService;
-import com.mnms.kafka.booking.dto.PaymentSuccessEvent;
+import com.mnms.kafka.booking.dto.PaymentSuccessEventDTO;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.kafka.annotation.KafkaListener;
@@ -10,12 +10,12 @@
 @Service
 @RequiredArgsConstructor
 @Slf4j
-public class KafkaPaymentListener {
+public class PaymentListener {
 
     private final BookingCommandService bookingCommandService;
 
     @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group",  containerFactory = "kafkaListenerContainerFactory")
-    public void consumePaymentSuccess(PaymentSuccessEvent event) {
+    public void consumePaymentSuccess(PaymentSuccessEventDTO event) {
         log.info("Received payment success event: {}", event);
         bookingCommandService.confirmTicket(event.getReservationNumber());
     }
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index a64f507..67ea4f3 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -23,6 +23,7 @@ spring.redis.port=6379
 
 # kafka
 app.kafka.topic.payment-event=payment-topic
+app.kafka.topic.festival-event=festival-topic
 #app.kafka.topic.booking-event=booking-events
 #app.kafka.topic.user-event: user-events
 

From 8e5242667ec73b16565d3d2c38f63f78fb7c4007 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 19 Aug 2025 10:21:26 +0900
Subject: [PATCH 035/149] =?UTF-8?q?MNMS-352=20Chore:=20API=20=EC=84=B1?=
 =?UTF-8?q?=EA=B3=B5=20=EC=9D=91=EB=8B=B5=EA=B0=92=20SuccessResponse?=
 =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java | 29 ++++++++++---------
 .../booking/controller/CaptchaController.java | 11 ++++---
 .../booking/controller/QrCodeController.java  |  6 ++--
 .../booking/controller/WaitingController.java | 28 +++++++++---------
 .../com/mnms/booking/exception/ErrorCode.java |  3 ++
 .../repository/FestivalRepository.java        |  1 +
 .../booking/repository/TicketRepository.java  |  6 ++++
 .../service/BookingCommandService.java        |  2 --
 .../mnms/booking/util/ApiResponseUtil.java    | 23 +++++++++++++++
 9 files changed, 73 insertions(+), 36 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/util/ApiResponseUtil.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 56a51c1..740efd4 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -7,9 +7,11 @@
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.service.UserService;
+import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -34,18 +36,18 @@ public class BookingController {
     @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId와 performanceDate(사용자가 선택한 날짜 시간) 으로 공연 상세 정보를 조회합니다." +
                     "selectedTicketCount는 0으로 넣을 것!")
-    public FestivalDetailResponseDTO getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
-        return bookingQueryService.getFestivalDetail(request);
+    public ResponseEntity> getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
+        return ApiResponseUtil.success(bookingQueryService.getFestivalDetail(request));
     }
 
     @GetMapping("/detail/phases/2")
     @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
-    public BookingDetailResponseDTO getFestivalBookingDetail(
+    public ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        return bookingQueryService.getFestivalBookingDetail(request, principal.userId());
+        return ApiResponseUtil.success(bookingQueryService.getFestivalBookingDetail(request, principal.userId()));
     }
 
 
@@ -54,22 +56,23 @@ public BookingDetailResponseDTO getFestivalBookingDetail(
     @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
             description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)를 입력하고 reservationNumber를 반환합니다."
     )
-    public String selectFestivalDate(
+    public ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
-        return bookingCommandService.selectFestivalDate(request, principal.userId());
+        return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, principal.userId()));
     }
 
     @PostMapping("/selectDeliveryMethod")
     @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법 선택",
             description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER)"
     )
-    public void selectFestivalDelivery(
+    public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
         bookingCommandService.selectFestivalDelivery(request, principal.userId());
+        return ApiResponseUtil.success(null, "예매 티켓 수령 방법 선택 완료");
     }
 
     /// POST : 3차 예매 완료 (결제 직전)
@@ -77,23 +80,24 @@ public void selectFestivalDelivery(
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
     )
-    public void reserveTicket(
+    public ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
         bookingCommandService.reserveTicket(request, principal.userId());
-        //return ResponseEntity.ok(response);
+        return ApiResponseUtil.success(null, "예매 티켓 생성 완료");
     }
 
     ///  예매 취소
     @PostMapping("/cancel")
     @Operation(summary = "예매 취소",
             description = "사용자가 예약한 티켓을 취소합니다. reservationNumber 필요")
-    public void cancelBooking(
+    public ResponseEntity> cancelBooking(
             @RequestBody BookingCancelRequestDTO request,
             @AuthenticationPrincipal JwtPrincipal principal
     ) {
         bookingCommandService.cancelBooking(request.getReservationNumber(), principal.userId());
+        return ApiResponseUtil.success(null, "페스티벌 예매 취소");
     }
 
     ///  GET
@@ -102,8 +106,7 @@ public void cancelBooking(
             description = "예매 과정에서 예매자 정보를 조회합니다." +
                     "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
     )
-    public ResponseEntity getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
-        UserInfoResponseDTO userInfo = userService.getUserInfoById(principal.userId());
-        return ResponseEntity.ok(userInfo);
+    public ResponseEntity> getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
+        return ApiResponseUtil.success(userService.getUserInfoById(principal.userId()));
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
index 85df93c..a98d812 100644
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -1,7 +1,9 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.response.CaptchaResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.CaptchaService;
+import com.mnms.booking.util.ApiResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletRequest;
@@ -28,8 +30,9 @@ public class CaptchaController {
             summary = "보안문자 이미지 요청",
             description = "새로운 보안문자 이미지를 생성하여 반환합니다."
     )
-    public void getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
+    public ResponseEntity> getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
         kaptchaService.writeCaptchaImage(request.getSession(), response);
+        return ApiResponseUtil.success(null, "보안문자 이미지가 생성 완료");
     }
 
     @PostMapping("/verify")
@@ -38,13 +41,13 @@ public void getCaptchaImage(HttpServletRequest request, HttpServletResponse resp
             description = "사용자가 입력한 보안문자 값이 올바른지 검증합니다. " +
                     "보안문자는 다섯 글자이며 대소문자 구분하지 않습니다. 만료시간은 3분이고, 불일치로 실패해도 만료시간 내에 입력하면 인증 가능합니다."
     )
-    public ResponseEntity verifyCaptcha(
+    public ResponseEntity> verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
 
         CaptchaResponseDTO result = kaptchaService.verifyCaptchaResult(captcha, session);
         return result.isSuccess()
-                ? ResponseEntity.ok(result)
-                : ResponseEntity.status(HttpStatus.BAD_REQUEST).body(result);
+                ? ApiResponseUtil.success(result)
+                : ApiResponseUtil.fail(result.getMessage() ,HttpStatus.BAD_REQUEST);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index 62a0c67..38c7040 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -7,7 +7,9 @@
 import com.google.zxing.qrcode.QRCodeWriter;
 import com.mnms.booking.dto.request.QrRequestDTO;
 import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.QrCodeService;
+import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -48,11 +50,11 @@ public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
     @PostMapping(value = "/validate/{qrCodeId}")
     @Operation(summary = "QR 코드 스캔 및 유효성 검사",
             description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
-    public ResponseEntity validateAndUseQrCode(
+    public ResponseEntity> validateAndUseQrCode(
             @PathVariable String qrCodeId,
             @AuthenticationPrincipal JwtPrincipal principal) {
 
         qrCodeService.validateAndUseQrCode(principal.userId(), qrCodeId);
-        return ResponseEntity.ok().build();
+        return ApiResponseUtil.success(null, "QR 스캔 완료");
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 7d04875..61d3370 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -1,9 +1,11 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.FestivalService;
 import com.mnms.booking.service.WaitingNotificationService;
 import com.mnms.booking.service.WaitingQueueKeyGenerator;
+import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.JwtPrincipal;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
@@ -40,7 +42,7 @@ public class WaitingController {
 
     /// 예매하기 버튼(front) 클릭 시 호출되는 API
     @GetMapping("/enter")
-    public ResponseEntity enterBookingPage(
+    public ResponseEntity> enterBookingPage(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @AuthenticationPrincipal JwtPrincipal principal) {
@@ -51,9 +53,9 @@ public ResponseEntity enterBookingPage(
         long waitingNumber = waitingService.enterWaitingQueue(festivalId, reservationDate, userId, availableNOP);
 
         if (waitingNumber == 0) {
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
+            return ApiResponseUtil.success(new WaitingNumberResponseDTO(userId, 0, true, "REDIRECT_TO_BOOKING_PAGE"));
         } else {
-            return ResponseEntity.ok(new WaitingNumberResponseDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
+            return ApiResponseUtil.success(new WaitingNumberResponseDTO(userId, waitingNumber, false, "WAITING_QUEUE_ENTERED"));
         }
     }
 
@@ -65,7 +67,7 @@ public ResponseEntity enterBookingPage(
                     "대기열에 있던 사용자가 예매 페이지로 입장 하게 됩니다. " +
                     "대기열에 있던 모든 대기자의 대기번호가 변경됩니다."
     )
-    public ResponseEntity releaseUser(
+    public ResponseEntity> releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) { ///  예매칸에 있는 예매자 accessToken
@@ -73,14 +75,12 @@ public ResponseEntity releaseUser(
         try {
             boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, userId);
             if (removed) {
-                return ResponseEntity.ok("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
+                return ApiResponseUtil.success("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
-                return ResponseEntity.status(HttpStatus.NOT_FOUND)
-                        .body("해당 사용자는 예매 사용자 목록에 없습니다.");
+                return ApiResponseUtil.fail("해당 사용자는 예매 사용자 목록에 없습니다.", HttpStatus.NOT_FOUND);
             }
         } catch (Exception e) {
-            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
-                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+            return ApiResponseUtil.fail("서버 오류로 인해 사용자를 처리하지 못했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
         }
     }
 
@@ -92,7 +92,7 @@ public ResponseEntity releaseUser(
                     "호출 시 해당 사용자는 대기열에서 제거됩니다."
     )
     @GetMapping("/exit")
-    public ResponseEntity exitWaitingUser(
+    public ResponseEntity> exitWaitingUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
             @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
@@ -100,14 +100,12 @@ public ResponseEntity exitWaitingUser(
         try {
             boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, userId);
             if (removed) {
-                return ResponseEntity.ok("대기하던 사용자가 대기열을 나갔습니다.");
+                return ApiResponseUtil.success("대기하던 사용자가 대기열을 나갔습니다.");
             } else {
-                return ResponseEntity.status(HttpStatus.NOT_FOUND)
-                        .body("해당 사용자는 대기열 목록에 없습니다.");
+                return ApiResponseUtil.fail("해당 사용자는 대기열 목록에 없습니다.", HttpStatus.NOT_FOUND);
             }
         } catch (Exception e) {
-            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
-                    .body("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+            return ApiResponseUtil.fail("서버 오류로 인해 사용자를 처리하지 못했습니다.", HttpStatus.INTERNAL_SERVER_ERROR);
         }
     }
 
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 212e73e..e4ef007 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -6,6 +6,9 @@
 @Getter
 public enum ErrorCode {
 
+    // 보안문자
+    SECURITY_NUMBER_INVALID("S001", "입력한 문자가 일치하지 않습니다.", HttpStatus.BAD_REQUEST),
+
     // FESTIVAL
     FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
     FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index 25ce591..b4030f8 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -10,4 +10,5 @@
 public interface FestivalRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByFestivalId(String festivalId);
+    Optional findByOrganizer(Long organizer);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 4b53965..42952a9 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -7,6 +7,7 @@
 import org.springframework.stereotype.Repository;
 
 import java.time.LocalDateTime;
+import java.util.List;
 import java.util.Optional;
 
 @Repository
@@ -34,4 +35,9 @@ Optional findByFestivalIdAndUserIdAndReservationNumber(
     );
 
     Optional findByReservationNumber(String reservationNumber);
+
+    // host
+    @Query("SELECT DISTINCT t.userId FROM Ticket t WHERE t.festival.festivalId = :festivalId")
+    List findUserIdByFestivalId(@Param("festivalId") String festivalId);
+
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index a2501ec..f0a0625 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -101,8 +101,6 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
         );
 
         ticketRepository.save(ticket);
-
-        //return BookingResponseDTO.fromEntity(ticket);
     }
 
 
diff --git a/src/main/java/com/mnms/booking/util/ApiResponseUtil.java b/src/main/java/com/mnms/booking/util/ApiResponseUtil.java
new file mode 100644
index 0000000..f288065
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/ApiResponseUtil.java
@@ -0,0 +1,23 @@
+package com.mnms.booking.util;
+
+import com.mnms.booking.exception.global.SuccessResponse;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+
+public class ApiResponseUtil {
+    public static  ResponseEntity> success(T data, String message) {
+        return ResponseEntity.ok(new SuccessResponse<>(true, data, message));
+    }
+
+    public static  ResponseEntity> success(T data) {
+        return ResponseEntity.ok(new SuccessResponse<>(true, data, "요청이 성공적으로 처리되었습니다."));
+    }
+
+    public static  ResponseEntity> success() {
+        return ResponseEntity.ok(new SuccessResponse<>(true, null, "요청이 성공적으로 처리되었습니다."));
+    }
+
+    public static  ResponseEntity> fail(String message, HttpStatus status) {
+        return ResponseEntity.status(status).body(new SuccessResponse<>(false, null, message));
+    }
+}
\ No newline at end of file

From 7178b462b6cd7ecc465ace1920ee6889bc5bae2f Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 19 Aug 2025 10:38:24 +0900
Subject: [PATCH 036/149] MNMS-352 Fix: set constructor of the Festival,
 Qrcode, Schedule, Ticket

---
 src/main/java/com/mnms/booking/entity/Festival.java | 7 ++++---
 src/main/java/com/mnms/booking/entity/QrCode.java   | 2 +-
 src/main/java/com/mnms/booking/entity/Schedule.java | 9 ++++-----
 src/main/java/com/mnms/booking/entity/Ticket.java   | 2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 76f51e4..d0cb2a7 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -4,9 +4,7 @@
 import com.mnms.booking.enums.EventType;
 import com.mnms.kafka.booking.dto.FestivalEventDTO;
 import jakarta.persistence.*;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.*;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -16,6 +14,8 @@
 @Entity
 @Getter
 @Builder
+@AllArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Festival {
 
     @Id
@@ -60,6 +60,7 @@ public class Festival {
 
     @OneToMany(mappedBy = "festival", cascade = CascadeType.ALL, orphanRemoval = true)
     @JsonManagedReference
+    @Builder.Default
     @Setter
     private List schedules = new ArrayList<>();
 
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index ac1b7a1..be965c8 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -9,8 +9,8 @@
 @Entity
 @Getter
 @Builder
-@NoArgsConstructor(access = AccessLevel.PROTECTED)
 @AllArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
 @Table(name = "qr_code")
 public class QrCode {
 
diff --git a/src/main/java/com/mnms/booking/entity/Schedule.java b/src/main/java/com/mnms/booking/entity/Schedule.java
index dd4c73e..1f43051 100644
--- a/src/main/java/com/mnms/booking/entity/Schedule.java
+++ b/src/main/java/com/mnms/booking/entity/Schedule.java
@@ -1,16 +1,15 @@
 package com.mnms.booking.entity;
 
 import com.fasterxml.jackson.annotation.JsonBackReference;
-import com.mnms.booking.dto.response.ScheduleResponseDTO;
 import com.mnms.kafka.booking.dto.ScheduleEventDTO;
 import jakarta.persistence.*;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.Setter;
+import lombok.*;
 
 @Entity
-@Getter @Setter
 @Builder
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Schedule {
 
     @Id
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 792d0e5..e0745eb 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -12,9 +12,9 @@
 
 @Entity
 @Builder @Getter
-@Table(name = "ticket")
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
+@Table(name = "ticket")
 public class Ticket {
 
     @Id

From 420ccdcac3d892c40753ba2899187938af34714d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 19 Aug 2025 14:33:20 +0900
Subject: [PATCH 037/149] =?UTF-8?q?MNMS-351=20Feat:=20=ED=8E=98=EC=8A=A4?=
 =?UTF-8?q?=ED=8B=B0=EB=B2=8C=20=EC=A3=BC=EC=B5=9C=EC=9E=90=EC=97=90?=
 =?UTF-8?q?=EA=B2=8C=20=EC=A0=9C=EA=B3=B5=ED=95=98=EB=8A=94=20API=20?=
 =?UTF-8?q?=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

주최자에게 해당하는 페스티벌 날짜, 시간에 맞는 예매자 리스트 제공
---
 .../mnms/booking/config/SecurityConfig.java   |  3 +-
 .../booking/controller/HostController.java    | 30 +++++++++++++++++++
 .../booking/dto/request/HostRequestDTO.java   | 10 +++++++
 .../booking/repository/TicketRepository.java  | 13 +++++---
 .../com/mnms/booking/service/HostService.java | 20 +++++++++++++
 5 files changed, 71 insertions(+), 5 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/controller/HostController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/HostRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/service/HostService.java

diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 7f23cf3..7d59eb2 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -31,7 +31,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                                 "/h2-console/**",
                                 "/api/captcha/**",
                                 "/api/qr/**",
-                                "/api/booking/detail/phases/1"
+                                "/api/booking/detail/phases/1",
+                                "/api/host/**"
                                 ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
new file mode 100644
index 0000000..852ae90
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -0,0 +1,30 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.request.HostRequestDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
+import com.mnms.booking.service.HostService;
+import com.mnms.booking.util.ApiResponseUtil;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/host")
+@Tag(name = "주최자 도메인 데이터 제공 API", description = "주최자 repo에 제공하는 데이터 입니다. front와 관련 없음")
+public class HostController {
+
+    private final HostService hostService;
+
+    @GetMapping("/booking/list")
+    @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
+            description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다."
+    )
+    public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
+        return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
+    }
+}
diff --git a/src/main/java/com/mnms/booking/dto/request/HostRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/HostRequestDTO.java
new file mode 100644
index 0000000..34a71e6
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/HostRequestDTO.java
@@ -0,0 +1,10 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Getter;
+import java.time.LocalDateTime;
+
+@Getter
+public class HostRequestDTO {
+    private String festivalId;
+    private LocalDateTime performanceDate;
+}
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 42952a9..4431282 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -27,7 +27,9 @@ Long sumSelectedTicketCount(
             @Param("endDate") LocalDateTime endDate);
 
 
-    @Query("SELECT t FROM Ticket t WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.reservationNumber = :reservationNumber")
+    @Query("SELECT t " +
+            "FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.reservationNumber = :reservationNumber")
     Optional findByFestivalIdAndUserIdAndReservationNumber(
             @Param("festivalId") String festivalId,
             @Param("userId") Long userId,
@@ -37,7 +39,10 @@ Optional findByFestivalIdAndUserIdAndReservationNumber(
     Optional findByReservationNumber(String reservationNumber);
 
     // host
-    @Query("SELECT DISTINCT t.userId FROM Ticket t WHERE t.festival.festivalId = :festivalId")
-    List findUserIdByFestivalId(@Param("festivalId") String festivalId);
-
+    @Query("SELECT DISTINCT t.userId " +
+            "FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId " +
+            "AND t.performanceDate = :performanceDate")
+    List findDistinctUserIdsByFestivalIdAndPerformanceDate(@Param("festivalId") String festivalId,
+                                                           @Param("performanceDate") LocalDateTime performanceDate);
 }
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
new file mode 100644
index 0000000..4fa4eb7
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -0,0 +1,20 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.request.HostRequestDTO;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+@RequiredArgsConstructor
+@Service
+public class HostService {
+
+    private final TicketRepository ticketRepository;
+
+    public List getBookingsByOrganizer(HostRequestDTO request) {
+        return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
+    }
+}

From f565929c8430b95da52b622390878aad1f570f24 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Tue, 19 Aug 2025 15:53:41 +0900
Subject: [PATCH 038/149] build(api-booking): add production Dockerfile for
 Spring Boot (Java 17)

---
 Dockerfile | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)
 create mode 100644 Dockerfile

diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..6cc9d46
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,18 @@
+# Production runtime for Spring Boot (Java 17)
+FROM eclipse-temurin:17-jre-alpine
+
+# Create non-root user
+RUN addgroup -S spring && adduser -S spring -G spring
+USER spring
+
+WORKDIR /app
+
+# Copy built jar from Gradle output (placed by CI step './gradlew bootJar')
+# If multiple jars exist, the newest will be chosen at build time by the builder.
+ARG JAR_FILE=build/libs/*.jar
+COPY ${JAR_FILE} /app/app.jar
+
+EXPOSE 8080
+ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75"
+
+ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]
\ No newline at end of file

From daefc2a10b046bb9f01167d13ecc7c0a2a0c386c Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Tue, 19 Aug 2025 15:53:52 +0900
Subject: [PATCH 039/149] ci(api-booking): add workflow
 api-booking-docker-dispatch.yml (build & GitOps dispatch)

---
 .../workflows/api-booking-docker-dispatch.yml | 77 +++++++++++++++++++
 1 file changed, 77 insertions(+)
 create mode 100644 .github/workflows/api-booking-docker-dispatch.yml

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
new file mode 100644
index 0000000..27fff25
--- /dev/null
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -0,0 +1,77 @@
+name: "💰 api-booking – Docker Build & GitOps Dispatch"
+
+on:
+  push:
+    branches: [ main, develop ]
+  workflow_dispatch: {}
+
+permissions:
+  contents: read
+
+concurrency:
+  group: api-booking-${{ github.ref_name }}
+  cancel-in-progress: true
+
+env:
+  SERVICE: booking
+  IMAGE:   ${{ secrets.DOCKER_USERNAME }}/api-booking
+  DEVOPS_REPO: 3-mnms/gitops-repo
+
+jobs:
+  build-push:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+
+      - uses: actions/setup-java@v3
+        with:
+          distribution: temurin
+          java-version: '17'
+
+      - run: chmod +x ./gradlew
+      - run: ./gradlew bootJar --no-daemon
+
+      - name: ⏱️ Tag & Env
+        run: |
+          echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
+          if [ "${GITHUB_REF_NAME}" = "main" ]; then echo "ENV=prod" >> $GITHUB_ENV; else echo "ENV=develop" >> $GITHUB_ENV; fi
+
+      - uses: docker/setup-buildx-action@v3
+
+      - uses: docker/login-action@v3
+        with:
+          username: ${{ secrets.DOCKER_USERNAME }}
+          password: ${{ secrets.DOCKER_TOKEN }}
+
+      - id: meta
+        uses: docker/metadata-action@v5
+        with:
+          images: ${{ env.IMAGE }}
+          tags: |
+            type=raw,value=${{ env.TAG }}
+            type=sha
+            type=raw,value=latest,enable=${{ github.ref_name == 'main' }}
+
+      - uses: docker/build-push-action@v5
+        with:
+          context: .
+          file: ./Dockerfile
+          push: true
+          tags: ${{ steps.meta.outputs.tags }}
+          labels: ${{ steps.meta.outputs.labels }}
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
+
+      - name: Dispatch to GitOps
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "env":     "${{ env.ENV }}"
+            }
\ No newline at end of file

From ab1a91b99a54b2c0cf3e97236280e6aed37d866f Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 11:17:08 +0900
Subject: [PATCH 040/149] =?UTF-8?q?MNMS-351=20Feat:=20=ED=8E=98=EC=8A=A4?=
 =?UTF-8?q?=ED=8B=B0=EB=B2=8C=20kafka=20&=20=EC=98=88=EB=A7=A4=EC=9E=90=20?=
 =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A1=B0=ED=9A=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

페스티벌 kafka api 1차 완료 - 추가, 삭제 테스트 완료, 수정 테스트 X
주최측에서 예매자 정보 조회
---
 .../com/mnms/booking/BookingApplication.java  |  2 +
 .../booking/controller/BookingController.java |  6 +--
 .../booking/controller/HostController.java    | 16 ++++--
 .../response/BookingUserInfoResponseDTO.java  | 15 ++++++
 .../booking/dto/response/HostResponseDTO.java | 25 ++++++++++
 .../dto/response/ScheduleResponseDTO.java     |  1 -
 .../com/mnms/booking/entity/Festival.java     | 49 +++++++++++++++---
 .../com/mnms/booking/entity/Schedule.java     |  4 +-
 .../kafka/Handler/CreateFestivalHandler.java  | 29 +++++++++++
 .../kafka/Handler/DeleteFestivalHandler.java  | 18 +++++++
 .../kafka/Handler/FestivalEventHandler.java   |  7 +++
 .../kafka/Handler/UpdateFestivalHandler.java  | 32 ++++++++++++
 .../kafka}/config/KafkaProducerConfig.java    |  8 ++-
 .../kafka}/config/KafkaTopicConfig.java       |  2 +-
 .../kafka}/dto/FestivalEventDTO.java          | 13 ++---
 .../kafka}/dto/PaymentSuccessEventDTO.java    |  2 +-
 .../kafka}/dto/ScheduleEventDTO.java          |  6 ++-
 .../kafka/listener/FestivalListener.java      | 44 ++++++++++++++++
 .../kafka}/listener/PaymentListener.java      |  4 +-
 .../repository/FestivalRepository.java        |  3 +-
 .../booking/repository/TicketRepository.java  |  7 +++
 .../booking/service/BookingQueryService.java  |  1 -
 .../com/mnms/booking/service/HostService.java | 50 +++++++++++++++++++
 .../com/mnms/booking/service/UserService.java | 23 ---------
 .../com/mnms/booking/util/UserApiClient.java  | 44 ++++++++++++++++
 .../booking/listener/FestivalListener.java    | 38 --------------
 src/main/resources/application-dev.properties | 11 ++--
 .../resources/application-test.properties     |  3 +-
 28 files changed, 364 insertions(+), 99 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/kafka/Handler/CreateFestivalHandler.java
 create mode 100644 src/main/java/com/mnms/booking/kafka/Handler/DeleteFestivalHandler.java
 create mode 100644 src/main/java/com/mnms/booking/kafka/Handler/FestivalEventHandler.java
 create mode 100644 src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/config/KafkaProducerConfig.java (82%)
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/config/KafkaTopicConfig.java (92%)
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/dto/FestivalEventDTO.java (60%)
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/dto/PaymentSuccessEventDTO.java (88%)
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/dto/ScheduleEventDTO.java (83%)
 create mode 100644 src/main/java/com/mnms/booking/kafka/listener/FestivalListener.java
 rename src/main/java/com/mnms/{kafka/booking => booking/kafka}/listener/PaymentListener.java (88%)
 delete mode 100644 src/main/java/com/mnms/booking/service/UserService.java
 create mode 100644 src/main/java/com/mnms/booking/util/UserApiClient.java
 delete mode 100644 src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java

diff --git a/src/main/java/com/mnms/booking/BookingApplication.java b/src/main/java/com/mnms/booking/BookingApplication.java
index 9044be3..08b2deb 100644
--- a/src/main/java/com/mnms/booking/BookingApplication.java
+++ b/src/main/java/com/mnms/booking/BookingApplication.java
@@ -2,10 +2,12 @@
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.kafka.annotation.EnableKafka;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 @EnableScheduling
+@EnableKafka
 public class BookingApplication {
 
 	public static void main(String[] args) {
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 740efd4..d11effa 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -10,9 +10,9 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
-import com.mnms.booking.service.UserService;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.JwtPrincipal;
+import com.mnms.booking.util.UserApiClient;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
@@ -29,7 +29,7 @@ public class BookingController {
 
     private final BookingCommandService bookingCommandService;
     private final BookingQueryService bookingQueryService;
-    private final UserService userService;
+    private final UserApiClient userApiClient;
 
     /// GET : 페스티벌 예매 정보 조회
     @GetMapping("/detail/phases/1")
@@ -107,6 +107,6 @@ public ResponseEntity> cancelBooking(
                     "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
     )
     public ResponseEntity> getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
-        return ApiResponseUtil.success(userService.getUserInfoById(principal.userId()));
+        return ApiResponseUtil.success(userApiClient.getUserInfoById(principal.userId()));
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 852ae90..beeb5fa 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -1,6 +1,8 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.request.HostRequestDTO;
+import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
+import com.mnms.booking.dto.response.HostResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.HostService;
 import com.mnms.booking.util.ApiResponseUtil;
@@ -15,16 +17,22 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/host")
-@Tag(name = "주최자 도메인 데이터 제공 API", description = "주최자 repo에 제공하는 데이터 입니다. front와 관련 없음")
+@Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
 public class HostController {
 
     private final HostService hostService;
-
-    @GetMapping("/booking/list")
+    @GetMapping("/list")
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
-            description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다."
+            description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
     )
     public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
+
+    // 주최자 측 예매자 조회
+    @PostMapping("/booking/list")
+    public ResponseEntity>> getBookingInfo(@RequestBody Long hostUserId) {
+        List bookings = hostService.getBookingInfoByHost(hostUserId);
+        return ApiResponseUtil.success(bookings);
+    }
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
new file mode 100644
index 0000000..0d6ba16
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
@@ -0,0 +1,15 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+@Builder
+public class BookingUserInfoResponseDTO {
+    private Long userId;
+    private String name;
+    private String phone;
+    private String address;
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
new file mode 100644
index 0000000..645869c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
@@ -0,0 +1,25 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.enums.TicketType;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import java.time.LocalDateTime;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class HostResponseDTO {
+    private String reservationNumber;
+    private LocalDateTime performanceDate;
+    private Long userId;
+    private int selectedTicketCount;
+    private TicketType deliveryMethod;
+
+    // user info
+    private String userName;
+    private String phoneNumber;
+    private String address;
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
index 600df73..14600d5 100644
--- a/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/ScheduleResponseDTO.java
@@ -9,7 +9,6 @@
 @Setter
 @Builder
 public class ScheduleResponseDTO {
-    private Long scheduleId; // 공연 일정 PK
     private String dayOfWeek; // 요일 코드
     private String time;      // 공연 시작 시간 (HH:mm)
 }
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index d0cb2a7..2f3b5db 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -2,13 +2,15 @@
 
 import com.fasterxml.jackson.annotation.JsonManagedReference;
 import com.mnms.booking.enums.EventType;
-import com.mnms.kafka.booking.dto.FestivalEventDTO;
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
 import jakarta.persistence.*;
 import lombok.*;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 @Entity
@@ -52,9 +54,6 @@ public class Festival {
     @Column(name = "available_nop")
     private int availableNOP; // 수용인원
 
-    @Column(name = "event_type")
-    private EventType eventType;
-
     @Column(name = "organizer")
     private Long organizer;
 
@@ -66,7 +65,7 @@ public class Festival {
 
     public static Festival fromDto(FestivalEventDTO dto) {
         return Festival.builder()
-                .festivalId(dto.getFestivalId())
+                .festivalId(dto.getId())
                 .fname(dto.getFname())
                 .fdfrom(dto.getFdfrom())
                 .fdto(dto.getFdto())
@@ -76,8 +75,44 @@ public static Festival fromDto(FestivalEventDTO dto) {
                 .maxPurchase(dto.getMaxPurchase())
                 .ticketPrice(dto.getTicketPrice())
                 .availableNOP(dto.getAvailableNOP())
-                .eventType(dto.getEventType())
-                .organizer(dto.getOrganizer())
+                .organizer(dto.getUserId())
                 .build();
     }
+
+    public void updateFromDto(FestivalEventDTO dto) {
+        if (dto.getFname() != null) this.fname = dto.getFname();
+        if (dto.getUserId() != null) this.organizer = dto.getUserId();
+        if (dto.getPosterFile() != null) this.posterFile = dto.getPosterFile();
+        if (dto.getFdfrom() != null) this.fdfrom = dto.getFdfrom();
+        if (dto.getFdto() != null) this.fdto = dto.getFdto();
+        if (dto.getFcltynm() != null) this.fcltynm = dto.getFcltynm();
+        if (dto.getMaxPurchase() != 0) this.maxPurchase = dto.getMaxPurchase();
+        if (dto.getAvailableNOP() != 0) this.availableNOP = dto.getAvailableNOP();
+        if (dto.getTicketPrice() != 0) this.ticketPrice = dto.getTicketPrice();
+        if (dto.getTicketPick() != 0) this.ticketPick = dto.getTicketPick();
+    }
+
+    public void mergeSchedules(List updatedSchedules) {
+        Map existingMap = this.schedules.stream()
+                .collect(Collectors.toMap(Schedule::getScheduleId, s -> s));
+
+        List merged = new ArrayList<>();
+
+        for (Schedule updated : updatedSchedules) {
+            Schedule schedule = existingMap.get(updated.getScheduleId());
+            if (schedule != null) {
+                schedule.setScheduleId(updated.getScheduleId());
+                schedule.setDayOfWeek(updated.getDayOfWeek());
+                schedule.setTime(updated.getTime());
+                merged.add(schedule);
+            } else {
+                updated.setFestival(this);
+                merged.add(updated);
+            }
+        }
+
+        // 기존에 있고 이번 업데이트에 없는 스케줄은 제거
+        this.schedules.clear();
+        this.schedules.addAll(merged);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Schedule.java b/src/main/java/com/mnms/booking/entity/Schedule.java
index 1f43051..279e080 100644
--- a/src/main/java/com/mnms/booking/entity/Schedule.java
+++ b/src/main/java/com/mnms/booking/entity/Schedule.java
@@ -1,13 +1,13 @@
 package com.mnms.booking.entity;
 
 import com.fasterxml.jackson.annotation.JsonBackReference;
-import com.mnms.kafka.booking.dto.ScheduleEventDTO;
+import com.mnms.booking.kafka.dto.ScheduleEventDTO;
 import jakarta.persistence.*;
 import lombok.*;
 
 @Entity
 @Builder
-@Getter
+@Getter @Setter
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Schedule {
diff --git a/src/main/java/com/mnms/booking/kafka/Handler/CreateFestivalHandler.java b/src/main/java/com/mnms/booking/kafka/Handler/CreateFestivalHandler.java
new file mode 100644
index 0000000..9850755
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/Handler/CreateFestivalHandler.java
@@ -0,0 +1,29 @@
+package com.mnms.booking.kafka.Handler;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Schedule;
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
+import com.mnms.booking.repository.FestivalRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class CreateFestivalHandler implements FestivalEventHandler {
+
+    private final FestivalRepository festivalRepository;
+
+    @Override
+    public void handle(FestivalEventDTO dto) {
+        Festival festival = Festival.fromDto(dto);
+
+        List schedules = dto.getSchedules().stream()
+                .map(s -> Schedule.fromDto(s, festival))
+                .toList();
+
+        festival.setSchedules(schedules);
+        festivalRepository.save(festival);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/kafka/Handler/DeleteFestivalHandler.java b/src/main/java/com/mnms/booking/kafka/Handler/DeleteFestivalHandler.java
new file mode 100644
index 0000000..0bff7c0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/Handler/DeleteFestivalHandler.java
@@ -0,0 +1,18 @@
+package com.mnms.booking.kafka.Handler;
+
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
+import com.mnms.booking.repository.FestivalRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class DeleteFestivalHandler implements FestivalEventHandler {
+
+    private final FestivalRepository festivalRepository;
+
+    @Override
+    public void handle(FestivalEventDTO dto) {
+        festivalRepository.findByFestivalId(dto.getId()).ifPresent(festivalRepository::delete);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/kafka/Handler/FestivalEventHandler.java b/src/main/java/com/mnms/booking/kafka/Handler/FestivalEventHandler.java
new file mode 100644
index 0000000..8e44920
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/Handler/FestivalEventHandler.java
@@ -0,0 +1,7 @@
+package com.mnms.booking.kafka.Handler;
+
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
+
+public interface FestivalEventHandler {
+    void handle(FestivalEventDTO dto);
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java b/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
new file mode 100644
index 0000000..73c4e11
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
@@ -0,0 +1,32 @@
+package com.mnms.booking.kafka.Handler;
+
+import com.mnms.booking.entity.Schedule;
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
+import com.mnms.booking.repository.FestivalRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+@RequiredArgsConstructor
+public class UpdateFestivalHandler implements FestivalEventHandler {
+
+    private final FestivalRepository festivalRepository;
+
+    @Override
+    public void handle(FestivalEventDTO dto) {
+        festivalRepository.findByFestivalId(dto.getId())
+                .ifPresent(festival -> {
+                    festival.updateFromDto(dto);
+
+                    List updatedSchedules = dto.getSchedules() == null ? List.of() :
+                            dto.getSchedules().stream()
+                                    .map(s -> Schedule.fromDto(s, festival))
+                                    .toList();
+
+                    festival.mergeSchedules(updatedSchedules);
+                    festivalRepository.save(festival);
+                });
+    }
+}
diff --git a/src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java b/src/main/java/com/mnms/booking/kafka/config/KafkaProducerConfig.java
similarity index 82%
rename from src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java
rename to src/main/java/com/mnms/booking/kafka/config/KafkaProducerConfig.java
index 375cf02..32303d4 100644
--- a/src/main/java/com/mnms/kafka/booking/config/KafkaProducerConfig.java
+++ b/src/main/java/com/mnms/booking/kafka/config/KafkaProducerConfig.java
@@ -1,8 +1,9 @@
-package com.mnms.kafka.booking.config;
+package com.mnms.booking.kafka.config;
 
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import org.apache.kafka.clients.producer.ProducerConfig;
 import org.apache.kafka.common.serialization.StringSerializer;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.kafka.core.DefaultKafkaProducerFactory;
@@ -16,9 +17,12 @@
 @Configuration
 public class KafkaProducerConfig {
 
+    @Value("${spring.kafka.bootstrap-servers}")
+    private String bootstrapServers;
+
     public  ProducerFactory producerFactory(Class clazz) {
         Map config = new HashMap<>();
-        config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
+        config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers);
         config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
         config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
         return new DefaultKafkaProducerFactory<>(config);
diff --git a/src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java b/src/main/java/com/mnms/booking/kafka/config/KafkaTopicConfig.java
similarity index 92%
rename from src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java
rename to src/main/java/com/mnms/booking/kafka/config/KafkaTopicConfig.java
index 4c26c2d..7e90b0b 100644
--- a/src/main/java/com/mnms/kafka/booking/config/KafkaTopicConfig.java
+++ b/src/main/java/com/mnms/booking/kafka/config/KafkaTopicConfig.java
@@ -1,4 +1,4 @@
-package com.mnms.kafka.booking.config;
+package com.mnms.booking.kafka.config;
 
 import org.apache.kafka.clients.admin.NewTopic;
 import org.springframework.context.annotation.Bean;
diff --git a/src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/FestivalEventDTO.java
similarity index 60%
rename from src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java
rename to src/main/java/com/mnms/booking/kafka/dto/FestivalEventDTO.java
index 99a92ac..8d54ce6 100644
--- a/src/main/java/com/mnms/kafka/booking/dto/FestivalEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/FestivalEventDTO.java
@@ -1,6 +1,5 @@
-package com.mnms.kafka.booking.dto;
+package com.mnms.booking.kafka.dto;
 
-import com.mnms.booking.dto.response.ScheduleResponseDTO;
 import com.mnms.booking.enums.EventType;
 import lombok.Data;
 
@@ -9,7 +8,11 @@
 
 @Data
 public class FestivalEventDTO {
-    private String festivalId;
+
+    private String eventType; // e.g. "FESTIVAL_CREATED" / "FESTIVAL_UPDATED" / "FESTIVAL_DELETED"
+    private String id;
+    private Long userId;
+
     private String fname;
     private LocalDate fdfrom;
     private LocalDate fdto;
@@ -19,8 +22,6 @@ public class FestivalEventDTO {
     private int maxPurchase;
     private int ticketPrice;
     private int availableNOP;
-    private EventType eventType;
-    private Long organizer;
 
-    private List schedules; // 추가
+    private List schedules; // 추가
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
similarity index 88%
rename from src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java
rename to src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
index 79521aa..6f24589 100644
--- a/src/main/java/com/mnms/kafka/booking/dto/PaymentSuccessEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
@@ -1,4 +1,4 @@
-package com.mnms.kafka.booking.dto;
+package com.mnms.booking.kafka.dto;
 
 import lombok.AllArgsConstructor;
 import lombok.Data;
diff --git a/src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/ScheduleEventDTO.java
similarity index 83%
rename from src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java
rename to src/main/java/com/mnms/booking/kafka/dto/ScheduleEventDTO.java
index 02a78b2..0e19126 100644
--- a/src/main/java/com/mnms/kafka/booking/dto/ScheduleEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/ScheduleEventDTO.java
@@ -1,17 +1,21 @@
-package com.mnms.kafka.booking.dto;
+package com.mnms.booking.kafka.dto;
 
 import com.mnms.booking.entity.Schedule;
 import jakarta.persistence.Column;
 import jakarta.persistence.GeneratedValue;
 import jakarta.persistence.GenerationType;
 import jakarta.persistence.Id;
+import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
+import lombok.NoArgsConstructor;
 
 import java.time.LocalDate;
 import java.time.LocalTime;
 
 @Data
+@NoArgsConstructor
+@AllArgsConstructor
 @Builder
 public class ScheduleEventDTO {
 
diff --git a/src/main/java/com/mnms/booking/kafka/listener/FestivalListener.java b/src/main/java/com/mnms/booking/kafka/listener/FestivalListener.java
new file mode 100644
index 0000000..5c0ada4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/kafka/listener/FestivalListener.java
@@ -0,0 +1,44 @@
+package com.mnms.booking.kafka.listener;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.mnms.booking.kafka.Handler.CreateFestivalHandler;
+import com.mnms.booking.kafka.Handler.DeleteFestivalHandler;
+import com.mnms.booking.kafka.Handler.FestivalEventHandler;
+import com.mnms.booking.kafka.Handler.UpdateFestivalHandler;
+import com.mnms.booking.kafka.dto.FestivalEventDTO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.kafka.annotation.KafkaListener;
+import org.springframework.stereotype.Service;
+
+@Service
+@RequiredArgsConstructor
+public class FestivalListener {
+
+    private final CreateFestivalHandler createHandler;
+    private final UpdateFestivalHandler updateHandler;
+    private final DeleteFestivalHandler deleteHandler;
+
+    @KafkaListener(topics = "${app.kafka.topic.festival-event}", groupId = "festival-service-group")
+    public void consumeFestival(String message) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        objectMapper.registerModule(new JavaTimeModule());
+        
+        FestivalEventDTO dto = objectMapper.readValue(message, FestivalEventDTO.class);
+
+        String eventType = dto.getEventType();
+        FestivalEventHandler handler = switch (eventType.toUpperCase()) {
+            case "FESTIVAL_CREATED" -> createHandler;
+            case "FESTIVAL_UPDATED" -> updateHandler;
+            case "FESTIVAL_DELETED" -> deleteHandler;
+            default -> null;
+        };
+
+        if (handler != null) {
+            handler.handle(dto);
+        } else {
+            System.out.println("Unknown eventType: " + eventType);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
similarity index 88%
rename from src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java
rename to src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index 464c43e..644fff9 100644
--- a/src/main/java/com/mnms/kafka/booking/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -1,7 +1,7 @@
-package com.mnms.kafka.booking.listener;
+package com.mnms.booking.kafka.listener;
 
+import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.service.BookingCommandService;
-import com.mnms.kafka.booking.dto.PaymentSuccessEventDTO;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.kafka.annotation.KafkaListener;
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index b4030f8..b5d81ee 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -4,11 +4,12 @@
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Optional;
 
 @Repository
 public interface FestivalRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByFestivalId(String festivalId);
-    Optional findByOrganizer(Long organizer);
+    List findByOrganizer(Long organizer);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 4431282..f67f1da 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.repository;
 
+import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
@@ -45,4 +46,10 @@ Optional findByFestivalIdAndUserIdAndReservationNumber(
             "AND t.performanceDate = :performanceDate")
     List findDistinctUserIdsByFestivalIdAndPerformanceDate(@Param("festivalId") String festivalId,
                                                            @Param("performanceDate") LocalDateTime performanceDate);
+
+
+    @Query("SELECT t " +
+            "FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId ")
+    List findByFestivalId(String festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingQueryService.java b/src/main/java/com/mnms/booking/service/BookingQueryService.java
index fbc14c1..8a3f182 100644
--- a/src/main/java/com/mnms/booking/service/BookingQueryService.java
+++ b/src/main/java/com/mnms/booking/service/BookingQueryService.java
@@ -88,7 +88,6 @@ private List getSchedules(Festival festival) {
         return scheduleRepository.findByFestivalId(festival.getFestivalId())
                 .stream()
                 .map(s -> ScheduleResponseDTO.builder()
-                        .scheduleId(s.getScheduleId())
                         .dayOfWeek(s.getDayOfWeek())
                         .time(s.getTime())
                         .build())
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index 4fa4eb7..41cf11e 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -1,11 +1,22 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.HostRequestDTO;
+import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
+import com.mnms.booking.dto.response.HostResponseDTO;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.TicketRepository;
+import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 
 @RequiredArgsConstructor
@@ -13,8 +24,47 @@
 public class HostService {
 
     private final TicketRepository ticketRepository;
+    private final FestivalRepository festivalRepository;
+    private final UserApiClient userApiClient;
 
     public List getBookingsByOrganizer(HostRequestDTO request) {
         return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
     }
+
+    public List getBookingInfoByHost(Long hostUserId) {
+        List festivals = festivalRepository.findByOrganizer(hostUserId);
+        if (festivals == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
+        }
+
+        List tickets = new ArrayList<>();
+        for (Festival festival : festivals) {
+            tickets.addAll(ticketRepository.findByFestivalId(festival.getFestivalId()));
+        }
+
+        List userIds = tickets.stream()
+                .map(Ticket::getUserId)
+                .distinct()
+                .toList();
+
+        List users = userApiClient.getUsersByIds(userIds);
+        Map userMap = users.stream()
+                .collect(Collectors.toMap(BookingUserInfoResponseDTO::getUserId, u -> u));
+
+        return tickets.stream()
+                .map(t -> {
+                    BookingUserInfoResponseDTO user = userMap.get(t.getUserId());
+                    return new HostResponseDTO(
+                            t.getReservationNumber(),
+                            t.getPerformanceDate(),
+                            t.getUserId(),
+                            t.getSelectedTicketCount(),
+                            t.getDeliveryMethod(),
+                            user != null ? user.getName() : null,
+                            user != null ? user.getPhone() : null,
+                            user != null ? user.getAddress() : null
+                    );
+                })
+                .toList();
+    }
 }
diff --git a/src/main/java/com/mnms/booking/service/UserService.java b/src/main/java/com/mnms/booking/service/UserService.java
deleted file mode 100644
index 49c4f17..0000000
--- a/src/main/java/com/mnms/booking/service/UserService.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package com.mnms.booking.service;
-
-import com.mnms.booking.dto.response.UserInfoResponseDTO;
-import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Service;
-import org.springframework.web.client.RestTemplate;
-
-
-@Service
-@RequiredArgsConstructor
-public class UserService {
-
-    private final RestTemplate restTemplate;
-
-    @Value("${user.service.url}")
-    private String userServiceUrl;
-
-    public UserInfoResponseDTO getUserInfoById(Long userId) {
-        String url = String.format("%s/%d", userServiceUrl, userId);
-        return restTemplate.getForObject(url, UserInfoResponseDTO.class);
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/UserApiClient.java b/src/main/java/com/mnms/booking/util/UserApiClient.java
new file mode 100644
index 0000000..61c55f0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/UserApiClient.java
@@ -0,0 +1,44 @@
+package com.mnms.booking.util;
+
+import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
+import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.List;
+
+@Component
+@RequiredArgsConstructor
+public class UserApiClient {
+
+    private final RestTemplate restTemplate;
+
+    @Value("${booking.user.service.url}")
+    private String bookingUserServiceUrl;
+
+    @Value("${user.service.url}")
+    private String userServiceUrl;
+
+    public List getUsersByIds(List userIds) {
+        //return restTemplate.postForObject(bookingUserServiceUrl, userIds, List.class);
+        ResponseEntity> response =
+                restTemplate.exchange(
+                        userServiceUrl,
+                        HttpMethod.POST,
+                        new HttpEntity<>(userIds),
+                        new ParameterizedTypeReference>() {}
+                );
+        return response.getBody();
+    }
+
+    public UserInfoResponseDTO getUserInfoById(Long userId) {
+        String url = String.format("%s/%d", userServiceUrl, userId);
+        return restTemplate.getForObject(url, UserInfoResponseDTO.class);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java b/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java
deleted file mode 100644
index 802c6fb..0000000
--- a/src/main/java/com/mnms/kafka/booking/listener/FestivalListener.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.mnms.kafka.booking.listener;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
-import com.mnms.booking.entity.Festival;
-import com.mnms.booking.entity.Schedule;
-import com.mnms.booking.repository.FestivalRepository;
-import com.mnms.kafka.booking.dto.FestivalEventDTO;
-import lombok.RequiredArgsConstructor;
-import org.springframework.kafka.annotation.KafkaListener;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-@Service
-@RequiredArgsConstructor
-public class FestivalListener {
-
-    private final FestivalRepository festivalRepository;
-
-    @KafkaListener(topics = "${app.kafka.topic.festival-event}", groupId = "festival-service-group")
-    public void consumeFestival(String message) throws JsonProcessingException {
-        ObjectMapper objectMapper = new ObjectMapper();
-        objectMapper.registerModule(new JavaTimeModule());
-        
-        FestivalEventDTO dto = objectMapper.readValue(message, FestivalEventDTO.class);
-
-        Festival festival = Festival.fromDto(dto);
-
-        List schedules = dto.getSchedules().stream()
-                .map(s -> Schedule.fromDto(s, festival))
-                .toList();
-
-        festival.setSchedules(schedules);
-        festivalRepository.save(festival);
-    }
-}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 67ea4f3..dd6423c 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -21,17 +21,17 @@ spring.redis.host=127.0.0.1
 spring.redis.port=6379
 #spring.redis.password=your_password
 
-# kafka
+## kafka
 app.kafka.topic.payment-event=payment-topic
 app.kafka.topic.festival-event=festival-topic
-#app.kafka.topic.booking-event=booking-events
-#app.kafka.topic.user-event: user-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
-spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
 spring.kafka.consumer.properties.spring.json.use.type.headers=false
+spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+
 #spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
 
 
@@ -51,4 +51,5 @@ springdoc.swagger-ui.path=/swagger-ui.html
 springdoc.override-with-generic-response=false
 
 # user api
-user.service.url=${USER_INFO_API}
\ No newline at end of file
+user.service.url=${USER_INFO_API}
+booking.user.service.url=${BOOKING_USER_INFO_API}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index affea0f..d5ffb53 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -51,4 +51,5 @@ springdoc.swagger-ui.path=/swagger-ui.html
 springdoc.override-with-generic-response=false
 
 # user api
-user.service.url=${USER_INFO_API}
\ No newline at end of file
+user.service.url=${USER_INFO_API}
+booking.user.servicel.url=${BOOKING_USER_INFO_API}
\ No newline at end of file

From b1e47b18e85078fa60fddf6f5f76dd4b40dbc924 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 11:24:55 +0900
Subject: [PATCH 041/149] =?UTF-8?q?MNMS-351=20Chore:=20=ED=8E=98=EC=8A=A4?=
 =?UTF-8?q?=ED=8B=B0=EB=B2=8C=20kafka=20=EC=88=98=EC=A0=95=20=ED=85=8C?=
 =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

LazyInitializationException 오류 해결
세션/트랜잭션이 없는 상태에서 접근해서 초기화를 못하는 오류 해결
---
 src/main/java/com/mnms/booking/controller/HostController.java  | 2 +-
 src/main/java/com/mnms/booking/entity/Festival.java            | 3 ++-
 .../com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java  | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index beeb5fa..98af957 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -29,7 +29,7 @@ public ResponseEntity>> getBookingsByOrganizer(@Reque
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
 
-    // 주최자 측 예매자 조회
+    /// 주최자 측 예매자 조회
     @PostMapping("/booking/list")
     public ResponseEntity>> getBookingInfo(@RequestBody Long hostUserId) {
         List bookings = hostService.getBookingInfoByHost(hostUserId);
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index 2f3b5db..d5f461b 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -1,10 +1,10 @@
 package com.mnms.booking.entity;
 
 import com.fasterxml.jackson.annotation.JsonManagedReference;
-import com.mnms.booking.enums.EventType;
 import com.mnms.booking.kafka.dto.FestivalEventDTO;
 import jakarta.persistence.*;
 import lombok.*;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
 import java.util.ArrayList;
@@ -92,6 +92,7 @@ public void updateFromDto(FestivalEventDTO dto) {
         if (dto.getTicketPick() != 0) this.ticketPick = dto.getTicketPick();
     }
 
+    @Transactional
     public void mergeSchedules(List updatedSchedules) {
         Map existingMap = this.schedules.stream()
                 .collect(Collectors.toMap(Schedule::getScheduleId, s -> s));
diff --git a/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java b/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
index 73c4e11..2797ace 100644
--- a/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
+++ b/src/main/java/com/mnms/booking/kafka/Handler/UpdateFestivalHandler.java
@@ -5,6 +5,7 @@
 import com.mnms.booking.repository.FestivalRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 
@@ -15,6 +16,7 @@ public class UpdateFestivalHandler implements FestivalEventHandler {
     private final FestivalRepository festivalRepository;
 
     @Override
+    @Transactional
     public void handle(FestivalEventDTO dto) {
         festivalRepository.findByFestivalId(dto.getId())
                 .ifPresent(festival -> {

From b661bc9783f27a919947e3d467207bcc84a766ea Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 13:36:51 +0900
Subject: [PATCH 042/149] =?UTF-8?q?MNMS-351=20Feat:=20=EA=B2=B0=EC=A0=9C?=
 =?UTF-8?q?=20kafka=20=EA=B5=AC=EB=8F=85=20=EC=BD=94=EB=93=9C=201=EC=B0=A8?=
 =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../kafka/dto/PaymentSuccessEventDTO.java      |  3 +--
 .../kafka/listener/PaymentListener.java        |  4 ++--
 .../booking/service/BookingCommandService.java | 18 ++++++++++++------
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
index 6f24589..2d7f735 100644
--- a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
@@ -9,6 +9,5 @@
 @AllArgsConstructor
 public class PaymentSuccessEventDTO {
     private String reservationNumber;
-    private Long userId;
-    private int amount; // 필요시 추가
+    private Boolean paymentStatus;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index 644fff9..087f418 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -16,7 +16,7 @@ public class PaymentListener {
 
     @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group",  containerFactory = "kafkaListenerContainerFactory")
     public void consumePaymentSuccess(PaymentSuccessEventDTO event) {
-        log.info("Received payment success event: {}", event);
-        bookingCommandService.confirmTicket(event.getReservationNumber());
+        log.info("Received payment success event: {}, {}", event.getReservationNumber(), event.getPaymentStatus());
+        bookingCommandService.confirmTicket(event.getReservationNumber(), event.getPaymentStatus());
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index f0a0625..cf19ef1 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -9,6 +9,7 @@
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
@@ -26,6 +27,7 @@
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoUnit;
 import java.util.Locale;
+import java.util.Optional;
 import java.util.UUID;
 import java.util.stream.IntStream;
 
@@ -105,12 +107,16 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
 
 
     ///  최종 예약 완료
-    public void confirmTicket(String reservationNumber) {
-        ticketRepository.findByReservationNumber(reservationNumber)
-                .ifPresent(ticket -> {
-                    ticket.setReservationStatus(ReservationStatus.CONFIRMED);
-                    ticketRepository.save(ticket);
-                });
+    public void confirmTicket(String reservationNumber, Boolean paymentStatus) {
+        Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)
+                        .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        if (paymentStatus) {
+            bookingTicket.setReservationStatus(ReservationStatus.CONFIRMED);
+        } else {
+            bookingTicket.setReservationStatus(ReservationStatus.CANCELED);
+        }
+        ticketRepository.save(bookingTicket);
     }
 
     ///  예매 취소

From 4db63103c7b0d3083d6d7ed96c710a32ff7743ee Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 15:11:35 +0900
Subject: [PATCH 043/149] =?UTF-8?q?MNMS-351=20Feat:=20=EA=B2=B0=EC=A0=9C?=
 =?UTF-8?q?=20kafka=20=EA=B5=AC=EB=8F=85=20=EC=BD=94=EB=93=9C=202=EC=B0=A8?=
 =?UTF-8?q?=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

reservation_status 변경 테스트 완료
front websocket 설정 완료 - 테스트X
---
 .../mnms/booking/config/SecurityConfig.java   |  3 +-
 .../dto/response/TicketStatusResponseDTO.java |  5 ++++
 .../kafka/dto/PaymentSuccessEventDTO.java     |  4 ++-
 .../kafka/listener/PaymentListener.java       | 17 ++++++++---
 .../service/BookingCommandService.java        | 30 ++++++++++++-------
 src/main/resources/application-dev.properties |  5 +---
 .../resources/application-test.properties     |  3 +-
 7 files changed, 45 insertions(+), 22 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TicketStatusResponseDTO.java

diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 7d59eb2..21f4012 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -32,7 +32,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                                 "/api/captcha/**",
                                 "/api/qr/**",
                                 "/api/booking/detail/phases/1",
-                                "/api/host/**"
+                                "/api/host/**",
+                                "/api/booking/confirm"
                                 ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().authenticated()
                 )
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketStatusResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketStatusResponseDTO.java
new file mode 100644
index 0000000..57fd743
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TicketStatusResponseDTO.java
@@ -0,0 +1,5 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.enums.ReservationStatus;
+
+public record TicketStatusResponseDTO(String reservationNumber, ReservationStatus status) {}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
index 2d7f735..dfdd3aa 100644
--- a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
@@ -1,7 +1,9 @@
 package com.mnms.booking.kafka.dto;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 
 @Data
@@ -9,5 +11,5 @@
 @AllArgsConstructor
 public class PaymentSuccessEventDTO {
     private String reservationNumber;
-    private Boolean paymentStatus;
+    private  boolean success;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index 087f418..c0db3cd 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -1,5 +1,9 @@
 package com.mnms.booking.kafka.listener;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.service.BookingCommandService;
 import lombok.RequiredArgsConstructor;
@@ -14,9 +18,14 @@ public class PaymentListener {
 
     private final BookingCommandService bookingCommandService;
 
-    @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group",  containerFactory = "kafkaListenerContainerFactory")
-    public void consumePaymentSuccess(PaymentSuccessEventDTO event) {
-        log.info("Received payment success event: {}, {}", event.getReservationNumber(), event.getPaymentStatus());
-        bookingCommandService.confirmTicket(event.getReservationNumber(), event.getPaymentStatus());
+    @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group")
+    public void consumePaymentSuccess(String message) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+        PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
+        bookingCommandService.confirmTicket(event.getReservationNumber(), event.isSuccess());
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index cf19ef1..b28153c 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -15,6 +15,7 @@
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -39,13 +40,14 @@
 public class BookingCommandService {
 
     private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
-    private static final int TEMP_RESERVATION_TTL_MINUTES = 5; // 가예매 유지 시간
+    private static final int TEMP_RESERVATION_TTL_MINUTES = 30; // 가예매 유지 시간
 
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
     private final FestivalRepository festivalRepository;
     private final QrCodeService qrCodeService;
     private final ThreadPoolTaskScheduler scheduler;
+    private final SimpMessagingTemplate messagingTemplate;
 
     /// 1차: 가예매 - 임시 예약
     @Transactional
@@ -86,7 +88,7 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
         ticketRepository.save(ticket);
     }
 
-    /// 3차: 가예매 - 최종 예약 - QR생성
+    /// 3차: 가예매 - 예약 - QR생성
     @Transactional
     public void reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = getFestivalOrThrow(request.getFestivalId());
@@ -105,18 +107,24 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
         ticketRepository.save(ticket);
     }
 
-
-    ///  최종 예약 완료
-    public void confirmTicket(String reservationNumber, Boolean paymentStatus) {
+    ///  최종 완료
+    @Transactional
+    public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)
-                        .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        if (paymentStatus) {
-            bookingTicket.setReservationStatus(ReservationStatus.CONFIRMED);
-        } else {
-            bookingTicket.setReservationStatus(ReservationStatus.CANCELED);
-        }
+        // 결제 상태 변경
+        ReservationStatus newStatus = paymentStatus ?
+                ReservationStatus.CONFIRMED :
+                ReservationStatus.CANCELED;
+        bookingTicket.setReservationStatus(newStatus);
         ticketRepository.save(bookingTicket);
+
+        // WebSocket 전송
+        messagingTemplate.convertAndSend(
+                "/topic/ticket-status",
+                new TicketStatusResponseDTO(bookingTicket.getReservationNumber(), newStatus)
+        );
     }
 
     ///  예매 취소
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index dd6423c..503ea62 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -22,8 +22,8 @@ spring.redis.port=6379
 #spring.redis.password=your_password
 
 ## kafka
-app.kafka.topic.payment-event=payment-topic
 app.kafka.topic.festival-event=festival-topic
+app.kafka.topic.payment-event= payment-status-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
@@ -32,9 +32,6 @@ spring.kafka.consumer.properties.spring.json.use.type.headers=false
 spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 
-#spring.kafka.consumer.properties.spring.json.value.default.type=com.mnms.booking.kafka.BookingEventListener$UserEventDTO
-
-
 # kafka 사용 X
 #spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
 
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index d5ffb53..6e264c7 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -26,7 +26,8 @@ spring.redis.port=6379
 
 # kafka
 app.kafka.topic.booking-event=booking-events
-app.kafka.topic.user-event: user-events
+app.kafka.topic.user-event= user-events
+app.kafka.topic.payment-event= payment-status-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest

From 00d576fc56503216acb0b6790c0b2d2e595d399f Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 15:28:36 +0900
Subject: [PATCH 044/149] =?UTF-8?q?MNMS-351=20Docs:=20=EC=A3=BC=EC=84=9D?=
 =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/mnms/booking/service/BookingCommandService.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index b28153c..bd0c8f6 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -107,7 +107,7 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
         ticketRepository.save(ticket);
     }
 
-    ///  최종 완료
+    /// 최종 완료 - status 변경
     @Transactional
     public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)

From d4b206fceeb53f29aa09b927e27c28959be86f71 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 16:00:04 +0900
Subject: [PATCH 045/149] =?UTF-8?q?MNMS-351=20Fix:=20user=20=EC=A0=95?=
 =?UTF-8?q?=EB=B3=B4=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20=EB=B3=80?=
 =?UTF-8?q?=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/dto/response/UserInfoResponseDTO.java     | 3 ---
 .../java/com/mnms/booking/service/BookingCommandService.java   | 1 -
 2 files changed, 4 deletions(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
index ab8b36f..4d1a88c 100644
--- a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
@@ -8,8 +8,5 @@
 @Data
 @Builder
 public class UserInfoResponseDTO {
-    private String phone;
     private String email;
-    private List address;
-    private String birth;
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index bd0c8f6..bfa1eb6 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -103,7 +103,6 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
                         .mapToObj(i -> createAndSaveQrCode(userId, festival, ticket))
                         .toList()
         );
-
         ticketRepository.save(ticket);
     }
 

From a3a78073791d08fcd7def791262d3814525d2ffa Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 17:11:43 +0900
Subject: [PATCH 046/149] =?UTF-8?q?MNMS-384=20Fix:=20ticket=EC=97=90=20Str?=
 =?UTF-8?q?ing=20type=EC=9D=98=20address=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/controller/BookingController.java    | 4 ++--
 .../dto/request/BookingSelectDeliveryRequestDTO.java      | 1 +
 src/main/java/com/mnms/booking/entity/Ticket.java         | 4 ++++
 .../com/mnms/booking/service/BookingCommandService.java   | 8 +++++---
 4 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index d11effa..557bbb7 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -64,8 +64,8 @@ public ResponseEntity> selectFestivalDate(
     }
 
     @PostMapping("/selectDeliveryMethod")
-    @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법 선택",
-            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER)"
+    @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법, 주소 선택",
+            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER), address(String)"
     )
     public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
diff --git a/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
index ba7b63d..636d38b 100644
--- a/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/BookingSelectDeliveryRequestDTO.java
@@ -9,4 +9,5 @@ public class BookingSelectDeliveryRequestDTO {
     private String festivalId;
     private String reservationNumber;
     private String deliveryMethod;
+    private String address;
 }
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index e0745eb..9f4c0cd 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -48,6 +48,10 @@ public class Ticket {
     @Column(name = "selected_ticket_count")
     private int selectedTicketCount; // 선택 매수
 
+    @Setter
+    @Column(name = "address")
+    private String address; // 수령주소
+
     @Setter
     @Builder.Default
     @OneToMany(mappedBy = "ticket", cascade = CascadeType.ALL, orphanRemoval = true)
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index bfa1eb6..049b700 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -82,9 +82,11 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
     public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long userId) {
         Ticket ticket = getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
         TicketType type = parseDeliveryMethod(request.getDeliveryMethod());
-
         ticket.setDeliveryMethod(type);
-        ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
+        if(TicketType.PAPER.equals(type)){
+            ticket.setAddress(request.getAddress());
+            ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
+        }
         ticketRepository.save(ticket);
     }
 
@@ -192,7 +194,7 @@ private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO r
     }
 
     private void ensureDeliveryStepCompleted(Ticket ticket) {
-        if (ticket.getDeliveryMethod() == null || ticket.getDeliveryDate() == null) {
+        if (ticket.getDeliveryMethod() == null && ticket.getDeliveryDate() == null) {
             throw new BusinessException(ErrorCode.TICKET_DELIVERY_NOT_COMPLETED);
         }
     }

From c3c0726757d36e9825274c25888d7480f8cccbf6 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 20 Aug 2025 17:47:49 +0900
Subject: [PATCH 047/149] =?UTF-8?q?MNMS-383=20Feat:=20/api/host/booking/li?=
 =?UTF-8?q?st=20API=EC=97=90=20HOST=20ROLE=20=EC=84=A4=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/config/SecurityConfig.java      | 1 +
 .../mnms/booking/exception/global/GlobalExceptionHandler.java  | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/config/SecurityConfig.java
index 21f4012..2a18bdf 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/config/SecurityConfig.java
@@ -25,6 +25,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                 )
                 .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                 .authorizeHttpRequests(auth -> auth
+                        .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
                         .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
                         .requestMatchers(
                                 "/public/**",
diff --git a/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
index 9d6cd0a..81d6d8b 100644
--- a/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
+++ b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
@@ -7,10 +7,11 @@
 import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ControllerAdvice;
 import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
 
 
-@ControllerAdvice
+@RestControllerAdvice
 public class GlobalExceptionHandler {
 
     /**

From 8fc133836d2bf09a10759143986b09bd2eb91917 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Thu, 21 Aug 2025 09:53:08 +0900
Subject: [PATCH 048/149] =?UTF-8?q?fix:=20workflow=20=ED=8C=8C=EC=9D=BC=20?=
 =?UTF-8?q?=EB=A7=A4=ED=95=91=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../workflows/api-booking-docker-dispatch.yml | 43 ++++++++++++++++---
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 27fff25..3334bb2 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -31,10 +31,8 @@ jobs:
       - run: chmod +x ./gradlew
       - run: ./gradlew bootJar --no-daemon
 
-      - name: ⏱️ Tag & Env
-        run: |
-          echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
-          if [ "${GITHUB_REF_NAME}" = "main" ]; then echo "ENV=prod" >> $GITHUB_ENV; else echo "ENV=develop" >> $GITHUB_ENV; fi
+      - name: ⏱️ Tag
+        run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
 
       - uses: docker/setup-buildx-action@v3
 
@@ -62,7 +60,9 @@ jobs:
           cache-from: type=gha
           cache-to: type=gha,mode=max
 
-      - name: Dispatch to GitOps
+      # develop → 두 환경 모두 디스패치
+      - name: Dispatch to GitOps (develop-gke)
+        if: ${{ github.ref_name == 'develop' }}
         uses: peter-evans/repository-dispatch@v3
         with:
           token:  ${{ secrets.GH_PAT }}
@@ -73,5 +73,36 @@ jobs:
               "service": "${{ env.SERVICE }}",
               "image":   "${{ env.IMAGE }}",
               "tag":     "${{ env.TAG }}",
-              "env":     "${{ env.ENV }}"
+              "env":     "develop-gke"
+            }
+
+      - name: Dispatch to GitOps (develop-aws)
+        if: ${{ github.ref_name == 'develop' }}
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "env":     "develop-aws"
+            }
+
+      # main → prod 디스패치
+      - name: Dispatch to GitOps (prod)
+        if: ${{ github.ref_name == 'main' }}
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "env":     "prod"
             }
\ No newline at end of file

From f562a6189b42b4eae1dd0313e37fe05ebb495b3f Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Thu, 21 Aug 2025 10:16:54 +0900
Subject: [PATCH 049/149] ci(api): single dispatch with multi-targets
 (develop-gke,develop-aws)

---
 .../workflows/api-booking-docker-dispatch.yml | 23 ++++---------------
 1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 3334bb2..6024347 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -60,8 +60,8 @@ jobs:
           cache-from: type=gha
           cache-to: type=gha,mode=max
 
-      # develop → 두 환경 모두 디스패치
-      - name: Dispatch to GitOps (develop-gke)
+      # develop → 한번만 디스패치 (두 타깃 동시)
+      - name: Dispatch to GitOps (develop-gke + develop-aws)
         if: ${{ github.ref_name == 'develop' }}
         uses: peter-evans/repository-dispatch@v3
         with:
@@ -73,25 +73,10 @@ jobs:
               "service": "${{ env.SERVICE }}",
               "image":   "${{ env.IMAGE }}",
               "tag":     "${{ env.TAG }}",
-              "env":     "develop-gke"
+              "targets": "develop-gke,develop-aws"
             }
 
-      - name: Dispatch to GitOps (develop-aws)
-        if: ${{ github.ref_name == 'develop' }}
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token:  ${{ secrets.GH_PAT }}
-          repository: ${{ env.DEVOPS_REPO }}
-          event-type: image-updated
-          client-payload: |
-            {
-              "service": "${{ env.SERVICE }}",
-              "image":   "${{ env.IMAGE }}",
-              "tag":     "${{ env.TAG }}",
-              "env":     "develop-aws"
-            }
-
-      # main → prod 디스패치
+      # main → prod
       - name: Dispatch to GitOps (prod)
         if: ${{ github.ref_name == 'main' }}
         uses: peter-evans/repository-dispatch@v3

From b1927e588a502e458b67878546ac8fa70d6fae2d Mon Sep 17 00:00:00 2001
From: BitedRadish 
Date: Thu, 21 Aug 2025 15:33:07 +0900
Subject: [PATCH 050/149] =?UTF-8?q?:sparkles:=20feat=20:=20OCR=20=EA=B8=B0?=
 =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84=201.=20ErrorCode=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80=202.=20TransferService=20=EC=B6=94=EA=B0=80=203.=20Tr?=
 =?UTF-8?q?ansferController=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/TransferController.java        |  26 ++++
 .../com/mnms/booking/exception/ErrorCode.java |   5 +-
 .../mnms/booking/service/TransferService.java | 112 ++++++++++++++++++
 src/main/resources/application.properties     |   7 ++
 .../mnms/booking/BookingApplicationTests.java |  13 --
 5 files changed, 148 insertions(+), 15 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/controller/TransferController.java
 create mode 100644 src/main/java/com/mnms/booking/service/TransferService.java
 delete mode 100644 src/test/java/com/mnms/booking/BookingApplicationTests.java

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
new file mode 100644
index 0000000..b5e2503
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -0,0 +1,26 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.exception.global.SuccessResponse;
+import com.mnms.booking.service.TransferService;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+@RestController
+@RequestMapping("/api/transfer")
+@RequiredArgsConstructor
+@Tag(name = "양도 API", description = "양도 및 OCR")
+@Slf4j
+public class TransferController {
+    private final TransferService transferService;
+
+
+    @PostMapping
+    public void transferController(@RequestParam("file") MultipartFile image, HttpServletRequest request){
+        transferService.callOcr(image);
+    }
+}
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index e4ef007..e2861a7 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -30,9 +30,10 @@ public enum ErrorCode {
     QR_CODE_NOT_FOUND("Q003", "QR 코드를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     QR_CODE_INVALID("Q004", "QR 코드가 유효하지 않습니다.", HttpStatus.BAD_REQUEST),
     QR_CODE_EXPIRED("Q005", "QR 코드의 만료일이 지났습니다.", HttpStatus.GONE),
-    QR_CODE_ALREADY_USED("Q006", "QR 코드가 이미 사용되었습니다.", HttpStatus.CONFLICT);
-
+    QR_CODE_ALREADY_USED("Q006", "QR 코드가 이미 사용되었습니다.", HttpStatus.CONFLICT),
 
+    // Transfer
+    TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE);
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
     private final HttpStatus status;  //http status 코드
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
new file mode 100644
index 0000000..b25c781
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -0,0 +1,112 @@
+package com.mnms.booking.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@Service
+@Slf4j
+public class TransferService {
+
+    @Value("${ocr.key}")
+    private String ocrKey;
+
+    @Value("${ocr.invoke_url}")
+    private String ocrInvokeUrl;
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+
+    public String callOcr(MultipartFile image){
+        try {
+            String extension = getExtension(image.getOriginalFilename());
+            if (!"pdf".equalsIgnoreCase(extension)) {
+                throw new BusinessException(ErrorCode.TRANSFER_NOT_VALID_FILE_TYPE);
+            }
+
+            // 2. MultipartFile → Resource
+            ByteArrayResource fileResource = new ByteArrayResource(image.getBytes()) {
+                @Override
+                public String getFilename() {
+                    return image.getOriginalFilename();
+                }
+            };
+
+            MultiValueMap multipartBody = getApiBody(image, fileResource);
+
+            // 5. 헤더 구성
+            HttpHeaders headers = getApiHeaders();
+
+
+            String response = postApi(headers, multipartBody);
+            return response;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String postApi(HttpHeaders headers, MultiValueMap multipartBody) {
+        RestClient restClient=RestClient.create();
+        String response = restClient.post()
+                .uri(ocrInvokeUrl)
+                .headers(h -> h.addAll(headers))
+                .body(multipartBody)
+                .retrieve()
+                .body(String.class);
+        return response;
+    }
+
+    private HttpHeaders getApiHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+        headers.set("X-OCR-SECRET", ocrKey);
+        return headers;
+    }
+
+    private static MultiValueMap getApiBody(MultipartFile image, ByteArrayResource fileResource) throws JsonProcessingException {
+        Map messageBody = new HashMap<>();
+        messageBody.put("version","V2");
+        messageBody.put("requestId", UUID.randomUUID().toString());
+        messageBody.put("timestamp",System.currentTimeMillis());
+        messageBody.put("lang","ko");
+        messageBody.put("enableTableDetection",false);
+
+        Map imageInfo = new HashMap<>();
+        imageInfo.put("format", "pdf");
+        imageInfo.put("name", image.getOriginalFilename());
+
+        messageBody.put("images", new Object[]{imageInfo});
+
+        String messageJson = objectMapper.writeValueAsString(messageBody);
+
+        // 4. multipart/form-data body 구성
+        MultiValueMap multipartBody = new LinkedMultiValueMap<>();
+        multipartBody.add("file", fileResource);
+        multipartBody.add("message", messageJson);
+        return multipartBody;
+    }
+
+    private String getExtension(String filename) {
+        if (filename == null || !filename.contains(".")) {
+            return "";
+        }
+        return filename.substring(filename.lastIndexOf('.') + 1);
+    }
+
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 3633a4e..1c26cbc 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -14,3 +14,10 @@ spring.profiles.active=dev
 
 # log file
 logging.file.path=logs
+
+ocr.key=${OCR_SECRET_KEY}
+ocr.invoke_url=${OCR_INVOKE_URL}
+
+spring.servlet.multipart.max-file-size=100MB
+spring.servlet.multipart.max-request-size=100MB
+spring.servlet.multipart.enabled=true
\ No newline at end of file
diff --git a/src/test/java/com/mnms/booking/BookingApplicationTests.java b/src/test/java/com/mnms/booking/BookingApplicationTests.java
deleted file mode 100644
index 723e7d1..0000000
--- a/src/test/java/com/mnms/booking/BookingApplicationTests.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.mnms.booking;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@SpringBootTest
-class BookingApplicationTests {
-
-	@Test
-	void contextLoads() {
-	}
-
-}

From 5819b09f89ff67987183b097dd8a9a6fbeeb95f0 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 21 Aug 2025 15:53:42 +0900
Subject: [PATCH 051/149] =?UTF-8?q?MNMS-383=20Fix:=20AuthenticationPrincip?=
 =?UTF-8?q?al=20->=20Authentication=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

gateway로 Authentication로 변경
---
 .../booking/controller/BookingController.java | 27 +++---
 .../booking/controller/QrCodeController.java  | 16 ++--
 .../booking/controller/WaitingController.java | 26 +++---
 .../com/mnms/booking/exception/ErrorCode.java |  3 +
 .../security/HeaderAuthenticationFilter.java  | 85 +++++++++++++++++++
 .../{config => security}/SecurityConfig.java  | 39 ++++-----
 .../com/mnms/booking/util/JwtAuthFilter.java  | 50 -----------
 .../com/mnms/booking/util/JwtPrincipal.java   |  5 --
 .../com/mnms/booking/util/RsaJwtVerifier.java | 79 -----------------
 .../com/mnms/booking/util/UserApiClient.java  | 12 ++-
 src/main/resources/application-dev.properties | 10 ++-
 .../resources/application-test.properties     |  2 +-
 12 files changed, 161 insertions(+), 193 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
 rename src/main/java/com/mnms/booking/{config => security}/SecurityConfig.java (51%)
 delete mode 100644 src/main/java/com/mnms/booking/util/JwtAuthFilter.java
 delete mode 100644 src/main/java/com/mnms/booking/util/JwtPrincipal.java
 delete mode 100644 src/main/java/com/mnms/booking/util/RsaJwtVerifier.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 557bbb7..4946869 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -11,13 +11,13 @@
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.JwtPrincipal;
 import com.mnms.booking.util.UserApiClient;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
@@ -45,9 +45,10 @@ public ResponseEntity> getFestivalDet
             description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
     public ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
+            Authentication authentication
     ) {
-        return ApiResponseUtil.success(bookingQueryService.getFestivalBookingDetail(request, principal.userId()));
+        Long userId = userApiClient.requireUserId(authentication);
+        return ApiResponseUtil.success(bookingQueryService.getFestivalBookingDetail(request, userId));
     }
 
 
@@ -58,9 +59,9 @@ public ResponseEntity> getFestivalBook
     )
     public ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
+            Authentication authentication
     ) {
-        return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, principal.userId()));
+        return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, userApiClient.requireUserId(authentication)));
     }
 
     @PostMapping("/selectDeliveryMethod")
@@ -69,9 +70,9 @@ public ResponseEntity> selectFestivalDate(
     )
     public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
+            Authentication authentication
     ) {
-        bookingCommandService.selectFestivalDelivery(request, principal.userId());
+        bookingCommandService.selectFestivalDelivery(request, userApiClient.requireUserId(authentication));
         return ApiResponseUtil.success(null, "예매 티켓 수령 방법 선택 완료");
     }
 
@@ -82,9 +83,9 @@ public ResponseEntity> selectFestivalDelivery(
     )
     public ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
+            Authentication authentication
     ) {
-        bookingCommandService.reserveTicket(request, principal.userId());
+        bookingCommandService.reserveTicket(request, userApiClient.requireUserId(authentication));
         return ApiResponseUtil.success(null, "예매 티켓 생성 완료");
     }
 
@@ -94,9 +95,9 @@ public ResponseEntity> reserveTicket(
             description = "사용자가 예약한 티켓을 취소합니다. reservationNumber 필요")
     public ResponseEntity> cancelBooking(
             @RequestBody BookingCancelRequestDTO request,
-            @AuthenticationPrincipal JwtPrincipal principal
+            Authentication authentication
     ) {
-        bookingCommandService.cancelBooking(request.getReservationNumber(), principal.userId());
+        bookingCommandService.cancelBooking(request.getReservationNumber(), userApiClient.requireUserId(authentication));
         return ApiResponseUtil.success(null, "페스티벌 예매 취소");
     }
 
@@ -106,7 +107,7 @@ public ResponseEntity> cancelBooking(
             description = "예매 과정에서 예매자 정보를 조회합니다." +
                     "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
     )
-    public ResponseEntity> getUserInfo(@AuthenticationPrincipal JwtPrincipal principal) {
-        return ApiResponseUtil.success(userApiClient.getUserInfoById(principal.userId()));
+    public ResponseEntity> getUserInfo(Authentication authentication) {
+        return ApiResponseUtil.success(userApiClient.getUserInfoById(userApiClient.requireUserId(authentication)));
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index 38c7040..b17212f 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -1,27 +1,20 @@
 package com.mnms.booking.controller;
 
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.WriterException;
-import com.google.zxing.client.j2se.MatrixToImageWriter;
-import com.google.zxing.common.BitMatrix;
-import com.google.zxing.qrcode.QRCodeWriter;
-import com.mnms.booking.dto.request.QrRequestDTO;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.QrCodeService;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.JwtPrincipal;
+import com.mnms.booking.util.UserApiClient;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
-import java.time.LocalDateTime;
-
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/qr")
@@ -29,6 +22,7 @@
 public class QrCodeController {
 
     private final QrCodeService qrCodeService;
+    private final UserApiClient userApiClient;
 
     /// Qrcode 이미지 조회
     @GetMapping(value = "/image/{qrCodeId}", produces = MediaType.IMAGE_PNG_VALUE)
@@ -52,9 +46,9 @@ public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
             description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
     public ResponseEntity> validateAndUseQrCode(
             @PathVariable String qrCodeId,
-            @AuthenticationPrincipal JwtPrincipal principal) {
+            Authentication authentication) {
 
-        qrCodeService.validateAndUseQrCode(principal.userId(), qrCodeId);
+        qrCodeService.validateAndUseQrCode(userApiClient.requireUserId(authentication), qrCodeId);
         return ApiResponseUtil.success(null, "QR 스캔 완료");
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 61d3370..9d592d2 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -6,7 +6,7 @@
 import com.mnms.booking.service.WaitingNotificationService;
 import com.mnms.booking.service.WaitingQueueKeyGenerator;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.JwtPrincipal;
+import com.mnms.booking.util.UserApiClient;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -18,6 +18,7 @@
 import org.springframework.http.ResponseEntity;
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.security.core.Authentication;
 import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
@@ -36,6 +37,7 @@ public class WaitingController {
     private final FestivalService festivalService;
     private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
     private final WaitingNotificationService waitingNotificationService;
+    private final UserApiClient userApiClient;
 
     @Autowired
     private SimpMessagingTemplate messagingTemplate;
@@ -45,9 +47,9 @@ public class WaitingController {
     public ResponseEntity> enterBookingPage(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
-            @AuthenticationPrincipal JwtPrincipal principal) {
+            Authentication authentication) {
 
-        String userId = principal != null ? String.valueOf(principal.userId()) : "swagger-test-user";
+        String userId =  authentication != null ? getUserId(authentication) : "swagger-test-user";
 
         int availableNOP = festivalService.getCapacity(festivalId); // 수용 인원 가져오기
         long waitingNumber = waitingService.enterWaitingQueue(festivalId, reservationDate, userId, availableNOP);
@@ -70,10 +72,9 @@ public ResponseEntity> enterBookingPag
     public ResponseEntity> releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
-            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) { ///  예매칸에 있는 예매자 accessToken
-        String userId = String.valueOf(principal.userId());
+            @Parameter(hidden = true) Authentication authentication) { ///  예매칸에 있는 예매자 accessToken
         try {
-            boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, userId);
+            boolean removed = waitingService.userExitBookingPage(festivalId, reservationDate, getUserId(authentication));
             if (removed) {
                 return ApiResponseUtil.success("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
@@ -95,10 +96,9 @@ public ResponseEntity> releaseUser(
     public ResponseEntity> exitWaitingUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
-            @Parameter(hidden = true) @AuthenticationPrincipal JwtPrincipal principal) {
-        String userId = String.valueOf(principal.userId());
+            @Parameter(hidden = true) Authentication authentication) {
         try {
-            boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, userId);
+            boolean removed = waitingService.removeUserFromQueue(festivalId, reservationDate, getUserId(authentication));
             if (removed) {
                 return ApiResponseUtil.success("대기하던 사용자가 대기열을 나갔습니다.");
             } else {
@@ -119,11 +119,15 @@ public ResponseEntity> exitWaitingUser(
     public void subscribeWaitingQueue(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
-            @AuthenticationPrincipal JwtPrincipal principal) {
-        String userId = String.valueOf(principal.userId());
+            Authentication authentication) {
+        String userId = getUserId(authentication);
         log.info("User {} subscribed to waiting queue updates.", userId);
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
         waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
     }
+
+    public String getUserId(Authentication authentication) {
+        return String.valueOf(userApiClient.requireUserId(authentication));
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index e4ef007..1bd4b27 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -6,6 +6,9 @@
 @Getter
 public enum ErrorCode {
 
+    // USER
+    USER_INVALID("U001", "잘못된 사용자 ID 형식입니다", HttpStatus.BAD_REQUEST),
+
     // 보안문자
     SECURITY_NUMBER_INVALID("S001", "입력한 문자가 일치하지 않습니다.", HttpStatus.BAD_REQUEST),
 
diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
new file mode 100644
index 0000000..31a4405
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -0,0 +1,85 @@
+package com.mnms.booking.security;
+
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class HeaderAuthenticationFilter extends OncePerRequestFilter {
+
+    @Override
+    protected void doFilterInternal(
+            HttpServletRequest request,
+            HttpServletResponse response,
+            FilterChain chain
+    ) throws ServletException, IOException {
+
+        // Actuator는 건너뜀
+        String uri = request.getRequestURI();
+        if (uri != null && uri.startsWith("/actuator")) {
+            chain.doFilter(request, response);
+            return;
+        }
+
+        // 게이트웨이가 붙여주는 헤더 (✅ userId 사용)
+        final String userIdHeader = trimToNull(request.getHeader("X-User-Id"));
+        final String rolesHdr     = trimToNull(request.getHeader("X-User-Role"));
+
+        Authentication current = SecurityContextHolder.getContext().getAuthentication();
+        boolean isAnonymous = (current instanceof AnonymousAuthenticationToken);
+        boolean canSetAuth = (current == null) || isAnonymous;
+
+        if (canSetAuth && userIdHeader != null && rolesHdr != null) {
+            // userId는 숫자여야 하므로 안전하게 파싱
+            final Long userId;
+            try {
+                userId = Long.valueOf(userIdHeader);
+            } catch (NumberFormatException e) {
+                // 잘못된 헤더면 인증 세팅 없이 통과
+                logger.warn("[HeaderAuth] invalid X-User-Id: " + userIdHeader);
+                chain.doFilter(request, response);
+                return;
+            }
+
+            List authorities = Arrays.stream(rolesHdr.split(","))
+                    .map(String::trim)
+                    .filter(s -> !s.isEmpty())
+                    .map(String::toUpperCase)
+                    .map(r -> r.startsWith("ROLE_") ? r : "ROLE_" + r)
+                    .map(SimpleGrantedAuthority::new)
+                    .collect(Collectors.toList());
+
+            logger.info("[HeaderAuth] userId=" + userId + ", rolesHeader=" + rolesHdr
+                    + " -> authorities=" + authorities);
+
+            // principal = userId(String) → Controller에서 Long.parseLong(principal.getName()) 가능
+            UsernamePasswordAuthenticationToken auth =
+                    new UsernamePasswordAuthenticationToken(String.valueOf(userId), null, authorities);
+            auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+            SecurityContextHolder.getContext().setAuthentication(auth);
+        }
+
+        chain.doFilter(request, response);
+    }
+
+    private static String trimToNull(String s) {
+        if (s == null) return null;
+        String t = s.trim();
+        return t.isEmpty() ? null : t;
+    }
+}
diff --git a/src/main/java/com/mnms/booking/config/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
similarity index 51%
rename from src/main/java/com/mnms/booking/config/SecurityConfig.java
rename to src/main/java/com/mnms/booking/security/SecurityConfig.java
index 2a18bdf..13c5951 100644
--- a/src/main/java/com/mnms/booking/config/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -1,29 +1,31 @@
-package com.mnms.booking.config;
+package com.mnms.booking.security;
 
-import com.mnms.booking.util.JwtAuthFilter;
+import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
 import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+import org.springframework.security.web.access.intercept.AuthorizationFilter;
 
 @Configuration
 @EnableWebSecurity
+@EnableMethodSecurity
 public class SecurityConfig {
-    private final JwtAuthFilter jwtAuthFilter;
-    public SecurityConfig(JwtAuthFilter jwtAuthFilter) { this.jwtAuthFilter = jwtAuthFilter; }
+
+    private final HeaderAuthenticationFilter headerAuthFilter;
+
+    public SecurityConfig(HeaderAuthenticationFilter headerAuthFilter) {
+        this.headerAuthFilter = headerAuthFilter;
+    }
 
     @Bean
-    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
-        http.csrf(AbstractHttpConfigurer::disable)
-                .headers(headers -> headers
-                        .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) // iframe 허용
-                )
-                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+    SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+        return http
+                .csrf(AbstractHttpConfigurer::disable)
                 .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
                         .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
@@ -35,11 +37,10 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
                                 "/api/booking/detail/phases/1",
                                 "/api/host/**",
                                 "/api/booking/confirm"
-                                ).permitAll() // 하위 경로 포함 허용
-                        .anyRequest().authenticated()
+                        ).permitAll() // 하위 경로 포함 허용
+                        .anyRequest().permitAll()
                 )
-                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
-
-        return http.build();
+                .addFilterBefore(headerAuthFilter, AuthorizationFilter.class)
+                .build();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/JwtAuthFilter.java b/src/main/java/com/mnms/booking/util/JwtAuthFilter.java
deleted file mode 100644
index 701026b..0000000
--- a/src/main/java/com/mnms/booking/util/JwtAuthFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.mnms.booking.util;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.JwtException;
-import jakarta.servlet.FilterChain;
-import jakarta.servlet.ServletException;
-import jakarta.servlet.http.HttpServletRequest;
-import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.web.filter.OncePerRequestFilter;
-
-import java.io.IOException;
-import java.util.List;
-
-@Component
-public class JwtAuthFilter extends OncePerRequestFilter {
-    private final RsaJwtVerifier jwt;
-
-    public JwtAuthFilter(RsaJwtVerifier jwt) { this.jwt = jwt; }
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
-            throws ServletException, IOException {
-
-        String header = req.getHeader(org.springframework.http.HttpHeaders.AUTHORIZATION);
-        if (header != null && header.startsWith("Bearer ")) {
-            String token = header.substring(7);
-            try {
-                Claims c = jwt.parse(token);
-                Long userId = c.get("userId", Long.class);
-                String loginId = c.getSubject();
-                // B 서비스는 "role": "USER" 형태니까 이렇게 권한 만들기
-                String role = c.get("role", String.class);
-                List auths = (role == null) ? List.of() : List.of(new SimpleGrantedAuthority("ROLE_" + role));
-                JwtPrincipal principal = new JwtPrincipal(userId, loginId, role == null ? List.of() : List.of(role));
-
-                var authentication = new UsernamePasswordAuthenticationToken(principal, null, auths);
-                SecurityContextHolder.getContext().setAuthentication(authentication);
-            } catch (JwtException e) {
-                res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
-                return;
-            }
-        }
-        chain.doFilter(req, res);
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/JwtPrincipal.java b/src/main/java/com/mnms/booking/util/JwtPrincipal.java
deleted file mode 100644
index 2cc7df0..0000000
--- a/src/main/java/com/mnms/booking/util/JwtPrincipal.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.mnms.booking.util;
-
-import java.util.List;
-
-public record JwtPrincipal(Long userId, String loginId, List roles) {}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java b/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java
deleted file mode 100644
index 4cca3f4..0000000
--- a/src/main/java/com/mnms/booking/util/RsaJwtVerifier.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.mnms.booking.util;
-
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.JwtParserBuilder;
-import io.jsonwebtoken.Jwts;
-import jakarta.annotation.PostConstruct;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.stereotype.Component;
-import java.security.PublicKey;
-import org.springframework.core.io.Resource;
-
-@Component
-public class RsaJwtVerifier {
-    @Value("${jwt.public-pem-path}")
-    private Resource publicPemPath;
-
-    @Value("${jwt.issuer:festival-user-service}")
-    private String issuer;
-
-    private PublicKey publicKey;
-
-//    @PostConstruct
-//    public void init() {
-//        try {
-//            String pem = new String(publicPemPath.getInputStream().readAllBytes(), java.nio.charset.StandardCharsets.UTF_8);
-//            this.publicKey = loadPublicKeyFromPem(pem);
-//        } catch (IOException e) {
-//            throw new IllegalStateException("Failed to read public PEM", e);
-//        }
-//    }
-    @PostConstruct
-    public void init() {
-        try {
-            System.out.println("[DEBUG] resource = " + publicPemPath);
-            System.out.println("[DEBUG] exists   = " + publicPemPath.exists());
-            byte[] bytes = publicPemPath.getInputStream().readAllBytes();
-            System.out.println("[DEBUG] size     = " + bytes.length);
-
-            String peek = new String(bytes, java.nio.charset.StandardCharsets.UTF_8);
-            System.out.println("[DEBUG] first line = " + peek.lines().findFirst().orElse("(empty)"));
-            // ↓ 여기서 바로 던지지 말고, 현재 로더로 시도
-            this.publicKey = loadPublicKeyFromPem(peek);
-            System.out.println("[DEBUG] loaded PublicKey: " + publicKey.getAlgorithm());
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new IllegalStateException("Failed to init RsaJwtVerifier", e);
-        }
-    }
-
-    public Claims parse(String token) {
-        JwtParserBuilder builder = Jwts.parserBuilder()
-                .setSigningKey(publicKey)
-                .setAllowedClockSkewSeconds(30); // 시계 오차 허용
-        if (!issuer.isBlank()) builder.requireIssuer(issuer); // 발급자 강제(옵션)
-        return builder.build().parseClaimsJws(token).getBody();
-    }
-
-    public Long getUserId(String token) {
-        return parse(token).get("userId", Long.class);
-    }
-
-    public String getLoginId(String token) {
-        return parse(token).getSubject(); // sub = loginId
-    }
-
-    // --- PEM 로더
-    private static PublicKey loadPublicKeyFromPem(String pem) {
-        try {
-            String content = pem.replace("-----BEGIN PUBLIC KEY-----","")
-                    .replace("-----END PUBLIC KEY-----","")
-                    .replaceAll("\\s","");
-            byte[] der = java.util.Base64.getDecoder().decode(content);
-            var spec = new java.security.spec.X509EncodedKeySpec(der);
-            return java.security.KeyFactory.getInstance("RSA").generatePublic(spec);
-        } catch (Exception e) {
-            throw new IllegalStateException("Failed to load RSA public key", e);
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/UserApiClient.java b/src/main/java/com/mnms/booking/util/UserApiClient.java
index 61c55f0..ca53f80 100644
--- a/src/main/java/com/mnms/booking/util/UserApiClient.java
+++ b/src/main/java/com/mnms/booking/util/UserApiClient.java
@@ -2,12 +2,15 @@
 
 import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
@@ -26,7 +29,6 @@ public class UserApiClient {
     private String userServiceUrl;
 
     public List getUsersByIds(List userIds) {
-        //return restTemplate.postForObject(bookingUserServiceUrl, userIds, List.class);
         ResponseEntity> response =
                 restTemplate.exchange(
                         userServiceUrl,
@@ -41,4 +43,12 @@ public UserInfoResponseDTO getUserInfoById(Long userId) {
         String url = String.format("%s/%d", userServiceUrl, userId);
         return restTemplate.getForObject(url, UserInfoResponseDTO.class);
     }
+
+    public Long requireUserId(Authentication authentication) {
+        try {
+            return Long.parseLong(authentication.getName());
+        } catch (NumberFormatException e) {
+            throw new BusinessException(ErrorCode.USER_INVALID);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 503ea62..708329b 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -2,9 +2,11 @@ myboot.name=Dev Env
 
 #log level
 logging.level.root=INFO
-logging.level.c.mnms.booking.config.RedisConfig=INFO
+#logging.level.c.mnms.booking.config.RedisConfig=DEBUG
 #logging.level.com.basic.myspringboot=debug
 
+logging.level.org.springframework.security=DEBUG
+
 #maria db info
 spring.datasource.url=${DB_URL}
 spring.datasource.username=${DB_USERNAME}
@@ -17,8 +19,10 @@ spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
 # redis 설정 - 로컬 설정
-spring.redis.host=127.0.0.1
-spring.redis.port=6379
+spring.data.redis.host=127.0.0.1
+spring.data.redis.port=6379
+
+
 #spring.redis.password=your_password
 
 ## kafka
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 6e264c7..405d35d 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -19,7 +19,7 @@ spring.jpa.hibernate.ddl-auto=update
 spring.h2.console.enabled=true
 spring.h2.console.path=/h2-console
 
-# redis 설정 - 로컬 설정
+# redis 설정 - 로컬 설정 data
 spring.redis.host=127.0.0.1
 spring.redis.port=6379
 #spring.redis.password=your_password

From 7e1f05d580de436873328862ae9870ec667a6d69 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 21 Aug 2025 19:14:43 +0900
Subject: [PATCH 052/149] =?UTF-8?q?MNMS-412=20fix:=20=EA=B2=B0=EC=A0=9C=20?=
 =?UTF-8?q?=EC=A0=9C=ED=95=9C=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ReservationStatus - PAYMENT_IN_PROGRESS 상태 추가
PAYMENT_IN_PROGRESS + CONFIRMED + 예매자 선택 매수 수량 체크
---
 .../booking/controller/BookingController.java | 13 ------
 .../booking/controller/HostController.java    |  1 -
 .../booking/controller/QrCodeController.java  |  1 -
 .../controller/TransferController.java        |  1 -
 .../dto/request/BookingRequestDTO.java        |  3 ++
 .../mnms/booking/enums/ReservationStatus.java |  1 +
 .../com/mnms/booking/exception/ErrorCode.java |  8 ++--
 .../kafka/dto/PaymentSuccessEventDTO.java     |  1 +
 .../kafka/listener/PaymentListener.java       | 11 +++++
 .../booking/repository/TicketRepository.java  | 15 +++++++
 .../service/BookingCommandService.java        | 43 ++++++++++++++-----
 src/main/resources/application-dev.properties |  1 +
 12 files changed, 70 insertions(+), 29 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 4946869..9af6d5b 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -18,7 +18,6 @@
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
 @RestController
@@ -89,18 +88,6 @@ public ResponseEntity> reserveTicket(
         return ApiResponseUtil.success(null, "예매 티켓 생성 완료");
     }
 
-    ///  예매 취소
-    @PostMapping("/cancel")
-    @Operation(summary = "예매 취소",
-            description = "사용자가 예약한 티켓을 취소합니다. reservationNumber 필요")
-    public ResponseEntity> cancelBooking(
-            @RequestBody BookingCancelRequestDTO request,
-            Authentication authentication
-    ) {
-        bookingCommandService.cancelBooking(request.getReservationNumber(), userApiClient.requireUserId(authentication));
-        return ApiResponseUtil.success(null, "페스티벌 예매 취소");
-    }
-
     ///  GET
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 98af957..065dd7d 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -1,7 +1,6 @@
 package com.mnms.booking.controller;
 
 import com.mnms.booking.dto.request.HostRequestDTO;
-import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
 import com.mnms.booking.dto.response.HostResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.HostService;
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index b17212f..d57c5e6 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -12,7 +12,6 @@
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.web.bind.annotation.*;
 
 @RestController
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index b5e2503..ba38836 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -18,7 +18,6 @@
 public class TransferController {
     private final TransferService transferService;
 
-
     @PostMapping
     public void transferController(@RequestParam("file") MultipartFile image, HttpServletRequest request){
         transferService.callOcr(image);
diff --git a/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
index 966fb77..206ca8d 100644
--- a/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/BookingRequestDTO.java
@@ -3,8 +3,11 @@
 import lombok.Data;
 import lombok.Getter;
 
+import java.time.LocalDateTime;
+
 @Data @Getter
 public class BookingRequestDTO {
     private String festivalId;
+    private LocalDateTime performanceDate;
     private String reservationNumber;
 }
diff --git a/src/main/java/com/mnms/booking/enums/ReservationStatus.java b/src/main/java/com/mnms/booking/enums/ReservationStatus.java
index 606e70a..801899c 100644
--- a/src/main/java/com/mnms/booking/enums/ReservationStatus.java
+++ b/src/main/java/com/mnms/booking/enums/ReservationStatus.java
@@ -2,6 +2,7 @@
 
 public enum ReservationStatus {
     TEMP_RESERVED,     // 가예매 (결제 전)
+    PAYMENT_IN_PROGRESS,  // 결제 중
     CONFIRMED,         // 결제 완료, 확정
     CANCELED,          // 결제 실패 or 취소
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 9a37194..d9005b2 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -18,14 +18,16 @@ public enum ErrorCode {
     FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     FESTIVAL_DELIVERY_INVALID("F004", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
     FESTIVAL_MISMATCH("F005", "해당하는 QR의 페스티벌 주최자가 아닙니다.", HttpStatus.FORBIDDEN),
-
+    FESTIVAL_LIMIT_AVALIABLE_PEOPLE("F006", "해당 페스티벌 수용 인원이 초과되어 예매를 진행할 수 없습니다.", HttpStatus.CONFLICT),
+    
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
     TICKET_NOT_FOUND("T002", "해당하는 티켓을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     TICKET_INVALID_DELIVERY_METHOD("T003", "수령 방법이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
     TICKET_DELIVERY_NOT_COMPLETED("T004", "티켓 수령 방법이 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
-    TICKET_USER_NOT_SAME("T005", "사용자가 티켓 소유자가 아닙니다.", HttpStatus.FORBIDDEN),
-    TICKET_ALREADY_CANCELED("T006", "티켓이 이미 예매 취소되었습니다.", HttpStatus.CONFLICT),
+    TICKET_FAIL_CANCEL("T005", "티켓 취소가 실패했습니다.", HttpStatus.CONFLICT),
+    TICKET_USER_NOT_SAME("T006", "사용자가 티켓 소유자가 아닙니다.", HttpStatus.FORBIDDEN),
+    TICKET_ALREADY_CANCELED("T007", "티켓이 이미 예매 취소되었습니다.", HttpStatus.CONFLICT),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
diff --git a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
index dfdd3aa..e9ecb00 100644
--- a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
@@ -10,6 +10,7 @@
 @NoArgsConstructor
 @AllArgsConstructor
 public class PaymentSuccessEventDTO {
+    private String method;
     private String reservationNumber;
     private  boolean success;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index c0db3cd..f664e87 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -28,4 +28,15 @@ public void consumePaymentSuccess(String message) throws JsonProcessingException
         PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
         bookingCommandService.confirmTicket(event.getReservationNumber(), event.isSuccess());
     }
+
+    @KafkaListener(topics = "${app.kafka.topic.payment-cancel-event}", groupId = "booking-service-group")
+    public void consumeRefundSuccess(String message) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+        PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
+        bookingCommandService.cancelBooking(event.getReservationNumber(), event.isSuccess());
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index f67f1da..628e21a 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
@@ -52,4 +53,18 @@ List findDistinctUserIdsByFestivalIdAndPerformanceDate(@Param("festivalId"
             "FROM Ticket t " +
             "WHERE t.festival.festivalId = :festivalId ")
     List findByFestivalId(String festivalId);
+
+    @Query("SELECT t.selectedTicketCount " +
+            "FROM Ticket t " +
+            "WHERE t.reservationNumber = :reservationNumber")
+    Long findSelectedTicketCountByReservationNumber(@Param("reservationNumber") String reservationNumber);
+
+    @Query("SELECT COALESCE(SUM(t.selectedTicketCount), 0) " +
+            "FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId " +
+            "AND t.performanceDate = :performanceDate " +
+            "AND t.reservationStatus IN (:statuses)")
+    int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
+                                    @Param("performanceDate") LocalDateTime performanceDate,
+                                    @Param("statuses") List statuses);
 }
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 049b700..c611aad 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -27,6 +27,7 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoUnit;
+import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
 import java.util.UUID;
@@ -94,18 +95,40 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
     @Transactional
     public void reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = getFestivalOrThrow(request.getFestivalId());
-        Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
+        Long selectedTicketCount = ticketRepository.findSelectedTicketCountByReservationNumber(request.getReservationNumber());
+
+        validateCapacity(festival, request, selectedTicketCount);
 
+        Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
+        ticket.setReservationStatus(ReservationStatus.PAYMENT_IN_PROGRESS);
         ensureDeliveryStepCompleted(ticket);
 
-        // 기존 QR 코드 초기화
+        regenerateQrCodes(ticket, userId, festival);
+
+        ticketRepository.save(ticket);
+    }
+
+    private void validateCapacity(Festival festival, BookingRequestDTO request, Long selectedTicketCount) {
+        int totalCount = ticketRepository.getTotalSelectedTicketCount(
+                request.getFestivalId(),
+                request.getPerformanceDate(),
+                List.of(ReservationStatus.CONFIRMED, ReservationStatus.PAYMENT_IN_PROGRESS)
+        );
+
+        log.info("total selected ticket count : {}", totalCount);
+
+        if (totalCount + selectedTicketCount > festival.getAvailableNOP()) {
+            throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVALIABLE_PEOPLE);
+        }
+    }
+
+    private void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
         ticket.getQrCodes().clear();
         ticket.getQrCodes().addAll(
                 IntStream.range(0, ticket.getSelectedTicketCount())
                         .mapToObj(i -> createAndSaveQrCode(userId, festival, ticket))
                         .toList()
         );
-        ticketRepository.save(ticket);
     }
 
     /// 최종 완료 - status 변경
@@ -130,21 +153,21 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
 
     ///  예매 취소
     @Transactional
-    public void cancelBooking(String reservationNumber, Long userId) {
+    public void cancelBooking(String reservationNumber, boolean paymentStatus) {
         Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        if(!ticket.getUserId().equals(userId)){
-            throw new BusinessException(ErrorCode.TICKET_USER_NOT_SAME);
-        }
+        ReservationStatus status = paymentStatus
+                ? ReservationStatus.CANCELED
+                : ticket.getReservationStatus();
 
-        if (ticket.getReservationStatus() == ReservationStatus.CANCELED) {
-            throw new BusinessException(ErrorCode.TICKET_ALREADY_CANCELED);
+        if (ticket.getReservationStatus() == ReservationStatus.CONFIRMED) {
+            throw new BusinessException(ErrorCode.TICKET_FAIL_CANCEL);
         }
 
         // qr 삭제 + ticket 상태 변경
         ticket.getQrCodes().clear();
-        ticket.setReservationStatus(ReservationStatus.CANCELED);
+        ticket.setReservationStatus(status);
         ticketRepository.save(ticket);
     }
 
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 708329b..96ad196 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -28,6 +28,7 @@ spring.data.redis.port=6379
 ## kafka
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
+app.kafka.topic.payment-cancel-event=payment-cancel-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest

From f6f0937a023025fff14b7558e09d064d3cea0c52 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 22 Aug 2025 14:15:35 +0900
Subject: [PATCH 053/149] =?UTF-8?q?MNMS-412=20Feat:=20ocr=20=EC=A0=95?=
 =?UTF-8?q?=EC=A0=9C=202,=203=EC=B0=A8=20=EC=88=98=ED=96=89=20=EC=99=84?=
 =?UTF-8?q?=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

1차 : 클로바 ocr 수행
2차 : 특수문자, 띄어쓰기 제거
3차 : request 이름, 주민번호 동일성 체크
---
 build.gradle                                  |   3 +
 .../mnms/booking/config/WebClientConfig.java  |  14 +++
 .../booking/controller/BookingController.java |  17 +--
 .../booking/controller/QrCodeController.java  |   6 +-
 .../controller/TransferController.java        |  31 ++++-
 .../booking/controller/WaitingController.java |   7 +-
 .../dto/request/TargetInfoRequestDTO.java     |  12 ++
 .../dto/response/PersonInfoResponseDTO.java   |  15 +++
 .../dto/response/TransferUserResponse.java    |   6 +
 .../com/mnms/booking/exception/ErrorCode.java |   5 +-
 .../mnms/booking/security/SecurityConfig.java |   3 +-
 .../booking/service/OcrParserService.java     |  72 ++++++++++++
 .../com/mnms/booking/service/OcrService.java  | 110 ++++++++++++++++++
 .../mnms/booking/service/TransferService.java |  92 ++-------------
 .../booking/util/SecurityResponseUtil.java    |  20 ++++
 .../com/mnms/booking/util/UserApiClient.java  |  45 +++----
 16 files changed, 329 insertions(+), 129 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/WebClientConfig.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/TargetInfoRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/PersonInfoResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TransferUserResponse.java
 create mode 100644 src/main/java/com/mnms/booking/service/OcrParserService.java
 create mode 100644 src/main/java/com/mnms/booking/service/OcrService.java
 create mode 100644 src/main/java/com/mnms/booking/util/SecurityResponseUtil.java

diff --git a/build.gradle b/build.gradle
index ae1dec7..0657fcc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -79,6 +79,9 @@ dependencies {
 
 	// swagger
 	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
+
+	// WebClient 사용
+	implementation 'org.springframework.boot:spring-boot-starter-webflux'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/config/WebClientConfig.java b/src/main/java/com/mnms/booking/config/WebClientConfig.java
new file mode 100644
index 0000000..63c1a43
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/WebClientConfig.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.reactive.function.client.WebClient;
+
+@Configuration
+public class WebClientConfig {
+
+    @Bean
+    public WebClient webClient(WebClient.Builder builder) {
+        return builder.build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 9af6d5b..be66443 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -1,6 +1,5 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.dto.request.BookingCancelRequestDTO;
 import com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
@@ -11,6 +10,7 @@
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.util.ApiResponseUtil;
+import com.mnms.booking.util.SecurityResponseUtil;
 import com.mnms.booking.util.UserApiClient;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -29,9 +29,10 @@ public class BookingController {
     private final BookingCommandService bookingCommandService;
     private final BookingQueryService bookingQueryService;
     private final UserApiClient userApiClient;
+    private final SecurityResponseUtil securityResponseUtil;
 
     /// GET : 페스티벌 예매 정보 조회
-    @GetMapping("/detail/phases/1")
+    @PostMapping("/detail/phases/1")
     @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId와 performanceDate(사용자가 선택한 날짜 시간) 으로 공연 상세 정보를 조회합니다." +
                     "selectedTicketCount는 0으로 넣을 것!")
@@ -39,14 +40,14 @@ public ResponseEntity> getFestivalDet
         return ApiResponseUtil.success(bookingQueryService.getFestivalDetail(request));
     }
 
-    @GetMapping("/detail/phases/2")
+    @PostMapping("/detail/phases/2")
     @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
     public ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
     ) {
-        Long userId = userApiClient.requireUserId(authentication);
+        Long userId = securityResponseUtil.requireUserId(authentication);
         return ApiResponseUtil.success(bookingQueryService.getFestivalBookingDetail(request, userId));
     }
 
@@ -60,7 +61,7 @@ public ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
             Authentication authentication
     ) {
-        return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, userApiClient.requireUserId(authentication)));
+        return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, securityResponseUtil.requireUserId(authentication)));
     }
 
     @PostMapping("/selectDeliveryMethod")
@@ -71,7 +72,7 @@ public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
             Authentication authentication
     ) {
-        bookingCommandService.selectFestivalDelivery(request, userApiClient.requireUserId(authentication));
+        bookingCommandService.selectFestivalDelivery(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(null, "예매 티켓 수령 방법 선택 완료");
     }
 
@@ -84,7 +85,7 @@ public ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
     ) {
-        bookingCommandService.reserveTicket(request, userApiClient.requireUserId(authentication));
+        bookingCommandService.reserveTicket(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(null, "예매 티켓 생성 완료");
     }
 
@@ -95,6 +96,6 @@ public ResponseEntity> reserveTicket(
                     "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
     )
     public ResponseEntity> getUserInfo(Authentication authentication) {
-        return ApiResponseUtil.success(userApiClient.getUserInfoById(userApiClient.requireUserId(authentication)));
+        return ApiResponseUtil.success(userApiClient.getUserInfoById(securityResponseUtil.requireUserId(authentication)));
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index d57c5e6..0d2ab45 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -4,7 +4,7 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.QrCodeService;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.UserApiClient;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
@@ -21,7 +21,7 @@
 public class QrCodeController {
 
     private final QrCodeService qrCodeService;
-    private final UserApiClient userApiClient;
+    private final SecurityResponseUtil securityResponseUtil;
 
     /// Qrcode 이미지 조회
     @GetMapping(value = "/image/{qrCodeId}", produces = MediaType.IMAGE_PNG_VALUE)
@@ -47,7 +47,7 @@ public ResponseEntity> validateAndUseQrCode(
             @PathVariable String qrCodeId,
             Authentication authentication) {
 
-        qrCodeService.validateAndUseQrCode(userApiClient.requireUserId(authentication), qrCodeId);
+        qrCodeService.validateAndUseQrCode(securityResponseUtil.requireUserId(authentication), qrCodeId);
         return ApiResponseUtil.success(null, "QR 스캔 완료");
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index ba38836..fbc2437 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -1,7 +1,14 @@
 package com.mnms.booking.controller;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.request.TargetInfoRequestDTO;
+import com.mnms.booking.dto.response.PersonInfoResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
+import com.mnms.booking.service.OcrParserService;
+import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferService;
+import com.mnms.booking.util.ApiResponseUtil;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
@@ -10,16 +17,36 @@
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.IOException;
+import java.util.*;
+
 @RestController
 @RequestMapping("/api/transfer")
 @RequiredArgsConstructor
 @Tag(name = "양도 API", description = "양도 및 OCR")
 @Slf4j
 public class TransferController {
+    private final OcrService ocrService;
     private final TransferService transferService;
+    private final OcrParserService ocrParserService;
+
+    @PostMapping("/extract")
+    public ResponseEntity>> extractPersonInfo(
+            @RequestPart("file") MultipartFile file,
+            @RequestPart("targetInfo") String targetInfoJson) throws IOException {
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        Map targetInfo = objectMapper.readValue(targetInfoJson, new TypeReference<>() {});
+
+        String ocrJson = ocrService.callOcr(file);
+        List people = OcrParserService.parseOcrResult(ocrJson, targetInfo);
+
+        return ApiResponseUtil.success(people);
+    }
+
 
     @PostMapping
-    public void transferController(@RequestParam("file") MultipartFile image, HttpServletRequest request){
-        transferService.callOcr(image);
+    public ResponseEntity> transferController(@RequestParam("file") MultipartFile image, HttpServletRequest request){
+        return ApiResponseUtil.success(ocrService.callOcr(image));
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 9d592d2..ee51b45 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -6,7 +6,7 @@
 import com.mnms.booking.service.WaitingNotificationService;
 import com.mnms.booking.service.WaitingQueueKeyGenerator;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.UserApiClient;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Hidden;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -19,7 +19,6 @@
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.security.core.Authentication;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
@@ -37,7 +36,7 @@ public class WaitingController {
     private final FestivalService festivalService;
     private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
     private final WaitingNotificationService waitingNotificationService;
-    private final UserApiClient userApiClient;
+    private final SecurityResponseUtil securityResponseUtil;
 
     @Autowired
     private SimpMessagingTemplate messagingTemplate;
@@ -128,6 +127,6 @@ public void subscribeWaitingQueue(
     }
 
     public String getUserId(Authentication authentication) {
-        return String.valueOf(userApiClient.requireUserId(authentication));
+        return String.valueOf(securityResponseUtil.requireUserId(authentication));
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TargetInfoRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TargetInfoRequestDTO.java
new file mode 100644
index 0000000..472fdd1
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/TargetInfoRequestDTO.java
@@ -0,0 +1,12 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Map;
+
+@Getter
+@Setter
+public class TargetInfoRequestDTO {
+    private Map targetInfo;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/PersonInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/PersonInfoResponseDTO.java
new file mode 100644
index 0000000..25bc284
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/PersonInfoResponseDTO.java
@@ -0,0 +1,15 @@
+package com.mnms.booking.dto.response;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.ToString;
+
+@Data
+@Getter
+@AllArgsConstructor
+@ToString
+public class PersonInfoResponseDTO {
+        private final String name;
+        private final String rrnFront;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TransferUserResponse.java b/src/main/java/com/mnms/booking/dto/response/TransferUserResponse.java
new file mode 100644
index 0000000..da29ad2
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TransferUserResponse.java
@@ -0,0 +1,6 @@
+package com.mnms.booking.dto.response;
+
+public class TransferUserResponse {
+    private String name;
+    private String birth; // 주민번호
+}
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index d9005b2..a3ba2b1 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -38,7 +38,10 @@ public enum ErrorCode {
     QR_CODE_ALREADY_USED("Q006", "QR 코드가 이미 사용되었습니다.", HttpStatus.CONFLICT),
 
     // Transfer
-    TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE);
+    TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE),
+    TRANSFER_NOT_FOUND_INFORM("TR002", "검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
+    TRANSFER_NOT_FOUND_NAME("TR003", "이름 검사에 실패하였습니다.", HttpStatus.NOT_FOUND);
+
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
     private final HttpStatus status;  //http status 코드
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 13c5951..772d33f 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -36,7 +36,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                                 "/api/qr/**",
                                 "/api/booking/detail/phases/1",
                                 "/api/host/**",
-                                "/api/booking/confirm"
+                                "/api/booking/confirm",
+                                "/api/transfer/**"
                         ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().permitAll()
                 )
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
new file mode 100644
index 0000000..c219560
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -0,0 +1,72 @@
+package com.mnms.booking.service;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.response.PersonInfoResponseDTO;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.regex.Pattern;
+
+@Service
+@Slf4j
+public class OcrParserService {
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    public static List parseOcrResult(
+            String ocrJson, Map targetInfo) throws IOException {
+
+        List result = new ArrayList<>();
+
+        JsonNode root = objectMapper.readTree(ocrJson);
+        JsonNode images = root.path("images");
+
+        // OCR 전체 텍스트 수집
+        List ocrTexts = new ArrayList<>();
+        for (JsonNode imageNode : images) {
+            JsonNode fields = imageNode.path("fields");
+            for (JsonNode field : fields) {
+                ocrTexts.add(field.path("inferText").asText());
+            }
+        }
+
+        log.info("ocr : {}", ocrTexts);
+
+        for (Map.Entry entry : targetInfo.entrySet()) {
+            String name = entry.getKey();
+            String rrn = entry.getValue();
+
+            Optional matchedName = ocrTexts.stream()
+                    .map(t -> t.replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
+                    .filter(t -> t.matches(".*\\b" + Pattern.quote(name) + "\\b.*"))
+                    .findFirst();
+
+            Optional matchedRrn = ocrTexts.stream()
+                    .filter(t -> t.contains(rrn) && t.matches(".*\\d{6}-[1-4].*"))
+                    .findFirst();
+
+            log.info("user : {}, {}", matchedName, matchedRrn);
+
+            // 결과 확인
+            if (matchedName.isEmpty() || matchedRrn.isEmpty()) {
+                throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_INFORM);
+            }
+
+            if (!name.equals(matchedName.get())) {
+                throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
+            }
+
+            result.add(new PersonInfoResponseDTO(
+                    matchedName.get(),
+                    matchedRrn.get()
+            ));
+        }
+
+        return result;
+    }
+}
diff --git a/src/main/java/com/mnms/booking/service/OcrService.java b/src/main/java/com/mnms/booking/service/OcrService.java
new file mode 100644
index 0000000..34d8fd8
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/OcrService.java
@@ -0,0 +1,110 @@
+package com.mnms.booking.service;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.ByteArrayResource;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestClient;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@Service
+@Slf4j
+public class OcrService {
+
+    @Value("${ocr.key}")
+    private String ocrKey;
+
+    @Value("${ocr.invoke_url}")
+    private String ocrInvokeUrl;
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    public String callOcr(MultipartFile image){
+        try {
+            String extension = getExtension(image.getOriginalFilename());
+            if (!"pdf".equalsIgnoreCase(extension)) {
+                throw new BusinessException(ErrorCode.TRANSFER_NOT_VALID_FILE_TYPE);
+            }
+
+            // 2. MultipartFile → Resource
+            ByteArrayResource fileResource = new ByteArrayResource(image.getBytes()) {
+                @Override
+                public String getFilename() {
+                    return image.getOriginalFilename();
+                }
+            };
+
+            MultiValueMap multipartBody = getApiBody(image, fileResource);
+
+            // 5. 헤더 구성
+            HttpHeaders headers = getApiHeaders();
+
+
+            String response = postApi(headers, multipartBody);
+            return response;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private String postApi(HttpHeaders headers, MultiValueMap multipartBody) {
+        RestClient restClient=RestClient.create();
+        String response = restClient.post()
+                .uri(ocrInvokeUrl)
+                .headers(h -> h.addAll(headers))
+                .body(multipartBody)
+                .retrieve()
+                .body(String.class);
+        return response;
+    }
+
+    private HttpHeaders getApiHeaders() {
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+        headers.set("X-OCR-SECRET", ocrKey);
+        return headers;
+    }
+
+    private static MultiValueMap getApiBody(MultipartFile image, ByteArrayResource fileResource) throws JsonProcessingException {
+        Map messageBody = new HashMap<>();
+        messageBody.put("version","V2");
+        messageBody.put("requestId", UUID.randomUUID().toString());
+        messageBody.put("timestamp",System.currentTimeMillis());
+        messageBody.put("lang","ko");
+        messageBody.put("enableTableDetection",false);
+
+        Map imageInfo = new HashMap<>();
+        imageInfo.put("format", "pdf");
+        imageInfo.put("name", image.getOriginalFilename());
+
+        messageBody.put("images", new Object[]{imageInfo});
+
+        String messageJson = objectMapper.writeValueAsString(messageBody);
+
+        // 4. multipart/form-data body 구성
+        MultiValueMap multipartBody = new LinkedMultiValueMap<>();
+        multipartBody.add("file", fileResource);
+        multipartBody.add("message", messageJson);
+        return multipartBody;
+    }
+
+    private String getExtension(String filename) {
+        if (filename == null || !filename.contains(".")) {
+            return "";
+        }
+        return filename.substring(filename.lastIndexOf('.') + 1);
+    }
+}
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index b25c781..96393f6 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -2,8 +2,11 @@
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.response.TransferUserResponse;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.util.UserApiClient;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.io.ByteArrayResource;
@@ -22,91 +25,12 @@
 
 @Service
 @Slf4j
+@RequiredArgsConstructor
 public class TransferService {
 
-    @Value("${ocr.key}")
-    private String ocrKey;
-
-    @Value("${ocr.invoke_url}")
-    private String ocrInvokeUrl;
-
-    private static final ObjectMapper objectMapper = new ObjectMapper();
-
-
-    public String callOcr(MultipartFile image){
-        try {
-            String extension = getExtension(image.getOriginalFilename());
-            if (!"pdf".equalsIgnoreCase(extension)) {
-                throw new BusinessException(ErrorCode.TRANSFER_NOT_VALID_FILE_TYPE);
-            }
-
-            // 2. MultipartFile → Resource
-            ByteArrayResource fileResource = new ByteArrayResource(image.getBytes()) {
-                @Override
-                public String getFilename() {
-                    return image.getOriginalFilename();
-                }
-            };
-
-            MultiValueMap multipartBody = getApiBody(image, fileResource);
-
-            // 5. 헤더 구성
-            HttpHeaders headers = getApiHeaders();
-
-
-            String response = postApi(headers, multipartBody);
-            return response;
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private String postApi(HttpHeaders headers, MultiValueMap multipartBody) {
-        RestClient restClient=RestClient.create();
-        String response = restClient.post()
-                .uri(ocrInvokeUrl)
-                .headers(h -> h.addAll(headers))
-                .body(multipartBody)
-                .retrieve()
-                .body(String.class);
-        return response;
-    }
-
-    private HttpHeaders getApiHeaders() {
-        HttpHeaders headers = new HttpHeaders();
-        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
-        headers.set("X-OCR-SECRET", ocrKey);
-        return headers;
-    }
-
-    private static MultiValueMap getApiBody(MultipartFile image, ByteArrayResource fileResource) throws JsonProcessingException {
-        Map messageBody = new HashMap<>();
-        messageBody.put("version","V2");
-        messageBody.put("requestId", UUID.randomUUID().toString());
-        messageBody.put("timestamp",System.currentTimeMillis());
-        messageBody.put("lang","ko");
-        messageBody.put("enableTableDetection",false);
-
-        Map imageInfo = new HashMap<>();
-        imageInfo.put("format", "pdf");
-        imageInfo.put("name", image.getOriginalFilename());
-
-        messageBody.put("images", new Object[]{imageInfo});
-
-        String messageJson = objectMapper.writeValueAsString(messageBody);
-
-        // 4. multipart/form-data body 구성
-        MultiValueMap multipartBody = new LinkedMultiValueMap<>();
-        multipartBody.add("file", fileResource);
-        multipartBody.add("message", messageJson);
-        return multipartBody;
-    }
-
-    private String getExtension(String filename) {
-        if (filename == null || !filename.contains(".")) {
-            return "";
-        }
-        return filename.substring(filename.lastIndexOf('.') + 1);
-    }
+    private final UserApiClient userApiClient;
 
+//    public String checkTransferee(String email) {
+//
+//    }
 }
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
new file mode 100644
index 0000000..7a08b32
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -0,0 +1,20 @@
+package com.mnms.booking.util;
+
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class SecurityResponseUtil {
+    // Authentication에서 userId 추출
+    public Long requireUserId(Authentication authentication) {
+        try {
+            return Long.parseLong(authentication.getName());
+        } catch (NumberFormatException e) {
+            throw new BusinessException(ErrorCode.USER_INVALID);
+        }
+    }
+}
diff --git a/src/main/java/com/mnms/booking/util/UserApiClient.java b/src/main/java/com/mnms/booking/util/UserApiClient.java
index ca53f80..83c128f 100644
--- a/src/main/java/com/mnms/booking/util/UserApiClient.java
+++ b/src/main/java/com/mnms/booking/util/UserApiClient.java
@@ -1,26 +1,21 @@
 package com.mnms.booking.util;
 
 import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
+import com.mnms.booking.dto.response.TransferUserResponse;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
-import com.mnms.booking.exception.BusinessException;
-import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpMethod;
-import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestTemplate;
+import org.springframework.web.reactive.function.client.WebClient;
 
 import java.util.List;
 
+
 @Component
 @RequiredArgsConstructor
 public class UserApiClient {
 
-    private final RestTemplate restTemplate;
+    private final WebClient webClient;
 
     @Value("${booking.user.service.url}")
     private String bookingUserServiceUrl;
@@ -28,27 +23,25 @@ public class UserApiClient {
     @Value("${user.service.url}")
     private String userServiceUrl;
 
+
+    // userId 리스트 요청
     public List getUsersByIds(List userIds) {
-        ResponseEntity> response =
-                restTemplate.exchange(
-                        userServiceUrl,
-                        HttpMethod.POST,
-                        new HttpEntity<>(userIds),
-                        new ParameterizedTypeReference>() {}
-                );
-        return response.getBody();
+        return webClient.post()
+                .uri(bookingUserServiceUrl)
+                .bodyValue(userIds)
+                .retrieve()
+                .bodyToFlux(BookingUserInfoResponseDTO.class)
+                .collectList()
+                .block();
     }
 
+    // userId로 요청
     public UserInfoResponseDTO getUserInfoById(Long userId) {
         String url = String.format("%s/%d", userServiceUrl, userId);
-        return restTemplate.getForObject(url, UserInfoResponseDTO.class);
-    }
-
-    public Long requireUserId(Authentication authentication) {
-        try {
-            return Long.parseLong(authentication.getName());
-        } catch (NumberFormatException e) {
-            throw new BusinessException(ErrorCode.USER_INVALID);
-        }
+        return webClient.get()
+                .uri(url)
+                .retrieve()
+                .bodyToMono(UserInfoResponseDTO.class)
+                .block();
     }
 }
\ No newline at end of file

From ae0c6afb327086c04c855335410bb146c5a68720 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 22 Aug 2025 17:53:43 +0900
Subject: [PATCH 054/149] =?UTF-8?q?MNMS-412=20Feat:=20=EC=96=91=EB=8F=84?=
 =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EA=B0=80=EC=A1=B1=EA=B4=80=EA=B3=84?=
 =?UTF-8?q?=EC=A6=9D=EB=AA=85=EC=84=9C=20=EC=9D=B8=EC=A6=9D=20=ED=9B=84=20?=
 =?UTF-8?q?=ED=8B=B0=EC=BC=93=20=EC=A0=95=EB=B3=B4=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java |  1 -
 .../controller/TransferController.java        | 19 +++---
 .../dto/request/UpdateTicketRequestDTO.java   | 14 +++++
 .../java/com/mnms/booking/entity/QrCode.java  |  3 +
 .../java/com/mnms/booking/entity/Ticket.java  | 13 ++++
 .../com/mnms/booking/exception/ErrorCode.java |  3 +-
 .../booking/repository/QrCodeRepository.java  |  3 +
 .../mnms/booking/security/SecurityConfig.java |  1 +
 .../service/BookingCommandService.java        | 10 +--
 .../booking/service/OcrParserService.java     | 63 +++++++++----------
 .../mnms/booking/service/TransferService.java | 62 ++++++++++++------
 .../com/mnms/booking/util/CommonUtils.java    | 16 +++++
 src/main/resources/application-dev.properties |  3 +-
 13 files changed, 143 insertions(+), 68 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/util/CommonUtils.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index be66443..b83aaf2 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -51,7 +51,6 @@ public ResponseEntity> getFestivalBook
         return ApiResponseUtil.success(bookingQueryService.getFestivalBookingDetail(request, userId));
     }
 
-
     /// POST
     @PostMapping("/selectDate")
     @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index fbc2437..93d17b1 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -2,18 +2,19 @@
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.mnms.booking.dto.request.TargetInfoRequestDTO;
+import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferService;
 import com.mnms.booking.util.ApiResponseUtil;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -23,12 +24,12 @@
 @RestController
 @RequestMapping("/api/transfer")
 @RequiredArgsConstructor
-@Tag(name = "양도 API", description = "양도 및 OCR")
+@Tag(name = "양도 API", description = "양도 및 OCR, Ticket 재생성")
 @Slf4j
 public class TransferController {
     private final OcrService ocrService;
     private final TransferService transferService;
-    private final OcrParserService ocrParserService;
+    private final SecurityResponseUtil securityResponseUtil;
 
     @PostMapping("/extract")
     public ResponseEntity>> extractPersonInfo(
@@ -44,9 +45,11 @@ public ResponseEntity>> extractPerso
         return ApiResponseUtil.success(people);
     }
 
-
-    @PostMapping
-    public ResponseEntity> transferController(@RequestParam("file") MultipartFile image, HttpServletRequest request){
-        return ApiResponseUtil.success(ocrService.callOcr(image));
+    @PutMapping("/{ticketId}")
+    public ResponseEntity> updateTicket(
+            @PathVariable Long ticketId,
+            @RequestBody UpdateTicketRequestDTO request) {
+        transferService.updateTicket(ticketId, request);
+        return ApiResponseUtil.success(null, "티켓 양도가 성공적으로 진행되었습니다.");
     }
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
new file mode 100644
index 0000000..5ffa0e1
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.dto.request;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UpdateTicketRequestDTO {
+    private Long transfereeId; // userId에 해당함
+    private String deliveryMethod;
+    private String address;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/QrCode.java b/src/main/java/com/mnms/booking/entity/QrCode.java
index be965c8..2eddb7b 100644
--- a/src/main/java/com/mnms/booking/entity/QrCode.java
+++ b/src/main/java/com/mnms/booking/entity/QrCode.java
@@ -18,6 +18,7 @@ public class QrCode {
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id; // qr_id
 
+    @Setter
     @Column(name = "qr_code_id", nullable = false)
     private String qrCodeId;
 
@@ -33,9 +34,11 @@ public class QrCode {
     @Column(name = "used_at")
     private LocalDateTime usedAt;
 
+    @Setter
     @Column(name = "user_id", nullable = false)
     private Long userId;
 
+    @Setter
     @ManyToOne(fetch = FetchType.LAZY)
     @JoinColumn(name = "ticket_id")
     private Ticket ticket; // ticket_id
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 9f4c0cd..37e5286 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -62,4 +62,17 @@ public class Ticket {
     @JoinColumn(name = "festival_id")
     private Festival festival;
 
+    public void updateTicketInfo(String reservationNumber,
+                                 TicketType deliveryMethod,
+                                 Long userId,
+                                 LocalDate reservationDate,
+                                 String address) {
+
+        this.reservationNumber = reservationNumber;
+        this.deliveryMethod = deliveryMethod;
+        this.userId = userId;
+        this.reservationDate = reservationDate;
+        this.address = address;
+    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index a3ba2b1..a08380f 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -40,7 +40,8 @@ public enum ErrorCode {
     // Transfer
     TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE),
     TRANSFER_NOT_FOUND_INFORM("TR002", "검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
-    TRANSFER_NOT_FOUND_NAME("TR003", "이름 검사에 실패하였습니다.", HttpStatus.NOT_FOUND);
+    TRANSFER_NOT_FOUND_NAME("TR003", "이름 검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
+    TRANSFER_NOT_FOUND_RRN("TR003", "주민등록 번호 검사에 실패하였습니다.", HttpStatus.NOT_FOUND);
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index cbcd3b8..a944c02 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -1,9 +1,11 @@
 package com.mnms.booking.repository;
 
 import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
 import java.util.Optional;
 
 @Repository
@@ -11,6 +13,7 @@ public interface QrCodeRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByQrCodeId(String qrCodeId);
     Boolean existsByQrCodeId(String qrCodeId);
+    Optional> findByTicketId(Long ticketId);
 }
 
 
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 772d33f..5ceba09 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -37,6 +37,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                                 "/api/booking/detail/phases/1",
                                 "/api/host/**",
                                 "/api/booking/confirm",
+                                "/api/transfer/**",
                                 "/api/transfer/**"
                         ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().permitAll()
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index c611aad..d510164 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -13,6 +13,7 @@
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
+import com.mnms.booking.util.CommonUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
@@ -49,6 +50,7 @@ public class BookingCommandService {
     private final QrCodeService qrCodeService;
     private final ThreadPoolTaskScheduler scheduler;
     private final SimpMessagingTemplate messagingTemplate;
+    private final CommonUtils commonUtils;
 
     /// 1차: 가예매 - 임시 예약
     @Transactional
@@ -63,7 +65,7 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
         Ticket ticket = Ticket.builder()
                 .festival(festival)
                 .userId(userId)
-                .reservationNumber(generateReservationNumber())
+                .reservationNumber(commonUtils.generateReservationNumber())
                 .selectedTicketCount(request.getSelectedTicketCount())
                 .performanceDate(performanceDate)
                 .reservationStatus(ReservationStatus.TEMP_RESERVED)
@@ -272,10 +274,4 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket
         qrCodeRepository.save(qrCode);
         return qrCode;
     }
-
-    ///  reservation number 랜덤 생성
-    private String generateReservationNumber() {
-        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
-        return "T" + uuidPart;
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index c219560..f2e1b59 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -11,6 +11,7 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 @Service
 @Slf4j
@@ -21,52 +22,50 @@ public class OcrParserService {
     public static List parseOcrResult(
             String ocrJson, Map targetInfo) throws IOException {
 
-        List result = new ArrayList<>();
+        List ocrTexts = extractOcrTexts(ocrJson);
+        log.info("ocr : {}", ocrTexts);
+
+        return targetInfo.entrySet().stream()
+                .map(entry -> matchPersonInfo(entry.getKey(), entry.getValue(), ocrTexts))
+                .collect(Collectors.toList());
+    }
 
+    /// OCR 2차 추출
+    private static List extractOcrTexts(String ocrJson) throws IOException {
         JsonNode root = objectMapper.readTree(ocrJson);
         JsonNode images = root.path("images");
 
-        // OCR 전체 텍스트 수집
-        List ocrTexts = new ArrayList<>();
+        List texts = new ArrayList<>();
         for (JsonNode imageNode : images) {
             JsonNode fields = imageNode.path("fields");
             for (JsonNode field : fields) {
-                ocrTexts.add(field.path("inferText").asText());
+                texts.add(field.path("inferText").asText());
             }
         }
+        return texts;
+    }
 
-        log.info("ocr : {}", ocrTexts);
-
-        for (Map.Entry entry : targetInfo.entrySet()) {
-            String name = entry.getKey();
-            String rrn = entry.getValue();
-
-            Optional matchedName = ocrTexts.stream()
-                    .map(t -> t.replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
-                    .filter(t -> t.matches(".*\\b" + Pattern.quote(name) + "\\b.*"))
-                    .findFirst();
+    /// OCR 3차 추출
+    private static PersonInfoResponseDTO matchPersonInfo(
+            String name, String rrn, List ocrTexts) {
 
-            Optional matchedRrn = ocrTexts.stream()
-                    .filter(t -> t.contains(rrn) && t.matches(".*\\d{6}-[1-4].*"))
-                    .findFirst();
+        String normalizedNamePattern = "\\b" + Pattern.quote(name.replaceAll("\\s", "")) + "\\b";
 
-            log.info("user : {}, {}", matchedName, matchedRrn);
+        String matchedName = ocrTexts.stream()
+                .map(t -> t.replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
+                .filter(t -> t.matches(".*" + normalizedNamePattern + ".*"))
+                .findFirst()
+                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME));
 
-            // 결과 확인
-            if (matchedName.isEmpty() || matchedRrn.isEmpty()) {
-                throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_INFORM);
-            }
-
-            if (!name.equals(matchedName.get())) {
-                throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
-            }
+        String matchedRrn = ocrTexts.stream()
+                .filter(t -> t.contains(rrn) && t.matches(".*\\d{6}-[1-4].*"))
+                .findFirst()
+                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_RRN));
 
-            result.add(new PersonInfoResponseDTO(
-                    matchedName.get(),
-                    matchedRrn.get()
-            ));
+        if (!name.equals(matchedName)) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
         }
 
-        return result;
+        return new PersonInfoResponseDTO(matchedName, matchedRrn);
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 96393f6..674573b 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -1,36 +1,62 @@
 package com.mnms.booking.service;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.mnms.booking.dto.response.TransferUserResponse;
+import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.io.ByteArrayResource;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
-import org.springframework.util.LinkedMultiValueMap;
-import org.springframework.util.MultiValueMap;
-import org.springframework.web.client.RestClient;
-import org.springframework.web.multipart.MultipartFile;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.time.LocalDate;
+import java.util.List;
 
 @Service
 @Slf4j
 @RequiredArgsConstructor
+@Transactional
 public class TransferService {
 
     private final UserApiClient userApiClient;
+    private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
+    private final CommonUtils commonUtils;
+    private final QrCodeService qrCodeService;
 
-//    public String checkTransferee(String email) {
-//
-//    }
+    public void updateTicket(Long ticketId, UpdateTicketRequestDTO request) {
+        Ticket ticket = ticketRepository.findById(ticketId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
+
+        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
+
+        // ticket 업데이트
+        ticket.updateTicketInfo(
+                commonUtils.generateReservationNumber(),
+                deliveryMethod,
+                request.getTransfereeId(),
+                LocalDate.now(),
+                request.getAddress()
+        );
+
+        // qr code 업데이트
+        existingQrs.forEach(qr -> {
+            qr.setQrCodeId(qrCodeService.generateQrCodeId());
+            qr.setUserId(request.getTransfereeId());
+            qr.setTicket(ticket);
+        });
+
+        // 기존 컬렉션 유지하면서 update
+        ticket.getQrCodes().clear();
+        ticket.getQrCodes().addAll(existingQrs);
+    }
 }
diff --git a/src/main/java/com/mnms/booking/util/CommonUtils.java b/src/main/java/com/mnms/booking/util/CommonUtils.java
new file mode 100644
index 0000000..c3a592b
--- /dev/null
+++ b/src/main/java/com/mnms/booking/util/CommonUtils.java
@@ -0,0 +1,16 @@
+package com.mnms.booking.util;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+@Component
+@RequiredArgsConstructor
+public class CommonUtils {
+    ///  reservation number 랜덤 생성
+    public String generateReservationNumber() {
+        String uuidPart = UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
+        return "T" + uuidPart;
+    }
+}
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 96ad196..5048ae2 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -19,7 +19,8 @@ spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
 # redis 설정 - 로컬 설정
-spring.data.redis.host=127.0.0.1
+#spring.data.redis.host=127.0.0.1
+spring.data.redis.host=34.22.92.22
 spring.data.redis.port=6379
 
 

From 0d54b59822ae6add6ed4d91ed67cd46f22c53fc4 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 22 Aug 2025 18:07:34 +0900
Subject: [PATCH 055/149] MNMS-412 Chore: update comments and remove
 unnecessary code

---
 .../com/mnms/booking/controller/TransferController.java     | 6 +-----
 src/main/java/com/mnms/booking/security/SecurityConfig.java | 2 --
 .../java/com/mnms/booking/service/OcrParserService.java     | 2 --
 src/main/java/com/mnms/booking/service/TransferService.java | 1 -
 4 files changed, 1 insertion(+), 10 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index 93d17b1..adfea5b 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -9,12 +9,10 @@
 import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferService;
 import com.mnms.booking.util.ApiResponseUtil;
-import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
-import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -29,20 +27,18 @@
 public class TransferController {
     private final OcrService ocrService;
     private final TransferService transferService;
-    private final SecurityResponseUtil securityResponseUtil;
 
     @PostMapping("/extract")
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
-
         ObjectMapper objectMapper = new ObjectMapper();
         Map targetInfo = objectMapper.readValue(targetInfoJson, new TypeReference<>() {});
 
         String ocrJson = ocrService.callOcr(file);
         List people = OcrParserService.parseOcrResult(ocrJson, targetInfo);
 
-        return ApiResponseUtil.success(people);
+        return ApiResponseUtil.success(people, "가족관계증명서 인증이 완료되었습니다.");
     }
 
     @PutMapping("/{ticketId}")
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 5ceba09..96a1090 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -1,9 +1,7 @@
 package com.mnms.booking.security;
 
-import lombok.RequiredArgsConstructor;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.HttpMethod;
 import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index f2e1b59..60d4eed 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -23,8 +23,6 @@ public static List parseOcrResult(
             String ocrJson, Map targetInfo) throws IOException {
 
         List ocrTexts = extractOcrTexts(ocrJson);
-        log.info("ocr : {}", ocrTexts);
-
         return targetInfo.entrySet().stream()
                 .map(entry -> matchPersonInfo(entry.getKey(), entry.getValue(), ocrTexts))
                 .collect(Collectors.toList());
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 674573b..f995b53 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -55,7 +55,6 @@ public void updateTicket(Long ticketId, UpdateTicketRequestDTO request) {
             qr.setTicket(ticket);
         });
 
-        // 기존 컬렉션 유지하면서 update
         ticket.getQrCodes().clear();
         ticket.getQrCodes().addAll(existingQrs);
     }

From 7738b61808ecefc8d29f78af45a9f756d468ab65 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 22 Aug 2025 18:26:08 +0900
Subject: [PATCH 056/149] =?UTF-8?q?ci(workflows):=20=EB=AA=A8=EB=93=A0=20?=
 =?UTF-8?q?=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A9=80=ED=8B=B0=EC=95=84?=
 =?UTF-8?q?=ED=82=A4=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=91=B8=EC=8B=9C(am?=
 =?UTF-8?q?d64/arm64)=20+=20=ED=83=9C=EA=B7=B8=20=EB=B6=84=EB=A6=AC(-win/-?=
 =?UTF-8?q?mac)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- 대상: api-booking, api-festival, api-gateway, api-payment, api-user, nginx-client
- buildx 멀티아키 빌드 추가: platforms=linux/amd64,linux/arm64
- 태그 규칙 분리:
  - TAG_AMD=v{UTC시각}-win
  - TAG_ARM=v{UTC시각}-mac
  - 호환성 유지 위해 TAG=TAG_AMD 로 설정(Repo Dispatch에 그대로 사용)
- docker/metadata-action: 두 태그(raw) 모두 발행, sha 및 main에서 latest 유지
- docker/build-push-action: 두 태그 모두 push
- GitOps Dispatch payload 스키마 변경 없음(`tag`만 전송), develop의 nginx-client는 기존 targets 유지
- Helm 태그 자동 반영 워크플로우 변경 없음

검증 방법
- develop/main 브랜치 push 후 Docker Hub에 -win / -mac 두 태그 생성 확인
- gitops-repo로 repository_dispatch 이벤트 수신 및 values 파일의 .image.tag 가 -win 으로 패치되는지 확인
---
 .../workflows/api-booking-docker-dispatch.yml | 10 +++-
 .github/workflows/booking-docker-publish.yml  | 55 -------------------
 2 files changed, 8 insertions(+), 57 deletions(-)
 delete mode 100644 .github/workflows/booking-docker-publish.yml

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 6024347..31777cd 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -32,7 +32,11 @@ jobs:
       - run: ./gradlew bootJar --no-daemon
 
       - name: ⏱️ Tag
-        run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
+        run: |
+          TS=$(date -u +'%Y%m%d%H%M%S')
+          echo "TAG_AMD=v${TS}-win" >> $GITHUB_ENV
+          echo "TAG_ARM=v${TS}-mac" >> $GITHUB_ENV
+          echo "TAG=v${TS}-win" >> $GITHUB_ENV
 
       - uses: docker/setup-buildx-action@v3
 
@@ -46,7 +50,8 @@ jobs:
         with:
           images: ${{ env.IMAGE }}
           tags: |
-            type=raw,value=${{ env.TAG }}
+            type=raw,value=${{ env.TAG_AMD }}
+            type=raw,value=${{ env.TAG_ARM }}
             type=sha
             type=raw,value=latest,enable=${{ github.ref_name == 'main' }}
 
@@ -55,6 +60,7 @@ jobs:
           context: .
           file: ./Dockerfile
           push: true
+          platforms: linux/amd64,linux/arm64
           tags: ${{ steps.meta.outputs.tags }}
           labels: ${{ steps.meta.outputs.labels }}
           cache-from: type=gha
diff --git a/.github/workflows/booking-docker-publish.yml b/.github/workflows/booking-docker-publish.yml
deleted file mode 100644
index 5fdeec6..0000000
--- a/.github/workflows/booking-docker-publish.yml
+++ /dev/null
@@ -1,55 +0,0 @@
-name: "💰 booking Docker & Dispatch"
-
-on:
-  push:
-    branches: [ 'feature/MNMS-318' ]
-  workflow_dispatch: {}
-
-env:
-  IMAGE: ${{ secrets.DOCKER_USERNAME }}/api-booking
-  SERVICE: booking
-  DEVOPS_REPO: 3-mnms/gitops-repo
-
-jobs:
-  build-push:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v4
-
-      - uses: actions/setup-java@v3
-        with:
-          distribution: temurin
-          java-version: '17'
-
-      - run: chmod +x ./gradlew
-      - run: ./gradlew bootJar --no-daemon
-
-      - name: ⏱️ Tag
-        run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> "$GITHUB_ENV"
-
-      - uses: docker/login-action@v3
-        with:
-          username: ${{ secrets.DOCKER_USERNAME }}
-          password: ${{ secrets.DOCKER_TOKEN }}
-
-      - uses: docker/build-push-action@v5
-        with:
-          context: .
-          file: ./Dockerfile
-          push: true
-          tags: |
-            ${{ env.IMAGE }}:${{ env.TAG }}
-
-      - name: Dispatch to gitops-repo
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token:  ${{ secrets.GH_PAT }}
-          repository: ${{ env.DEVOPS_REPO }}
-          event-type: image-updated
-          client-payload: |
-            {
-              "service": "${{ env.SERVICE }}",
-              "image":   "${{ env.IMAGE }}",
-              "tag":     "${{ env.TAG }}",
-              "targetBranch": "feature/MNMS-299"
-            }

From 88c267cbd7f988cf4bdff72601f0ccd5bf601878 Mon Sep 17 00:00:00 2001
From: dogun 
Date: Fri, 22 Aug 2025 18:51:38 +0900
Subject: [PATCH 057/149] Update api-booking-docker-dispatch.yml

---
 .../workflows/api-booking-docker-dispatch.yml | 61 ++++++++++---------
 1 file changed, 31 insertions(+), 30 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 31777cd..d55aa33 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -61,39 +61,40 @@ jobs:
           file: ./Dockerfile
           push: true
           platforms: linux/amd64,linux/arm64
-          tags: ${{ steps.meta.outputs.tags }}
+          # tags: ${{ steps.meta.outputs.tags }}
+          tags: v0.1
           labels: ${{ steps.meta.outputs.labels }}
           cache-from: type=gha
           cache-to: type=gha,mode=max
 
       # develop → 한번만 디스패치 (두 타깃 동시)
-      - name: Dispatch to GitOps (develop-gke + develop-aws)
-        if: ${{ github.ref_name == 'develop' }}
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token:  ${{ secrets.GH_PAT }}
-          repository: ${{ env.DEVOPS_REPO }}
-          event-type: image-updated
-          client-payload: |
-            {
-              "service": "${{ env.SERVICE }}",
-              "image":   "${{ env.IMAGE }}",
-              "tag":     "${{ env.TAG }}",
-              "targets": "develop-gke,develop-aws"
-            }
+      # - name: Dispatch to GitOps (develop-gke + develop-aws)
+      #   if: ${{ github.ref_name == 'develop' }}
+      #   uses: peter-evans/repository-dispatch@v3
+      #   with:
+      #     token:  ${{ secrets.GH_PAT }}
+      #     repository: ${{ env.DEVOPS_REPO }}
+      #     event-type: image-updated
+      #     client-payload: |
+      #       {
+      #         "service": "${{ env.SERVICE }}",
+      #         "image":   "${{ env.IMAGE }}",
+      #         "tag":     "${{ env.TAG }}",
+      #         "targets": "develop-gke,develop-aws"
+      #       }
 
-      # main → prod
-      - name: Dispatch to GitOps (prod)
-        if: ${{ github.ref_name == 'main' }}
-        uses: peter-evans/repository-dispatch@v3
-        with:
-          token:  ${{ secrets.GH_PAT }}
-          repository: ${{ env.DEVOPS_REPO }}
-          event-type: image-updated
-          client-payload: |
-            {
-              "service": "${{ env.SERVICE }}",
-              "image":   "${{ env.IMAGE }}",
-              "tag":     "${{ env.TAG }}",
-              "env":     "prod"
-            }
\ No newline at end of file
+      # # main → prod
+      # - name: Dispatch to GitOps (prod)
+      #   if: ${{ github.ref_name == 'main' }}
+      #   uses: peter-evans/repository-dispatch@v3
+      #   with:
+      #     token:  ${{ secrets.GH_PAT }}
+      #     repository: ${{ env.DEVOPS_REPO }}
+      #     event-type: image-updated
+      #     client-payload: |
+      #       {
+      #         "service": "${{ env.SERVICE }}",
+      #         "image":   "${{ env.IMAGE }}",
+      #         "tag":     "${{ env.TAG }}",
+      #         "env":     "prod"
+      #       }

From 9552e8409c7fd3cae63ffb1a4c725c194c8a0a2d Mon Sep 17 00:00:00 2001
From: dogun 
Date: Fri, 22 Aug 2025 19:27:45 +0900
Subject: [PATCH 058/149] Update api-booking-docker-dispatch.yml

---
 .github/workflows/api-booking-docker-dispatch.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index d55aa33..9b038ba 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -52,6 +52,7 @@ jobs:
           tags: |
             type=raw,value=${{ env.TAG_AMD }}
             type=raw,value=${{ env.TAG_ARM }}
+            type=raw,value=latest
             type=sha
             type=raw,value=latest,enable=${{ github.ref_name == 'main' }}
 
@@ -61,8 +62,7 @@ jobs:
           file: ./Dockerfile
           push: true
           platforms: linux/amd64,linux/arm64
-          # tags: ${{ steps.meta.outputs.tags }}
-          tags: v0.1
+          tags: ${{ steps.meta.outputs.tags }}
           labels: ${{ steps.meta.outputs.labels }}
           cache-from: type=gha
           cache-to: type=gha,mode=max

From 72c22ce60e78b34aad2367a9561c1ee38aa61b06 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 22 Aug 2025 19:45:18 +0900
Subject: [PATCH 059/149] =?UTF-8?q?ci(booking):=20=EB=A9=80=ED=8B=B0?=
 =?UTF-8?q?=EC=95=84=ED=82=A4=20=EB=B9=8C=EB=93=9C=20+=20latest(dev/main),?=
 =?UTF-8?q?=20v0.1=20=ED=83=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- 타임스탬프 태그 유지, 나머지 변경 없음
---
 .../workflows/api-booking-docker-dispatch.yml | 75 +++++++++----------
 1 file changed, 37 insertions(+), 38 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 9b038ba..16f9249 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -32,11 +32,7 @@ jobs:
       - run: ./gradlew bootJar --no-daemon
 
       - name: ⏱️ Tag
-        run: |
-          TS=$(date -u +'%Y%m%d%H%M%S')
-          echo "TAG_AMD=v${TS}-win" >> $GITHUB_ENV
-          echo "TAG_ARM=v${TS}-mac" >> $GITHUB_ENV
-          echo "TAG=v${TS}-win" >> $GITHUB_ENV
+        run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
 
       - uses: docker/setup-buildx-action@v3
 
@@ -50,11 +46,14 @@ jobs:
         with:
           images: ${{ env.IMAGE }}
           tags: |
-            type=raw,value=${{ env.TAG_AMD }}
-            type=raw,value=${{ env.TAG_ARM }}
-            type=raw,value=latest
+            # 1) 타임스탬프 태그 (기본)
+            type=raw,value=${{ env.TAG }}
+            # 2) git sha 태그
             type=sha
-            type=raw,value=latest,enable=${{ github.ref_name == 'main' }}
+            # 3) 고정 별칭
+            type=raw,value=v0.1
+            # 4) latest (main, develop 모두에서 발행)
+            type=raw,value=latest
 
       - uses: docker/build-push-action@v5
         with:
@@ -68,33 +67,33 @@ jobs:
           cache-to: type=gha,mode=max
 
       # develop → 한번만 디스패치 (두 타깃 동시)
-      # - name: Dispatch to GitOps (develop-gke + develop-aws)
-      #   if: ${{ github.ref_name == 'develop' }}
-      #   uses: peter-evans/repository-dispatch@v3
-      #   with:
-      #     token:  ${{ secrets.GH_PAT }}
-      #     repository: ${{ env.DEVOPS_REPO }}
-      #     event-type: image-updated
-      #     client-payload: |
-      #       {
-      #         "service": "${{ env.SERVICE }}",
-      #         "image":   "${{ env.IMAGE }}",
-      #         "tag":     "${{ env.TAG }}",
-      #         "targets": "develop-gke,develop-aws"
-      #       }
+      - name: Dispatch to GitOps (develop-gke + develop-aws)
+        if: ${{ github.ref_name == 'develop' }}
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "targets": "develop-gke,develop-aws"
+            }
 
-      # # main → prod
-      # - name: Dispatch to GitOps (prod)
-      #   if: ${{ github.ref_name == 'main' }}
-      #   uses: peter-evans/repository-dispatch@v3
-      #   with:
-      #     token:  ${{ secrets.GH_PAT }}
-      #     repository: ${{ env.DEVOPS_REPO }}
-      #     event-type: image-updated
-      #     client-payload: |
-      #       {
-      #         "service": "${{ env.SERVICE }}",
-      #         "image":   "${{ env.IMAGE }}",
-      #         "tag":     "${{ env.TAG }}",
-      #         "env":     "prod"
-      #       }
+      # main → prod
+      - name: Dispatch to GitOps (prod)
+        if: ${{ github.ref_name == 'main' }}
+        uses: peter-evans/repository-dispatch@v3
+        with:
+          token:  ${{ secrets.GH_PAT }}
+          repository: ${{ env.DEVOPS_REPO }}
+          event-type: image-updated
+          client-payload: |
+            {
+              "service": "${{ env.SERVICE }}",
+              "image":   "${{ env.IMAGE }}",
+              "tag":     "${{ env.TAG }}",
+              "env":     "prod"
+            }
\ No newline at end of file

From 0cd28385ed164c96b790099a759bc16cfa5fb55c Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 23 Aug 2025 08:44:39 +0900
Subject: [PATCH 060/149] =?UTF-8?q?MNMS-412=20Chore:=20swagger=20=EB=A9=94?=
 =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/controller/TransferController.java    | 7 +++++++
 .../java/com/mnms/booking/service/TransferService.java     | 5 +++++
 2 files changed, 12 insertions(+)

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index adfea5b..66e2419 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -9,6 +9,7 @@
 import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferService;
 import com.mnms.booking.util.ApiResponseUtil;
+import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -29,6 +30,9 @@ public class TransferController {
     private final TransferService transferService;
 
     @PostMapping("/extract")
+    @Operation(summary = "가족 간 양도 진행 인증 시도",
+            description = "가족관계증명서 pdf를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
+    )
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -42,6 +46,9 @@ public ResponseEntity>> extractPerso
     }
 
     @PutMapping("/{ticketId}")
+    @Operation(summary = "양도 완료",
+            description = "양도가 완료되면 티켓과 QR 정보가 업데이트 됩니다."
+    )
     public ResponseEntity> updateTicket(
             @PathVariable Long ticketId,
             @RequestBody UpdateTicketRequestDTO request) {
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index f995b53..cd571f1 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -34,6 +34,11 @@ public void updateTicket(Long ticketId, UpdateTicketRequestDTO request) {
         Ticket ticket = ticketRepository.findById(ticketId)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
+        // 예외 처리 하다가 멈춤
+//        if (ticket.isUsed() || ticket.isExpired() || ticket.isCanceled()) {
+//            throw new BusinessException(ErrorCode.INVALID_TICKET_STATUS);
+//        }
+
         TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
 
         List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())

From 151f695c53667db0de7d0f2c3ae9ce9c3e17a379 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 24 Aug 2025 01:00:46 +0900
Subject: [PATCH 061/149] =?UTF-8?q?MNMS-412=20Feat:=20=EC=A3=BC=EC=B5=9C?=
 =?UTF-8?q?=EC=B8=A1=20=EC=98=88=EB=A7=A4=EC=9E=90=20=EC=A0=95=EB=B3=B4=20?=
 =?UTF-8?q?=EC=A1=B0=ED=9A=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

WEBCLIENT로 USER API 호출
API RESPONSE DTO 형식에 따라 하나 더 추가
주최측으로 로그인해야 가능한 기능
ROLR 설정 했지만, USER도 가능한지 테스트 진행 X
---
 ...pplication.java => TeckitApplication.java} |  4 +--
 .../booking/controller/HostController.java    | 13 ++++++--
 .../controller/TransferController.java        | 19 ++++++++++--
 .../booking/dto/response/ApiResponseDTO.java  | 13 ++++++++
 .../response/BookingUserInfoResponseDTO.java  |  1 -
 .../booking/dto/response/HostResponseDTO.java |  2 +-
 .../com/mnms/booking/entity/Transfer.java     | 31 +++++++++++++++++++
 .../mnms/booking/enums/TransferStatus.java    |  9 ++++++
 .../com/mnms/booking/enums/TransferType.java  |  7 +++++
 .../com/mnms/booking/exception/ErrorCode.java |  3 +-
 .../com/mnms/booking/service/HostService.java | 25 ++++++++++++---
 .../mnms/booking/service/TransferService.java |  3 +-
 .../com/mnms/booking/util/UserApiClient.java  | 18 ++++++-----
 src/main/resources/application-dev.properties |  5 ++-
 14 files changed, 128 insertions(+), 25 deletions(-)
 rename src/main/java/com/mnms/booking/{BookingApplication.java => TeckitApplication.java} (80%)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/ApiResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/entity/Transfer.java
 create mode 100644 src/main/java/com/mnms/booking/enums/TransferStatus.java
 create mode 100644 src/main/java/com/mnms/booking/enums/TransferType.java

diff --git a/src/main/java/com/mnms/booking/BookingApplication.java b/src/main/java/com/mnms/booking/TeckitApplication.java
similarity index 80%
rename from src/main/java/com/mnms/booking/BookingApplication.java
rename to src/main/java/com/mnms/booking/TeckitApplication.java
index 08b2deb..8fc86db 100644
--- a/src/main/java/com/mnms/booking/BookingApplication.java
+++ b/src/main/java/com/mnms/booking/TeckitApplication.java
@@ -8,10 +8,10 @@
 @SpringBootApplication
 @EnableScheduling
 @EnableKafka
-public class BookingApplication {
+public class TeckitApplication {
 
 	public static void main(String[] args) {
-		SpringApplication.run(BookingApplication.class, args);
+		SpringApplication.run(TeckitApplication.class, args);
 	}
 
 }
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 065dd7d..fc9b7f7 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -5,10 +5,13 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.HostService;
 import com.mnms.booking.util.ApiResponseUtil;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
@@ -19,7 +22,10 @@
 @Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
 public class HostController {
 
+    private final SecurityResponseUtil securityResponseUtil;
     private final HostService hostService;
+
+
     @GetMapping("/list")
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
@@ -30,8 +36,11 @@ public ResponseEntity>> getBookingsByOrganizer(@Reque
 
     /// 주최자 측 예매자 조회
     @PostMapping("/booking/list")
-    public ResponseEntity>> getBookingInfo(@RequestBody Long hostUserId) {
-        List bookings = hostService.getBookingInfoByHost(hostUserId);
+    @Operation(summary = "예매자 정보 조회",
+            description = "예매자 정보 조회, 주최자 혹은 운영자로 로그인해야합니다.")
+    @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
+    public ResponseEntity>> getBookingInfo(Authentication authentication) {
+        List bookings = hostService.getBookingInfoByHost(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(bookings);
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index 66e2419..412eac1 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -45,14 +45,29 @@ public ResponseEntity>> extractPerso
         return ApiResponseUtil.success(people, "가족관계증명서 인증이 완료되었습니다.");
     }
 
+    // 가족간 양도 요청
+    /*
+    @PostMapping("/{ticketId}")
+    @Operation(summary = "양도 요청",
+            description = "양도자가 양도 요청 보내기"
+    )
+    public ResponseEntity> updateTicket(){
+
+    }*/
+
+
+    // 가족간 양도 승인
     @PutMapping("/{ticketId}")
     @Operation(summary = "양도 완료",
-            description = "양도가 완료되면 티켓과 QR 정보가 업데이트 됩니다."
+            description = "양수자가 양도 요청 승인시, 양도가 완료되며 티켓과 QR 정보가 업데이트 됩니다."
     )
     public ResponseEntity> updateTicket(
             @PathVariable Long ticketId,
             @RequestBody UpdateTicketRequestDTO request) {
-        transferService.updateTicket(ticketId, request);
+        transferService.updateFamilyTicket(ticketId, request);
         return ApiResponseUtil.success(null, "티켓 양도가 성공적으로 진행되었습니다.");
     }
+
+    // 지인간 양도 승인
+
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/ApiResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/ApiResponseDTO.java
new file mode 100644
index 0000000..9ed4985
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/ApiResponseDTO.java
@@ -0,0 +1,13 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Getter;
+
+public class ApiResponseDTO {
+    private boolean success;
+
+    @Getter
+    private T data;
+    private String message;
+
+    // getter, setter
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
index 0d6ba16..5a07415 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingUserInfoResponseDTO.java
@@ -11,5 +11,4 @@ public class BookingUserInfoResponseDTO {
     private Long userId;
     private String name;
     private String phone;
-    private String address;
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
index 645869c..58d0c08 100644
--- a/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/HostResponseDTO.java
@@ -17,9 +17,9 @@ public class HostResponseDTO {
     private Long userId;
     private int selectedTicketCount;
     private TicketType deliveryMethod;
+    private String address;
 
     // user info
     private String userName;
     private String phoneNumber;
-    private String address;
 }
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
new file mode 100644
index 0000000..32ec823
--- /dev/null
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -0,0 +1,31 @@
+package com.mnms.booking.entity;
+
+import com.mnms.booking.enums.TransferStatus;
+import com.mnms.booking.enums.TransferType;
+import jakarta.persistence.*;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Getter
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor(access = AccessLevel.PROTECTED)
+public class Transfer {
+
+    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    private Long senderId;
+    private Long receiverId;
+
+    @Enumerated(EnumType.STRING)
+    private TransferType type;
+
+    @Enumerated(EnumType.STRING)
+    private TransferStatus status = TransferStatus.PENDING;
+
+    private LocalDateTime createdAt = LocalDateTime.now();
+    private LocalDateTime updatedAt;
+}
diff --git a/src/main/java/com/mnms/booking/enums/TransferStatus.java b/src/main/java/com/mnms/booking/enums/TransferStatus.java
new file mode 100644
index 0000000..6f98148
--- /dev/null
+++ b/src/main/java/com/mnms/booking/enums/TransferStatus.java
@@ -0,0 +1,9 @@
+package com.mnms.booking.enums;
+
+// 요청, 승인, 거절
+
+public enum TransferStatus {
+    PENDING,  //요청
+    APPROVED, //승인
+    REJECTED //거절
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/enums/TransferType.java b/src/main/java/com/mnms/booking/enums/TransferType.java
new file mode 100644
index 0000000..b7c9a34
--- /dev/null
+++ b/src/main/java/com/mnms/booking/enums/TransferType.java
@@ -0,0 +1,7 @@
+package com.mnms.booking.enums;
+
+// 가족, 지인
+
+public enum TransferType {
+    FAMILY, OTHERS
+}
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index a08380f..e880036 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -8,7 +8,8 @@ public enum ErrorCode {
 
     // USER
     USER_INVALID("U001", "잘못된 사용자 ID 형식입니다", HttpStatus.BAD_REQUEST),
-
+    USER_API_ERROR("U002", "예매자 정보를 가져오는데 실패했습니다.", HttpStatus.CONFLICT),
+    UNKNOWN_ERROR("U003", "알 수 없는 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
     // 보안문자
     SECURITY_NUMBER_INVALID("S001", "입력한 문자가 일치하지 않습니다.", HttpStatus.BAD_REQUEST),
 
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index 41cf11e..b14e4cb 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -11,16 +11,20 @@
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.reactive.function.client.WebClientResponseException;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
-
 @RequiredArgsConstructor
 @Service
+@Slf4j
 public class HostService {
 
     private final TicketRepository ticketRepository;
@@ -42,12 +46,25 @@ public List getBookingInfoByHost(Long hostUserId) {
             tickets.addAll(ticketRepository.findByFestivalId(festival.getFestivalId()));
         }
 
+        if (tickets.isEmpty()) {
+            return Collections.emptyList();
+        }
+
         List userIds = tickets.stream()
                 .map(Ticket::getUserId)
                 .distinct()
                 .toList();
 
-        List users = userApiClient.getUsersByIds(userIds);
+        List users;
+        try {
+            users = userApiClient.getUsersByIds(userIds);
+            if (users == null) users = Collections.emptyList();
+        } catch (WebClientResponseException e) {
+            throw new BusinessException(ErrorCode.USER_API_ERROR);
+        } catch (Exception e) {
+            throw new BusinessException(ErrorCode.UNKNOWN_ERROR);
+        }
+
         Map userMap = users.stream()
                 .collect(Collectors.toMap(BookingUserInfoResponseDTO::getUserId, u -> u));
 
@@ -60,9 +77,9 @@ public List getBookingInfoByHost(Long hostUserId) {
                             t.getUserId(),
                             t.getSelectedTicketCount(),
                             t.getDeliveryMethod(),
+                            t.getAddress(),
                             user != null ? user.getName() : null,
-                            user != null ? user.getPhone() : null,
-                            user != null ? user.getAddress() : null
+                            user != null ? user.getPhone() : null
                     );
                 })
                 .toList();
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index cd571f1..b2e04a2 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -30,7 +30,8 @@ public class TransferService {
     private final CommonUtils commonUtils;
     private final QrCodeService qrCodeService;
 
-    public void updateTicket(Long ticketId, UpdateTicketRequestDTO request) {
+    // 가족간 양도
+    public void updateFamilyTicket(Long ticketId, UpdateTicketRequestDTO request) {
         Ticket ticket = ticketRepository.findById(ticketId)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
diff --git a/src/main/java/com/mnms/booking/util/UserApiClient.java b/src/main/java/com/mnms/booking/util/UserApiClient.java
index 83c128f..0e70e3f 100644
--- a/src/main/java/com/mnms/booking/util/UserApiClient.java
+++ b/src/main/java/com/mnms/booking/util/UserApiClient.java
@@ -1,13 +1,16 @@
 package com.mnms.booking.util;
 
+import com.mnms.booking.dto.response.ApiResponseDTO;
 import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
-import com.mnms.booking.dto.response.TransferUserResponse;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.stereotype.Component;
 import org.springframework.web.reactive.function.client.WebClient;
 
+
+import java.util.Collections;
 import java.util.List;
 
 
@@ -17,22 +20,21 @@ public class UserApiClient {
 
     private final WebClient webClient;
 
-    @Value("${booking.user.service.url}")
-    private String bookingUserServiceUrl;
-
-    @Value("${user.service.url}")
+    @Value("${base.service.url}${user.service.url}")
     private String userServiceUrl;
 
+    @Value("${base.service.url}${booking.user.service.url}")
+    private String bookingUserServiceUrl;
 
     // userId 리스트 요청
     public List getUsersByIds(List userIds) {
-        return webClient.post()
+        ApiResponseDTO> response = webClient.post()
                 .uri(bookingUserServiceUrl)
                 .bodyValue(userIds)
                 .retrieve()
-                .bodyToFlux(BookingUserInfoResponseDTO.class)
-                .collectList()
+                .bodyToMono(new ParameterizedTypeReference>>() {})
                 .block();
+        return response != null ? response.getData() : Collections.emptyList();
     }
 
     // userId로 요청
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 5048ae2..58bd762 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -22,8 +22,6 @@ spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 #spring.data.redis.host=127.0.0.1
 spring.data.redis.host=34.22.92.22
 spring.data.redis.port=6379
-
-
 #spring.redis.password=your_password
 
 ## kafka
@@ -54,5 +52,6 @@ springdoc.swagger-ui.path=/swagger-ui.html
 springdoc.override-with-generic-response=false
 
 # user api
+base.service.url=${BASE_API}
 user.service.url=${USER_INFO_API}
-booking.user.service.url=${BOOKING_USER_INFO_API}
\ No newline at end of file
+booking.user.service.url=${BOOKING_USER_INFO_API}

From 6b8101cf677978c6b79f7d6a989833e543129385 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 25 Aug 2025 23:04:41 +0900
Subject: [PATCH 062/149] =?UTF-8?q?MNMS-459=20Fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20=EB=8F=99=EC=8B=9C=EC=84=B1=20=EB=AC=B8=EC=A0=9C=20?=
 =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=AF=B8?=
 =?UTF-8?q?=EC=99=84)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Lua script로 대기열 동시성 문제 해결 진행
설치 버전 문제로 테스트 미완
---
 build.gradle                                  | 22 +++++------
 ...pplication.java => TekcitApplication.java} |  4 +-
 .../booking/controller/HostController.java    |  2 +-
 .../booking/controller/WaitingController.java |  3 +-
 .../com/mnms/booking/entity/Transfer.java     |  2 +
 .../service/WaitingQueueRedisService.java     | 37 +++++++++++++++++++
 .../mnms/booking/service/WaitingService.java  | 16 +++-----
 src/main/resources/application-dev.properties |  4 +-
 8 files changed, 62 insertions(+), 28 deletions(-)
 rename src/main/java/com/mnms/booking/{TeckitApplication.java => TekcitApplication.java} (80%)

diff --git a/build.gradle b/build.gradle
index 0657fcc..69624e1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -43,10 +43,14 @@ dependencies {
 	runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
 	runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
 
-
-	// h2
+	// mariadb + h2
+	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
 	runtimeOnly 'com.h2database:h2'
 
+	// mongodb
+	//implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
+
+
 	// websocket
 	implementation 'org.springframework.boot:spring-boot-starter-websocket'
 
@@ -54,13 +58,6 @@ dependencies {
 	implementation 'org.springframework.boot:spring-boot-starter-data-redis'
 	implementation 'redis.clients:jedis' // 삭제 가능
 
-	// mariadb
-	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
-	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
-
-	// mongodb
-	//implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
-
 	// kaptcha
 	implementation 'com.github.penggle:kaptcha:2.3.2'
 
@@ -68,20 +65,23 @@ dependencies {
 	implementation 'org.springframework.kafka:spring-kafka'
 
 	// JSON 직렬화용
-	implementation 'com.fasterxml.jackson.core:jackson-databind'
+	//implementation 'com.fasterxml.jackson.core:jackson-databind'
+	implementation 'com.fasterxml.jackson.core:jackson-databind:2.19.2'
 	implementation 'org.springframework.boot:spring-boot-starter-json'
 	testImplementation 'org.springframework.kafka:spring-kafka-test'
 
 	// QR 생성
 	implementation 'com.google.zxing:core:3.5.2'
 	implementation 'com.google.zxing:javase:3.5.2'
-	implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
 
 	// swagger
 	implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0'
 
 	// WebClient 사용
 	implementation 'org.springframework.boot:spring-boot-starter-webflux'
+
+	// test
+	testImplementation 'it.ozimov:embedded-redis:0.7.3'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/TeckitApplication.java b/src/main/java/com/mnms/booking/TekcitApplication.java
similarity index 80%
rename from src/main/java/com/mnms/booking/TeckitApplication.java
rename to src/main/java/com/mnms/booking/TekcitApplication.java
index 8fc86db..a336bcd 100644
--- a/src/main/java/com/mnms/booking/TeckitApplication.java
+++ b/src/main/java/com/mnms/booking/TekcitApplication.java
@@ -8,10 +8,10 @@
 @SpringBootApplication
 @EnableScheduling
 @EnableKafka
-public class TeckitApplication {
+public class TekcitApplication {
 
 	public static void main(String[] args) {
-		SpringApplication.run(TeckitApplication.class, args);
+		SpringApplication.run(TekcitApplication.class, args);
 	}
 
 }
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index fc9b7f7..00ad8b1 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -38,7 +38,7 @@ public ResponseEntity>> getBookingsByOrganizer(@Reque
     @PostMapping("/booking/list")
     @Operation(summary = "예매자 정보 조회",
             description = "예매자 정보 조회, 주최자 혹은 운영자로 로그인해야합니다.")
-    @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
+    @PreAuthorize("hasAnyRole('HOST')")
     public ResponseEntity>> getBookingInfo(Authentication authentication) {
         List bookings = hostService.getBookingInfoByHost(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(bookings);
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index ee51b45..1b31bea 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -20,12 +20,13 @@
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.security.core.Authentication;
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
 
 import java.time.LocalDateTime;
 
-@Controller
+@RestController
 @Slf4j
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
index 32ec823..f80e541 100644
--- a/src/main/java/com/mnms/booking/entity/Transfer.java
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -24,8 +24,10 @@ public class Transfer {
     private TransferType type;
 
     @Enumerated(EnumType.STRING)
+    @Builder.Default
     private TransferStatus status = TransferStatus.PENDING;
 
+    @Builder.Default
     private LocalDateTime createdAt = LocalDateTime.now();
     private LocalDateTime updatedAt;
 }
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index dcd9eda..aea6814 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -4,8 +4,10 @@
 import lombok.RequiredArgsConstructor;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
 import java.util.Set;
 
 @Service
@@ -14,6 +16,41 @@ public class WaitingQueueRedisService {
     private final RedisTemplate redisTemplate;
     private final ZSetOperations zSetOperations;
 
+    /// Lua 스크립트
+    private static final String ENTER_SCRIPT =
+            "local current = redis.call('SCARD', KEYS[1]); " +
+                    "if current < tonumber(ARGV[1]) then " +
+                    "  redis.call('SADD', KEYS[1], ARGV[2]); " +
+                    "  return 1; " +
+                    "else " +
+                    "  return 0; " +
+                    "end";
+
+    private final DefaultRedisScript enterScript;
+
+    {
+        enterScript = new DefaultRedisScript<>();
+        enterScript.setScriptText(ENTER_SCRIPT);
+        enterScript.setResultType(Long.class);
+    }
+
+    /**
+     * Lua 스크립트로 안전하게 유저 추가 시도
+     * @return true = 즉시 입장, false = 대기열 필요
+     */
+    public boolean tryEnterBooking(String bookingUsersKey, long availableNOP, String userId) {
+        Long result = redisTemplate.execute(
+                enterScript,
+                Collections.singletonList(bookingUsersKey),
+                String.valueOf(availableNOP),
+                userId
+        );
+        return result != null && result == 1;
+    }
+    //
+
+
+
     public WaitingQueueRedisService(RedisTemplate redisTemplate) {
         this.redisTemplate = redisTemplate;
         this.zSetOperations = redisTemplate.opsForZSet();
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 64b06db..f9be340 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -16,27 +16,21 @@ public class WaitingService {
     private final WaitingNotificationService waitingNotificationService;
     private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
 
-    /**
-     * 사용자 대기열 진입 처리
-     * @return 대기 순번 (즉시 입장 가능 시 0)
-     */
+    /// 사용자 대기열 진입 처리
     public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate, String userId, long availableNOP) {
         String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
 
-        long currentUserCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
+        boolean entered = waitingQueueRedisService.tryEnterBooking(bookingUsersKey, availableNOP, userId);
 
-        if (currentUserCount < availableNOP) {
-            log.info("User {} can enter booking page immediately ({} < {}).", userId, currentUserCount, availableNOP);
-            waitingQueueRedisService.addBookingUser(bookingUsersKey, userId);
-            return 0L;
+        if (entered) {
+            log.info("User {} entered booking page immediately.", userId);
+            return 0L; // 즉시 입장
         } else {
             waitingQueueRedisService.addUserToQueue(waitingQueueKey, userId);
             log.info("User {} added to waiting queue {}.", userId, waitingQueueKey);
-
             waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
-
             return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
         }
     }
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 58bd762..23a6410 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -20,8 +20,8 @@ spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
 # redis 설정 - 로컬 설정
 #spring.data.redis.host=127.0.0.1
-spring.data.redis.host=34.22.92.22
-spring.data.redis.port=6379
+spring.data.redis.host=${SERVER_URL}
+spring.data.redis.port=${REDIS_PORT}
 #spring.redis.password=your_password
 
 ## kafka

From b87275fa9097431ab46c3930556fe077212c6001 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 26 Aug 2025 15:03:19 +0900
Subject: [PATCH 063/149] =?UTF-8?q?MNMS-459=20Feat:=20=EA=B0=9C=EC=9D=B8?=
 =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=98=88=EB=A7=A4=20=EB=82=B4?=
 =?UTF-8?q?=EC=97=AD=20=EC=A1=B0=ED=9A=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

사용자 예매 내역 전체 조회
사용자 예매 디테일 조회
QR id 리스트 요청으로 QR 이미지 일괄 생성
---
 build.gradle                                  |  1 +
 .../booking/controller/BookingController.java |  3 ++
 .../booking/controller/QrCodeController.java  | 27 ++++++++++
 .../booking/controller/TicketController.java  | 54 +++++++++++++++++++
 .../dto/response/TicketDetailResponseDTO.java | 45 ++++++++++++++++
 .../dto/response/TicketResponseDTO.java       | 46 ++++++++++++++++
 .../com/mnms/booking/exception/ErrorCode.java |  1 +
 .../booking/repository/TicketRepository.java  |  3 ++
 .../mnms/booking/service/TicketService.java   | 54 +++++++++++++++++++
 .../booking/util/SecurityResponseUtil.java    | 22 ++++++++
 10 files changed, 256 insertions(+)
 create mode 100644 src/main/java/com/mnms/booking/controller/TicketController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/service/TicketService.java

diff --git a/build.gradle b/build.gradle
index 69624e1..68db442 100644
--- a/build.gradle
+++ b/build.gradle
@@ -37,6 +37,7 @@ dependencies {
 
 	// security
 	implementation 'org.springframework.boot:spring-boot-starter-security'
+	implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
 
 	// JWT
 	implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index b83aaf2..ef0a5fa 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -6,6 +6,7 @@
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
@@ -20,6 +21,8 @@
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index 0d2ab45..7427c8d 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -14,6 +14,10 @@
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.List;
+
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/qr")
@@ -39,6 +43,29 @@ public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
         }
     }
 
+    ///  Qrcode 이미지 qrCodeId 리스트로 조회
+    @GetMapping("/images")
+    @Operation(summary = "QR 코드 이미지 다수 조회",
+            description = "qrCodeId 리스트로 여러 개의 QR 코드 이미지를 Base64 인코딩된 문자열로 반환합니다.")
+    public ResponseEntity> getQrCodeImages(@RequestParam List qrCodeIds) {
+        List images = new ArrayList<>();
+        for (String qrCodeId : qrCodeIds) {
+            QrCode qrCode = qrCodeService.getQrCodeByCode(qrCodeId);
+            String qrCodeText = qrCode.getQrCodeId();
+
+            try {
+                byte[] imageBytes = qrCodeService.generateQrCodeImage(qrCodeText, 250, 250);
+                String base64Image = Base64.getEncoder().encodeToString(imageBytes);
+                images.add(base64Image);
+            } catch (Exception e) {
+                images.add(null);
+                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
+            }
+        }
+        return ResponseEntity.ok(images);
+    }
+
+
     /// 페스티벌 주최자 QR 스캔
     @PostMapping(value = "/validate/{qrCodeId}")
     @Operation(summary = "QR 코드 스캔 및 유효성 검사",
diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
new file mode 100644
index 0000000..05e38cf
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -0,0 +1,54 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.response.TicketDetailResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
+import com.mnms.booking.service.TicketService;
+import com.mnms.booking.util.ApiResponseUtil;
+import com.mnms.booking.util.SecurityResponseUtil;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/api/ticket")
+@Tag(name = "예매 내역 API", description = "예매 내역 조회")
+public class TicketController {
+
+    private final TicketService ticketService;
+    private final SecurityResponseUtil securityResponseUtil;
+
+    @GetMapping("/user")
+    @Operation(summary = "예매 정보 정보 조회",
+            description = "예매 완료한 티켓 정보를 조회" +
+                    "예매자가 예매 완료한 티켓 정보를 조회할 수 있다."
+    )
+    public ResponseEntity>> getUserTickets(Authentication authentication) {
+        List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(tickets);
+    }
+
+    @GetMapping("/user/detail")
+    @Operation(summary = "예매자 정보 조회",
+            description = "예매 완료한 티켓 정보를 조회" +
+                    "예매자가 예매 완료한 티켓 정보를 조회할 수 있다."
+    )
+    public ResponseEntity> getUserTicketDetail(@Valid @RequestBody String reservationNumber,
+                                                                                        Authentication authentication) {
+        TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(ticket);
+    }
+
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
new file mode 100644
index 0000000..4586de5
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -0,0 +1,45 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.TicketType;
+import lombok.Builder;
+import lombok.Data;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Data
+@Builder
+public class TicketDetailResponseDTO {
+
+    // ticket
+    private Long id;
+    private String reservationNumber; // 예매 번호
+    private LocalDateTime performanceDate; // 공연 일시
+    private TicketType deliveryMethod; // 티켓 수령 방법
+    private List qrId;
+    private String address;
+
+    // festival
+    private String fname; // 공연명
+    private String fcltynm; // 장소
+
+    public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival) {
+        List qrIds = ticket.getQrCodes().stream()
+                .map(QrCode::getQrCodeId)
+                .toList();
+
+        return TicketDetailResponseDTO.builder()
+                .id(ticket.getId())
+                .reservationNumber(ticket.getReservationNumber())
+                .performanceDate(ticket.getPerformanceDate())
+                .deliveryMethod(ticket.getDeliveryMethod())
+                .address(ticket.getAddress())
+                .qrId(qrIds)
+                .fname(festival.getFname())
+                .fcltynm(festival.getFcltynm())
+                .build();
+    }
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
new file mode 100644
index 0000000..d8dc4c6
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -0,0 +1,46 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.enums.TicketType;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.stream.Collectors;
+
+
+// 예매 내역 기본 조회
+@Data
+@Builder
+public class TicketResponseDTO {
+
+    // ticket
+    private Long id;
+    private String reservationNumber; // 예매 번호
+    private LocalDateTime performanceDate; // 공연 일시
+    private int selectedTicketCount; // 매수
+    private TicketType deliveryMethod; // 티켓 수령 방법
+    private LocalDate reservationDate; // 예매를 수행한 날짜
+    private ReservationStatus reservationStatus; // 예매상태
+
+    // festival
+    private String fname; // 공연명
+    private String fcltynm; // 장소
+
+    public static TicketResponseDTO fromEntity(Ticket ticket, Festival festival) {
+        return TicketResponseDTO.builder()
+                .id(ticket.getId())
+                .reservationNumber(ticket.getReservationNumber())
+                .performanceDate(ticket.getPerformanceDate())
+                .selectedTicketCount(ticket.getSelectedTicketCount())
+                .deliveryMethod(ticket.getDeliveryMethod())
+                .reservationDate(ticket.getReservationDate())
+                .reservationStatus(ticket.getReservationStatus())
+                .fname(festival.getFname())
+                .fcltynm(festival.getFcltynm())
+                .build();
+    }
+}
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index e880036..309b541 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -10,6 +10,7 @@ public enum ErrorCode {
     USER_INVALID("U001", "잘못된 사용자 ID 형식입니다", HttpStatus.BAD_REQUEST),
     USER_API_ERROR("U002", "예매자 정보를 가져오는데 실패했습니다.", HttpStatus.CONFLICT),
     UNKNOWN_ERROR("U003", "알 수 없는 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    USER_UNAUTHORIZED_ACCESS("U004", "잘못된 사용자 예매내역 입니다.", HttpStatus.UNAUTHORIZED),
     // 보안문자
     SECURITY_NUMBER_INVALID("S001", "입력한 문자가 일치하지 않습니다.", HttpStatus.BAD_REQUEST),
 
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 628e21a..e1be0c8 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -67,4 +67,7 @@ List findDistinctUserIdsByFestivalIdAndPerformanceDate(@Param("festivalId"
     int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
                                     @Param("performanceDate") LocalDateTime performanceDate,
                                     @Param("statuses") List statuses);
+
+    List findByUserIdAndReservationStatusIn(Long userId, List statuses);
+    Optional findByUserIdAndReservationNumber(Long userId, String reservationNumber);
 }
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
new file mode 100644
index 0000000..989bba5
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -0,0 +1,54 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.response.TicketDetailResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Optional;
+
+@Service
+@Slf4j
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+public class TicketService {
+
+    private final TicketRepository ticketRepository;
+
+    // 예매 리스트 기본 조회
+    public List getTicketsByUser(Long userId) {
+
+        // status가 CONFIRMED, CANCELED 일 때
+        List statuses = List.of(
+                ReservationStatus.CONFIRMED,
+                ReservationStatus.CANCELED
+        );
+        List tickets = ticketRepository.findByUserIdAndReservationStatusIn(userId, statuses);
+
+        if(tickets.isEmpty()){
+            throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
+        }
+        return tickets.stream()
+                .map(ticket -> TicketResponseDTO.fromEntity(ticket, ticket.getFestival()))
+                .toList();
+    }
+
+    // 예매 상세 조회
+    public TicketDetailResponseDTO getTicketDetailByUser(String reservationNumber, Long userId) {
+        Ticket ticket = ticketRepository.findByUserIdAndReservationNumber(userId, reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        if (!ticket.getUserId().equals(userId)) {
+            throw new BusinessException(ErrorCode.USER_UNAUTHORIZED_ACCESS);
+        }
+        return TicketDetailResponseDTO.fromEntity(ticket, ticket.getFestival());
+    }
+}
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
index 7a08b32..d784f6a 100644
--- a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -3,10 +3,14 @@
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.oauth2.jwt.Jwt;
+import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 import org.springframework.stereotype.Component;
 
 @Component
+@Slf4j
 @RequiredArgsConstructor
 public class SecurityResponseUtil {
     // Authentication에서 userId 추출
@@ -17,4 +21,22 @@ public Long requireUserId(Authentication authentication) {
             throw new BusinessException(ErrorCode.USER_INVALID);
         }
     }
+
+    // Authentication에서 name 추출
+    public String requireName(Authentication authentication) {
+        log.info("authentication : {}", authentication);
+        if (!(authentication instanceof JwtAuthenticationToken jwtAuth)) {
+            throw new BusinessException(ErrorCode.USER_INVALID);
+        }
+
+        Jwt jwt = jwtAuth.getToken();
+        String name = jwt.getClaimAsString("name");
+
+        if (name == null || name.isEmpty()) {
+            throw new BusinessException(ErrorCode.USER_INVALID);
+        }
+
+        return name;
+    }
+
 }

From 3a82e715b97803eeb8813de6b545290119037e8d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 26 Aug 2025 15:29:37 +0900
Subject: [PATCH 064/149] =?UTF-8?q?MNMS-459=20Fix:=20ticket/detail=20param?=
 =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20swagger=20=EB=B3=80?=
 =?UTF-8?q?=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

param @RequestBody -> @RequestParam
swagger ticket 수정
---
 .../booking/controller/TicketController.java  | 22 ++++++++-----------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index 05e38cf..a8172f7 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -13,10 +13,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -30,22 +27,21 @@ public class TicketController {
     private final TicketService ticketService;
     private final SecurityResponseUtil securityResponseUtil;
 
-    @GetMapping("/user")
-    @Operation(summary = "예매 정보 정보 조회",
-            description = "예매 완료한 티켓 정보를 조회" +
-                    "예매자가 예매 완료한 티켓 정보를 조회할 수 있다."
+    @GetMapping
+    @Operation(summary = "예매한 티켓 정보 조회",
+            description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
     )
     public ResponseEntity>> getUserTickets(Authentication authentication) {
         List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(tickets);
     }
 
-    @GetMapping("/user/detail")
-    @Operation(summary = "예매자 정보 조회",
-            description = "예매 완료한 티켓 정보를 조회" +
-                    "예매자가 예매 완료한 티켓 정보를 조회할 수 있다."
+    @GetMapping("/detail")
+    @Operation(summary = "예매한 티켓 정보 디테일 조회",
+            description = "예매자가 예매 완료한 티켓 정보를 조회합니다. " +
+                    "ex : /api/ticket/detail?reservationNumber=T24CBD629 조회"
     )
-    public ResponseEntity> getUserTicketDetail(@Valid @RequestBody String reservationNumber,
+    public ResponseEntity> getUserTicketDetail(@RequestParam String reservationNumber,
                                                                                         Authentication authentication) {
         TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(ticket);

From a1812a9d781446f41972a6e3ac12f33877315288 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 26 Aug 2025 16:28:58 +0900
Subject: [PATCH 065/149] =?UTF-8?q?MNMS-458=20Chore:=20=EC=A3=BC=EC=B5=9C?=
 =?UTF-8?q?=EC=9E=90=20=EC=B8=A1=20=EC=98=88=EB=A7=A4=EC=9E=90=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

요청 파람으로 festivalId 추가
ReservationStatus CONFIRMED인 것만 조회 가능 조건 추가
---
 .../com/mnms/booking/controller/BookingController.java     | 1 -
 .../java/com/mnms/booking/controller/HostController.java   | 7 ++++---
 .../com/mnms/booking/repository/FestivalRepository.java    | 3 +--
 .../java/com/mnms/booking/repository/TicketRepository.java | 6 ++++++
 src/main/java/com/mnms/booking/service/HostService.java    | 7 ++++---
 5 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index ef0a5fa..16f2fa4 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -6,7 +6,6 @@
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
-import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 00ad8b1..b48ef94 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -30,7 +30,7 @@ public class HostController {
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
     )
-    public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
+    public ResponseEntity>> getBookingsByOrXSanizer(@RequestBody HostRequestDTO hostRequestDTO) {
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
 
@@ -39,8 +39,9 @@ public ResponseEntity>> getBookingsByOrganizer(@Reque
     @Operation(summary = "예매자 정보 조회",
             description = "예매자 정보 조회, 주최자 혹은 운영자로 로그인해야합니다.")
     @PreAuthorize("hasAnyRole('HOST')")
-    public ResponseEntity>> getBookingInfo(Authentication authentication) {
-        List bookings = hostService.getBookingInfoByHost(securityResponseUtil.requireUserId(authentication));
+    public ResponseEntity>> getBookingInfo(@RequestParam String festivalId,
+                                                                                 Authentication authentication) {
+        List bookings = hostService.getBookingInfoByHost(festivalId, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(bookings);
     }
 }
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index b5d81ee..163d081 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -9,7 +9,6 @@
 
 @Repository
 public interface FestivalRepository extends JpaRepository {
-    // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByFestivalId(String festivalId);
-    List findByOrganizer(Long organizer);
+    List findByFestivalIdAndOrganizer(String festivalId , Long organizer);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index e1be0c8..664d3be 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -70,4 +70,10 @@ int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
 
     List findByUserIdAndReservationStatusIn(Long userId, List statuses);
     Optional findByUserIdAndReservationNumber(Long userId, String reservationNumber);
+
+    @Query("SELECT t FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId " +
+            "AND t.reservationStatus = :status")
+    List findByFestivalIdAndReservationStatus(@Param("festivalId") String festivalId,
+                                                      @Param("status") ReservationStatus status);
 }
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index b14e4cb..feb9309 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -5,6 +5,7 @@
 import com.mnms.booking.dto.response.HostResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.FestivalRepository;
@@ -35,15 +36,15 @@ public List getBookingsByOrganizer(HostRequestDTO request) {
         return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
     }
 
-    public List getBookingInfoByHost(Long hostUserId) {
-        List festivals = festivalRepository.findByOrganizer(hostUserId);
+    public List getBookingInfoByHost(String festivalId, Long hostUserId) {
+        List festivals = festivalRepository.findByFestivalIdAndOrganizer(festivalId, hostUserId);
         if (festivals == null) {
             throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
         }
 
         List tickets = new ArrayList<>();
         for (Festival festival : festivals) {
-            tickets.addAll(ticketRepository.findByFestivalId(festival.getFestivalId()));
+            tickets.addAll(ticketRepository.findByFestivalIdAndReservationStatus(festival.getFestivalId(), ReservationStatus.CONFIRMED));
         }
 
         if (tickets.isEmpty()) {

From 9c08423f1ae843041167c0de54a1daa785fb2b60 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 27 Aug 2025 10:37:16 +0900
Subject: [PATCH 066/149] =?UTF-8?q?MNMS-458=20Chore:=20=EC=A3=BC=EC=B5=9C?=
 =?UTF-8?q?=EC=9E=90=20=EC=B8=A1=20=EC=98=88=EB=A7=A4=EC=9E=90=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20+=20=EC=9A=B4=EC=98=81=EC=9E=90=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/HostController.java    |  6 ++++--
 .../booking/controller/WaitingController.java |  2 --
 .../repository/FestivalRepository.java        |  3 ++-
 .../com/mnms/booking/service/HostService.java | 19 ++++++++++++-------
 .../booking/util/SecurityResponseUtil.java    | 16 ++++++++++++++++
 5 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index b48ef94..c685d91 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -9,6 +9,7 @@
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.Authentication;
@@ -17,6 +18,7 @@
 import java.util.List;
 
 @RestController
+@Slf4j
 @RequiredArgsConstructor
 @RequestMapping("/api/host")
 @Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
@@ -38,10 +40,10 @@ public ResponseEntity>> getBookingsByOrXSanizer(@Requ
     @PostMapping("/booking/list")
     @Operation(summary = "예매자 정보 조회",
             description = "예매자 정보 조회, 주최자 혹은 운영자로 로그인해야합니다.")
-    @PreAuthorize("hasAnyRole('HOST')")
+    @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
     public ResponseEntity>> getBookingInfo(@RequestParam String festivalId,
                                                                                  Authentication authentication) {
-        List bookings = hostService.getBookingInfoByHost(festivalId, securityResponseUtil.requireUserId(authentication));
+        List bookings = hostService.getBookingInfoByHost(festivalId, securityResponseUtil.requireUserId(authentication), securityResponseUtil.requireRole(authentication));
         return ApiResponseUtil.success(bookings);
     }
 }
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 1b31bea..63c963c 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -19,8 +19,6 @@
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.security.core.Authentication;
-import org.springframework.stereotype.Controller;
-import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 import com.mnms.booking.service.WaitingService;
 
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index 163d081..cbdd498 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -9,6 +9,7 @@
 
 @Repository
 public interface FestivalRepository extends JpaRepository {
+
     Optional findByFestivalId(String festivalId);
-    List findByFestivalIdAndOrganizer(String festivalId , Long organizer);
+    Festival findByFestivalIdAndOrganizer(String festivalId , Long organizer);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index feb9309..326d6c4 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -36,17 +36,22 @@ public List getBookingsByOrganizer(HostRequestDTO request) {
         return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
     }
 
-    public List getBookingInfoByHost(String festivalId, Long hostUserId) {
-        List festivals = festivalRepository.findByFestivalIdAndOrganizer(festivalId, hostUserId);
-        if (festivals == null) {
-            throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
+    public List getBookingInfoByHost(String festivalId, Long hostUserId, List role) {
+
+        Festival festival;
+        if (role.contains("ROLE_ADMIN")) {
+            festival = festivalRepository.findByFestivalId(festivalId)
+                    .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+        } else {
+            festival = festivalRepository.findByFestivalIdAndOrganizer(festivalId, hostUserId);
         }
 
-        List tickets = new ArrayList<>();
-        for (Festival festival : festivals) {
-            tickets.addAll(ticketRepository.findByFestivalIdAndReservationStatus(festival.getFestivalId(), ReservationStatus.CONFIRMED));
+        if (festival == null) {
+            throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
         }
 
+        List tickets = new ArrayList<>(ticketRepository.findByFestivalIdAndReservationStatus(festival.getFestivalId(), ReservationStatus.CONFIRMED));
+
         if (tickets.isEmpty()) {
             return Collections.emptyList();
         }
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
index d784f6a..57c6347 100644
--- a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -5,10 +5,14 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.oauth2.jwt.Jwt;
 import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 import org.springframework.stereotype.Component;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 @Component
 @Slf4j
 @RequiredArgsConstructor
@@ -39,4 +43,16 @@ public String requireName(Authentication authentication) {
         return name;
     }
 
+    // Authentication에서 ROLE 빼오기
+    public List requireRole(Authentication authentication) {
+        if (authentication == null || authentication.getAuthorities() == null) {
+            return List.of(); // 빈 리스트 반환
+        }
+
+        return authentication.getAuthorities()
+                .stream()
+                .map(GrantedAuthority::getAuthority)
+                .collect(Collectors.toList());
+    }
+
 }

From acb75d33a843ef40f54339b0a1e425d9488c8656 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 27 Aug 2025 11:12:44 +0900
Subject: [PATCH 067/149] =?UTF-8?q?MNMS-458=20Chore:=20=EA=B0=80=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EC=A1=B0=ED=9A=8C=20seller=20ID=20=EB=B0=98?=
 =?UTF-8?q?=ED=99=98=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/mnms/booking/controller/BookingController.java   | 4 ++--
 .../mnms/booking/dto/response/BookingDetailResponseDTO.java   | 2 ++
 .../mnms/booking/service/WaitingQueueSchedulingService.java   | 1 -
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 16f2fa4..29dab2a 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -36,7 +36,7 @@ public class BookingController {
     /// GET : 페스티벌 예매 정보 조회
     @PostMapping("/detail/phases/1")
     @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId와 performanceDate(사용자가 선택한 날짜 시간) 으로 공연 상세 정보를 조회합니다." +
+            description = "festivalId와 performanceDate(사용자가 선택한 날짜, 시간)으로 공연 상세 정보를 조회합니다." +
                     "selectedTicketCount는 0으로 넣을 것!")
     public ResponseEntity> getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
         return ApiResponseUtil.success(bookingQueryService.getFestivalDetail(request));
@@ -67,7 +67,7 @@ public ResponseEntity> selectFestivalDate(
 
     @PostMapping("/selectDeliveryMethod")
     @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법, 주소 선택",
-            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수), deliveryMethod(MOBILE or PAPER), address(String)"
+            description = "festivalId, performanceDate(선택한날짜,시간), deliveryMethod(MOBILE or PAPER), address(String)"
     )
     public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
index 3dff1b1..22e27a0 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
@@ -17,11 +17,13 @@ public class BookingDetailResponseDTO {
     private String posterFile;
     private LocalDateTime performanceDate;
     private int ticketCount;
+    private Long sellerId;
 
     public static BookingDetailResponseDTO fromEntities(Festival festival, Ticket ticket) {
         return BookingDetailResponseDTO.builder()
                 .festivalName(festival.getFname())
                 .posterFile(festival.getPosterFile())
+                .sellerId(festival.getOrganizer())
                 .ticketPrice(festival.getTicketPrice())
                 .performanceDate(ticket.getPerformanceDate())
                 .ticketCount(ticket.getSelectedTicketCount())
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index 4233960..cd066c5 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -1,6 +1,5 @@
 package com.mnms.booking.service;
 
-import jakarta.annotation.PostConstruct;
 import jakarta.annotation.PreDestroy;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;

From d05593348bbce458ad30639eab413f1696248fec Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Wed, 27 Aug 2025 13:17:01 +0900
Subject: [PATCH 068/149] =?UTF-8?q?MNMS-511=20Story:=20=EA=B3=B5=EC=97=B0?=
 =?UTF-8?q?=20=EB=B3=84=20=EC=98=88=EB=A7=A4=EC=9E=90=20=EC=84=B1=EB=B3=84?=
 =?UTF-8?q?=20/=20=EB=82=98=EC=9D=B4=20=ED=86=B5=EA=B3=84=20=EA=B8=B0?=
 =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/HostController.java    |   2 +-
 .../controller/StatisticsController.java      |  39 +++++
 .../repository/StatisticsRepository.java      |  16 ++
 .../booking/service/StatisticsService.java    | 142 ++++++++++++++++++
 src/main/resources/application-dev.properties |   4 +
 5 files changed, 202 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/mnms/booking/controller/StatisticsController.java
 create mode 100644 src/main/java/com/mnms/booking/repository/StatisticsRepository.java
 create mode 100644 src/main/java/com/mnms/booking/service/StatisticsService.java

diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index b48ef94..0339f14 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -26,7 +26,7 @@ public class HostController {
     private final HostService hostService;
 
 
-    @GetMapping("/list")
+    @PostMapping("/list")
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
     )
diff --git a/src/main/java/com/mnms/booking/controller/StatisticsController.java b/src/main/java/com/mnms/booking/controller/StatisticsController.java
new file mode 100644
index 0000000..3fc61e0
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/StatisticsController.java
@@ -0,0 +1,39 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.service.StatisticsService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/statistics")
+@Tag(name = "통계 API", description = "공연 별 예매자의 정보를 통해 성별/나이, 입장 인원 상황을 확인 가능")
+public class StatisticsController {
+
+    private final StatisticsService statisticsService;
+
+    // 생성자 주입
+    public StatisticsController(StatisticsService statisticsService) {
+        this.statisticsService = statisticsService;
+    }
+
+    @PostMapping("/{festivalId}")
+    @Operation(summary = "feestivalId별 예매자의 성별/나이 통계 조회", description = "")
+    public ResponseEntity> getFestivalStatistics(@PathVariable String festivalId) {
+        try {
+            Map statistics = statisticsService.getFestivalStatistics(festivalId);
+            return ResponseEntity.ok(statistics);
+        } catch (Exception e) {
+            // 예외 처리 로직 추가
+            e.printStackTrace(); // 실제 서비스에서는 로깅으로 대체
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/StatisticsRepository.java b/src/main/java/com/mnms/booking/repository/StatisticsRepository.java
new file mode 100644
index 0000000..f5f44a4
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/StatisticsRepository.java
@@ -0,0 +1,16 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.Ticket;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Repository
+public interface StatisticsRepository extends JpaRepository {
+
+    @Query("SELECT t.userId FROM Ticket t WHERE t.festival.festivalId = :festivalId")
+    List findUserIdsByFestivalId(String festivalId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/StatisticsService.java b/src/main/java/com/mnms/booking/service/StatisticsService.java
new file mode 100644
index 0000000..e904b66
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/StatisticsService.java
@@ -0,0 +1,142 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.repository.StatisticsRepository;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.ParameterizedTypeReference;
+import org.springframework.stereotype.Service;
+import org.springframework.web.reactive.function.client.WebClient;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.text.DecimalFormat;
+
+@Service
+public class StatisticsService {
+    private static final Logger logger = LoggerFactory.getLogger(StatisticsService.class);
+    private final StatisticsRepository statisticsRepository;
+    private final WebClient webClient;
+    private final String userStatsListApi;
+    private static final DecimalFormat df = new DecimalFormat("0.00");
+
+    public StatisticsService(
+            StatisticsRepository statisticsRepository,
+            WebClient.Builder webClientBuilder,
+            @Value("${base.service.url}") String baseApiUrl,
+            @Value("${user.service.stats.url}") String userStatsListApi
+    ) {
+        this.statisticsRepository = statisticsRepository;
+        this.webClient = webClientBuilder.baseUrl(baseApiUrl).build();
+        this.userStatsListApi = userStatsListApi;
+    }
+
+    public Map getFestivalStatistics(String festivalId) {
+        List userIds = statisticsRepository.findUserIdsByFestivalId(festivalId);
+
+        if (userIds.isEmpty()) {
+            logger.warn("No bookings found for festival ID: {}. Returning zero statistics.", festivalId);
+            return calculateStatistics(List.of());
+        }
+
+        logger.info("Found {} user IDs for festival ID: {}", userIds.size(), festivalId);
+        logger.debug("User IDs: {}", userIds);
+
+        List> userDemographics = getUserDemographicsFromUserMSA(userIds);
+        logger.info("Received user demographics from User MSA. Count: {}", userDemographics.size());
+
+        Map statistics = calculateStatistics(userDemographics);
+
+        return statistics;
+    }
+
+    private List> getUserDemographicsFromUserMSA(List userIds) {
+        List longUserIds = userIds.stream()
+                .map(Long::valueOf)
+                .collect(Collectors.toList());
+
+        // WebClient 호출 직전 로그 추가
+        logger.info("Attempting to call User MSA API at: {}", this.userStatsListApi);
+        try {
+            return webClient.post()
+                    .uri(this.userStatsListApi)
+                    .bodyValue(longUserIds)
+                    .retrieve()
+                    .bodyToMono(new ParameterizedTypeReference>>() {})
+                    .block();
+        } catch (Exception e) {
+            // WebClient 호출 실패 시 로그 추가
+            logger.error("Failed to call User MSA API: {}", e.getMessage());
+            return List.of(); // 빈 리스트 반환하여 NullPointerException 방지
+        }
+    }
+
+    private Map calculateStatistics(List> demographics) {
+        int maleCount = 0;
+        int femaleCount = 0;
+        Map ageGroupCount = new HashMap<>();
+        Map ageGroupPercentage = new HashMap<>();
+
+        ageGroupCount.put("10대", 0);
+        ageGroupCount.put("20대", 0);
+        ageGroupCount.put("30대", 0);
+        ageGroupCount.put("40대", 0);
+        ageGroupCount.put("50대 이상", 0);
+
+        // 1. 총 인원수 계산
+        int totalPopulation = demographics.size();
+        if (totalPopulation == 0) {
+            Map result = new HashMap<>();
+            result.put("gender", Map.of("male", 0, "female", 0));
+            result.put("gender_percentage", Map.of("male", "0.00%", "female", "0.00%"));
+            result.put("age_groups", ageGroupCount);
+            ageGroupCount.forEach((key, value) -> ageGroupPercentage.put(key, "0.00%"));
+            result.put("age_group_percentage", ageGroupPercentage);
+            return result;
+        }
+
+        // 2. 카운트 계산
+        for (Map user : demographics) {
+            String gender = (String) user.get("gender");
+            Integer age = (Integer) user.get("age");
+
+            if ("MALE".equalsIgnoreCase(gender)) {
+                maleCount++;
+            } else if ("FEMALE".equalsIgnoreCase(gender)) {
+                femaleCount++;
+            }
+
+            if (age != null && age > 0) {
+                String ageGroup = getAgeGroup(age);
+                ageGroupCount.put(ageGroup, ageGroupCount.getOrDefault(ageGroup, 0) + 1);
+            }
+        }
+
+        // 3. 비율 계산 (소수점 두 자리까지)
+        String malePercentage = df.format(((double) maleCount / totalPopulation) * 100) + "%";
+        String femalePercentage = df.format(((double) femaleCount / totalPopulation) * 100) + "%";
+
+        ageGroupCount.forEach((key, value) -> {
+            String percentage = df.format(((double) value / totalPopulation) * 100) + "%";
+            ageGroupPercentage.put(key, percentage);
+        });
+
+        // 4. 최종 결과 Map 구성
+        Map result = new HashMap<>();
+        result.put("total_population", totalPopulation);
+        result.put("gender_count", Map.of("male", maleCount, "female", femaleCount));
+        result.put("gender_percentage", Map.of("male", malePercentage, "female", femalePercentage));
+        result.put("age_group_count", ageGroupCount);
+        result.put("age_group_percentage", ageGroupPercentage);
+        return result;
+    }
+
+    private String getAgeGroup(int age) {
+        if (age < 20) return "10대";
+        if (age < 30) return "20대";
+        if (age < 40) return "30대";
+        if (age < 50) return "40대";
+        return "50대 이상";
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 23a6410..3a3e4b9 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -53,5 +53,9 @@ springdoc.override-with-generic-response=false
 
 # user api
 base.service.url=${BASE_API}
+user.base.service.url=${USER_BASE_API}
 user.service.url=${USER_INFO_API}
+user.service.stats.url=${USER_STATS_LIST_API}
 booking.user.service.url=${BOOKING_USER_INFO_API}
+
+logging.level.com.mnms.booking.service=DEBUG
\ No newline at end of file

From e60f9b8fa54e0d07c10b87f5dd955c494f8e8011 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 27 Aug 2025 14:45:47 +0900
Subject: [PATCH 069/149] =?UTF-8?q?MNMS-455=20Feat:=20=EA=B3=B5=ED=86=B5?=
 =?UTF-8?q?=20=EC=96=91=EB=8F=84=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 요청
양도 요청 받기 (조회)
---
 .../controller/TransferController.java        | 33 +++++++---
 .../dto/request/TicketTransferRequestDTO.java | 13 ++++
 .../dto/request/UpdateTicketRequestDTO.java   |  5 +-
 .../response/TicketTransferResponseDTO.java   | 50 +++++++++++++++
 .../java/com/mnms/booking/entity/Ticket.java  |  7 +++
 .../com/mnms/booking/entity/Transfer.java     |  7 ++-
 .../mnms/booking/enums/TransferStatus.java    |  7 ++-
 .../com/mnms/booking/exception/ErrorCode.java |  6 +-
 .../booking/repository/TicketRepository.java  |  4 ++
 .../repository/TransferRepository.java        | 11 ++++
 .../mnms/booking/service/TransferService.java | 61 +++++++++++++++++--
 11 files changed, 185 insertions(+), 19 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
 create mode 100644 src/main/java/com/mnms/booking/repository/TransferRepository.java

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index 412eac1..bd2dbed 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -2,18 +2,23 @@
 
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.request.TicketTransferRequestDTO;
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
+import com.mnms.booking.dto.response.TicketTransferResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferService;
 import com.mnms.booking.util.ApiResponseUtil;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -28,6 +33,7 @@
 public class TransferController {
     private final OcrService ocrService;
     private final TransferService transferService;
+    private final SecurityResponseUtil securityResponseUtil;
 
     @PostMapping("/extract")
     @Operation(summary = "가족 간 양도 진행 인증 시도",
@@ -45,18 +51,31 @@ public ResponseEntity>> extractPerso
         return ApiResponseUtil.success(people, "가족관계증명서 인증이 완료되었습니다.");
     }
 
-    // 가족간 양도 요청
-    /*
-    @PostMapping("/{ticketId}")
+    // 양도 요청
+    @PostMapping("/request")
     @Operation(summary = "양도 요청",
             description = "양도자가 양도 요청 보내기"
     )
-    public ResponseEntity> updateTicket(){
-
-    }*/
+    public ResponseEntity> requestTransfer(
+            @RequestBody @Valid TicketTransferRequestDTO dto,
+            Authentication authentication
+    ){
+        transferService.requestTransfer(dto, securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(null, "티켓 양도 요청이 완료되었습니다.");
+    }
 
+    // 양도 요청 받기 (조회)
+    @GetMapping("/watch")
+    @Operation(summary = "양도 요청 조회",
+            description = "양수자가 양도 요청을 조회합니다."
+    )
+    public ResponseEntity>> watchTransfer(Authentication authentication){
+        List response = transferService.watchTransfer(securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(response);
+    }
 
-    // 가족간 양도 승인
+    // 수령 방법, 주소, 수락 완료
+    // 가족 간 양도 승인
     @PutMapping("/{ticketId}")
     @Operation(summary = "양도 완료",
             description = "양수자가 양도 요청 승인시, 양도가 완료되며 티켓과 QR 정보가 업데이트 됩니다."
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
new file mode 100644
index 0000000..53db70c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
@@ -0,0 +1,13 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Data;
+
+@Data
+public class TicketTransferRequestDTO {
+    private String reservationNumber;
+    private Long recipientId; // 양도받을 가족/지인 ID
+    private String transferType; // "FAMILY" 또는 "OTHERS"
+    private String senderName;
+    //private String receiveMethod; // 수령 방법 (예: QR, 배송)
+    //private String address;       // 필요시
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
index 5ffa0e1..3267233 100644
--- a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
@@ -8,7 +8,10 @@
 @NoArgsConstructor
 @AllArgsConstructor
 public class UpdateTicketRequestDTO {
-    private Long transfereeId; // userId에 해당함
+    private Long transferId;
+    private Long receiverId;
+    private String transferStatus;
+
     private String deliveryMethod;
     private String address;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
new file mode 100644
index 0000000..256f137
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
@@ -0,0 +1,50 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.TransferType;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class TicketTransferResponseDTO {
+
+    ///  TRANSFER
+    private String senderName;
+    private TransferType type;
+    private LocalDateTime createdAt;
+    private String status;
+
+    ///  FESTIVAL
+    private String fname;
+    private String posterFile;
+    private String fcltynm;
+    private int ticketPrice;
+
+    ///  TICKET
+    private LocalDateTime performanceDate;
+    private int selectedTicketCount;
+
+    public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, Festival festival) {
+        return TicketTransferResponseDTO.builder()
+                .senderName(transfer.getSenderName())
+                .type(transfer.getType())
+                .createdAt(transfer.getCreatedAt())
+                .status(String.valueOf(transfer.getStatus()))
+                .fname(festival.getFname())
+                .posterFile(festival.getPosterFile())
+                .fcltynm(festival.getFcltynm())
+                .ticketPrice(festival.getTicketPrice())
+                .performanceDate(ticket.getPerformanceDate())
+                .selectedTicketCount(ticket.getSelectedTicketCount())
+                .build();
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 37e5286..1322eec 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -75,4 +75,11 @@ public void updateTicketInfo(String reservationNumber,
         this.address = address;
     }
 
+    public boolean isCanceled() {
+        return reservationStatus.equals(ReservationStatus.CANCELED);
+    }
+
+    public boolean isExpired() {
+        return performanceDate.isBefore(LocalDateTime.now());
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
index f80e541..309a5d6 100644
--- a/src/main/java/com/mnms/booking/entity/Transfer.java
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -7,9 +7,9 @@
 
 import java.time.LocalDateTime;
 
+@Builder
 @Entity
 @Getter
-@Builder
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Transfer {
@@ -18,6 +18,9 @@ public class Transfer {
     private Long id;
 
     private Long senderId;
+
+    private String senderName;
+
     private Long receiverId;
 
     @Enumerated(EnumType.STRING)
@@ -25,7 +28,7 @@ public class Transfer {
 
     @Enumerated(EnumType.STRING)
     @Builder.Default
-    private TransferStatus status = TransferStatus.PENDING;
+    private TransferStatus status = TransferStatus.REQUESTED;
 
     @Builder.Default
     private LocalDateTime createdAt = LocalDateTime.now();
diff --git a/src/main/java/com/mnms/booking/enums/TransferStatus.java b/src/main/java/com/mnms/booking/enums/TransferStatus.java
index 6f98148..07be05d 100644
--- a/src/main/java/com/mnms/booking/enums/TransferStatus.java
+++ b/src/main/java/com/mnms/booking/enums/TransferStatus.java
@@ -3,7 +3,8 @@
 // 요청, 승인, 거절
 
 public enum TransferStatus {
-    PENDING,  //요청
-    APPROVED, //승인
-    REJECTED //거절
+    REQUESTED,  // 요청
+    APPROVED, // 승인
+    COMPLETED, // 완료
+    CANCELED // 취소 (거절)
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 309b541..867b8ed 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -1,6 +1,7 @@
 package com.mnms.booking.exception;
 
 import lombok.Getter;
+import org.springframework.boot.autoconfigure.graphql.GraphQlProperties;
 import org.springframework.http.HttpStatus;
 
 @Getter
@@ -30,6 +31,8 @@ public enum ErrorCode {
     TICKET_FAIL_CANCEL("T005", "티켓 취소가 실패했습니다.", HttpStatus.CONFLICT),
     TICKET_USER_NOT_SAME("T006", "사용자가 티켓 소유자가 아닙니다.", HttpStatus.FORBIDDEN),
     TICKET_ALREADY_CANCELED("T007", "티켓이 이미 예매 취소되었습니다.", HttpStatus.CONFLICT),
+    TICKET_EXPIRED("T008", "티켓의 유효기간이 만료되었습니다.", HttpStatus.CONFLICT),
+    TICKET_CANCELED("T009", "취소된 티켓입니다.", HttpStatus.CONFLICT),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
@@ -43,7 +46,8 @@ public enum ErrorCode {
     TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE),
     TRANSFER_NOT_FOUND_INFORM("TR002", "검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
     TRANSFER_NOT_FOUND_NAME("TR003", "이름 검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
-    TRANSFER_NOT_FOUND_RRN("TR003", "주민등록 번호 검사에 실패하였습니다.", HttpStatus.NOT_FOUND);
+    TRANSFER_NOT_FOUND_RRN("TR003", "주민등록 번호 검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
+    TRANSFER_NOT_EXIST("TR004", "양도 요청이 존재하지 않습니다.", HttpStatus.NOT_FOUND);
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 664d3be..bea0f45 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -76,4 +76,8 @@ int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
             "AND t.reservationStatus = :status")
     List findByFestivalIdAndReservationStatus(@Param("festivalId") String festivalId,
                                                       @Param("status") ReservationStatus status);
+
+    Optional findReservationNumber(String reservationNumber);
+
+    Optional findByUserId(Long userId);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
new file mode 100644
index 0000000..247a464
--- /dev/null
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -0,0 +1,11 @@
+package com.mnms.booking.repository;
+
+import com.mnms.booking.entity.Transfer;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface TransferRepository extends JpaRepository {
+    List findByReceiverId(Long userId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index b2e04a2..d63d1e5 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -1,44 +1,58 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.request.TicketTransferRequestDTO;
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.dto.response.TicketTransferResponseDTO;
+import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.Transfer;
 import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.enums.TransferStatus;
+import com.mnms.booking.enums.TransferType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
+import com.mnms.booking.repository.TransferRepository;
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
+import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
+import java.util.ArrayList;
 import java.util.List;
 
 @Service
 @Slf4j
 @RequiredArgsConstructor
-@Transactional
+@Transactional(readOnly = true)
 public class TransferService {
 
     private final UserApiClient userApiClient;
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
+    private final TransferRepository transferRepository;
     private final CommonUtils commonUtils;
     private final QrCodeService qrCodeService;
 
     // 가족간 양도
+    @Transactional
     public void updateFamilyTicket(Long ticketId, UpdateTicketRequestDTO request) {
+
         Ticket ticket = ticketRepository.findById(ticketId)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        // 예외 처리 하다가 멈춤
-//        if (ticket.isUsed() || ticket.isExpired() || ticket.isCanceled()) {
-//            throw new BusinessException(ErrorCode.INVALID_TICKET_STATUS);
-//        }
+        if (ticket.isExpired()) {
+            throw new BusinessException(ErrorCode.TICKET_EXPIRED);
+        }
+        if (ticket.isCanceled()) {
+            throw new BusinessException(ErrorCode.TICKET_CANCELED);
+        }
 
         TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
 
@@ -64,4 +78,41 @@ public void updateFamilyTicket(Long ticketId, UpdateTicketRequestDTO request) {
         ticket.getQrCodes().clear();
         ticket.getQrCodes().addAll(existingQrs);
     }
+
+    @Transactional
+    public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
+        Ticket ticket = ticketRepository.findReservationNumber(dto.getReservationNumber())
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        if(!ticket.getUserId().equals(userId)){
+            throw new BusinessException(ErrorCode.TICKET_USER_NOT_SAME);
+        }
+
+        Transfer transfer = Transfer.builder()
+                .senderId(userId)
+                .senderName(dto.getSenderName())
+                .receiverId(dto.getRecipientId())
+                .type("OTHERS".equals(dto.getTransferType()) ? TransferType.OTHERS : TransferType.FAMILY)
+                .status(TransferStatus.REQUESTED)
+                .build();
+
+        transferRepository.save(transfer);
+    }
+
+    public List watchTransfer(Long userId) {
+        List transfers = transferRepository.findByReceiverId(userId);
+
+        if (transfers.isEmpty()) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_EXIST);
+        }
+
+        return transfers.stream()
+                .map(transfer -> {
+                    Ticket ticket = ticketRepository.findByUserId(transfer.getSenderId())
+                            .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+                    Festival festival = ticket.getFestival();
+                    return TicketTransferResponseDTO.from(transfer, ticket, festival);
+                })
+                .toList();
+    }
 }

From acd332c9382170519fe22d9376aed3f8359e5ad7 Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Thu, 28 Aug 2025 10:56:48 +0900
Subject: [PATCH 070/149] =?UTF-8?q?MNMS-511=20Story:=20=EA=B3=B5=EC=97=B0-?=
 =?UTF-8?q?=EA=B3=B5=EC=97=B0=EC=8B=9C=EC=9E=91=EB=82=A0=EC=A7=9C=EC=8B=9C?=
 =?UTF-8?q?=EA=B0=84=20=EB=B3=84=20=EC=9E=85=EC=A0=95=20=EC=9D=B8=EC=9B=90?=
 =?UTF-8?q?=20=ED=98=84=ED=99=A9=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5?=
 =?UTF-8?q?=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/StatisticsController.java      | 50 ++++++++++-------
 .../repository/FestivalRepository.java        |  3 +
 .../booking/repository/QrCodeRepository.java  |  7 +++
 .../booking/repository/TicketRepository.java  |  4 ++
 .../service/StatisticsQrCodeService.java      | 55 +++++++++++++++++++
 ...ervice.java => StatisticsUserService.java} |  6 +-
 6 files changed, 103 insertions(+), 22 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
 rename src/main/java/com/mnms/booking/service/{StatisticsService.java => StatisticsUserService.java} (98%)

diff --git a/src/main/java/com/mnms/booking/controller/StatisticsController.java b/src/main/java/com/mnms/booking/controller/StatisticsController.java
index 3fc61e0..0557af6 100644
--- a/src/main/java/com/mnms/booking/controller/StatisticsController.java
+++ b/src/main/java/com/mnms/booking/controller/StatisticsController.java
@@ -1,15 +1,17 @@
 package com.mnms.booking.controller;
 
-import com.mnms.booking.service.StatisticsService;
+import com.mnms.booking.service.StatisticsUserService;
+import com.mnms.booking.service.StatisticsQrCodeService;
+import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import org.springframework.http.HttpStatus;
+import lombok.RequiredArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.*;
 
+import java.time.LocalDateTime;
 import java.util.Map;
 
 @RestController
@@ -17,23 +19,33 @@
 @Tag(name = "통계 API", description = "공연 별 예매자의 정보를 통해 성별/나이, 입장 인원 상황을 확인 가능")
 public class StatisticsController {
 
-    private final StatisticsService statisticsService;
+    private final StatisticsUserService statisticsUserService;
+    private final StatisticsQrCodeService statisticsQrCodeService;
 
-    // 생성자 주입
-    public StatisticsController(StatisticsService statisticsService) {
-        this.statisticsService = statisticsService;
+    public StatisticsController(StatisticsUserService statisticsUserService, StatisticsQrCodeService statisticsQrCodeService) {
+        this.statisticsUserService = statisticsUserService;
+        this.statisticsQrCodeService = statisticsQrCodeService;
     }
 
     @PostMapping("/{festivalId}")
-    @Operation(summary = "feestivalId별 예매자의 성별/나이 통계 조회", description = "")
+    @Operation(summary = "feestivalId별 예매자의 성별/나이 통계 조회", description = "특정 페스티벌의 예매자 통계를 조회합니다.")
     public ResponseEntity> getFestivalStatistics(@PathVariable String festivalId) {
-        try {
-            Map statistics = statisticsService.getFestivalStatistics(festivalId);
-            return ResponseEntity.ok(statistics);
-        } catch (Exception e) {
-            // 예외 처리 로직 추가
-            e.printStackTrace(); // 실제 서비스에서는 로깅으로 대체
-            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
-        }
+        Map statistics = statisticsUserService.getFestivalStatistics(festivalId);
+        return ResponseEntity.ok(statistics);
+    }
+
+    @GetMapping("/{festivalId}/performance-date/attendance")
+    @Operation(summary = "공연 날짜별 입장 통계", description = "예매자 및 주최자가 자신의 공연 날짜별 입장 통계를 조회합니다.")
+    public ResponseEntity> getPerformanceAttendanceStatistics(
+            @PathVariable String festivalId,
+            @RequestParam("performanceDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime performanceDate,
+            Authentication authentication) {
+
+        String userId = authentication.getName();
+        boolean isHost = authentication.getAuthorities().stream()
+                .anyMatch(a -> a.getAuthority().equals("ROLE_HOST"));
+
+        Map statistics = statisticsQrCodeService.getPerformanceAttendanceStatistics(festivalId, performanceDate, userId, isHost);
+        return ResponseEntity.ok(statistics);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/FestivalRepository.java b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
index 163d081..c80b57e 100644
--- a/src/main/java/com/mnms/booking/repository/FestivalRepository.java
+++ b/src/main/java/com/mnms/booking/repository/FestivalRepository.java
@@ -11,4 +11,7 @@
 public interface FestivalRepository extends JpaRepository {
     Optional findByFestivalId(String festivalId);
     List findByFestivalIdAndOrganizer(String festivalId , Long organizer);
+
+    // festivalId와 organizer(userId)가 일치하는 엔티티가 존재하는지 확인
+    boolean existsByFestivalIdAndOrganizer(String festivalId, Long organizer);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index a944c02..a537017 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -2,9 +2,12 @@
 
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
+import io.lettuce.core.dynamic.annotation.Param;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
+import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
 
@@ -14,6 +17,10 @@ public interface QrCodeRepository extends JpaRepository {
     Optional findByQrCodeId(String qrCodeId);
     Boolean existsByQrCodeId(String qrCodeId);
     Optional> findByTicketId(Long ticketId);
+
+    // 특정 페스티벌의 특정 공연 날짜에 입장(used=true)한 인원 수를 집계
+    @Query("SELECT COUNT(q) FROM QrCode q JOIN q.ticket t WHERE q.used = true AND t.festival.festivalId = :festivalId AND t.performanceDate = :performanceDate")
+    int countAdmittedAttendees(@Param("festivalId") String festivalId, @Param("performanceDate") LocalDateTime performanceDate);;
 }
 
 
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 664d3be..1356277 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -76,4 +76,8 @@ int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
             "AND t.reservationStatus = :status")
     List findByFestivalIdAndReservationStatus(@Param("festivalId") String festivalId,
                                                       @Param("status") ReservationStatus status);
+
+    // userId와 festivalId가 일치하는 티켓이 존재하는지 확인
+    @Query("SELECT CASE WHEN COUNT(t) > 0 THEN true ELSE false END FROM Ticket t WHERE t.userId = :userId AND t.festival.festivalId = :festivalId")
+    boolean existsByUserIdAndFestivalId(@Param("userId") Long userId, @Param("festivalId") String festivalId);
 }
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
new file mode 100644
index 0000000..907638f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
@@ -0,0 +1,55 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.AccessDeniedException;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+@Service
+@RequiredArgsConstructor
+public class StatisticsQrCodeService {
+
+    private final QrCodeRepository qrCodeRepository;
+    private final FestivalRepository festivalRepository;
+    private final TicketRepository ticketRepository;
+
+    public Map getPerformanceAttendanceStatistics(String festivalId, LocalDateTime performanceDate, String userId, boolean isHost) {
+
+        Long longUserId = Long.valueOf(userId);
+
+        // 1. 접근 권한 검증
+        if (isHost) {
+            boolean isOwner = festivalRepository.existsByFestivalIdAndOrganizer(festivalId, longUserId);
+            if (!isOwner) {
+                throw new AccessDeniedException("이 공연의 통계 정보에 접근할 권한이 없습니다.");
+            }
+        } else {
+            boolean hasTicket = ticketRepository.existsByUserIdAndFestivalId(longUserId, festivalId);
+            if (!hasTicket) {
+                throw new AccessDeniedException("이 공연의 통계 정보에 접근할 권한이 없습니다.");
+            }
+        }
+
+        // 2. 통계 로직
+        Optional festivalOpt = festivalRepository.findByFestivalId(festivalId);
+        int capacity = festivalOpt.map(Festival::getAvailableNOP).orElse(0);
+
+        int admittedCount = qrCodeRepository.countAdmittedAttendees(festivalId, performanceDate);
+
+        Map statistics = new HashMap<>();
+        statistics.put("festivalId", festivalId);
+        statistics.put("performanceDate", performanceDate);
+        statistics.put("capacity", capacity);
+        statistics.put("admittedCount", admittedCount);
+
+        return statistics;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/StatisticsService.java b/src/main/java/com/mnms/booking/service/StatisticsUserService.java
similarity index 98%
rename from src/main/java/com/mnms/booking/service/StatisticsService.java
rename to src/main/java/com/mnms/booking/service/StatisticsUserService.java
index e904b66..44d52c9 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsUserService.java
@@ -14,14 +14,14 @@
 import java.text.DecimalFormat;
 
 @Service
-public class StatisticsService {
-    private static final Logger logger = LoggerFactory.getLogger(StatisticsService.class);
+public class StatisticsUserService {
+    private static final Logger logger = LoggerFactory.getLogger(StatisticsUserService.class);
     private final StatisticsRepository statisticsRepository;
     private final WebClient webClient;
     private final String userStatsListApi;
     private static final DecimalFormat df = new DecimalFormat("0.00");
 
-    public StatisticsService(
+    public StatisticsUserService(
             StatisticsRepository statisticsRepository,
             WebClient.Builder webClientBuilder,
             @Value("${base.service.url}") String baseApiUrl,

From d46062bdaf02876188146292d085fd08c730bc90 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 28 Aug 2025 15:02:44 +0900
Subject: [PATCH 071/149] =?UTF-8?q?MNMS-455=20Feat:=20=EC=96=91=EB=8F=84?=
 =?UTF-8?q?=20=EC=8A=B9=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EC=99=84=EB=A3=8C?=
 =?UTF-8?q?=20=EB=B0=8F=20=EC=A3=BC=EC=B5=9C=EC=B8=A1=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=EC=9E=90=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 : (공통) 양도 요청, 지인 양도 승인, 가족 양도 승인 [Feat]
양도 : 가족관계증명서 인증 수정 [Chore]
주최측 예매자 리스트 조회 : 예매자 디테일 조회 - posterFile 추가 [Chore]
---
 .../booking/controller/HostController.java    |   3 +-
 .../controller/TransferController.java        |  37 ++--
 .../dto/request/UpdateTicketRequestDTO.java   |   8 +-
 .../dto/response/TicketDetailResponseDTO.java |   2 +
 .../response/TicketTransferResponseDTO.java   |   2 +
 .../response/TransferOthersResponseDTO.java   |  24 ++
 .../com/mnms/booking/entity/Transfer.java     |   8 +-
 .../com/mnms/booking/exception/ErrorCode.java |   5 +-
 .../booking/repository/TicketRepository.java  |   4 +-
 .../repository/TransferRepository.java        |   1 +
 .../booking/service/OcrParserService.java     |   3 +-
 .../mnms/booking/service/TransferService.java | 208 ++++++++++++++----
 12 files changed, 238 insertions(+), 67 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java

diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index c685d91..4a7bfb8 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -27,8 +27,7 @@ public class HostController {
     private final SecurityResponseUtil securityResponseUtil;
     private final HostService hostService;
 
-
-    @GetMapping("/list")
+    @PostMapping("/list")
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
     )
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index bd2dbed..b0af3ce 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -6,6 +6,7 @@
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
+import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
@@ -35,6 +36,8 @@ public class TransferController {
     private final TransferService transferService;
     private final SecurityResponseUtil securityResponseUtil;
 
+
+    ///  가족 인증
     @PostMapping("/extract")
     @Operation(summary = "가족 간 양도 진행 인증 시도",
             description = "가족관계증명서 pdf를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
@@ -51,7 +54,7 @@ public ResponseEntity>> extractPerso
         return ApiResponseUtil.success(people, "가족관계증명서 인증이 완료되었습니다.");
     }
 
-    // 양도 요청
+    /// 양도 요청
     @PostMapping("/request")
     @Operation(summary = "양도 요청",
             description = "양도자가 양도 요청 보내기"
@@ -64,7 +67,7 @@ public ResponseEntity> requestTransfer(
         return ApiResponseUtil.success(null, "티켓 양도 요청이 완료되었습니다.");
     }
 
-    // 양도 요청 받기 (조회)
+    /// 양도 요청 받기 (조회)
     @GetMapping("/watch")
     @Operation(summary = "양도 요청 조회",
             description = "양수자가 양도 요청을 조회합니다."
@@ -74,19 +77,27 @@ public ResponseEntity>> watchTra
         return ApiResponseUtil.success(response);
     }
 
-    // 수령 방법, 주소, 수락 완료
-    // 가족 간 양도 승인
-    @PutMapping("/{ticketId}")
-    @Operation(summary = "양도 완료",
-            description = "양수자가 양도 요청 승인시, 양도가 완료되며 티켓과 QR 정보가 업데이트 됩니다."
+    /// 가족 간 양도 요청 승인
+    @PutMapping("/acceptance/family")
+    @Operation(summary = "가족 간 양도 요청 수락",
+            description = "가족 간 양도 요청 시, 양수자가 요청을 수락하면 양도가 완료되며 티켓과 QR 정보가 업데이트 됩니다."
     )
-    public ResponseEntity> updateTicket(
-            @PathVariable Long ticketId,
-            @RequestBody UpdateTicketRequestDTO request) {
-        transferService.updateFamilyTicket(ticketId, request);
+    public ResponseEntity> responseTicketFamily(
+            @RequestBody UpdateTicketRequestDTO request,
+            Authentication authentication) {
+        transferService.updateFamilyTicket(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(null, "티켓 양도가 성공적으로 진행되었습니다.");
     }
 
-    // 지인간 양도 승인
-
+    /// 지인간 양도 요청 승인
+    @PutMapping("/acceptance/others")
+    @Operation(summary = "타인 간 양도 요청 완료",
+            description = "타인 간 양도 요청 시, 양수자가 요청을 수락하면 결제 요청이 넘어가게 됩니다."
+    )
+    public ResponseEntity> responseTicketOthers(
+            @RequestBody UpdateTicketRequestDTO request,
+            Authentication authentication) {
+            TransferOthersResponseDTO response = transferService.proceedOthersTicket(request, securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(response);
+    }
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
index 3267233..9166339 100644
--- a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
@@ -1,5 +1,7 @@
 package com.mnms.booking.dto.request;
 
+import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.enums.TransferStatus;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
@@ -9,9 +11,13 @@
 @AllArgsConstructor
 public class UpdateTicketRequestDTO {
     private Long transferId;
-    private Long receiverId;
+    private Long senderId;
     private String transferStatus;
 
     private String deliveryMethod;
     private String address;
+
+    public TransferStatus getTransferStatusEnum() {
+        return TransferStatus.valueOf(this.transferStatus);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index 4586de5..7a1fe16 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -21,6 +21,7 @@ public class TicketDetailResponseDTO {
     private TicketType deliveryMethod; // 티켓 수령 방법
     private List qrId;
     private String address;
+    private String posterFile;
 
     // festival
     private String fname; // 공연명
@@ -40,6 +41,7 @@ public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festiva
                 .qrId(qrIds)
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
+                .posterFile(festival.getPosterFile())
                 .build();
     }
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
index 256f137..1cb97d4 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
@@ -18,6 +18,7 @@
 public class TicketTransferResponseDTO {
 
     ///  TRANSFER
+    private Long senderId;
     private String senderName;
     private TransferType type;
     private LocalDateTime createdAt;
@@ -35,6 +36,7 @@ public class TicketTransferResponseDTO {
 
     public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, Festival festival) {
         return TicketTransferResponseDTO.builder()
+                .senderId(transfer.getSenderId())
                 .senderName(transfer.getSenderName())
                 .type(transfer.getType())
                 .createdAt(transfer.getCreatedAt())
diff --git a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
new file mode 100644
index 0000000..e7cb863
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
@@ -0,0 +1,24 @@
+package com.mnms.booking.dto.response;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+// 지인 간 결제 시 반환할 내용
+
+@Data
+@Builder
+public class TransferOthersResponseDTO {
+    private Long receiverId; // 양수자 id
+
+    private Long senderId; // 양도자 id
+
+    private String reservationNumber;
+    private int selectedTicketCount; // 티켓 개수
+    private LocalDateTime performanceDate;
+
+    private int ticketPrice;
+    private String fname;
+    private String posterFile;
+}
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
index 309a5d6..4884898 100644
--- a/src/main/java/com/mnms/booking/entity/Transfer.java
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -10,6 +10,7 @@
 @Builder
 @Entity
 @Getter
+@ToString
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 public class Transfer {
@@ -23,10 +24,13 @@ public class Transfer {
 
     private Long receiverId;
 
-    @Enumerated(EnumType.STRING)
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "ticket_id", nullable = false)
+    private Ticket ticket;
+
     private TransferType type;
 
-    @Enumerated(EnumType.STRING)
+    @Setter
     @Builder.Default
     private TransferStatus status = TransferStatus.REQUESTED;
 
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 867b8ed..4f3fc11 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -47,7 +47,10 @@ public enum ErrorCode {
     TRANSFER_NOT_FOUND_INFORM("TR002", "검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
     TRANSFER_NOT_FOUND_NAME("TR003", "이름 검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
     TRANSFER_NOT_FOUND_RRN("TR003", "주민등록 번호 검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
-    TRANSFER_NOT_EXIST("TR004", "양도 요청이 존재하지 않습니다.", HttpStatus.NOT_FOUND);
+    TRANSFER_NOT_EXIST("TR004", "양도 요청이 존재하지 않습니다.", HttpStatus.NOT_FOUND),
+    TRANSFER_NOT_MATCH_RECEIVER("TR005", "양도 승인하는 양수자가 맞지 않습니다.", HttpStatus.BAD_REQUEST),
+    TRANSFER_NOT_MATCH_TYPE("TR006", "양도 타입이 맞지 않습니다.", HttpStatus.BAD_REQUEST),
+    TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT);
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index bea0f45..0c5af98 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -77,7 +77,5 @@ int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
     List findByFestivalIdAndReservationStatus(@Param("festivalId") String festivalId,
                                                       @Param("status") ReservationStatus status);
 
-    Optional findReservationNumber(String reservationNumber);
-
-    Optional findByUserId(Long userId);
+    Optional> findByUserId(Long userId);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index 247a464..9fb90ea 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -8,4 +8,5 @@
 
 public interface TransferRepository extends JpaRepository {
     List findByReceiverId(Long userId);
+    Optional findById(Long id);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index 60d4eed..3cd83ab 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -50,7 +50,8 @@ private static PersonInfoResponseDTO matchPersonInfo(
         String normalizedNamePattern = "\\b" + Pattern.quote(name.replaceAll("\\s", "")) + "\\b";
 
         String matchedName = ocrTexts.stream()
-                .map(t -> t.replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
+                .map(t -> t.replaceAll("\\([^)]*\\)", "")
+                        .replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
                 .filter(t -> t.matches(".*" + normalizedNamePattern + ".*"))
                 .findFirst()
                 .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME));
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index d63d1e5..42011dd 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -3,6 +3,7 @@
 import com.mnms.booking.dto.request.TicketTransferRequestDTO;
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
+import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
@@ -16,15 +17,14 @@
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.repository.TransferRepository;
 import com.mnms.booking.util.CommonUtils;
-import com.mnms.booking.util.UserApiClient;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.expression.ExpressionException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
-import java.util.ArrayList;
 import java.util.List;
 
 @Service
@@ -33,55 +33,17 @@
 @Transactional(readOnly = true)
 public class TransferService {
 
-    private final UserApiClient userApiClient;
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
     private final TransferRepository transferRepository;
     private final CommonUtils commonUtils;
     private final QrCodeService qrCodeService;
 
-    // 가족간 양도
-    @Transactional
-    public void updateFamilyTicket(Long ticketId, UpdateTicketRequestDTO request) {
-
-        Ticket ticket = ticketRepository.findById(ticketId)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
-        if (ticket.isExpired()) {
-            throw new BusinessException(ErrorCode.TICKET_EXPIRED);
-        }
-        if (ticket.isCanceled()) {
-            throw new BusinessException(ErrorCode.TICKET_CANCELED);
-        }
-
-        TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
-
-        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
-
-        // ticket 업데이트
-        ticket.updateTicketInfo(
-                commonUtils.generateReservationNumber(),
-                deliveryMethod,
-                request.getTransfereeId(),
-                LocalDate.now(),
-                request.getAddress()
-        );
-
-        // qr code 업데이트
-        existingQrs.forEach(qr -> {
-            qr.setQrCodeId(qrCodeService.generateQrCodeId());
-            qr.setUserId(request.getTransfereeId());
-            qr.setTicket(ticket);
-        });
-
-        ticket.getQrCodes().clear();
-        ticket.getQrCodes().addAll(existingQrs);
-    }
 
+    ///  양도 요청
     @Transactional
     public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
-        Ticket ticket = ticketRepository.findReservationNumber(dto.getReservationNumber())
+        Ticket ticket = ticketRepository.findByReservationNumber(dto.getReservationNumber())
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
         if(!ticket.getUserId().equals(userId)){
@@ -89,6 +51,7 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
         }
 
         Transfer transfer = Transfer.builder()
+                .ticket(ticket)
                 .senderId(userId)
                 .senderName(dto.getSenderName())
                 .receiverId(dto.getRecipientId())
@@ -99,6 +62,7 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
         transferRepository.save(transfer);
     }
 
+    ///  양도 요청 조회
     public List watchTransfer(Long userId) {
         List transfers = transferRepository.findByReceiverId(userId);
 
@@ -106,13 +70,169 @@ public List watchTransfer(Long userId) {
             throw new BusinessException(ErrorCode.TRANSFER_NOT_EXIST);
         }
 
+        transfers.forEach(transfer -> log.info("transfer: {}", transfer));
+
         return transfers.stream()
                 .map(transfer -> {
-                    Ticket ticket = ticketRepository.findByUserId(transfer.getSenderId())
-                            .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+                    Ticket ticket = transfer.getTicket();
+                    if(ticket==null) throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
                     Festival festival = ticket.getFestival();
+                    if(festival==null) throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
                     return TicketTransferResponseDTO.from(transfer, ticket, festival);
                 })
                 .toList();
     }
+
+
+    ///  양도 수락
+    /// 가족 간 양도 수락
+    @Transactional
+    public void updateFamilyTicket(UpdateTicketRequestDTO request, Long userId) {
+        Transfer transfer = getTransferOrThrow(request.getTransferId());
+
+        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
+
+        if(!transfer.getType().equals(TransferType.FAMILY)){
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
+        }
+        validateReceiver(transfer, userId);
+
+        // CANCELED 처리
+        if (request.getTransferStatusEnum() == TransferStatus.CANCELED) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return;
+        }
+
+        // ticket 점검
+        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
+        validateTicketStatus(ticket);
+
+        // transfer 상태 업데이트
+        transfer.setStatus(TransferStatus.COMPLETED);
+
+        // ticket 정보 업데이트
+        updateTicketInfo(ticket, request, userId);
+
+        // QR 코드 업데이트
+        updateQrCodes(ticket, request, userId);
+    }
+
+    /// 지인 간 양도 요청 수락
+    @Transactional
+    public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO request, Long userId) {
+
+        Transfer transfer = getTransferOrThrow(request.getTransferId());
+        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
+
+        if(!transfer.getType().equals(TransferType.OTHERS)){
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
+        }
+
+        String reservationNumber = transfer.getTicket().getReservationNumber();
+        validateReceiver(transfer, userId);
+
+        // CANCELED 처리
+        if (request.getTransferStatusEnum() == TransferStatus.CANCELED) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return TransferOthersResponseDTO.builder()
+                    .reservationNumber(reservationNumber)
+                    .senderId(transfer.getSenderId())
+                    .receiverId(userId)
+                    .build();
+        }
+
+        Ticket ticket = getTicketOrThrow(reservationNumber);
+        validateTicketStatus(ticket);
+        Festival festival = ticket.getFestival();
+
+        // transfer 업데이트
+        transfer.setStatus(TransferStatus.APPROVED);
+
+        return TransferOthersResponseDTO.builder()
+                .reservationNumber(ticket.getReservationNumber())
+                .senderId(transfer.getSenderId())
+                .receiverId(userId)
+                .selectedTicketCount(ticket.getSelectedTicketCount())
+                .ticketPrice(festival.getTicketPrice())
+                .fname(festival.getFname())
+                .posterFile(festival.getPosterFile())
+                .performanceDate(ticket.getPerformanceDate())
+                .build();
+    }
+
+
+    /// 결제 KAFKA 구독 메시지 받고 결제 완료 수행
+    @Transactional
+    public void updateOthersTicket(UpdateTicketRequestDTO request, Long receiverId) {
+        Transfer transfer = getTransferOrThrow(request.getTransferId());
+
+        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
+        validateTicketStatus(ticket);
+
+        transfer.setStatus(TransferStatus.COMPLETED);
+
+        updateTicketInfo(ticket, request, receiverId);
+        updateQrCodes(ticket, request, receiverId);
+    }
+
+
+    /// UTIL
+    private void validateSenderId(Long senderId, Long ticketUserId) {
+        if (!senderId.equals(ticketUserId)) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_SENDER);
+        }
+    }
+
+    private void validateReceiver(Transfer transfer, Long userId){
+        // 양수자 확인
+        if (!userId.equals(transfer.getReceiverId())){
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_RECEIVER);
+        }
+    }
+    private Transfer getTransferOrThrow(Long transferId) {
+        return transferRepository.findById(transferId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_EXIST));
+    }
+
+    private Ticket getTicketOrThrow(String reservationNumber) {
+        return ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    private void validateTicketStatus(Ticket ticket) {
+        if (ticket.isExpired()) {
+            throw new BusinessException(ErrorCode.TICKET_EXPIRED);
+        }
+        if (ticket.isCanceled()) {
+            throw new BusinessException(ErrorCode.TICKET_CANCELED);
+        }
+    }
+
+    /// ticket 정보 업데이트
+    private void updateTicketInfo(Ticket ticket, UpdateTicketRequestDTO request, Long receiverId) {
+        TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
+
+        ticket.updateTicketInfo(
+                commonUtils.generateReservationNumber(),
+                deliveryMethod,
+                receiverId,
+                LocalDate.now(),
+                request.getAddress()
+        );
+    }
+
+    /// qr 정보 업데이트
+    private void updateQrCodes(Ticket ticket, UpdateTicketRequestDTO request,  Long receiverId) {
+        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
+
+        existingQrs.forEach(qr -> {
+            qr.setQrCodeId(qrCodeService.generateQrCodeId());
+            qr.setUserId(receiverId);
+            qr.setTicket(ticket);
+        });
+
+        ticket.getQrCodes().clear();
+        ticket.getQrCodes().addAll(existingQrs);
+    }
 }

From c101c29acd6f20ba5f60491da436b36ca8803675 Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Thu, 28 Aug 2025 15:35:38 +0900
Subject: [PATCH 072/149] =?UTF-8?q?MNMS-524=20Story:=20=EC=A3=BC=EC=B5=9C?=
 =?UTF-8?q?=EC=9E=90=EB=8A=94=20=EA=B3=B5=EC=97=B0=EC=9D=98=20=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=EC=9E=90=20=EC=88=98=20/=20=EC=88=98=EC=9A=A9?=
 =?UTF-8?q?=EC=9D=B8=EC=9B=90=EC=9D=84=20=ED=99=95=EC=9D=B8=20=EA=B8=B0?=
 =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/StatisticsController.java      | 19 +++++++
 .../dto/response/StatisticsBookingDTO.java    | 24 +++++++++
 .../service/StatisticsQueryService.java       | 52 +++++++++++++++++++
 3 files changed, 95 insertions(+)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java

diff --git a/src/main/java/com/mnms/booking/controller/StatisticsController.java b/src/main/java/com/mnms/booking/controller/StatisticsController.java
index fb549d0..0aeadd9 100644
--- a/src/main/java/com/mnms/booking/controller/StatisticsController.java
+++ b/src/main/java/com/mnms/booking/controller/StatisticsController.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.controller;
 
+import com.mnms.booking.dto.response.StatisticsBookingDTO;
 import com.mnms.booking.dto.response.StatisticsQrCodeResponseDTO;
 import com.mnms.booking.dto.response.StatisticsUserResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
@@ -66,4 +67,22 @@ public ResponseEntity> getPerforman
 
         return ApiResponseUtil.success(statistics, "공연 입장 통계 정보가 성공적으로 조회되었습니다.");
     }
+
+    @GetMapping("/booking/{festivalId}")
+    @Operation(summary = "공연별 예매자 수 / 수용 인원 요약 조회",
+            description = "주최자가 자신의 페스티벌에 대한 각 공연(날짜/시간)별 예매 현황과 총 수용 인원을 요약하여 조회합니다.")
+    public ResponseEntity>> getBookingSummary(
+            @PathVariable String festivalId,
+            Authentication authentication) {
+
+        String userId = authentication.getName();
+        boolean isAdmin = authentication.getAuthorities().stream()
+                .anyMatch(a -> a.getAuthority().equals("ROLE_ADMIN"));
+
+        statisticsQueryService.validateHostOrAdminAccess(festivalId, userId, isAdmin);
+
+        List summary = statisticsQueryService.getBookingSummary(festivalId);
+
+        return ApiResponseUtil.success(summary, "공연 요약 정보가 성공적으로 조회되었습니다.");
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java b/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java
new file mode 100644
index 0000000..4d0de1d
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java
@@ -0,0 +1,24 @@
+package com.mnms.booking.dto.response;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.time.LocalDateTime;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@Schema(description = "공연 날짜별 예매 현황 및 수용 인원 정보 DTO")
+public class StatisticsBookingDTO {
+
+    @Schema(description = "공연 날짜 및 시간", example = "2025-09-01T19:00:00")
+    private LocalDateTime performanceDate;
+
+    @Schema(description = "해당 공연의 총 예매자 수", example = "150")
+    private int bookingCount;
+
+    @Schema(description = "해당 페스티벌의 총 수용 인원", example = "500")
+    private int availableNOP;
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
index 832f54e..4e3d41c 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
@@ -1,19 +1,40 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.response.StatisticsBookingDTO;
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 @Service
 @RequiredArgsConstructor
 public class StatisticsQueryService {
 
     private final TicketRepository ticketRepository;
+    private final FestivalRepository festivalRepository;
+
+    public void validateHostOrAdminAccess(String festivalId, String userId, boolean isAdmin) {
+        if (isAdmin) {
+            return;
+        }
+        Long longUserId;
+        try {
+            longUserId = Long.valueOf(userId);
+        } catch (NumberFormatException e) {
+            throw new BusinessException(ErrorCode.USER_INVALID);
+        }
+        if (!festivalRepository.existsByFestivalIdAndOrganizer(festivalId, longUserId)) {
+            throw new BusinessException(ErrorCode.STATISTICS_ACCESS_DENIED);
+        }
+    }
 
     public List getPerformanceDatesByFestivalId(String festivalId) {
         List performanceDates = ticketRepository.findDistinctPerformanceDateByFestivalId(festivalId);
@@ -22,4 +43,35 @@ public List getPerformanceDatesByFestivalId(String festivalId) {
         }
         return performanceDates;
     }
+
+    public List getBookingSummary(String festivalId) {
+        int availableCapacity = festivalRepository.findByFestivalId(festivalId)
+                .map(festival -> festival.getAvailableNOP())
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+
+        List allTickets = ticketRepository.findByFestivalId(festivalId);
+
+        if (allTickets.isEmpty()) {
+            throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
+        }
+
+        Map bookedCounts = allTickets.stream()
+                .collect(Collectors.groupingBy(
+                        ticket -> ticket.getPerformanceDate(),
+                        Collectors.summingLong(Ticket::getSelectedTicketCount)
+                ));
+
+        List performanceDates = allTickets.stream()
+                .map(Ticket::getPerformanceDate)
+                .distinct()
+                .collect(Collectors.toList());
+
+        return performanceDates.stream()
+                .map(date -> new StatisticsBookingDTO(
+                        date,
+                        bookedCounts.getOrDefault(date, 0L).intValue(),
+                        availableCapacity
+                ))
+                .collect(Collectors.toList());
+    }
 }
\ No newline at end of file

From 66ef7204d213b3195b72e663d78b21e4e9a61dd1 Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Fri, 29 Aug 2025 12:57:20 +0900
Subject: [PATCH 073/149] =?UTF-8?q?MNMS-524=20Bug:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=EC=9E=90=EC=88=98=20=EC=A7=91=EA=B3=84=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dto/response/StatisticsBookingDTO.java    |  2 +-
 .../booking/repository/TicketRepository.java  |  8 ++++++
 .../service/StatisticsQueryService.java       | 28 ++++++-------------
 3 files changed, 17 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java b/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java
index 4d0de1d..871ba2d 100644
--- a/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/StatisticsBookingDTO.java
@@ -17,7 +17,7 @@ public class StatisticsBookingDTO {
     private LocalDateTime performanceDate;
 
     @Schema(description = "해당 공연의 총 예매자 수", example = "150")
-    private int bookingCount;
+    private Long bookingCount;
 
     @Schema(description = "해당 페스티벌의 총 수용 인원", example = "500")
     private int availableNOP;
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 09c09ed..cbb3003 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.repository;
 
+import com.mnms.booking.dto.response.StatisticsBookingDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.ReservationStatus;
@@ -84,4 +85,11 @@ List findByFestivalIdAndReservationStatus(@Param("festivalId") String fe
     // 특정 festivalId에 대한 유효한 공연 날짜-시간을 모두 조회
     @Query("SELECT DISTINCT t.performanceDate FROM Ticket t WHERE t.festival.festivalId = :festivalId")
     List findDistinctPerformanceDateByFestivalId(@Param("festivalId") String festivalId);
+
+    @Query("SELECT new com.mnms.booking.dto.response.StatisticsBookingDTO(" +
+            "t.performanceDate, SUM(t.selectedTicketCount), 0) " +
+            "FROM Ticket t " +
+            "WHERE t.festival.festivalId = :festivalId AND t.reservationStatus = :status " +
+            "GROUP BY t.performanceDate")
+    List findBookedSummary(String festivalId, ReservationStatus status);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
index 4e3d41c..560ad4e 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.dto.response.StatisticsBookingDTO;
 import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.FestivalRepository;
@@ -10,6 +11,7 @@
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -49,29 +51,15 @@ public List getBookingSummary(String festivalId) {
                 .map(festival -> festival.getAvailableNOP())
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
-        List allTickets = ticketRepository.findByFestivalId(festivalId);
+        // 유효한 티켓을 가져오는 올바른 방법
+        List bookingSummary = ticketRepository.findBookedSummary(festivalId, ReservationStatus.CONFIRMED);
 
-        if (allTickets.isEmpty()) {
-            throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
+        if (bookingSummary.isEmpty()) {
+            return new ArrayList<>();
         }
 
-        Map bookedCounts = allTickets.stream()
-                .collect(Collectors.groupingBy(
-                        ticket -> ticket.getPerformanceDate(),
-                        Collectors.summingLong(Ticket::getSelectedTicketCount)
-                ));
-
-        List performanceDates = allTickets.stream()
-                .map(Ticket::getPerformanceDate)
-                .distinct()
-                .collect(Collectors.toList());
+        bookingSummary.forEach(dto -> dto.setAvailableNOP(availableCapacity));
 
-        return performanceDates.stream()
-                .map(date -> new StatisticsBookingDTO(
-                        date,
-                        bookedCounts.getOrDefault(date, 0L).intValue(),
-                        availableCapacity
-                ))
-                .collect(Collectors.toList());
+        return bookingSummary;
     }
 }
\ No newline at end of file

From 1205cca90a7f53cd5eb4e13731309172ca45ac91 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 13:01:24 +0900
Subject: [PATCH 074/149] =?UTF-8?q?MNMS-454=20Feat&Chore&Refactor=20:=20?=
 =?UTF-8?q?=EC=A7=80=EC=9D=B8=20=EC=96=91=EB=8F=84=20=EC=BD=94=EB=93=9C=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20ocr=20=EC=9E=84=EC=8B=9C=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A6=AC=ED=8C=A9=ED=86=A0?=
 =?UTF-8?q?=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

지인 양도 코드 추가 : 결제 kafka 구독 (테스트 미완)
양도 리팩토링 진행 중
ocr 임시 수정 : ocr parser 문제 임시 수정 (조건 느슨하게 수정)
---
 .../controller/TransferController.java        |   6 +-
 .../dto/request/TicketTransferRequestDTO.java |   2 -
 .../dto/request/UpdateTicketRequestDTO.java   |  18 +-
 .../response/TransferOthersResponseDTO.java   |  16 ++
 .../com/mnms/booking/entity/Transfer.java     |   8 +-
 .../kafka/listener/PaymentListener.java       |  13 ++
 .../repository/TransferRepository.java        |   2 +
 .../booking/service/OcrParserService.java     |   9 +-
 .../service/TransferCompletionService.java    | 194 ++++++++++++++++++
 .../mnms/booking/service/TransferService.java | 167 ---------------
 src/main/resources/application-dev.properties |   1 +
 11 files changed, 256 insertions(+), 180 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/TransferCompletionService.java

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index b0af3ce..f58e3b5 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -10,6 +10,7 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
+import com.mnms.booking.service.TransferCompletionService;
 import com.mnms.booking.service.TransferService;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
@@ -35,6 +36,7 @@ public class TransferController {
     private final OcrService ocrService;
     private final TransferService transferService;
     private final SecurityResponseUtil securityResponseUtil;
+    private final TransferCompletionService transferCompletionService;
 
 
     ///  가족 인증
@@ -85,7 +87,7 @@ public ResponseEntity>> watchTra
     public ResponseEntity> responseTicketFamily(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
-        transferService.updateFamilyTicket(request, securityResponseUtil.requireUserId(authentication));
+        transferCompletionService.updateFamilyTicket(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(null, "티켓 양도가 성공적으로 진행되었습니다.");
     }
 
@@ -97,7 +99,7 @@ public ResponseEntity> responseTicketFamily(
     public ResponseEntity> responseTicketOthers(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
-            TransferOthersResponseDTO response = transferService.proceedOthersTicket(request, securityResponseUtil.requireUserId(authentication));
+            TransferOthersResponseDTO response = transferCompletionService.proceedOthersTicket(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(response);
     }
 }
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
index 53db70c..7e35176 100644
--- a/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/TicketTransferRequestDTO.java
@@ -8,6 +8,4 @@ public class TicketTransferRequestDTO {
     private Long recipientId; // 양도받을 가족/지인 ID
     private String transferType; // "FAMILY" 또는 "OTHERS"
     private String senderName;
-    //private String receiveMethod; // 수령 방법 (예: QR, 배송)
-    //private String address;       // 필요시
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
index 9166339..0e571e0 100644
--- a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
@@ -1,23 +1,31 @@
 package com.mnms.booking.dto.request;
 
+import com.mnms.booking.dto.response.BookingResponseDTO;
+import com.mnms.booking.dto.response.QrResponseDTO;
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.stream.Collectors;
+
 @Data
+@Builder
 @NoArgsConstructor
 @AllArgsConstructor
 public class UpdateTicketRequestDTO {
     private Long transferId;
     private Long senderId;
-    private String transferStatus;
+    private TransferStatus transferStatus;
 
-    private String deliveryMethod;
+    private TicketType ticketType;
     private String address;
 
-    public TransferStatus getTransferStatusEnum() {
-        return TransferStatus.valueOf(this.transferStatus);
-    }
+//    public TransferStatus getTransferStatusEnum() {
+//        return TransferStatus.valueOf(this.transferStatus);
+//    }
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
index e7cb863..94b8eba 100644
--- a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
@@ -1,5 +1,8 @@
 package com.mnms.booking.dto.response;
 
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.Transfer;
 import lombok.Builder;
 import lombok.Data;
 
@@ -21,4 +24,17 @@ public class TransferOthersResponseDTO {
     private int ticketPrice;
     private String fname;
     private String posterFile;
+
+    public static TransferOthersResponseDTO from(Transfer transfer, Ticket ticket, Festival festival, Long userId) {
+        return TransferOthersResponseDTO.builder()
+                .reservationNumber(ticket.getReservationNumber())
+                .senderId(transfer.getSenderId())
+                .receiverId(userId)
+                .selectedTicketCount(ticket.getSelectedTicketCount())
+                .ticketPrice(festival.getTicketPrice())
+                .fname(festival.getFname())
+                .posterFile(festival.getPosterFile())
+                .performanceDate(ticket.getPerformanceDate())
+                .build();
+    }
 }
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
index 4884898..e6c8f63 100644
--- a/src/main/java/com/mnms/booking/entity/Transfer.java
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.entity;
 
+import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
 import jakarta.persistence.*;
@@ -30,11 +31,16 @@ public class Transfer {
 
     private TransferType type;
 
+    @Setter
+    private TicketType ticketType;
+
+    @Setter
+    private String address;
+
     @Setter
     @Builder.Default
     private TransferStatus status = TransferStatus.REQUESTED;
 
     @Builder.Default
     private LocalDateTime createdAt = LocalDateTime.now();
-    private LocalDateTime updatedAt;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index f664e87..6250294 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -6,6 +6,7 @@
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.service.BookingCommandService;
+import com.mnms.booking.service.TransferCompletionService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.kafka.annotation.KafkaListener;
@@ -17,6 +18,7 @@
 public class PaymentListener {
 
     private final BookingCommandService bookingCommandService;
+    private final TransferCompletionService transferCompletionService;
 
     @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group")
     public void consumePaymentSuccess(String message) throws JsonProcessingException {
@@ -39,4 +41,15 @@ public void consumeRefundSuccess(String message) throws JsonProcessingException
         PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
         bookingCommandService.cancelBooking(event.getReservationNumber(), event.isSuccess());
     }
+
+    @KafkaListener(topics = "${app.kafka.topic.transfer-payment-event}", groupId = "booking-service-group")
+    public void consumeTransferSuccess(String message) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+
+        PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
+        transferCompletionService.updateOthersTicket(event.getReservationNumber(), event.isSuccess());
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index 9fb90ea..dec45e2 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.repository;
 
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
 import org.springframework.data.jpa.repository.JpaRepository;
 
@@ -7,6 +8,7 @@
 import java.util.Optional;
 
 public interface TransferRepository extends JpaRepository {
+    Transfer findByTicket(Ticket ticket);
     List findByReceiverId(Long userId);
     Optional findById(Long id);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index 3cd83ab..fdc58ff 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -47,12 +47,14 @@ private static List extractOcrTexts(String ocrJson) throws IOException {
     private static PersonInfoResponseDTO matchPersonInfo(
             String name, String rrn, List ocrTexts) {
 
-        String normalizedNamePattern = "\\b" + Pattern.quote(name.replaceAll("\\s", "")) + "\\b";
+        // 임시 수정
+        String normalizedNamePattern = name.replaceAll("\\s", "").replaceAll("\\\\[bQE]", "");
+        log.info("normalizedNamePattern : {}", normalizedNamePattern);
 
         String matchedName = ocrTexts.stream()
                 .map(t -> t.replaceAll("\\([^)]*\\)", "")
                         .replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
-                .filter(t -> t.matches(".*" + normalizedNamePattern + ".*"))
+                .filter(t -> t.contains(normalizedNamePattern))
                 .findFirst()
                 .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME));
 
@@ -61,9 +63,10 @@ private static PersonInfoResponseDTO matchPersonInfo(
                 .findFirst()
                 .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_RRN));
 
+        /* 임시 삭제
         if (!name.equals(matchedName)) {
             throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
-        }
+        }*/
 
         return new PersonInfoResponseDTO(matchedName, matchedRrn);
     }
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
new file mode 100644
index 0000000..3752aa1
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -0,0 +1,194 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.dto.response.TransferOthersResponseDTO;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.enums.TransferStatus;
+import com.mnms.booking.enums.TransferType;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import com.mnms.booking.repository.TransferRepository;
+import com.mnms.booking.util.CommonUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.util.List;
+
+///  양도 수락
+@Service
+@Slf4j
+@RequiredArgsConstructor
+@Transactional
+public class TransferCompletionService {
+
+    private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
+    private final TransferRepository transferRepository;
+    private final CommonUtils commonUtils;
+    private final QrCodeService qrCodeService;
+
+    /// 가족 간 양도 수락
+    @Transactional(rollbackFor = BusinessException.class)
+    public void updateFamilyTicket(UpdateTicketRequestDTO request, Long userId) {
+        Transfer transfer = getTransferOrThrow(request.getTransferId());
+
+        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
+        validateTransferType(transfer, TransferType.FAMILY);
+        validateReceiver(transfer, userId);
+
+        // CANCELED 처리
+        if (request.getTransferStatus() == TransferStatus.CANCELED) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return;
+        }
+
+        // ticket 점검
+        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
+        validateTicketStatus(ticket);
+
+        // transfer 상태 업데이트
+        transfer.setStatus(TransferStatus.COMPLETED);
+        transfer.setTicketType(request.getTicketType());
+        transfer.setAddress(request.getAddress());
+
+        // ticket, QR 정보 업데이트
+        updateTicketInfo(ticket, request, userId);
+        updateQrCodes(ticket, request, userId);
+    }
+
+    /// 지인 간 양도 요청 수락
+    @Transactional
+    public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO request, Long userId) {
+
+        Transfer transfer = getTransferOrThrow(request.getTransferId());
+        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
+        validateTransferType(transfer, TransferType.OTHERS);
+
+        String reservationNumber = transfer.getTicket().getReservationNumber();
+        validateReceiver(transfer, userId);
+
+        // CANCELED 처리
+        if (request.getTransferStatus() == TransferStatus.CANCELED) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return TransferOthersResponseDTO.builder()
+                    .reservationNumber(reservationNumber)
+                    .senderId(transfer.getSenderId())
+                    .receiverId(userId)
+                    .build();
+        }
+
+        Ticket ticket = getTicketOrThrow(reservationNumber);
+        validateTicketStatus(ticket);
+        Festival festival = ticket.getFestival();
+
+        // transfer 업데이트
+        transfer.setStatus(TransferStatus.APPROVED);
+        transfer.setTicketType(request.getTicketType());
+        transfer.setAddress(request.getAddress());
+
+        return TransferOthersResponseDTO.from(transfer, ticket, festival, userId);
+    }
+
+
+    /// 결제 KAFKA 구독 메시지 받고 결제 완료 수행
+    @Transactional
+    public void updateOthersTicket(String reservationNumber, boolean paymentStatus) {
+        Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
+        Transfer transfer = transferRepository.findByTicket(ticket);
+        if (!paymentStatus) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return;
+        }
+
+        transfer.setStatus(TransferStatus.COMPLETED);
+
+        UpdateTicketRequestDTO request = UpdateTicketRequestDTO.builder()
+                .transferId(transfer.getId())
+                .senderId(transfer.getSenderId())
+                .transferStatus(transfer.getStatus())
+                .ticketType(transfer.getTicketType())
+                .address(transfer.getAddress())
+                .build();
+
+        updateTicketInfo(ticket, request, transfer.getReceiverId());
+        updateQrCodes(ticket, request, transfer.getReceiverId());
+    }
+
+
+    /// UTIL
+    private void validateTransferType(Transfer transfer, TransferType expectedType) {
+        if (!transfer.getType().equals(expectedType)) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
+        }
+    }
+
+    private void validateSenderId(Long senderId, Long ticketUserId) {
+        if (!senderId.equals(ticketUserId)) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_SENDER);
+        }
+    }
+
+    private void validateReceiver(Transfer transfer, Long userId){
+        // 양수자 확인
+        if (!userId.equals(transfer.getReceiverId())){
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_RECEIVER);
+        }
+    }
+    private Transfer getTransferOrThrow(Long transferId) {
+        return transferRepository.findById(transferId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_EXIST));
+    }
+
+    private Ticket getTicketOrThrow(String reservationNumber) {
+        return ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    private void validateTicketStatus(Ticket ticket) {
+        if (ticket.isExpired()) {
+            throw new BusinessException(ErrorCode.TICKET_EXPIRED);
+        }
+        if (ticket.isCanceled()) {
+            throw new BusinessException(ErrorCode.TICKET_CANCELED);
+        }
+    }
+
+    /// ticket 정보 업데이트
+    private void updateTicketInfo(Ticket ticket, UpdateTicketRequestDTO request, Long receiverId) {
+        TicketType deliveryMethod = request.getTicketType();
+
+        ticket.updateTicketInfo(
+                commonUtils.generateReservationNumber(),
+                deliveryMethod,
+                receiverId,
+                LocalDate.now(),
+                request.getAddress()
+        );
+    }
+
+    /// qr 정보 업데이트
+    private void updateQrCodes(Ticket ticket, UpdateTicketRequestDTO request,  Long receiverId) {
+        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
+                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
+
+        existingQrs.forEach(qr -> {
+            qr.setQrCodeId(qrCodeService.generateQrCodeId());
+            qr.setUserId(receiverId);
+            qr.setTicket(ticket);
+        });
+
+        ticket.getQrCodes().clear();
+        ticket.getQrCodes().addAll(existingQrs);
+    }
+}
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 42011dd..24ef673 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -1,30 +1,21 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.TicketTransferRequestDTO;
-import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
-import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.entity.Festival;
-import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
-import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
-import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.repository.TransferRepository;
-import com.mnms.booking.util.CommonUtils;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.expression.ExpressionException;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDate;
 import java.util.List;
 
 @Service
@@ -34,11 +25,7 @@
 public class TransferService {
 
     private final TicketRepository ticketRepository;
-    private final QrCodeRepository qrCodeRepository;
     private final TransferRepository transferRepository;
-    private final CommonUtils commonUtils;
-    private final QrCodeService qrCodeService;
-
 
     ///  양도 요청
     @Transactional
@@ -58,7 +45,6 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
                 .type("OTHERS".equals(dto.getTransferType()) ? TransferType.OTHERS : TransferType.FAMILY)
                 .status(TransferStatus.REQUESTED)
                 .build();
-
         transferRepository.save(transfer);
     }
 
@@ -82,157 +68,4 @@ public List watchTransfer(Long userId) {
                 })
                 .toList();
     }
-
-
-    ///  양도 수락
-    /// 가족 간 양도 수락
-    @Transactional
-    public void updateFamilyTicket(UpdateTicketRequestDTO request, Long userId) {
-        Transfer transfer = getTransferOrThrow(request.getTransferId());
-
-        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
-
-        if(!transfer.getType().equals(TransferType.FAMILY)){
-            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
-        }
-        validateReceiver(transfer, userId);
-
-        // CANCELED 처리
-        if (request.getTransferStatusEnum() == TransferStatus.CANCELED) {
-            transfer.setStatus(TransferStatus.CANCELED);
-            return;
-        }
-
-        // ticket 점검
-        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
-        validateTicketStatus(ticket);
-
-        // transfer 상태 업데이트
-        transfer.setStatus(TransferStatus.COMPLETED);
-
-        // ticket 정보 업데이트
-        updateTicketInfo(ticket, request, userId);
-
-        // QR 코드 업데이트
-        updateQrCodes(ticket, request, userId);
-    }
-
-    /// 지인 간 양도 요청 수락
-    @Transactional
-    public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO request, Long userId) {
-
-        Transfer transfer = getTransferOrThrow(request.getTransferId());
-        validateSenderId(request.getSenderId(), transfer.getTicket().getUserId());
-
-        if(!transfer.getType().equals(TransferType.OTHERS)){
-            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
-        }
-
-        String reservationNumber = transfer.getTicket().getReservationNumber();
-        validateReceiver(transfer, userId);
-
-        // CANCELED 처리
-        if (request.getTransferStatusEnum() == TransferStatus.CANCELED) {
-            transfer.setStatus(TransferStatus.CANCELED);
-            return TransferOthersResponseDTO.builder()
-                    .reservationNumber(reservationNumber)
-                    .senderId(transfer.getSenderId())
-                    .receiverId(userId)
-                    .build();
-        }
-
-        Ticket ticket = getTicketOrThrow(reservationNumber);
-        validateTicketStatus(ticket);
-        Festival festival = ticket.getFestival();
-
-        // transfer 업데이트
-        transfer.setStatus(TransferStatus.APPROVED);
-
-        return TransferOthersResponseDTO.builder()
-                .reservationNumber(ticket.getReservationNumber())
-                .senderId(transfer.getSenderId())
-                .receiverId(userId)
-                .selectedTicketCount(ticket.getSelectedTicketCount())
-                .ticketPrice(festival.getTicketPrice())
-                .fname(festival.getFname())
-                .posterFile(festival.getPosterFile())
-                .performanceDate(ticket.getPerformanceDate())
-                .build();
-    }
-
-
-    /// 결제 KAFKA 구독 메시지 받고 결제 완료 수행
-    @Transactional
-    public void updateOthersTicket(UpdateTicketRequestDTO request, Long receiverId) {
-        Transfer transfer = getTransferOrThrow(request.getTransferId());
-
-        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
-        validateTicketStatus(ticket);
-
-        transfer.setStatus(TransferStatus.COMPLETED);
-
-        updateTicketInfo(ticket, request, receiverId);
-        updateQrCodes(ticket, request, receiverId);
-    }
-
-
-    /// UTIL
-    private void validateSenderId(Long senderId, Long ticketUserId) {
-        if (!senderId.equals(ticketUserId)) {
-            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_SENDER);
-        }
-    }
-
-    private void validateReceiver(Transfer transfer, Long userId){
-        // 양수자 확인
-        if (!userId.equals(transfer.getReceiverId())){
-            throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_RECEIVER);
-        }
-    }
-    private Transfer getTransferOrThrow(Long transferId) {
-        return transferRepository.findById(transferId)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_EXIST));
-    }
-
-    private Ticket getTicketOrThrow(String reservationNumber) {
-        return ticketRepository.findByReservationNumber(reservationNumber)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-    }
-
-    private void validateTicketStatus(Ticket ticket) {
-        if (ticket.isExpired()) {
-            throw new BusinessException(ErrorCode.TICKET_EXPIRED);
-        }
-        if (ticket.isCanceled()) {
-            throw new BusinessException(ErrorCode.TICKET_CANCELED);
-        }
-    }
-
-    /// ticket 정보 업데이트
-    private void updateTicketInfo(Ticket ticket, UpdateTicketRequestDTO request, Long receiverId) {
-        TicketType deliveryMethod = TicketType.valueOf(request.getDeliveryMethod());
-
-        ticket.updateTicketInfo(
-                commonUtils.generateReservationNumber(),
-                deliveryMethod,
-                receiverId,
-                LocalDate.now(),
-                request.getAddress()
-        );
-    }
-
-    /// qr 정보 업데이트
-    private void updateQrCodes(Ticket ticket, UpdateTicketRequestDTO request,  Long receiverId) {
-        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
-
-        existingQrs.forEach(qr -> {
-            qr.setQrCodeId(qrCodeService.generateQrCodeId());
-            qr.setUserId(receiverId);
-            qr.setTicket(ticket);
-        });
-
-        ticket.getQrCodes().clear();
-        ticket.getQrCodes().addAll(existingQrs);
-    }
 }
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 23a6410..f70dace 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -28,6 +28,7 @@ spring.data.redis.port=${REDIS_PORT}
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
 app.kafka.topic.payment-cancel-event=payment-cancel-events
+app.kafka.topic.transfer-payment-event=payment-transfer-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest

From e1c1a1184d10a5b93a04c68048676bdc7a9d270c Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 13:09:51 +0900
Subject: [PATCH 075/149] =?UTF-8?q?MNMS-454=20Chore:=20merge=20=EC=B6=A9?=
 =?UTF-8?q?=EB=8F=8C=20=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/exception/ErrorCode.java | 2 +-
 src/main/resources/application-dev.properties           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 4428f0a..952a0b7 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -50,7 +50,7 @@ public enum ErrorCode {
     TRANSFER_NOT_EXIST("TR004", "양도 요청이 존재하지 않습니다.", HttpStatus.NOT_FOUND),
     TRANSFER_NOT_MATCH_RECEIVER("TR005", "양도 승인하는 양수자가 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_TYPE("TR006", "양도 타입이 맞지 않습니다.", HttpStatus.BAD_REQUEST),
-    TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT);
+    TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT),
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 270ff42..41d8f99 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -28,7 +28,7 @@ spring.data.redis.port=${REDIS_PORT}
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
 app.kafka.topic.payment-cancel-event=payment-cancel-events
-app.kafka.topic.transfer-payment-event=payment-transfer-events
+app.kafka.topic.transfer-payment-event=payment-transfer-status-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest

From 91d9db3a228b04361b8d42aa24fe6f8e4b259601 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 13:46:54 +0900
Subject: [PATCH 076/149] =?UTF-8?q?MNMS-454=20Fix:=20=EC=96=91=EB=8F=84=20?=
 =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20ocr=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 진행 중일 경우, 다시 양도 요청 금지 조건 추가
양도 요청 조회 시, 완료/거절한 양도 조회 제외
ocr 비효율적인 코드 수정
---
 .../java/com/mnms/booking/enums/TicketType.java    |  2 +-
 .../java/com/mnms/booking/exception/ErrorCode.java |  1 +
 .../booking/repository/TransferRepository.java     | 14 +++++++++++++-
 .../java/com/mnms/booking/service/OcrService.java  |  7 ++-----
 .../booking/service/TransferCompletionService.java |  3 ++-
 .../com/mnms/booking/service/TransferService.java  |  8 ++++++--
 6 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/src/main/java/com/mnms/booking/enums/TicketType.java b/src/main/java/com/mnms/booking/enums/TicketType.java
index 556d80b..7a9dbde 100644
--- a/src/main/java/com/mnms/booking/enums/TicketType.java
+++ b/src/main/java/com/mnms/booking/enums/TicketType.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.enums;
 
-public enum TicketType {
+public enum  TicketType {
     MOBILE,
     PAPER
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 952a0b7..2185e38 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -51,6 +51,7 @@ public enum ErrorCode {
     TRANSFER_NOT_MATCH_RECEIVER("TR005", "양도 승인하는 양수자가 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_TYPE("TR006", "양도 타입이 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT),
+    TRANSFER_ALREADY_EXIST_REQUEST("T008", "이미 진행되고 있는 양도 거래가 존재합니다.", HttpStatus.CONFLICT),
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index dec45e2..6ae3827 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -2,13 +2,25 @@
 
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.TransferStatus;
 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;
 
 public interface TransferRepository extends JpaRepository {
     Transfer findByTicket(Ticket ticket);
-    List findByReceiverId(Long userId);
     Optional findById(Long id);
+    boolean existsByTicket(Ticket ticket);
+
+    @Query("SELECT t FROM Transfer t " +
+            "JOIN FETCH t.ticket ticket " +
+            "JOIN FETCH ticket.festival " +
+            "WHERE t.receiverId = :receiverId " +
+            "AND t.status NOT IN :excludedStatuses")
+    List findByReceiverIdWithTicketAndFestival(
+            @Param("receiverId") Long receiverId,
+            @Param("excludedStatuses") List excludedStatuses);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/OcrService.java b/src/main/java/com/mnms/booking/service/OcrService.java
index 34d8fd8..7b9df5f 100644
--- a/src/main/java/com/mnms/booking/service/OcrService.java
+++ b/src/main/java/com/mnms/booking/service/OcrService.java
@@ -52,9 +52,7 @@ public String getFilename() {
             // 5. 헤더 구성
             HttpHeaders headers = getApiHeaders();
 
-
-            String response = postApi(headers, multipartBody);
-            return response;
+            return postApi(headers, multipartBody);
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
@@ -62,13 +60,12 @@ public String getFilename() {
 
     private String postApi(HttpHeaders headers, MultiValueMap multipartBody) {
         RestClient restClient=RestClient.create();
-        String response = restClient.post()
+        return restClient.post()
                 .uri(ocrInvokeUrl)
                 .headers(h -> h.addAll(headers))
                 .body(multipartBody)
                 .retrieve()
                 .body(String.class);
-        return response;
     }
 
     private HttpHeaders getApiHeaders() {
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 3752aa1..fbe1450 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -104,8 +104,9 @@ public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO requ
     public void updateOthersTicket(String reservationNumber, boolean paymentStatus) {
         Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
         Transfer transfer = transferRepository.findByTicket(ticket);
+
+        // 결제 kafka 로직 변경 시 수정 예정
         if (!paymentStatus) {
             transfer.setStatus(TransferStatus.CANCELED);
             return;
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 24ef673..fc9366d 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -33,6 +33,10 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
         Ticket ticket = ticketRepository.findByReservationNumber(dto.getReservationNumber())
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
+        if(transferRepository.existsByTicket(ticket)){
+            throw new BusinessException(ErrorCode.TRANSFER_ALREADY_EXIST_REQUEST);
+        }
+
         if(!ticket.getUserId().equals(userId)){
             throw new BusinessException(ErrorCode.TICKET_USER_NOT_SAME);
         }
@@ -50,14 +54,14 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
 
     ///  양도 요청 조회
     public List watchTransfer(Long userId) {
-        List transfers = transferRepository.findByReceiverId(userId);
+        List transfers = transferRepository.findByReceiverIdWithTicketAndFestival(
+                userId, List.of(TransferStatus.COMPLETED, TransferStatus.CANCELED));
 
         if (transfers.isEmpty()) {
             throw new BusinessException(ErrorCode.TRANSFER_NOT_EXIST);
         }
 
         transfers.forEach(transfer -> log.info("transfer: {}", transfer));
-
         return transfers.stream()
                 .map(transfer -> {
                     Ticket ticket = transfer.getTicket();

From 97a64f273847f2e0622661479d68aad9d82ce459 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 15:50:31 +0900
Subject: [PATCH 077/149] =?UTF-8?q?MNMS-454=20Refactor:=20=EC=96=91?=
 =?UTF-8?q?=EB=8F=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EB=A6=AC?=
 =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 1회 진행하거나, 양도 진행 중인 티켓 또다른 양도 금지 조건 추가
양도 N+1 문제 해결
---
 .../controller/TransferController.java        |  9 ++-
 .../dto/response/TicketDetailResponseDTO.java |  2 +
 .../dto/response/TicketResponseDTO.java       |  2 +
 .../response/TicketTransferResponseDTO.java   |  6 +-
 .../response/TransferOthersResponseDTO.java   |  9 +++
 .../com/mnms/booking/entity/Transfer.java     |  2 +-
 .../com/mnms/booking/exception/ErrorCode.java |  2 +-
 .../repository/TransferRepository.java        |  6 +-
 .../booking/service/OcrParserService.java     |  1 -
 .../service/TransferCompletionService.java    | 56 ++++++++++---------
 .../mnms/booking/service/TransferService.java |  4 +-
 11 files changed, 59 insertions(+), 40 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index f58e3b5..acab772 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -18,7 +18,6 @@
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
@@ -31,7 +30,6 @@
 @RequestMapping("/api/transfer")
 @RequiredArgsConstructor
 @Tag(name = "양도 API", description = "양도 및 OCR, Ticket 재생성")
-@Slf4j
 public class TransferController {
     private final OcrService ocrService;
     private final TransferService transferService;
@@ -39,10 +37,10 @@ public class TransferController {
     private final TransferCompletionService transferCompletionService;
 
 
-    ///  가족 인증
+    ///  가족관계증명서 인증
     @PostMapping("/extract")
     @Operation(summary = "가족 간 양도 진행 인증 시도",
-            description = "가족관계증명서 pdf를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
+            description = "가족관계증명서 PDF를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
     )
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
@@ -94,7 +92,8 @@ public ResponseEntity> responseTicketFamily(
     /// 지인간 양도 요청 승인
     @PutMapping("/acceptance/others")
     @Operation(summary = "타인 간 양도 요청 완료",
-            description = "타인 간 양도 요청 시, 양수자가 요청을 수락하면 결제 요청이 넘어가게 됩니다."
+            description = "타인 간 양도 요청 시, 양수자가 요청을 수락하면 결제 요청이 넘어가게 됩니다. " +
+            "결제 완료 후 kafka 메시지 받으면 양도 완료됩니다."
     )
     public ResponseEntity> responseTicketOthers(
             @RequestBody UpdateTicketRequestDTO request,
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index 7a1fe16..7bb5d80 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -24,6 +24,7 @@ public class TicketDetailResponseDTO {
     private String posterFile;
 
     // festival
+    private String festivalId; // festivalId
     private String fname; // 공연명
     private String fcltynm; // 장소
 
@@ -39,6 +40,7 @@ public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festiva
                 .deliveryMethod(ticket.getDeliveryMethod())
                 .address(ticket.getAddress())
                 .qrId(qrIds)
+                .festivalId(festival.getFestivalId())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
                 .posterFile(festival.getPosterFile())
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index d8dc4c6..090f0c5 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -27,6 +27,7 @@ public class TicketResponseDTO {
     private ReservationStatus reservationStatus; // 예매상태
 
     // festival
+    private String festivalId; // festivalId
     private String fname; // 공연명
     private String fcltynm; // 장소
 
@@ -39,6 +40,7 @@ public static TicketResponseDTO fromEntity(Ticket ticket, Festival festival) {
                 .deliveryMethod(ticket.getDeliveryMethod())
                 .reservationDate(ticket.getReservationDate())
                 .reservationStatus(ticket.getReservationStatus())
+                .festivalId(festival.getFestivalId())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
                 .build();
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
index 1cb97d4..c74e2c4 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
@@ -20,7 +20,7 @@ public class TicketTransferResponseDTO {
     ///  TRANSFER
     private Long senderId;
     private String senderName;
-    private TransferType type;
+    private TransferType transferType;
     private LocalDateTime createdAt;
     private String status;
 
@@ -32,13 +32,14 @@ public class TicketTransferResponseDTO {
 
     ///  TICKET
     private LocalDateTime performanceDate;
+    private String reservationNumber;
     private int selectedTicketCount;
 
     public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, Festival festival) {
         return TicketTransferResponseDTO.builder()
                 .senderId(transfer.getSenderId())
                 .senderName(transfer.getSenderName())
-                .type(transfer.getType())
+                .transferType(transfer.getTransferType())
                 .createdAt(transfer.getCreatedAt())
                 .status(String.valueOf(transfer.getStatus()))
                 .fname(festival.getFname())
@@ -46,6 +47,7 @@ public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, F
                 .fcltynm(festival.getFcltynm())
                 .ticketPrice(festival.getTicketPrice())
                 .performanceDate(ticket.getPerformanceDate())
+                .reservationNumber(ticket.getReservationNumber())
                 .selectedTicketCount(ticket.getSelectedTicketCount())
                 .build();
     }
diff --git a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
index 94b8eba..17b06b7 100644
--- a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
@@ -37,4 +37,13 @@ public static TransferOthersResponseDTO from(Transfer transfer, Ticket ticket, F
                 .performanceDate(ticket.getPerformanceDate())
                 .build();
     }
+
+    // 취소
+    public static TransferOthersResponseDTO canceled(String reservationNumber, Long senderId, Long receiverId) {
+        return TransferOthersResponseDTO.builder()
+                .reservationNumber(reservationNumber)
+                .senderId(senderId)
+                .receiverId(receiverId)
+                .build();
+    }
 }
diff --git a/src/main/java/com/mnms/booking/entity/Transfer.java b/src/main/java/com/mnms/booking/entity/Transfer.java
index e6c8f63..6378e39 100644
--- a/src/main/java/com/mnms/booking/entity/Transfer.java
+++ b/src/main/java/com/mnms/booking/entity/Transfer.java
@@ -29,7 +29,7 @@ public class Transfer {
     @JoinColumn(name = "ticket_id", nullable = false)
     private Ticket ticket;
 
-    private TransferType type;
+    private TransferType transferType;
 
     @Setter
     private TicketType ticketType;
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 2185e38..9cfb152 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -51,7 +51,7 @@ public enum ErrorCode {
     TRANSFER_NOT_MATCH_RECEIVER("TR005", "양도 승인하는 양수자가 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_TYPE("TR006", "양도 타입이 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT),
-    TRANSFER_ALREADY_EXIST_REQUEST("T008", "이미 진행되고 있는 양도 거래가 존재합니다.", HttpStatus.CONFLICT),
+    TRANSFER_ALREADY_EXIST_REQUEST("T008", "진행되고 있는 양도 거래가 존재하거나, 양도 1회 진행한 티켓입니다. 양도는 1회로 제한됩니다.", HttpStatus.CONFLICT),
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index 6ae3827..8e1061f 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -3,6 +3,7 @@
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
 import com.mnms.booking.enums.TransferStatus;
+import org.springframework.data.jpa.repository.EntityGraph;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.data.repository.query.Param;
@@ -12,8 +13,11 @@
 
 public interface TransferRepository extends JpaRepository {
     Transfer findByTicket(Ticket ticket);
+
+    @EntityGraph(attributePaths = {"ticket", "ticket.qrCodes"})
     Optional findById(Long id);
-    boolean existsByTicket(Ticket ticket);
+
+    boolean existsByTicket_Id(Long id);
 
     @Query("SELECT t FROM Transfer t " +
             "JOIN FETCH t.ticket ticket " +
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index fdc58ff..0e0614d 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -10,7 +10,6 @@
 
 import java.io.IOException;
 import java.util.*;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 @Service
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index fbe1450..f14744b 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -46,23 +46,13 @@ public void updateFamilyTicket(UpdateTicketRequestDTO request, Long userId) {
         validateReceiver(transfer, userId);
 
         // CANCELED 처리
-        if (request.getTransferStatus() == TransferStatus.CANCELED) {
-            transfer.setStatus(TransferStatus.CANCELED);
+        if (handleCancel(transfer, request)) {
             return;
         }
 
-        // ticket 점검
-        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
-        validateTicketStatus(ticket);
-
         // transfer 상태 업데이트
         transfer.setStatus(TransferStatus.COMPLETED);
-        transfer.setTicketType(request.getTicketType());
-        transfer.setAddress(request.getAddress());
-
-        // ticket, QR 정보 업데이트
-        updateTicketInfo(ticket, request, userId);
-        updateQrCodes(ticket, request, userId);
+        applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), true);
     }
 
     /// 지인 간 양도 요청 수락
@@ -77,13 +67,8 @@ public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO requ
         validateReceiver(transfer, userId);
 
         // CANCELED 처리
-        if (request.getTransferStatus() == TransferStatus.CANCELED) {
-            transfer.setStatus(TransferStatus.CANCELED);
-            return TransferOthersResponseDTO.builder()
-                    .reservationNumber(reservationNumber)
-                    .senderId(transfer.getSenderId())
-                    .receiverId(userId)
-                    .build();
+        if(handleCancel(transfer, request)){
+            return TransferOthersResponseDTO.canceled(reservationNumber, transfer.getSenderId(), userId);
         }
 
         Ticket ticket = getTicketOrThrow(reservationNumber);
@@ -104,6 +89,7 @@ public TransferOthersResponseDTO proceedOthersTicket(UpdateTicketRequestDTO requ
     public void updateOthersTicket(String reservationNumber, boolean paymentStatus) {
         Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+
         Transfer transfer = transferRepository.findByTicket(ticket);
 
         // 결제 kafka 로직 변경 시 수정 예정
@@ -113,7 +99,6 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
         }
 
         transfer.setStatus(TransferStatus.COMPLETED);
-
         UpdateTicketRequestDTO request = UpdateTicketRequestDTO.builder()
                 .transferId(transfer.getId())
                 .senderId(transfer.getSenderId())
@@ -122,14 +107,34 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
                 .address(transfer.getAddress())
                 .build();
 
-        updateTicketInfo(ticket, request, transfer.getReceiverId());
-        updateQrCodes(ticket, request, transfer.getReceiverId());
+        applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
     }
 
-
     /// UTIL
+    private void applyTicketAndQrUpdate(Transfer transfer, UpdateTicketRequestDTO request,
+                                        Long receiverId, boolean updateTransferFields) {
+        Ticket ticket = getTicketOrThrow(transfer.getTicket().getReservationNumber());
+        validateTicketStatus(ticket);
+
+        if (updateTransferFields) {
+            transfer.setTicketType(request.getTicketType());
+            transfer.setAddress(request.getAddress());
+        }
+
+        updateTicketInfo(ticket, request, receiverId);
+        updateQrCodes(ticket, request, receiverId);
+    }
+
+    private boolean handleCancel(Transfer transfer, UpdateTicketRequestDTO request) {
+        if (request.getTransferStatus() == TransferStatus.CANCELED) {
+            transfer.setStatus(TransferStatus.CANCELED);
+            return true;
+        }
+        return false;
+    }
+
     private void validateTransferType(Transfer transfer, TransferType expectedType) {
-        if (!transfer.getType().equals(expectedType)) {
+        if (!transfer.getTransferType().equals(expectedType)) {
             throw new BusinessException(ErrorCode.TRANSFER_NOT_MATCH_TYPE);
         }
     }
@@ -188,8 +193,5 @@ private void updateQrCodes(Ticket ticket, UpdateTicketRequestDTO request,  Long
             qr.setUserId(receiverId);
             qr.setTicket(ticket);
         });
-
-        ticket.getQrCodes().clear();
-        ticket.getQrCodes().addAll(existingQrs);
     }
 }
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index fc9366d..45d7cbd 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -33,7 +33,7 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
         Ticket ticket = ticketRepository.findByReservationNumber(dto.getReservationNumber())
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        if(transferRepository.existsByTicket(ticket)){
+        if(transferRepository.existsByTicket_Id(ticket.getId())){
             throw new BusinessException(ErrorCode.TRANSFER_ALREADY_EXIST_REQUEST);
         }
 
@@ -46,7 +46,7 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
                 .senderId(userId)
                 .senderName(dto.getSenderName())
                 .receiverId(dto.getRecipientId())
-                .type("OTHERS".equals(dto.getTransferType()) ? TransferType.OTHERS : TransferType.FAMILY)
+                .transferType("OTHERS".equals(dto.getTransferType()) ? TransferType.OTHERS : TransferType.FAMILY)
                 .status(TransferStatus.REQUESTED)
                 .build();
         transferRepository.save(transfer);

From 397ccae4a62bc6199ef8af98ff57ce371aa0af4b Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 16:00:56 +0900
Subject: [PATCH 078/149] =?UTF-8?q?MNMS-454=20Fix:=20=EC=A7=80=EC=9D=B8=20?=
 =?UTF-8?q?=EC=96=91=EB=8F=84=20=EA=B2=B0=EC=A0=9C=20=EC=99=84=EB=A3=8C=20?=
 =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

websocket 코드 추가
---
 .../service/TransferCompletionService.java    | 36 ++++++++++++-------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index f14744b..a8b2dc1 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -1,11 +1,13 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.dto.response.TicketStatusResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
@@ -17,6 +19,7 @@
 import com.mnms.booking.util.CommonUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -35,6 +38,7 @@ public class TransferCompletionService {
     private final TransferRepository transferRepository;
     private final CommonUtils commonUtils;
     private final QrCodeService qrCodeService;
+    private final SimpMessagingTemplate messagingTemplate;
 
     /// 가족 간 양도 수락
     @Transactional(rollbackFor = BusinessException.class)
@@ -92,22 +96,28 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
 
         Transfer transfer = transferRepository.findByTicket(ticket);
 
+        ReservationStatus newStatus = paymentStatus ?
+                ReservationStatus.CONFIRMED :
+                ReservationStatus.CANCELED;
+
         // 결제 kafka 로직 변경 시 수정 예정
-        if (!paymentStatus) {
+        if (paymentStatus) {
+            transfer.setStatus(TransferStatus.COMPLETED);
+            UpdateTicketRequestDTO request = UpdateTicketRequestDTO.builder()
+                    .transferId(transfer.getId())
+                    .senderId(transfer.getSenderId())
+                    .transferStatus(transfer.getStatus())
+                    .ticketType(transfer.getTicketType())
+                    .address(transfer.getAddress())
+                    .build();
+            applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
+        } else{
             transfer.setStatus(TransferStatus.CANCELED);
-            return;
         }
-
-        transfer.setStatus(TransferStatus.COMPLETED);
-        UpdateTicketRequestDTO request = UpdateTicketRequestDTO.builder()
-                .transferId(transfer.getId())
-                .senderId(transfer.getSenderId())
-                .transferStatus(transfer.getStatus())
-                .ticketType(transfer.getTicketType())
-                .address(transfer.getAddress())
-                .build();
-
-        applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
+        // websocket 전송
+        messagingTemplate.convertAndSend(
+                "/topic/transfer/" + transfer.getReceiverId(),
+                new TicketStatusResponseDTO(ticket.getReservationNumber(), newStatus));
     }
 
     /// UTIL

From 977a02fbd4e6fa2c152cb9f0885d07b06ced00aa Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 16:09:48 +0900
Subject: [PATCH 079/149] =?UTF-8?q?MNMS-454=20Chore:=20=EA=B2=B0=EC=A0=9C?=
 =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

websocket 반환값으로 TransferStatus 변경
---
 .../dto/response/TransferStatusResponseDTO.java       |  5 +++++
 .../booking/service/TransferCompletionService.java    | 11 +++++------
 2 files changed, 10 insertions(+), 6 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/dto/response/TransferStatusResponseDTO.java

diff --git a/src/main/java/com/mnms/booking/dto/response/TransferStatusResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TransferStatusResponseDTO.java
new file mode 100644
index 0000000..bf73945
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/response/TransferStatusResponseDTO.java
@@ -0,0 +1,5 @@
+package com.mnms.booking.dto.response;
+
+import com.mnms.booking.enums.TransferStatus;
+
+public record TransferStatusResponseDTO(String reservationNumber, TransferStatus status) {}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index a8b2dc1..913da3e 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -3,6 +3,7 @@
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.TicketStatusResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
+import com.mnms.booking.dto.response.TransferStatusResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
@@ -96,9 +97,9 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
 
         Transfer transfer = transferRepository.findByTicket(ticket);
 
-        ReservationStatus newStatus = paymentStatus ?
-                ReservationStatus.CONFIRMED :
-                ReservationStatus.CANCELED;
+        TransferStatus newStatus = paymentStatus ?
+                TransferStatus.COMPLETED :
+                TransferStatus.APPROVED;
 
         // 결제 kafka 로직 변경 시 수정 예정
         if (paymentStatus) {
@@ -111,13 +112,11 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
                     .address(transfer.getAddress())
                     .build();
             applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
-        } else{
-            transfer.setStatus(TransferStatus.CANCELED);
         }
         // websocket 전송
         messagingTemplate.convertAndSend(
                 "/topic/transfer/" + transfer.getReceiverId(),
-                new TicketStatusResponseDTO(ticket.getReservationNumber(), newStatus));
+                new TransferStatusResponseDTO(ticket.getReservationNumber(), newStatus));
     }
 
     /// UTIL

From a43b7dd0011d87f54367fba8af6a56f7b37001f4 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 29 Aug 2025 17:23:11 +0900
Subject: [PATCH 080/149] =?UTF-8?q?MNMS-454=20Fix:=20OCR=203=EC=B0=A8=20?=
 =?UTF-8?q?=EC=B6=94=EC=B6=9C=20=EC=BD=94=EB=93=9C=20=EB=B3=80=EA=B2=BD=20?=
 =?UTF-8?q?(=ED=9A=A8=EC=9C=A8=EC=84=B1)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

문제 : 이름 조건이 너무 느슨해져서 다 통과함
---
 .../booking/controller/TicketController.java  |  9 +----
 .../booking/service/OcrParserService.java     | 36 ++++++++++---------
 2 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index a8172f7..5e6d507 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -27,14 +27,7 @@ public class TicketController {
     private final TicketService ticketService;
     private final SecurityResponseUtil securityResponseUtil;
 
-    @GetMapping
-    @Operation(summary = "예매한 티켓 정보 조회",
-            description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
-    )
-    public ResponseEntity>> getUserTickets(Authentication authentication) {
-        List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
-        return ApiResponseUtil.success(tickets);
-    }
+
 
     @GetMapping("/detail")
     @Operation(summary = "예매한 티켓 정보 디테일 조회",
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index 0e0614d..36ce561 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -10,6 +10,7 @@
 
 import java.io.IOException;
 import java.util.*;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 @Service
@@ -46,27 +47,28 @@ private static List extractOcrTexts(String ocrJson) throws IOException {
     private static PersonInfoResponseDTO matchPersonInfo(
             String name, String rrn, List ocrTexts) {
 
-        // 임시 수정
-        String normalizedNamePattern = name.replaceAll("\\s", "").replaceAll("\\\\[bQE]", "");
-        log.info("normalizedNamePattern : {}", normalizedNamePattern);
-
-        String matchedName = ocrTexts.stream()
+        List cleanedOcrTexts = ocrTexts.stream()
                 .map(t -> t.replaceAll("\\([^)]*\\)", "")
                         .replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
-                .filter(t -> t.contains(normalizedNamePattern))
-                .findFirst()
-                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME));
+                .toList();
 
-        String matchedRrn = ocrTexts.stream()
-                .filter(t -> t.contains(rrn) && t.matches(".*\\d{6}-[1-4].*"))
-                .findFirst()
-                .orElseThrow(() -> new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_RRN));
+        String normalizedName = name.replaceAll("\\s", "").replaceAll("\\\\[bQE]", "");
+        String foundName = null, foundRrn = null;
 
-        /* 임시 삭제
-        if (!name.equals(matchedName)) {
-            throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
-        }*/
+        for (String text : cleanedOcrTexts) {
+            if (foundName == null && text.contains(normalizedName)) foundName = text;
+            if (foundRrn == null && text.contains(rrn) && text.matches(".*\\d{6}-[1-4].*")) {
+                foundRrn = text;
+            }
+            if (foundName != null && foundRrn != null) break;
+        }
 
-        return new PersonInfoResponseDTO(matchedName, matchedRrn);
+        if (foundName == null) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_NAME);
+        }
+        if (foundRrn == null) {
+            throw new BusinessException(ErrorCode.TRANSFER_NOT_FOUND_RRN);
+        }
+        return new PersonInfoResponseDTO(foundName, foundRrn);
     }
 }
\ No newline at end of file

From 24ee2543a095746f39fb7915a3154fc8cccbce38 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 30 Aug 2025 14:50:11 +0900
Subject: [PATCH 081/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20=EC=82=AD=EC=A0=9C=EB=90=9C=20?=
 =?UTF-8?q?=ED=8B=B0=EC=BC=93=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0?=
 =?UTF-8?q?=ED=9A=8C=20controller=20code=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/controller/TicketController.java | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index 5e6d507..2f56dec 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -8,7 +8,6 @@
 import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
@@ -17,6 +16,7 @@
 
 import java.util.List;
 
+
 @Slf4j
 @RestController
 @RequiredArgsConstructor
@@ -27,7 +27,14 @@ public class TicketController {
     private final TicketService ticketService;
     private final SecurityResponseUtil securityResponseUtil;
 
-
+    @GetMapping
+    @Operation(summary = "예매한 티켓 정보 조회",
+            description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
+    )
+    public ResponseEntity>> getUserTickets(Authentication authentication) {
+        List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(tickets);
+    }
 
     @GetMapping("/detail")
     @Operation(summary = "예매한 티켓 정보 디테일 조회",

From f00382f31ada97d2130711aece78ef3fdd9f625b Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 30 Aug 2025 16:53:09 +0900
Subject: [PATCH 082/149] =?UTF-8?q?MNMS-548=20fix:=20ocr=20parser=20?=
 =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/TransferController.java   | 16 ++++++++++++++++
 .../mnms/booking/service/OcrParserService.java   |  9 ++-------
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index acab772..c97423e 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -42,6 +42,21 @@ public class TransferController {
     @Operation(summary = "가족 간 양도 진행 인증 시도",
             description = "가족관계증명서 PDF를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
     )
+    public ResponseEntity> extractPersonAuth(
+            @RequestPart("file") MultipartFile file,
+            @RequestPart("targetInfo") String targetInfoJson) throws IOException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        Map targetInfo = objectMapper.readValue(targetInfoJson, new TypeReference<>() {});
+        String ocrJson = ocrService.callOcr(file);
+        OcrParserService.parseOcrResult(ocrJson, targetInfo);
+
+        return ApiResponseUtil.success(null,"가족관계증명서 인증이 완료되었습니다.");
+    }
+
+    @PostMapping("/extract/result")
+    @Operation(summary = "가족 간 양도 진행 인증 시도",
+            description = "가족관계증명서 PDF를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답과 결과를 보냅니다."
+    )
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -54,6 +69,7 @@ public ResponseEntity>> extractPerso
         return ApiResponseUtil.success(people, "가족관계증명서 인증이 완료되었습니다.");
     }
 
+
     /// 양도 요청
     @PostMapping("/request")
     @Operation(summary = "양도 요청",
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index 36ce561..571243c 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -5,24 +5,21 @@
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
 import java.util.*;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 @Service
-@Slf4j
 public class OcrParserService {
 
     private static final ObjectMapper objectMapper = new ObjectMapper();
 
     public static List parseOcrResult(
             String ocrJson, Map targetInfo) throws IOException {
-
         List ocrTexts = extractOcrTexts(ocrJson);
+
         return targetInfo.entrySet().stream()
                 .map(entry -> matchPersonInfo(entry.getKey(), entry.getValue(), ocrTexts))
                 .collect(Collectors.toList());
@@ -51,12 +48,10 @@ private static PersonInfoResponseDTO matchPersonInfo(
                 .map(t -> t.replaceAll("\\([^)]*\\)", "")
                         .replaceAll("[\\s\\(\\)\\[\\]{}]", ""))
                 .toList();
-
-        String normalizedName = name.replaceAll("\\s", "").replaceAll("\\\\[bQE]", "");
         String foundName = null, foundRrn = null;
 
         for (String text : cleanedOcrTexts) {
-            if (foundName == null && text.contains(normalizedName)) foundName = text;
+            if (foundName == null && text.contains(name)) foundName = text;
             if (foundRrn == null && text.contains(rrn) && text.matches(".*\\d{6}-[1-4].*")) {
                 foundRrn = text;
             }

From 0d6f2ea9f047a9bf32fd4b6dc0372dabbdf77052 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 30 Aug 2025 18:24:24 +0900
Subject: [PATCH 083/149] =?UTF-8?q?MNMS-513=20Refactor:=20WebSocket=20?=
 =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=88=84=EB=9D=BD=20=EB=B0=8F=20?=
 =?UTF-8?q?Transaction=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

WebSocket 메시지 누락 방지 예매 완료 및 취소, 양도 결제 완료 API 작성
Tranactional 누락된 service 코드 보충
---
 .../booking/controller/BookingController.java | 10 ++++++++++
 .../controller/TransferController.java        | 10 ++++++++++
 .../booking/repository/TicketRepository.java  |  3 +++
 .../repository/TransferRepository.java        |  3 +++
 .../service/BookingCommandService.java        | 19 ++++++++++++++-----
 .../mnms/booking/service/CaptchaService.java  |  8 +++++---
 .../mnms/booking/service/FestivalService.java |  7 +++----
 .../com/mnms/booking/service/HostService.java |  8 ++++----
 .../booking/service/OcrParserService.java     |  2 ++
 .../com/mnms/booking/service/OcrService.java  |  3 ++-
 .../mnms/booking/service/QrCodeService.java   |  8 +++-----
 .../service/RedisMessageSubscriber.java       |  4 +++-
 .../service/StatisticsQrCodeService.java      |  1 +
 .../service/StatisticsQueryService.java       |  1 +
 .../mnms/booking/service/TicketService.java   |  1 -
 .../service/TransferCompletionService.java    |  6 +-----
 .../mnms/booking/service/TransferService.java |  7 ++++---
 17 files changed, 69 insertions(+), 32 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 29dab2a..01d9a8a 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -6,6 +6,7 @@
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
 import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
@@ -90,6 +91,15 @@ public ResponseEntity> reserveTicket(
         return ApiResponseUtil.success(null, "예매 티켓 생성 완료");
     }
 
+    ///  Websocket 메시지 누락 방지 api요청
+    @GetMapping("reservation/status")
+    @Operation( summary = "예매 완료/취소 정보 조회",
+            description = "Websocket 메시지 누락 시, " +
+                    "예매 완료 혹은 취소 되었는지 확인합니다. ")
+    public ResponseEntity> checkStatus(@RequestParam String reservationNumber){
+        return ApiResponseUtil.success(bookingCommandService.checkStatus(reservationNumber));
+    }
+
     ///  GET
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index c97423e..6029416 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -7,6 +7,7 @@
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
@@ -117,4 +118,13 @@ public ResponseEntity> responseTicket
             TransferOthersResponseDTO response = transferCompletionService.proceedOthersTicket(request, securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(response);
     }
+
+    ///  Websocket 메시지 누락 방지 api요청
+    @GetMapping("/reservation/status")
+    @Operation( summary = "양도 결제 완료 조회",
+            description = "Websocket 메시지 누락 시, " +
+                    "양도 결제 완료 혹은 실패를 확인합니다. ")
+    public ResponseEntity> checkStatus(@RequestParam Long transferId){
+        return ApiResponseUtil.success(transferService.checkStatus(transferId));
+    }
 }
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index dbb402a..7774cf4 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -86,4 +86,7 @@ List findByFestivalIdAndReservationStatus(@Param("festivalId") String fe
     // 특정 festivalId에 대한 유효한 공연 날짜-시간을 모두 조회
     @Query("SELECT DISTINCT t.performanceDate FROM Ticket t WHERE t.festival.festivalId = :festivalId")
     List findDistinctPerformanceDateByFestivalId(@Param("festivalId") String festivalId);
+
+    @Query("SELECT t.reservationStatus FROM Ticket t WHERE t.reservationNumber = :reservationNumber")
+    ReservationStatus findReservationStatusByReservationNumber(@Param("reservationNumber") String reservationNumber);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index 8e1061f..b76e7be 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -27,4 +27,7 @@ public interface TransferRepository extends JpaRepository {
     List findByReceiverIdWithTicketAndFestival(
             @Param("receiverId") Long receiverId,
             @Param("excludedStatuses") List excludedStatuses);
+
+    @Query("SELECT t.status FROM Transfer t WHERE t.id = :transferId")
+    TransferStatus findTransferStatusById(Long transferId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index d510164..20923c5 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -139,12 +139,15 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
-        // 결제 상태 변경
         ReservationStatus newStatus = paymentStatus ?
                 ReservationStatus.CONFIRMED :
                 ReservationStatus.CANCELED;
-        bookingTicket.setReservationStatus(newStatus);
-        ticketRepository.save(bookingTicket);
+        // 결제 상태 변경
+        if(bookingTicket.getReservationStatus() != ReservationStatus.CONFIRMED
+                && bookingTicket.getReservationStatus() != ReservationStatus.CANCELED) {
+            bookingTicket.setReservationStatus(newStatus);
+            ticketRepository.save(bookingTicket);
+        }
 
         // WebSocket 전송
         messagingTemplate.convertAndSend(
@@ -163,10 +166,12 @@ public void cancelBooking(String reservationNumber, boolean paymentStatus) {
                 ? ReservationStatus.CANCELED
                 : ticket.getReservationStatus();
 
-        if (ticket.getReservationStatus() == ReservationStatus.CONFIRMED) {
+        if(ticket.getReservationStatus() == ReservationStatus.CANCELED){
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_CANCELED);
+        }
+        if (ticket.getReservationStatus() != ReservationStatus.CONFIRMED) {
             throw new BusinessException(ErrorCode.TICKET_FAIL_CANCEL);
         }
-
         // qr 삭제 + ticket 상태 변경
         ticket.getQrCodes().clear();
         ticket.setReservationStatus(status);
@@ -274,4 +279,8 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket
         qrCodeRepository.save(qrCode);
         return qrCode;
     }
+
+    public ReservationStatus checkStatus(String reservationNumber) {
+        return ticketRepository.findReservationStatusByReservationNumber(reservationNumber);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/CaptchaService.java b/src/main/java/com/mnms/booking/service/CaptchaService.java
index 83f611b..e9e9668 100644
--- a/src/main/java/com/mnms/booking/service/CaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/CaptchaService.java
@@ -8,14 +8,16 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
 import javax.imageio.ImageIO;
 import java.awt.image.BufferedImage;
 import java.io.IOException;
 import java.io.OutputStream;
 
-@Slf4j
-@RequiredArgsConstructor
 @Service
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
 public class CaptchaService {
 
     private final DefaultKaptcha captchaProducer;
@@ -40,10 +42,10 @@ public void writeCaptchaImage(HttpSession session, HttpServletResponse response)
         }
     }
 
+    @Transactional
     private BufferedImage generateCaptchaImage(HttpSession session) {
         String captchaText = captchaProducer.createText();
         session.setAttribute(CAPTCHA_SESSION_KEY, new CaptchaRequestDTO(captchaText));
-        log.info("Generated Kaptcha Text: {}", captchaText);
         return captchaProducer.createImage(captchaText);
     }
 
diff --git a/src/main/java/com/mnms/booking/service/FestivalService.java b/src/main/java/com/mnms/booking/service/FestivalService.java
index c07fd48..d0c1e83 100644
--- a/src/main/java/com/mnms/booking/service/FestivalService.java
+++ b/src/main/java/com/mnms/booking/service/FestivalService.java
@@ -6,17 +6,16 @@
 import com.mnms.booking.repository.FestivalRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
 @RequiredArgsConstructor
+@Transactional(readOnly = true)
 public class FestivalService {
 
     private final FestivalRepository festivalRepository;
 
-    /**
-     * 특정 festivalId에 해당하는 공연의 수용 인원을 조회
-     * @return 수용 인원
-     */
+    ///특정 festivalId에 해당하는 공연의 수용 인원을 조회
     public int getCapacity(String festivalId) {
         Festival festival = festivalRepository.findByFestivalId(festivalId)
             .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index 326d6c4..d0d7222 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -12,9 +12,8 @@
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
-import org.springframework.security.core.Authentication;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.reactive.function.client.WebClientResponseException;
 
 import java.util.ArrayList;
@@ -23,9 +22,9 @@
 import java.util.Map;
 import java.util.stream.Collectors;
 
-@RequiredArgsConstructor
 @Service
-@Slf4j
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
 public class HostService {
 
     private final TicketRepository ticketRepository;
@@ -36,6 +35,7 @@ public List getBookingsByOrganizer(HostRequestDTO request) {
         return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
     }
 
+    @Transactional
     public List getBookingInfoByHost(String festivalId, Long hostUserId, List role) {
 
         Festival festival;
diff --git a/src/main/java/com/mnms/booking/service/OcrParserService.java b/src/main/java/com/mnms/booking/service/OcrParserService.java
index 571243c..f4cb7f8 100644
--- a/src/main/java/com/mnms/booking/service/OcrParserService.java
+++ b/src/main/java/com/mnms/booking/service/OcrParserService.java
@@ -6,12 +6,14 @@
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.io.IOException;
 import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
+@Transactional
 public class OcrParserService {
 
     private static final ObjectMapper objectMapper = new ObjectMapper();
diff --git a/src/main/java/com/mnms/booking/service/OcrService.java b/src/main/java/com/mnms/booking/service/OcrService.java
index 7b9df5f..9a9b466 100644
--- a/src/main/java/com/mnms/booking/service/OcrService.java
+++ b/src/main/java/com/mnms/booking/service/OcrService.java
@@ -10,6 +10,7 @@
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
 import org.springframework.web.client.RestClient;
@@ -21,7 +22,7 @@
 import java.util.UUID;
 
 @Service
-@Slf4j
+@Transactional
 public class OcrService {
 
     @Value("${ocr.key}")
diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index c4fb983..3730860 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -11,16 +11,17 @@
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.QrCodeRepository;
-import jakarta.transaction.Transactional;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.security.SecureRandom;
 import java.time.LocalDateTime;
+import org.springframework.transaction.annotation.Transactional;
 
 @Service
 @RequiredArgsConstructor
+@Transactional(readOnly = true)
 public class QrCodeService {
 
     private final ObjectMapper objectMapper;
@@ -40,10 +41,7 @@ public String generateQrCodeId() {
         return sb.toString();
     }
 
-    /**
-     * QR IMG 조회
-     * @param qrCodeText = qrCodeId
-     */
+    /// QR IMG 조회
     public byte[] generateQrCodeImage(String qrCodeText, int width, int height) throws WriterException, IOException {
         QRCodeWriter qrCodeWriter = new QRCodeWriter();
         BitMatrix bitMatrix = qrCodeWriter.encode(qrCodeText, BarcodeFormat.QR_CODE, width, height);
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 5499182..805d9e6 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -6,11 +6,13 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 // MessageListener 인터페이스 구현
 @Service
-@RequiredArgsConstructor
 @Slf4j
+@RequiredArgsConstructor
+@Transactional
 public class RedisMessageSubscriber {
 
     private final SimpMessagingTemplate messagingTemplate; // WebSocket 메시지 전송
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
index fa46d25..8a542d3 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
@@ -9,6 +9,7 @@
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
index 4e3d41c..5357a80 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
@@ -8,6 +8,7 @@
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.util.List;
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index 989bba5..ff7c129 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -13,7 +13,6 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
-import java.util.Optional;
 
 @Service
 @Slf4j
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 913da3e..03e6c21 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -1,14 +1,12 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
-import com.mnms.booking.dto.response.TicketStatusResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.dto.response.TransferStatusResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
-import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
@@ -19,7 +17,6 @@
 import com.mnms.booking.repository.TransferRepository;
 import com.mnms.booking.util.CommonUtils;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -29,7 +26,6 @@
 
 ///  양도 수락
 @Service
-@Slf4j
 @RequiredArgsConstructor
 @Transactional
 public class TransferCompletionService {
@@ -102,7 +98,7 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
                 TransferStatus.APPROVED;
 
         // 결제 kafka 로직 변경 시 수정 예정
-        if (paymentStatus) {
+        if (paymentStatus && transfer.getStatus() != TransferStatus.COMPLETED) {
             transfer.setStatus(TransferStatus.COMPLETED);
             UpdateTicketRequestDTO request = UpdateTicketRequestDTO.builder()
                     .transferId(transfer.getId())
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 45d7cbd..26b0815 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -13,13 +13,11 @@
 import com.mnms.booking.repository.TransferRepository;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import java.util.List;
 
 @Service
-@Slf4j
 @RequiredArgsConstructor
 @Transactional(readOnly = true)
 public class TransferService {
@@ -61,7 +59,6 @@ public List watchTransfer(Long userId) {
             throw new BusinessException(ErrorCode.TRANSFER_NOT_EXIST);
         }
 
-        transfers.forEach(transfer -> log.info("transfer: {}", transfer));
         return transfers.stream()
                 .map(transfer -> {
                     Ticket ticket = transfer.getTicket();
@@ -72,4 +69,8 @@ public List watchTransfer(Long userId) {
                 })
                 .toList();
     }
+
+    public Boolean checkStatus(Long transferId) {
+        return transferRepository.findTransferStatusById(transferId).equals(TransferStatus.COMPLETED);
+    }
 }

From ebc79126becd9123d305f7bde8f92a18c0540612 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sun, 31 Aug 2025 02:14:09 +0900
Subject: [PATCH 084/149] =?UTF-8?q?MNMS-513=20Fix:=20WebSocket=20=EC=BD=94?=
 =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/service/BookingCommandService.java  |  5 +++--
 .../mnms/booking/service/RedisMessageSubscriber.java |  2 --
 .../booking/service/TransferCompletionService.java   | 12 ++++++++----
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 20923c5..ccfd8d5 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -150,8 +150,9 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         }
 
         // WebSocket 전송
-        messagingTemplate.convertAndSend(
-                "/topic/ticket-status",
+        messagingTemplate.convertAndSendToUser(
+                String.valueOf(bookingTicket.getUserId()),
+                "/queue/ticket-status",
                 new TicketStatusResponseDTO(bookingTicket.getReservationNumber(), newStatus)
         );
     }
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 805d9e6..13624a5 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -25,9 +25,7 @@ public void onMessage(String message, String channel) {
 
         // message는 JSON 문자열 -> DTO로 변환
         try {
-            // 여기에 로그 추가
             log.info("Received message from Redis channel: {}", message);
-
             WaitingNumberResponseDTO dto = new ObjectMapper().readValue(message, WaitingNumberResponseDTO.class);
 
             // userId 기준으로 메시지 전송
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 03e6c21..4e6595d 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -1,6 +1,7 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.dto.response.TicketStatusResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.dto.response.TransferStatusResponseDTO;
 import com.mnms.booking.entity.Festival;
@@ -109,10 +110,13 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
                     .build();
             applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
         }
-        // websocket 전송
-        messagingTemplate.convertAndSend(
-                "/topic/transfer/" + transfer.getReceiverId(),
-                new TransferStatusResponseDTO(ticket.getReservationNumber(), newStatus));
+
+        // WebSocket 전송
+        messagingTemplate.convertAndSendToUser(
+                String.valueOf(ticket.getUserId()),
+                "/queue/transfer-status",
+                new TransferStatusResponseDTO(ticket.getReservationNumber(), newStatus)
+        );
     }
 
     /// UTIL

From e5ddd5731572ea5f8dfdf4d1b537a52a1e76de8b Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 1 Sep 2025 09:44:58 +0900
Subject: [PATCH 085/149] =?UTF-8?q?MNMS-513=20Chore:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=97=90=20poster=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/mnms/booking/dto/response/TicketResponseDTO.java   | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index 090f0c5..89a9410 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -28,6 +28,7 @@ public class TicketResponseDTO {
 
     // festival
     private String festivalId; // festivalId
+    private String posterFile;
     private String fname; // 공연명
     private String fcltynm; // 장소
 
@@ -41,6 +42,7 @@ public static TicketResponseDTO fromEntity(Ticket ticket, Festival festival) {
                 .reservationDate(ticket.getReservationDate())
                 .reservationStatus(ticket.getReservationStatus())
                 .festivalId(festival.getFestivalId())
+                .posterFile(festival.getPosterFile())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
                 .build();

From bb9b46657054870782bafcf9f417612f1c9c0bef Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 1 Sep 2025 12:56:47 +0900
Subject: [PATCH 086/149] =?UTF-8?q?MNMS-513=20Refactor:=20=EB=8C=80?=
 =?UTF-8?q?=EA=B8=B0=EC=97=B4=20->=20=EC=98=88=EB=A7=A4=20=ED=8E=98?=
 =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=ED=81=90=20=EC=97=85=EB=8D=B0=EC=9D=B4?=
 =?UTF-8?q?=ED=8A=B8=20=EB=B0=A9=EC=8B=9D=20=ED=99=95=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

사용자 예매 페이지 퇴장 시, 대기열 대기자 입장 로직 X
스케줄러로 사용자 자동 입장
---
 .../booking/controller/WaitingController.java | 10 ++---
 .../service/WaitingNotificationService.java   | 12 ++----
 .../service/WaitingQueueRedisService.java     |  1 +
 .../WaitingQueueSchedulingService.java        |  9 ++---
 .../mnms/booking/service/WaitingService.java  | 39 ++-----------------
 5 files changed, 15 insertions(+), 56 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 63c963c..22251f1 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -59,13 +59,13 @@ public ResponseEntity> enterBookingPag
         }
     }
 
-    /// 예매 페이지 퇴장 - 대기열 대기자 예매 페이지 진입 (추후 수정 가능)
+    /// 예매 페이지 퇴장
     @GetMapping("/release")
     @Operation(
-            summary = "예매 페이지 진입 완료 처리",
-            description = "예매 페이지에 있던 사용자가 예매 페이지에서 나가면, " +
-                    "대기열에 있던 사용자가 예매 페이지로 입장 하게 됩니다. " +
-                    "대기열에 있던 모든 대기자의 대기번호가 변경됩니다."
+            summary = "예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)",
+            description = "예매 페이지에 있던 사용자가 퇴장했을 때 실행됩니다. " +
+                    "(대기열에 있던 대기번호 1번 사용자는 스케쥴러에 의해 예매 페이지로 자동 입장 하게 되고, " +
+                    "대기열에 있던 모든 대기자의 대기번호가 변경됩니다.)"
     )
     public ResponseEntity> releaseUser(
             @RequestParam String festivalId,
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index 2f6ac90..2e66e3e 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -19,9 +19,7 @@ public class WaitingNotificationService {
     private final ObjectMapper objectMapper;
     private final WaitingQueueRedisService waitingQueueRedisService;
 
-    /**
-     * 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
-     */
+    /// 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
     public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
         long waitingNumber = waitingQueueRedisService.getWaitingNumber(waitingQueueKey, loginId);
         if (waitingNumber != -1) {
@@ -31,9 +29,7 @@ public long getAndPublishWaitingNumber(String waitingQueueKey, String notificati
         return -1;
     }
 
-    /**
-     * Redis Pub/Sub 채널로 대기 순번 정보 발행
-     */
+    /// Redis Pub/Sub 채널로 대기 순번 정보 발행
     private void publishWaitingNumber(String userId, long waitingNumber, String notificationChannelKey) {
         try {
             WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
@@ -44,9 +40,7 @@ private void publishWaitingNumber(String userId, long waitingNumber, String noti
         }
     }
 
-    /**
-     * 모든 대기열 사용자에게 순번 업데이트 알림
-     */
+    /// 모든 대기열 사용자에게 순번 업데이트 알림
     public void notifyAllWaitingUsers(String waitingQueueKey, String notificationChannelKey) {
         Set allUsersInQueue = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
 
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index aea6814..57b2761 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -80,6 +80,7 @@ public long getWaitingNumber(String waitingQueueKey, String userId) {
         return (rank != null) ? rank + 1 : -1;
     }
 
+    // 현 예매 페이지에 있는 사용자 수
     public long getBookingUserCount(String bookingUsersKey) {
         Long count = redisTemplate.opsForSet().size(bookingUsersKey);
         return (count != null) ? count : 0L;
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index cd066c5..e4a269d 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -21,9 +21,7 @@ public class WaitingQueueSchedulingService {
     private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
     private final Map> scheduledTasks = new ConcurrentHashMap<>();
 
-    /**
-     * 스케줄러 시작 (중복 시작 방지)
-     */
+    /// 스케줄러 시작 (중복 시작 방지)
     public synchronized void startScheduler(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
         if (scheduledTasks.containsKey(waitingQueueKey) && !scheduledTasks.get(waitingQueueKey).isDone()) {
             return;
@@ -48,9 +46,7 @@ public synchronized void stopScheduler(String waitingQueueKey) {
         }
     }
 
-    /**
-     * 주기적으로 대기열 순번 발행 및 입장 처리
-     */
+    /// 주기적으로 대기열 순번 발행 및 입장 처리
     private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
         Set waitingUsers = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
 
@@ -66,6 +62,7 @@ private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, S
         long currentBookingCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
 
         while (currentBookingCount < availableNOP) {
+            // 대기번호 1 유저
             String nextUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
             if (nextUser == null) {
                 break;
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index f9be340..802f225 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -27,7 +27,7 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
         if (entered) {
             log.info("User {} entered booking page immediately.", userId);
             return 0L; // 즉시 입장
-        } else {
+        } else { // 대기열 입장
             waitingQueueRedisService.addUserToQueue(waitingQueueKey, userId);
             log.info("User {} added to waiting queue {}.", userId, waitingQueueKey);
             waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
@@ -35,17 +35,13 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
         }
     }
 
-    /**
-     * 예매 페이지에서 사용자 이탈 처리 (예매 완료 또는 타임아웃)
-     */
+    /// 예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)
     public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId){
         String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
         boolean removed = waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
 
         if(removed){
             log.info("User {} exited booking page and removed from booking user set.", userId);
-            // 대기열에서 다음 사용자 입장 처리
-            releaseWaitingUser(festivalId, reservationDate);
             return true;
         }else{
             log.warn("User {} was not found in booking user set on exit.", userId);
@@ -53,36 +49,7 @@ public boolean userExitBookingPage(String festivalId, LocalDateTime reservationD
         }
     }
 
-    /**
-     * 대기열에서 다음 사용자 입장 처리
-     */
-    private void releaseWaitingUser(String festivalId, LocalDateTime reservationDate) {
-        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
-        String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
-        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
-
-        // 대기열 큐 가장 앞에 있는 사람
-        String releasedUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
-
-        if (releasedUser != null) {
-            boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, releasedUser);
-
-            if (removed) {
-                log.info("User {} removed from waiting queue.", releasedUser);
-
-                waitingQueueRedisService.addBookingUser(bookingUsersKey, releasedUser);
-                log.info("User {} added to booking user set.", releasedUser);
-
-                waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
-            } else {
-                log.warn("Failed to remove user {} from waiting queue.", releasedUser);
-            }
-        }
-    }
-
-    /**
-     * 특정 사용자가 대기열에서 이탈했음을 처리
-     */
+    /// 특정 사용자가 대기열에서 이탈했음을 처리
     public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationDate, String userId) {
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);

From 2315fc08ac8908a4fe8fef61d11df5528bb8553d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 1 Sep 2025 14:40:58 +0900
Subject: [PATCH 087/149] =?UTF-8?q?MNMS-513=20Refactor:=20=EC=98=88?=
 =?UTF-8?q?=EC=95=BD=EC=9E=90/=EB=8C=80=EA=B8=B0=EC=9E=90=20=ED=82=A4=20?=
 =?UTF-8?q?=EA=B4=80=EB=A6=AC=20=EC=A4=91=EB=B3=B5=20=EA=B4=80=EB=A6=AC=20?=
 =?UTF-8?q?=EC=88=98=ED=96=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

중복 삭제 관리 안해주면 Redis 메모리 누적 → 성능 저하
개선 : TTL(2일)을 걸어두기 + 예약 종료 시점에 Redis 키 정리 로직 사용
---
 .../service/WaitingQueueRedisService.java       | 17 +++++++++++++++++
 .../service/WaitingQueueSchedulingService.java  |  4 ++++
 .../mnms/booking/service/WaitingService.java    | 15 +++++++++++++++
 3 files changed, 36 insertions(+)

diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index 57b2761..737f5d6 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -7,6 +7,8 @@
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
 
+import java.time.Duration;
+import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.Set;
 
@@ -59,6 +61,7 @@ public WaitingQueueRedisService(RedisTemplate redisTemplate) {
     public void addUserToQueue(String waitingQueueKey, String loginId) {
         long timestamp = System.currentTimeMillis();
         zSetOperations.add(waitingQueueKey, loginId, timestamp);
+        redisTemplate.expire(waitingQueueKey, Duration.ofDays(2));
     }
 
     public boolean removeUserFromQueue(String waitingQueueKey, String userId) {
@@ -86,12 +89,26 @@ public long getBookingUserCount(String bookingUsersKey) {
         return (count != null) ? count : 0L;
     }
 
+    public long getWaitingUserCount(String waitingQueueKey) {
+        Long count = redisTemplate.opsForZSet().zCard(waitingQueueKey);
+        return (count != null) ? count : 0L;
+    }
+
+
+
     public void addBookingUser(String bookingUsersKey, String userId) {
         redisTemplate.opsForSet().add(bookingUsersKey, userId);
+
+        // ttl 생성
+        redisTemplate.expire(bookingUsersKey, Duration.ofDays(2));
     }
 
     public boolean removeBookingUser(String bookingUsersKey, String userId) {
         Long removed = redisTemplate.opsForSet().remove(bookingUsersKey, userId);
         return removed != null && removed > 0;
     }
+
+    public void cleanKey(String key){
+        redisTemplate.delete(key);
+    }
 }
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index e4a269d..523ec69 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -52,6 +52,10 @@ private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, S
 
         if (waitingUsers == null || waitingUsers.isEmpty()) {
             stopScheduler(waitingQueueKey);
+
+            //
+
+
             return;
         }
 
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 802f225..b956491 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -38,10 +38,25 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
     /// 예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)
     public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId){
         String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
+        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         boolean removed = waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
 
         if(removed){
             log.info("User {} exited booking page and removed from booking user set.", userId);
+
+            // 예약자 Set이 비어 있는지 확인
+            long booking_remaining = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
+            long waiting_remaining = waitingQueueRedisService.getWaitingUserCount(waitingQueueKey);
+
+            if (booking_remaining == 0) {
+                // 대기열도 비어 있으면 키 삭제
+                waitingQueueRedisService.cleanKey(bookingUsersKey);
+                log.info("Cleaned up all Booking Redis keys for festival {}.", bookingUsersKey);
+            }
+            if(waiting_remaining == 0) {
+                waitingQueueRedisService.cleanKey(waitingQueueKey);
+                log.info("Cleaned up all Waiting Redis keys for festival {}.", waitingQueueKey);
+            }
             return true;
         }else{
             log.warn("User {} was not found in booking user set on exit.", userId);

From eda3b52fb5cba72125d08ea9c0a5e66e2c111428 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 1 Sep 2025 15:57:35 +0900
Subject: [PATCH 088/149] =?UTF-8?q?MNMS-513=20Refactor:=20=EB=8C=80?=
 =?UTF-8?q?=EA=B8=B0=EC=97=B4=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20?=
 =?UTF-8?q?=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/WaitingController.java |  4 +-
 .../dto/response/TicketDetailResponseDTO.java |  2 +
 .../com/mnms/booking/exception/ErrorCode.java | 12 ++++
 .../service/WaitingNotificationService.java   | 20 +++++--
 .../service/WaitingQueueRedisService.java     | 40 +++++++------
 .../WaitingQueueSchedulingService.java        | 56 +++++++++++--------
 .../mnms/booking/service/WaitingService.java  | 54 +++++++++---------
 7 files changed, 116 insertions(+), 72 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 22251f1..d5ee45c 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -83,8 +83,7 @@ public ResponseEntity> releaseUser(
         }
     }
 
-
-    // 대기열에서 퇴장
+    /// 대기열에서 퇴장
     @Operation(
             summary = "대기열 퇴장",
             description = "대기 중인 사용자가 스스로 대기열에서 나갈 때 호출됩니다. " +
@@ -107,7 +106,6 @@ public ResponseEntity> exitWaitingUser(
         }
     }
 
-
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index 7bb5d80..dfe78b9 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -27,6 +27,7 @@ public class TicketDetailResponseDTO {
     private String festivalId; // festivalId
     private String fname; // 공연명
     private String fcltynm; // 장소
+    private int ticketPrice; // 1매 티켓 가격
 
     public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival) {
         List qrIds = ticket.getQrCodes().stream()
@@ -43,6 +44,7 @@ public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festiva
                 .festivalId(festival.getFestivalId())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
+                .ticketPrice(festival.getTicketPrice())
                 .posterFile(festival.getPosterFile())
                 .build();
     }
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 9cfb152..d664c22 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -42,6 +42,18 @@ public enum ErrorCode {
     QR_CODE_EXPIRED("Q005", "QR 코드의 만료일이 지났습니다.", HttpStatus.GONE),
     QR_CODE_ALREADY_USED("Q006", "QR 코드가 이미 사용되었습니다.", HttpStatus.CONFLICT),
 
+    // waiting : 대기열 관련 예외
+    USER_NOT_FOUND_IN_BOOKING("W001", "사용자가 예매 페이지에 존재하지 않습니다.", HttpStatus.NOT_FOUND),
+    USER_NOT_FOUND_IN_WAITING("W002", "사용자가 대기열에 존재하지 않습니다.", HttpStatus.NOT_FOUND),
+    FAILED_TO_ENTER_QUEUE("W003", "대기열 진입에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    FAILED_TO_REMOVE_USER("W004", "사용자 제거에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    REDIS_CONNECTION_FAILED("R001", "Redis 연결에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    FAILED_TO_EXECUTE_SCRIPT("R002", "대기열 Lua 스크립트 실행에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    FAILED_TO_ENTER_BOOKING("W005", "예매 진입 처리에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    REDIS_PUBLISH_FAILED("R003", "Redis Pub/Sub 발행에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    JSON_SERIALIZATION_FAILED("S001", "메시지 직렬화에 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+    REDIS_OPERATION_FAILED("R004", "Redis 명령 실행 중 오류가 발생했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
+
     // Transfer
     TRANSFER_NOT_VALID_FILE_TYPE("TR001","유효하지 않은 파일 확장자입니다.",HttpStatus.NOT_ACCEPTABLE),
     TRANSFER_NOT_FOUND_INFORM("TR002", "검사에 실패하였습니다.", HttpStatus.NOT_FOUND),
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index 2e66e3e..e20f672 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -3,8 +3,12 @@
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.RedisConnectionFailureException;
+import org.springframework.data.redis.RedisSystemException;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -21,12 +25,18 @@ public class WaitingNotificationService {
 
     /// 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
     public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
-        long waitingNumber = waitingQueueRedisService.getWaitingNumber(waitingQueueKey, loginId);
-        if (waitingNumber != -1) {
+        try {
+            long waitingNumber = waitingQueueRedisService.getWaitingNumber(waitingQueueKey, loginId);
+            if (waitingNumber == -1) {
+                throw new BusinessException(ErrorCode.USER_NOT_FOUND_IN_WAITING);
+            }
             publishWaitingNumber(loginId, waitingNumber, notificationChannelKey);
             return waitingNumber;
+        } catch (RedisConnectionFailureException e) {
+            throw new BusinessException(ErrorCode.REDIS_CONNECTION_FAILED);
+        } catch (RedisSystemException e) {
+            throw new BusinessException(ErrorCode.REDIS_PUBLISH_FAILED);
         }
-        return -1;
     }
 
     /// Redis Pub/Sub 채널로 대기 순번 정보 발행
@@ -36,7 +46,9 @@ private void publishWaitingNumber(String userId, long waitingNumber, String noti
             String message = objectMapper.writeValueAsString(waitingNumberDto);
             stringRedisTemplate.convertAndSend(notificationChannelKey, message);
         } catch (JsonProcessingException e) {
-            log.error("Error converting DTO to JSON: {}", e.getMessage());
+            throw new BusinessException(ErrorCode.JSON_SERIALIZATION_FAILED);
+        } catch (RedisConnectionFailureException e) {
+            throw new BusinessException(ErrorCode.REDIS_CONNECTION_FAILED);
         }
     }
 
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index 737f5d6..08b9691 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -1,15 +1,17 @@
 package com.mnms.booking.service;
 
-import lombok.AllArgsConstructor;
-import lombok.RequiredArgsConstructor;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import org.springframework.data.redis.RedisConnectionFailureException;
+import org.springframework.data.redis.RedisSystemException;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ZSetOperations;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.stereotype.Service;
 
 import java.time.Duration;
-import java.time.LocalDateTime;
 import java.util.Collections;
+import java.util.Optional;
 import java.util.Set;
 
 @Service
@@ -41,16 +43,23 @@ public class WaitingQueueRedisService {
      * @return true = 즉시 입장, false = 대기열 필요
      */
     public boolean tryEnterBooking(String bookingUsersKey, long availableNOP, String userId) {
-        Long result = redisTemplate.execute(
-                enterScript,
-                Collections.singletonList(bookingUsersKey),
-                String.valueOf(availableNOP),
-                userId
-        );
-        return result != null && result == 1;
+        try {
+            Long result = redisTemplate.execute(
+                    enterScript,
+                    Collections.singletonList(bookingUsersKey),
+                    String.valueOf(availableNOP),
+                    userId
+            );
+
+            return Optional.of(result)
+                    .map(r -> r == 1)
+                    .orElseThrow(() -> new BusinessException(ErrorCode.FAILED_TO_ENTER_BOOKING));
+        } catch (RedisConnectionFailureException e) {
+            throw new BusinessException(ErrorCode.REDIS_CONNECTION_FAILED);
+        } catch (RedisSystemException e) {
+            throw new BusinessException(ErrorCode.FAILED_TO_EXECUTE_SCRIPT);
+        }
     }
-    //
-
 
 
     public WaitingQueueRedisService(RedisTemplate redisTemplate) {
@@ -58,10 +67,11 @@ public WaitingQueueRedisService(RedisTemplate redisTemplate) {
         this.zSetOperations = redisTemplate.opsForZSet();
     }
 
-    public void addUserToQueue(String waitingQueueKey, String loginId) {
+    public boolean addUserToQueue(String waitingQueueKey, String loginId) {
         long timestamp = System.currentTimeMillis();
-        zSetOperations.add(waitingQueueKey, loginId, timestamp);
+        Boolean result = zSetOperations.add(waitingQueueKey, loginId, timestamp);
         redisTemplate.expire(waitingQueueKey, Duration.ofDays(2));
+        return result != null && result; // null 방어
     }
 
     public boolean removeUserFromQueue(String waitingQueueKey, String userId) {
@@ -94,8 +104,6 @@ public long getWaitingUserCount(String waitingQueueKey) {
         return (count != null) ? count : 0L;
     }
 
-
-
     public void addBookingUser(String bookingUsersKey, String userId) {
         redisTemplate.opsForSet().add(bookingUsersKey, userId);
 
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index 523ec69..ae72082 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -1,8 +1,12 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import jakarta.annotation.PreDestroy;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.RedisConnectionFailureException;
+import org.springframework.data.redis.RedisSystemException;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 
@@ -48,43 +52,49 @@ public synchronized void stopScheduler(String waitingQueueKey) {
 
     /// 주기적으로 대기열 순번 발행 및 입장 처리
     private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, String notificationChannelKey, long availableNOP) {
-        Set waitingUsers = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
+        try {
+            Set waitingUsers = waitingQueueRedisService.getAllUsersInQueue(waitingQueueKey);
 
-        if (waitingUsers == null || waitingUsers.isEmpty()) {
-            stopScheduler(waitingQueueKey);
-
-            //
-
-
-            return;
-        }
+            if (waitingUsers == null || waitingUsers.isEmpty()) {
+                stopScheduler(waitingQueueKey);
+                return;
+            }
 
-        for (String loginId : waitingUsers) {
-            waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
-        }
+            for (String loginId : waitingUsers) {
+                try {
+                    waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, loginId);
+                } catch (BusinessException e) {
+                    log.warn("Failed to notify waiting number for user {}: {}", loginId, e.getMessage());
+                }
+            }
 
-        long currentBookingCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
+            long currentBookingCount = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
 
-        while (currentBookingCount < availableNOP) {
-            // 대기번호 1 유저
-            String nextUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
-            if (nextUser == null) {
-                break;
-            }
+            while (currentBookingCount < availableNOP) {
+                String nextUser = waitingQueueRedisService.getFirstUserInQueue(waitingQueueKey);
+                if (nextUser == null) {
+                    break;
+                }
 
-            boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, nextUser);
+                boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, nextUser);
+                if (!removed) {
+                    throw new BusinessException(ErrorCode.FAILED_TO_REMOVE_USER);
+                }
 
-            if (removed) {
                 waitingQueueRedisService.addBookingUser(bookingUsersKey, nextUser);
                 log.info("User {} moved from waiting queue to booking users for queue {}", nextUser, waitingQueueKey);
+
                 waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
                 currentBookingCount++;
-            } else {
-                break;
             }
+        } catch (RedisConnectionFailureException e) {
+            throw new BusinessException(ErrorCode.REDIS_CONNECTION_FAILED);
+        } catch (RedisSystemException e) {
+            throw new BusinessException(ErrorCode.REDIS_OPERATION_FAILED);
         }
     }
 
+
     @PreDestroy
     public void cleanup() {
         scheduler.shutdown();
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index b956491..8e5b202 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -1,5 +1,7 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -28,7 +30,10 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
             log.info("User {} entered booking page immediately.", userId);
             return 0L; // 즉시 입장
         } else { // 대기열 입장
-            waitingQueueRedisService.addUserToQueue(waitingQueueKey, userId);
+            boolean added = waitingQueueRedisService.addUserToQueue(waitingQueueKey, userId);
+            if (!added) {
+                throw new BusinessException(ErrorCode.FAILED_TO_ENTER_QUEUE);
+            }
             log.info("User {} added to waiting queue {}.", userId, waitingQueueKey);
             waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
             return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
@@ -41,27 +46,26 @@ public boolean userExitBookingPage(String festivalId, LocalDateTime reservationD
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         boolean removed = waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
 
-        if(removed){
-            log.info("User {} exited booking page and removed from booking user set.", userId);
+        if(!removed){
+            throw new BusinessException(ErrorCode.USER_NOT_FOUND_IN_BOOKING);
+        }
 
-            // 예약자 Set이 비어 있는지 확인
-            long booking_remaining = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
-            long waiting_remaining = waitingQueueRedisService.getWaitingUserCount(waitingQueueKey);
+        log.info("User {} exited booking page and removed from booking user set.", userId);
 
-            if (booking_remaining == 0) {
-                // 대기열도 비어 있으면 키 삭제
-                waitingQueueRedisService.cleanKey(bookingUsersKey);
-                log.info("Cleaned up all Booking Redis keys for festival {}.", bookingUsersKey);
-            }
-            if(waiting_remaining == 0) {
-                waitingQueueRedisService.cleanKey(waitingQueueKey);
-                log.info("Cleaned up all Waiting Redis keys for festival {}.", waitingQueueKey);
-            }
-            return true;
-        }else{
-            log.warn("User {} was not found in booking user set on exit.", userId);
-            return false;
+        // 예약자 Set이 비어 있는지 확인
+        long booking_remaining = waitingQueueRedisService.getBookingUserCount(bookingUsersKey);
+        long waiting_remaining = waitingQueueRedisService.getWaitingUserCount(waitingQueueKey);
+
+        if (booking_remaining == 0) {
+            // 대기열도 비어 있으면 키 삭제
+            waitingQueueRedisService.cleanKey(bookingUsersKey);
+            log.info("Cleaned up all Booking Redis keys for festival {}.", bookingUsersKey);
+        }
+        if(waiting_remaining == 0) {
+            waitingQueueRedisService.cleanKey(waitingQueueKey);
+            log.info("Cleaned up all Waiting Redis keys for festival {}.", waitingQueueKey);
         }
+        return true;
     }
 
     /// 특정 사용자가 대기열에서 이탈했음을 처리
@@ -71,13 +75,11 @@ public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationD
 
         boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, userId);
 
-        if (removed) {
-            log.info("User {} removed from waiting queue (manual removal).", userId);
-            waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
-            return true;
-        } else {
-            log.warn("Attempted to remove user {} from queue, but user was not found or removal failed.", userId);
-            return false;
+        if (!removed) {
+            throw new BusinessException(ErrorCode.USER_NOT_FOUND_IN_WAITING);
         }
+        log.info("User {} removed from waiting queue (manual removal).", userId);
+        waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
+        return true;
     }
 }
\ No newline at end of file

From d89f085f556df3f09c6925ecda8dfd56a6cd1186 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 1 Sep 2025 16:19:35 +0900
Subject: [PATCH 089/149] =?UTF-8?q?MNMS-513=20Refactor:=20WebSocket=20?=
 =?UTF-8?q?=EA=B5=AC=EB=8F=85=20=EB=B0=A9=EC=8B=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

controller request header로 변경
---
 .../com/mnms/booking/controller/WaitingController.java | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index d5ee45c..f48523a 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -16,6 +16,7 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
+import org.springframework.messaging.handler.annotation.Header;
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.security.core.Authentication;
@@ -108,21 +109,22 @@ public ResponseEntity> exitWaitingUser(
 
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
-     * 클라이언트가 /app/subscribe/waiting/{userId} 로 메시지를 보냄 (최초 구독 요청)
+     * 클라이언트가 /app/subscribe/waiting로 메시지를 보냄 (최초 구독 요청)
      */
-    @Hidden
     @MessageMapping("/subscribe/waiting")
     public void subscribeWaitingQueue(
-            @RequestParam String festivalId,
-            @RequestParam LocalDateTime reservationDate,
+            @Header("festivalId") String festivalId,
+            @Header("reservationDate") LocalDateTime reservationDate,
             Authentication authentication) {
         String userId = getUserId(authentication);
         log.info("User {} subscribed to waiting queue updates.", userId);
+
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
         waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
     }
 
+
     public String getUserId(Authentication authentication) {
         return String.valueOf(securityResponseUtil.requireUserId(authentication));
     }

From 0e475ae7d7aeee4c0e824d893ec13ca7cdfecfb3 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 2 Sep 2025 09:47:53 +0900
Subject: [PATCH 090/149] =?UTF-8?q?MNMS-513=20Refactor:=20=EB=8C=80?=
 =?UTF-8?q?=EA=B8=B0=EC=97=B4=20=EB=B2=88=ED=98=B8=20=EC=A0=84=EC=B2=B4=20?=
 =?UTF-8?q?=EA=B0=B1=EC=8B=A0=20=EB=B0=A9=EC=8B=9D=20=EB=B6=80=EB=B6=84=20?=
 =?UTF-8?q?=EA=B0=B1=EC=8B=A0=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

대기열에서 대기자 퇴장 시, 전체 대기자 조회 X
대기자 대기번호 뒤에 있는 대기자만 조회 O
---
 .../service/WaitingNotificationService.java        | 14 ++++++++++++++
 .../booking/service/WaitingQueueRedisService.java  |  9 ++++++++-
 .../service/WaitingQueueSchedulingService.java     |  1 -
 .../com/mnms/booking/service/WaitingService.java   |  3 ++-
 4 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index e20f672..e551c1d 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -62,4 +62,18 @@ public void notifyAllWaitingUsers(String waitingQueueKey, String notificationCha
             }
         }
     }
+
+    public void notifyAffectedWaitingUsers(String waitingQueueKey, String notificationChannelKey, Long removedRank) {
+        if (removedRank == null) {
+            return;
+        }
+
+        // 대기열 퇴장한 사람 뒤에 있는 사용자만 조회
+        Set affectedUsers = waitingQueueRedisService.getUsersByRange(waitingQueueKey, removedRank, -1);
+        if (affectedUsers != null) {
+            for (String userId : affectedUsers) {
+                getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index 08b9691..1aa94e4 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -83,6 +83,11 @@ public Set getAllUsersInQueue(String waitingQueueKey) {
         return zSetOperations.range(waitingQueueKey, 0, -1);
     }
 
+    // 수정 필요
+    public Set getUsersByRange(String waitingQueueKey, long start, long end) {
+        return zSetOperations.range(waitingQueueKey, start, end);
+    }
+
     public String getFirstUserInQueue(String waitingQueueKey) {
         Set users = zSetOperations.range(waitingQueueKey, 0, 0);
         return (users != null && !users.isEmpty()) ? users.iterator().next() : null;
@@ -115,7 +120,9 @@ public boolean removeBookingUser(String bookingUsersKey, String userId) {
         Long removed = redisTemplate.opsForSet().remove(bookingUsersKey, userId);
         return removed != null && removed > 0;
     }
-
+    public Long getRank(String waitingQueueKey, String userId){
+        return zSetOperations.rank(waitingQueueKey, userId);
+    }
     public void cleanKey(String key){
         redisTemplate.delete(key);
     }
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index ae72082..eba3dac 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -94,7 +94,6 @@ private void runSchedulerLogic(String waitingQueueKey, String bookingUsersKey, S
         }
     }
 
-
     @PreDestroy
     public void cleanup() {
         scheduler.shutdown();
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 8e5b202..5b7ec83 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -73,13 +73,14 @@ public boolean removeUserFromQueue(String festivalId, LocalDateTime reservationD
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
         String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
 
+        Long removedRank = waitingQueueRedisService.getRank(waitingQueueKey, userId);
         boolean removed = waitingQueueRedisService.removeUserFromQueue(waitingQueueKey, userId);
 
         if (!removed) {
             throw new BusinessException(ErrorCode.USER_NOT_FOUND_IN_WAITING);
         }
         log.info("User {} removed from waiting queue (manual removal).", userId);
-        waitingNotificationService.notifyAllWaitingUsers(waitingQueueKey, notificationChannelKey);
+        waitingNotificationService.notifyAffectedWaitingUsers(waitingQueueKey, notificationChannelKey, removedRank);
         return true;
     }
 }
\ No newline at end of file

From 4809ebd084966ca8788b9a13f5046baa5ea000db Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 2 Sep 2025 15:55:09 +0900
Subject: [PATCH 091/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20=EC=96=91=EB=8F=84=20/transfer/watch?=
 =?UTF-8?q?=20api=20response=EC=97=90=20transferId=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/dto/response/TicketTransferResponseDTO.java    | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
index c74e2c4..a081bc1 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
@@ -18,6 +18,7 @@
 public class TicketTransferResponseDTO {
 
     ///  TRANSFER
+    private Long transferId;
     private Long senderId;
     private String senderName;
     private TransferType transferType;
@@ -37,6 +38,7 @@ public class TicketTransferResponseDTO {
 
     public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, Festival festival) {
         return TicketTransferResponseDTO.builder()
+                .transferId(transfer.getId())
                 .senderId(transfer.getSenderId())
                 .senderName(transfer.getSenderName())
                 .transferType(transfer.getTransferType())

From 8d040adb48ed396b657e453647c2244341185015 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 3 Sep 2025 09:48:03 +0900
Subject: [PATCH 092/149] =?UTF-8?q?MNMS-462=20Refactor:=20=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EB=94=94=ED=85=8C=EC=9D=BC=20=EB=82=B4=EC=97=AD=20?=
 =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20authentication=20name=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/TicketController.java   |  5 ++++-
 .../dto/response/TicketDetailResponseDTO.java  |  6 +++++-
 .../com/mnms/booking/security/AuthDetails.java | 16 ++++++++++++++++
 .../security/HeaderAuthenticationFilter.java   | 13 +++++++++----
 .../mnms/booking/service/TicketService.java    |  4 ++--
 .../booking/util/SecurityResponseUtil.java     | 18 ++++++++----------
 6 files changed, 44 insertions(+), 18 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/security/AuthDetails.java

diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index 2f56dec..795d189 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -43,8 +43,11 @@ public ResponseEntity>> getUserTickets(A
     )
     public ResponseEntity> getUserTicketDetail(@RequestParam String reservationNumber,
                                                                                         Authentication authentication) {
-        TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication));
+        TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication), securityResponseUtil.requireName(authentication));
         return ApiResponseUtil.success(ticket);
     }
 
+
+
+
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index dfe78b9..1eb7e7b 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -14,6 +14,9 @@
 @Builder
 public class TicketDetailResponseDTO {
 
+    // authentication name
+    private String userName;
+
     // ticket
     private Long id;
     private String reservationNumber; // 예매 번호
@@ -29,13 +32,14 @@ public class TicketDetailResponseDTO {
     private String fcltynm; // 장소
     private int ticketPrice; // 1매 티켓 가격
 
-    public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival) {
+    public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival, String userName) {
         List qrIds = ticket.getQrCodes().stream()
                 .map(QrCode::getQrCodeId)
                 .toList();
 
         return TicketDetailResponseDTO.builder()
                 .id(ticket.getId())
+                .userName(userName)
                 .reservationNumber(ticket.getReservationNumber())
                 .performanceDate(ticket.getPerformanceDate())
                 .deliveryMethod(ticket.getDeliveryMethod())
diff --git a/src/main/java/com/mnms/booking/security/AuthDetails.java b/src/main/java/com/mnms/booking/security/AuthDetails.java
new file mode 100644
index 0000000..f604d77
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/AuthDetails.java
@@ -0,0 +1,16 @@
+package com.mnms.booking.security;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.security.web.authentication.WebAuthenticationDetails;
+
+public class AuthDetails extends WebAuthenticationDetails {
+    private final String userName;
+
+    public AuthDetails(HttpServletRequest request, String userName) {
+        super(request);
+        this.userName = userName;
+    }
+    public String getUserName() {
+        return userName;
+    }
+}
diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index 31a4405..ede95f9 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -1,5 +1,4 @@
 package com.mnms.booking.security;
-
 import jakarta.servlet.FilterChain;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
@@ -10,7 +9,6 @@
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
 import org.springframework.stereotype.Component;
 import org.springframework.web.filter.OncePerRequestFilter;
 
@@ -39,7 +37,14 @@ protected void doFilterInternal(
         // 게이트웨이가 붙여주는 헤더 (✅ userId 사용)
         final String userIdHeader = trimToNull(request.getHeader("X-User-Id"));
         final String rolesHdr     = trimToNull(request.getHeader("X-User-Role"));
-
+        final String userNameHeader = trimToNull(request.getHeader("X-User-Name"));
+        String userName = "";
+        if(userNameHeader != null) {
+            userName = new String(
+                    java.util.Base64.getUrlDecoder().decode(userNameHeader),
+                    java.nio.charset.StandardCharsets.UTF_8
+            );
+        }
         Authentication current = SecurityContextHolder.getContext().getAuthentication();
         boolean isAnonymous = (current instanceof AnonymousAuthenticationToken);
         boolean canSetAuth = (current == null) || isAnonymous;
@@ -70,7 +75,7 @@ protected void doFilterInternal(
             // principal = userId(String) → Controller에서 Long.parseLong(principal.getName()) 가능
             UsernamePasswordAuthenticationToken auth =
                     new UsernamePasswordAuthenticationToken(String.valueOf(userId), null, authorities);
-            auth.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+            auth.setDetails(new com.mnms.booking.security.AuthDetails(request, userName));
             SecurityContextHolder.getContext().setAuthentication(auth);
         }
 
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index ff7c129..d186211 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -41,13 +41,13 @@ public List getTicketsByUser(Long userId) {
     }
 
     // 예매 상세 조회
-    public TicketDetailResponseDTO getTicketDetailByUser(String reservationNumber, Long userId) {
+    public TicketDetailResponseDTO getTicketDetailByUser(String reservationNumber, Long userId, String userName) {
         Ticket ticket = ticketRepository.findByUserIdAndReservationNumber(userId, reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
         if (!ticket.getUserId().equals(userId)) {
             throw new BusinessException(ErrorCode.USER_UNAUTHORIZED_ACCESS);
         }
-        return TicketDetailResponseDTO.fromEntity(ticket, ticket.getFestival());
+        return TicketDetailResponseDTO.fromEntity(ticket, ticket.getFestival(), userName);
     }
 }
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
index 57c6347..142765d 100644
--- a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.security.AuthDetails;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.Authentication;
@@ -28,20 +29,17 @@ public Long requireUserId(Authentication authentication) {
 
     // Authentication에서 name 추출
     public String requireName(Authentication authentication) {
+        String userName = null;
         log.info("authentication : {}", authentication);
-        if (!(authentication instanceof JwtAuthenticationToken jwtAuth)) {
-            throw new BusinessException(ErrorCode.USER_INVALID);
+        Object details = authentication.getDetails();
+        if (details instanceof AuthDetails d) {
+            userName = d.getUserName();
+            log.info("authentication name : {}", userName);
         }
+        return userName;
+    }
 
-        Jwt jwt = jwtAuth.getToken();
-        String name = jwt.getClaimAsString("name");
-
-        if (name == null || name.isEmpty()) {
-            throw new BusinessException(ErrorCode.USER_INVALID);
-        }
 
-        return name;
-    }
 
     // Authentication에서 ROLE 빼오기
     public List requireRole(Authentication authentication) {

From befbaebb9da6896544d56a1187e9ca1fb3dd9a1c Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 3 Sep 2025 13:56:29 +0900
Subject: [PATCH 093/149] =?UTF-8?q?MNMS-462=20Feat:=20=EC=96=91=EB=8F=84?=
 =?UTF-8?q?=EC=9E=90=20=EC=96=91=EB=8F=84=20=EA=B0=80=EB=8A=A5=20=ED=8B=B0?=
 =?UTF-8?q?=EC=BC=93=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 받은 티켓 양도 불가능
---
 build.gradle                                  |  3 +++
 .../booking/controller/BookingController.java |  2 +-
 .../controller/TransferController.java        | 11 +++++++++
 .../dto/request/UpdateTicketRequestDTO.java   | 10 --------
 .../response/TransferOthersResponseDTO.java   |  1 -
 .../java/com/mnms/booking/entity/Ticket.java  |  1 +
 .../booking/repository/TicketRepository.java  |  3 ++-
 .../repository/TransferRepository.java        |  2 ++
 .../service/BookingCommandService.java        | 12 ++++++----
 .../mnms/booking/service/TransferService.java | 23 +++++++++++++++++++
 10 files changed, 50 insertions(+), 18 deletions(-)

diff --git a/build.gradle b/build.gradle
index 68db442..30b7acf 100644
--- a/build.gradle
+++ b/build.gradle
@@ -83,6 +83,9 @@ dependencies {
 
 	// test
 	testImplementation 'it.ozimov:embedded-redis:0.7.3'
+
+	//Mail
+	implementation 'org.springframework.boot:spring-boot-starter-mail'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 01d9a8a..6cd440a 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -104,7 +104,7 @@ public ResponseEntity> checkStatus(@RequestPa
     @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
             description = "예매 과정에서 예매자 정보를 조회합니다." +
-                    "예매자 role이 user인 사람만 조회 가능합니다. (phone, email, address, birth)"
+                    "예매자 role이 user인 사람만 조회 가능합니다. (email)"
     )
     public ResponseEntity> getUserInfo(Authentication authentication) {
         return ApiResponseUtil.success(userApiClient.getUserInfoById(securityResponseUtil.requireUserId(authentication)));
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index 6029416..f6c8c17 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -5,6 +5,7 @@
 import com.mnms.booking.dto.request.TicketTransferRequestDTO;
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
 import com.mnms.booking.dto.response.PersonInfoResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.enums.ReservationStatus;
@@ -37,6 +38,16 @@ public class TransferController {
     private final SecurityResponseUtil securityResponseUtil;
     private final TransferCompletionService transferCompletionService;
 
+    ///  양도할 수 있는 티켓 조회
+    @GetMapping("/transferor")
+    @Operation(summary = "양도 가능한 티켓 정보 조회",
+            description = "사용자가 양도 가능한 티켓을 조회할 수 있습니다. (status : 양도 받은 티켓 양도 불가능)"
+    )
+    public ResponseEntity>> getUserTickets(Authentication authentication) {
+        List tickets = transferService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
+        return ApiResponseUtil.success(tickets);
+    }
+
 
     ///  가족관계증명서 인증
     @PostMapping("/extract")
diff --git a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
index 0e571e0..3f10c91 100644
--- a/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
+++ b/src/main/java/com/mnms/booking/dto/request/UpdateTicketRequestDTO.java
@@ -1,8 +1,5 @@
 package com.mnms.booking.dto.request;
 
-import com.mnms.booking.dto.response.BookingResponseDTO;
-import com.mnms.booking.dto.response.QrResponseDTO;
-import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import lombok.AllArgsConstructor;
@@ -10,8 +7,6 @@
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.util.stream.Collectors;
-
 @Data
 @Builder
 @NoArgsConstructor
@@ -23,9 +18,4 @@ public class UpdateTicketRequestDTO {
 
     private TicketType ticketType;
     private String address;
-
-//    public TransferStatus getTransferStatusEnum() {
-//        return TransferStatus.valueOf(this.transferStatus);
-//    }
-
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
index 17b06b7..711eabb 100644
--- a/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TransferOthersResponseDTO.java
@@ -14,7 +14,6 @@
 @Builder
 public class TransferOthersResponseDTO {
     private Long receiverId; // 양수자 id
-
     private Long senderId; // 양도자 id
 
     private String reservationNumber;
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 1322eec..085878c 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -15,6 +15,7 @@
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 @Table(name = "ticket")
+@ToString
 public class Ticket {
 
     @Id
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 7774cf4..72c1718 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -14,7 +14,6 @@
 
 @Repository
 public interface TicketRepository extends JpaRepository {
-    int countByUserIdAndFestivalIdAndPerformanceDate(Long userId, Long festivalId, LocalDateTime performanceDate);
 
     @Query("SELECT COALESCE(SUM(t.selectedTicketCount), 0) " +
             "FROM Ticket t " +
@@ -89,4 +88,6 @@ List findByFestivalIdAndReservationStatus(@Param("festivalId") String fe
 
     @Query("SELECT t.reservationStatus FROM Ticket t WHERE t.reservationNumber = :reservationNumber")
     ReservationStatus findReservationStatusByReservationNumber(@Param("reservationNumber") String reservationNumber);
+
+    List findByUserIdAndReservationStatus(Long userId, ReservationStatus status);
 }
diff --git a/src/main/java/com/mnms/booking/repository/TransferRepository.java b/src/main/java/com/mnms/booking/repository/TransferRepository.java
index b76e7be..8ea8620 100644
--- a/src/main/java/com/mnms/booking/repository/TransferRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TransferRepository.java
@@ -30,4 +30,6 @@ List findByReceiverIdWithTicketAndFestival(
 
     @Query("SELECT t.status FROM Transfer t WHERE t.id = :transferId")
     TransferStatus findTransferStatusById(Long transferId);
+
+    boolean existsByTicketId(Long ticketId);
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index ccfd8d5..7b0a4ec 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -14,6 +14,7 @@
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.CommonUtils;
+import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
@@ -28,10 +29,7 @@
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
 import java.time.temporal.ChronoUnit;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.UUID;
+import java.util.*;
 import java.util.stream.IntStream;
 
 
@@ -51,6 +49,7 @@ public class BookingCommandService {
     private final ThreadPoolTaskScheduler scheduler;
     private final SimpMessagingTemplate messagingTemplate;
     private final CommonUtils commonUtils;
+    private final UserApiClient userApiClient;
 
     /// 1차: 가예매 - 임시 예약
     @Transactional
@@ -133,7 +132,7 @@ private void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
         );
     }
 
-    /// 최종 완료 - status 변경
+    /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
     @Transactional
     public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)
@@ -155,6 +154,9 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
                 "/queue/ticket-status",
                 new TicketStatusResponseDTO(bookingTicket.getReservationNumber(), newStatus)
         );
+
+        //String email;
+        //email = userApiClient.getUsersByIds();
     }
 
     ///  예매 취소
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 26b0815..5c42486 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -1,10 +1,12 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.TicketTransferRequestDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
 import com.mnms.booking.exception.BusinessException;
@@ -13,18 +15,39 @@
 import com.mnms.booking.repository.TransferRepository;
 import jakarta.validation.Valid;
 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;
 
 @Service
 @RequiredArgsConstructor
+@Slf4j
 @Transactional(readOnly = true)
 public class TransferService {
 
     private final TicketRepository ticketRepository;
     private final TransferRepository transferRepository;
 
+    ///  양도 가능한 티켓 조회
+    public List getTicketsByUser(Long userId) {
+
+        List tickets = ticketRepository.findByUserIdAndReservationStatus(userId, ReservationStatus.CONFIRMED);
+        if(tickets.isEmpty()){
+            throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
+        }
+        log.info("tickets : {}", tickets);
+
+        return tickets.stream()
+                .filter(ticket -> ticket.getPerformanceDate().isAfter(LocalDateTime.now()))
+                .filter(ticket -> !transferRepository.existsByTicketId(ticket.getId()))
+                .map(ticket -> TicketResponseDTO.fromEntity(ticket, ticket.getFestival()))
+                .toList();
+    }
+
+
     ///  양도 요청
     @Transactional
     public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {

From df64a454df966d080e23efb7f36841785fb999c5 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Wed, 3 Sep 2025 14:08:57 +0900
Subject: [PATCH 094/149] =?UTF-8?q?MNMS-575=20feat:=20prod=20=EC=9A=A9=20?=
 =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=A0=9C=EC=9E=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../resources/application-prod.properties     | 53 +++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 src/main/resources/application-prod.properties

diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
new file mode 100644
index 0000000..52e06d2
--- /dev/null
+++ b/src/main/resources/application-prod.properties
@@ -0,0 +1,53 @@
+myboot.name=Dev Env
+
+#log level
+logging.level.root=INFO
+logging.level.org.springframework.security=INFO
+logging.level.com.mnms.booking.service=INFO
+
+#maria db info
+spring.datasource.url=${DB_URL}
+spring.datasource.username=${DB_USERNAME}
+spring.datasource.password=${DB_PASSWORD}
+spring.datasource.driverClassName=org.mariadb.jdbc.Driver
+
+# hibernate info
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
+
+# redis 설정
+spring.data.redis.host=${REDIS_SERVER_URL}
+spring.data.redis.port=${REDIS_PORT}
+
+## kafka
+app.kafka.topic.festival-event=festival-topic
+app.kafka.topic.payment-event= payment-status-events
+app.kafka.topic.payment-cancel-event=payment-cancel-events
+app.kafka.topic.transfer-payment-event=payment-transfer-status-events
+
+spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
+spring.kafka.consumer.auto-offset-reset=earliest
+spring.kafka.consumer.properties.spring.json.trusted.packages=*
+spring.kafka.consumer.properties.spring.json.use.type.headers=false
+spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
+
+
+# jwt
+jwt.public-pem-path=classpath:keys/public.pem
+jwt.issuer=festival-user-service
+spring.config.import=optional:file:.env[.properties]
+
+# swagger
+springdoc.api-docs.enabled=true
+springdoc.swagger-ui.enabled=true
+springdoc.swagger-ui.path=/swagger-ui.html
+springdoc.override-with-generic-response=false
+
+# user api
+base.service.url=${BASE_API}
+user.base.service.url=${USER_BASE_API}
+user.service.url=${USER_INFO_API}
+user.service.stats.url=${USER_STATS_LIST_API}
+booking.user.service.url=${BOOKING_USER_INFO_API}

From e7c3686119dfcba184309751497a76d656f36952 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 09:25:50 +0900
Subject: [PATCH 095/149] =?UTF-8?q?MNMS-462=20Feat:=20=EC=98=88=EB=A7=A4?=
 =?UTF-8?q?=20=EC=99=84=EB=A3=8C=20=EC=8B=9C=20=EC=98=88=EB=A7=A4=EC=9E=90?=
 =?UTF-8?q?=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EB=A1=9C=20=EC=98=88=EB=A7=A4=20?=
 =?UTF-8?q?=EC=A0=95=EB=B3=B4=20=EC=A0=84=EC=86=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java | 21 +++++--
 ...seDTO.java => BookingUserResponseDTO.java} |  9 ++-
 .../kafka/listener/PaymentListener.java       |  2 +-
 .../service/BookingCommandService.java        | 61 +++++++++++++------
 .../mnms/booking/service/EmailService.java    | 29 +++++++++
 .../com/mnms/booking/util/UserApiClient.java  | 15 +++--
 src/main/resources/application-dev.properties | 21 ++++++-
 .../templates/email/ticket-confirmation.txt   | 13 ++++
 8 files changed, 135 insertions(+), 36 deletions(-)
 rename src/main/java/com/mnms/booking/dto/response/{UserInfoResponseDTO.java => BookingUserResponseDTO.java} (50%)
 create mode 100644 src/main/java/com/mnms/booking/service/EmailService.java
 create mode 100644 src/main/resources/templates/email/ticket-confirmation.txt

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 6cd440a..c63c75e 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -4,8 +4,8 @@
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
 import com.mnms.booking.dto.response.BookingDetailResponseDTO;
+import com.mnms.booking.dto.response.BookingUserResponseDTO;
 import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
-import com.mnms.booking.dto.response.UserInfoResponseDTO;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
@@ -17,12 +17,11 @@
 import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.List;
-
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
@@ -106,7 +105,21 @@ public ResponseEntity> checkStatus(@RequestPa
             description = "예매 과정에서 예매자 정보를 조회합니다." +
                     "예매자 role이 user인 사람만 조회 가능합니다. (email)"
     )
-    public ResponseEntity> getUserInfo(Authentication authentication) {
+    public ResponseEntity> getUserInfo(Authentication authentication) {
         return ApiResponseUtil.success(userApiClient.getUserInfoById(securityResponseUtil.requireUserId(authentication)));
     }
+
+    ///  이메일 임시 테스트
+    @PostMapping("/email/test")
+    public ResponseEntity confirmTicket(
+            @RequestParam String reservationNumber,
+            @RequestParam boolean paymentStatus) {
+        try {
+            bookingCommandService.confirmTicket(reservationNumber, paymentStatus);
+            return ResponseEntity.ok("예매 상태가 성공적으로 업데이트되고 이메일이 전송되었습니다.");
+        } catch (Exception e) {
+            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+                    .body("에러 발생: " + e.getMessage());
+        }
+    }
 }
diff --git a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingUserResponseDTO.java
similarity index 50%
rename from src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
rename to src/main/java/com/mnms/booking/dto/response/BookingUserResponseDTO.java
index 4d1a88c..6dfb136 100644
--- a/src/main/java/com/mnms/booking/dto/response/UserInfoResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingUserResponseDTO.java
@@ -1,12 +1,11 @@
 package com.mnms.booking.dto.response;
 
-import lombok.Builder;
 import lombok.Data;
-
-import java.util.List;
+import lombok.Getter;
 
 @Data
-@Builder
-public class UserInfoResponseDTO {
+@Getter
+public class BookingUserResponseDTO {
+    private String name;
     private String email;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index 6250294..4885867 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -21,7 +21,7 @@ public class PaymentListener {
     private final TransferCompletionService transferCompletionService;
 
     @KafkaListener(topics = "${app.kafka.topic.payment-event}", groupId = "booking-service-group")
-    public void consumePaymentSuccess(String message) throws JsonProcessingException {
+    public void consumePaymentSuccess(String message) throws Exception {
         ObjectMapper objectMapper = new ObjectMapper();
 
         objectMapper.registerModule(new JavaTimeModule());
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 7b0a4ec..96c3e7b 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.service;
 
-import com.mnms.booking.dto.request.BookingRequestDTO;
+import  com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
 import com.mnms.booking.dto.response.*;
@@ -9,19 +9,19 @@
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
-import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.repository.FestivalRepository;
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
@@ -35,7 +35,6 @@
 
 @Service
 @RequiredArgsConstructor
-@Slf4j
 @Transactional(readOnly = true)
 public class BookingCommandService {
 
@@ -45,7 +44,10 @@ public class BookingCommandService {
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
     private final FestivalRepository festivalRepository;
+
     private final QrCodeService qrCodeService;
+    private final EmailService emailService;
+
     private final ThreadPoolTaskScheduler scheduler;
     private final SimpMessagingTemplate messagingTemplate;
     private final CommonUtils commonUtils;
@@ -116,8 +118,6 @@ private void validateCapacity(Festival festival, BookingRequestDTO request, Long
                 List.of(ReservationStatus.CONFIRMED, ReservationStatus.PAYMENT_IN_PROGRESS)
         );
 
-        log.info("total selected ticket count : {}", totalCount);
-
         if (totalCount + selectedTicketCount > festival.getAvailableNOP()) {
             throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVALIABLE_PEOPLE);
         }
@@ -134,29 +134,56 @@ private void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
 
     /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
     @Transactional
-    public void confirmTicket(String reservationNumber, boolean paymentStatus) {
-        Ticket bookingTicket = ticketRepository.findByReservationNumber(reservationNumber)
+    public void confirmTicket(String reservationNumber, boolean paymentStatus) throws Exception {
+        Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
         ReservationStatus newStatus = paymentStatus ?
                 ReservationStatus.CONFIRMED :
                 ReservationStatus.CANCELED;
         // 결제 상태 변경
-        if(bookingTicket.getReservationStatus() != ReservationStatus.CONFIRMED
-                && bookingTicket.getReservationStatus() != ReservationStatus.CANCELED) {
-            bookingTicket.setReservationStatus(newStatus);
-            ticketRepository.save(bookingTicket);
+        if(ticket.getReservationStatus() != ReservationStatus.CONFIRMED
+                && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
+            ticket.setReservationStatus(newStatus);
+            ticketRepository.save(ticket);
+        }
+
+        // 예매 내역 전송
+        BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
+        String subject = String.format("[예매확인] %s 티켓", ticket.getFestival().getFname());
+
+        InputStream is = getClass().getClassLoader()
+                .getResourceAsStream("templates/email/ticket-confirmation.txt");
+        if (is == null) {
+            throw new IllegalStateException("이메일 템플릿을 찾을 수 없습니다.");
         }
 
+        String template = new String(is.readAllBytes(), StandardCharsets.UTF_8);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년MM월dd일 a h시");
+
+        String content = String.format(
+                template,
+                user.getName(),
+                ticket.getReservationNumber(),
+                ticket.getFestival().getFname(),
+                ticket.getPerformanceDate().format(formatter),
+                ticket.getFestival().getFcltynm(),
+                ticket.getFestival().getTicketPrice() * ticket.getSelectedTicketCount(),
+                ticket.getDeliveryMethod() == TicketType.MOBILE ? "모바일" : "지류"
+        );
+
+        emailService.sendEmail(
+                user.getEmail(),
+                subject,
+                content
+        );
+
         // WebSocket 전송
         messagingTemplate.convertAndSendToUser(
-                String.valueOf(bookingTicket.getUserId()),
+                String.valueOf(ticket.getUserId()),
                 "/queue/ticket-status",
-                new TicketStatusResponseDTO(bookingTicket.getReservationNumber(), newStatus)
+                new TicketStatusResponseDTO(ticket.getReservationNumber(), newStatus)
         );
-
-        //String email;
-        //email = userApiClient.getUsersByIds();
     }
 
     ///  예매 취소
diff --git a/src/main/java/com/mnms/booking/service/EmailService.java b/src/main/java/com/mnms/booking/service/EmailService.java
new file mode 100644
index 0000000..50cf912
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/EmailService.java
@@ -0,0 +1,29 @@
+package com.mnms.booking.service;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.stereotype.Service;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+@Service
+@RequiredArgsConstructor
+public class EmailService {
+    private final JavaMailSender mailSender;
+
+    public void sendEmail(String to, String subject, String text) {
+        SimpleMailMessage message = new SimpleMailMessage();
+        message.setTo(to);           // 수신자
+        message.setSubject(subject); // 제목
+        message.setText(text);       // 내용
+        message.setFrom("your_email@gmail.com"); // 발신자 (설정 가능)
+
+        mailSender.send(message);
+    }
+
+    public static String loadTemplate(String path) throws Exception {
+        return new String(Files.readAllBytes(Paths.get(path)));
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/util/UserApiClient.java b/src/main/java/com/mnms/booking/util/UserApiClient.java
index 0e70e3f..9c8cf9d 100644
--- a/src/main/java/com/mnms/booking/util/UserApiClient.java
+++ b/src/main/java/com/mnms/booking/util/UserApiClient.java
@@ -2,7 +2,7 @@
 
 import com.mnms.booking.dto.response.ApiResponseDTO;
 import com.mnms.booking.dto.response.BookingUserInfoResponseDTO;
-import com.mnms.booking.dto.response.UserInfoResponseDTO;
+import com.mnms.booking.dto.response.BookingUserResponseDTO;
 import lombok.RequiredArgsConstructor;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.core.ParameterizedTypeReference;
@@ -20,10 +20,10 @@ public class UserApiClient {
 
     private final WebClient webClient;
 
-    @Value("${base.service.url}${user.service.url}")
+    @Value("${base.service.url}${user.service.email.url}")
     private String userServiceUrl;
 
-    @Value("${base.service.url}${booking.user.service.url}")
+    @Value("${base.service.url}${user.service.booking.url}")
     private String bookingUserServiceUrl;
 
     // userId 리스트 요청
@@ -38,12 +38,15 @@ public List getUsersByIds(List userIds) {
     }
 
     // userId로 요청
-    public UserInfoResponseDTO getUserInfoById(Long userId) {
+    public BookingUserResponseDTO getUserInfoById(Long userId) {
         String url = String.format("%s/%d", userServiceUrl, userId);
-        return webClient.get()
+        ApiResponseDTO response = webClient.get()
                 .uri(url)
                 .retrieve()
-                .bodyToMono(UserInfoResponseDTO.class)
+                .bodyToMono(new ParameterizedTypeReference>() {
+                })
                 .block();
+
+        return response != null ? response.getData() : null;
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 41d8f99..1b08b27 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -55,8 +55,23 @@ springdoc.override-with-generic-response=false
 # user api
 base.service.url=${BASE_API}
 user.base.service.url=${USER_BASE_API}
-user.service.url=${USER_INFO_API}
+user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
-booking.user.service.url=${BOOKING_USER_INFO_API}
+user.service.booking.url=${BOOKING_USER_INFO_API}
 
-logging.level.com.mnms.booking.service=DEBUG
\ No newline at end of file
+logging.level.com.mnms.booking.service=DEBUG
+
+
+# mail
+spring.mail.host=smtp.gmail.com
+spring.mail.port=587
+spring.mail.username=${MAIL_USERNAME}
+spring.mail.password=${MAIL_PASSWORD}
+
+spring.mail.properties.mail.smtp.auth=true
+spring.mail.properties.mail.smtp.starttls.enable=true
+spring.mail.properties.mail.smtp.starttls.required=true
+spring.mail.properties.mail.smtp.connectiontimeout=5000
+spring.mail.properties.mail.smtp.timeout=5000
+spring.mail.properties.mail.smtp.writetimeout=5000
+spring.mail.default-encoding=UTF-8
diff --git a/src/main/resources/templates/email/ticket-confirmation.txt b/src/main/resources/templates/email/ticket-confirmation.txt
new file mode 100644
index 0000000..59e75b3
--- /dev/null
+++ b/src/main/resources/templates/email/ticket-confirmation.txt
@@ -0,0 +1,13 @@
+%s 님, 예매가 완료되었습니다.
+
+예매번호: %s
+공연명: %s
+공연일시: %s
+공연장: %s
+결제금액: %s원
+
+티켓 수령: %s (앱에서 확인 가능)
+입장 시 QR코드를 제시해 주세요.
+
+※ 취소 마감: 공연 전일 17시까지
+문의: 고객센터 1588-0000
\ No newline at end of file

From 6903db990f04b5d39db9e37cd1a93432d0211178 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 10:57:33 +0900
Subject: [PATCH 096/149] =?UTF-8?q?MNMS-462=20Refactor:=20host,=20ticket,?=
 =?UTF-8?q?=20errorcode=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Host : status 예매 완료된 사용자만 조회 가능 변경
Ticket : reservationDate 기준 최신순 정렬
Email : errorCode 추가
---
 .../com/mnms/booking/controller/HostController.java    |  2 +-
 .../java/com/mnms/booking/exception/ErrorCode.java     |  1 +
 .../com/mnms/booking/repository/TicketRepository.java  | 10 +++++++---
 .../mnms/booking/service/BookingCommandService.java    |  2 +-
 .../java/com/mnms/booking/service/HostService.java     |  7 ++++++-
 .../java/com/mnms/booking/service/TicketService.java   |  2 ++
 6 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 4a7bfb8..87115b7 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -31,7 +31,7 @@ public class HostController {
     @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
     )
-    public ResponseEntity>> getBookingsByOrXSanizer(@RequestBody HostRequestDTO hostRequestDTO) {
+    public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
 
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index d664c22..6cdd8dd 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -33,6 +33,7 @@ public enum ErrorCode {
     TICKET_ALREADY_CANCELED("T007", "티켓이 이미 예매 취소되었습니다.", HttpStatus.CONFLICT),
     TICKET_EXPIRED("T008", "티켓의 유효기간이 만료되었습니다.", HttpStatus.CONFLICT),
     TICKET_CANCELED("T009", "취소된 티켓입니다.", HttpStatus.CONFLICT),
+    TICKET_EMAIL_TEMPLATE_NOT_FOUND("T010", "이메일 템플릿 오류로 이메일 전송에 실패하였습니다.", HttpStatus.NOT_FOUND),
 
     // QR
     QR_CODE_SAVE_FAILED("Q001", "QR 코드 생성 또는 저장을 실패했습니다.", HttpStatus.INTERNAL_SERVER_ERROR),
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 72c1718..446a766 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -8,6 +8,7 @@
 import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 
+import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
@@ -43,9 +44,12 @@ Optional findByFestivalIdAndUserIdAndReservationNumber(
     @Query("SELECT DISTINCT t.userId " +
             "FROM Ticket t " +
             "WHERE t.festival.festivalId = :festivalId " +
-            "AND t.performanceDate = :performanceDate")
-    List findDistinctUserIdsByFestivalIdAndPerformanceDate(@Param("festivalId") String festivalId,
-                                                           @Param("performanceDate") LocalDateTime performanceDate);
+            "AND t.performanceDate = :performanceDate " +
+            "AND t.reservationStatus = :reservationStatus")
+    List findDistinctUserIdsByFestivalIdAndPerformanceDateAndReservationStatus(
+            @Param("festivalId") String festivalId,
+            @Param("performanceDate") LocalDateTime performanceDate,
+            @Param("reservationStatus") ReservationStatus reservationStatus);
 
 
     @Query("SELECT t " +
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 96c3e7b..af3c0e3 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -155,7 +155,7 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) throw
         InputStream is = getClass().getClassLoader()
                 .getResourceAsStream("templates/email/ticket-confirmation.txt");
         if (is == null) {
-            throw new IllegalStateException("이메일 템플릿을 찾을 수 없습니다.");
+            throw new BusinessException(ErrorCode.TICKET_EMAIL_TEMPLATE_NOT_FOUND);
         }
 
         String template = new String(is.readAllBytes(), StandardCharsets.UTF_8);
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index d0d7222..c0599b0 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -32,7 +32,12 @@ public class HostService {
     private final UserApiClient userApiClient;
 
     public List getBookingsByOrganizer(HostRequestDTO request) {
-        return ticketRepository.findDistinctUserIdsByFestivalIdAndPerformanceDate(request.getFestivalId(), request.getPerformanceDate());
+        return ticketRepository
+                .findDistinctUserIdsByFestivalIdAndPerformanceDateAndReservationStatus(
+                        request.getFestivalId(),
+                        request.getPerformanceDate(),
+                        ReservationStatus.CONFIRMED
+                );
     }
 
     @Transactional
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index d186211..5128f29 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -12,6 +12,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Comparator;
 import java.util.List;
 
 @Service
@@ -36,6 +37,7 @@ public List getTicketsByUser(Long userId) {
             throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
         }
         return tickets.stream()
+                .sorted(Comparator.comparing(Ticket::getReservationDate).reversed())
                 .map(ticket -> TicketResponseDTO.fromEntity(ticket, ticket.getFestival()))
                 .toList();
     }

From 037026f99df669c919b19c90fd84498381c9ba04 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 12:48:12 +0900
Subject: [PATCH 097/149] =?UTF-8?q?MNMS-462=20Refactor:=20booking=20email?=
 =?UTF-8?q?=20=EC=A0=84=EC=86=A1=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EB=A6=AC?=
 =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../service/BookingCommandService.java        | 73 +++++++------------
 .../mnms/booking/service/EmailService.java    | 42 ++++++++++-
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index af3c0e3..cfbd912 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -134,56 +134,18 @@ private void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
 
     /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
     @Transactional
-    public void confirmTicket(String reservationNumber, boolean paymentStatus) throws Exception {
-        Ticket ticket = ticketRepository.findByReservationNumber(reservationNumber)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    public void confirmTicket(String reservationNumber, boolean paymentStatus) {
+        Ticket ticket = getTicketByReservationNumberOrThrow(reservationNumber);
+        ReservationStatus newStatus = determineReservationStatus(paymentStatus);
 
-        ReservationStatus newStatus = paymentStatus ?
-                ReservationStatus.CONFIRMED :
-                ReservationStatus.CANCELED;
         // 결제 상태 변경
-        if(ticket.getReservationStatus() != ReservationStatus.CONFIRMED
-                && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
-            ticket.setReservationStatus(newStatus);
-            ticketRepository.save(ticket);
-        }
+        updateTicketStatusIfNecessary(ticket, newStatus);
 
-        // 예매 내역 전송
         BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
-        String subject = String.format("[예매확인] %s 티켓", ticket.getFestival().getFname());
-
-        InputStream is = getClass().getClassLoader()
-                .getResourceAsStream("templates/email/ticket-confirmation.txt");
-        if (is == null) {
-            throw new BusinessException(ErrorCode.TICKET_EMAIL_TEMPLATE_NOT_FOUND);
-        }
+        emailService.sendTicketConfirmationEmail(ticket, user);
 
-        String template = new String(is.readAllBytes(), StandardCharsets.UTF_8);
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년MM월dd일 a h시");
-
-        String content = String.format(
-                template,
-                user.getName(),
-                ticket.getReservationNumber(),
-                ticket.getFestival().getFname(),
-                ticket.getPerformanceDate().format(formatter),
-                ticket.getFestival().getFcltynm(),
-                ticket.getFestival().getTicketPrice() * ticket.getSelectedTicketCount(),
-                ticket.getDeliveryMethod() == TicketType.MOBILE ? "모바일" : "지류"
-        );
-
-        emailService.sendEmail(
-                user.getEmail(),
-                subject,
-                content
-        );
-
-        // WebSocket 전송
-        messagingTemplate.convertAndSendToUser(
-                String.valueOf(ticket.getUserId()),
-                "/queue/ticket-status",
-                new TicketStatusResponseDTO(ticket.getReservationNumber(), newStatus)
-        );
+        // websocket
+        notifyTicketStatus(ticket, newStatus);
     }
 
     ///  예매 취소
@@ -260,6 +222,27 @@ private void ensureDeliveryStepCompleted(Ticket ticket) {
     }
 
     /// 기타
+    private ReservationStatus determineReservationStatus(boolean paymentStatus) {
+        return paymentStatus ? ReservationStatus.CONFIRMED : ReservationStatus.CANCELED;
+    }
+
+    private void updateTicketStatusIfNecessary(Ticket ticket, ReservationStatus newStatus) {
+        if (ticket.getReservationStatus() != ReservationStatus.CONFIRMED
+                && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
+            ticket.setReservationStatus(newStatus);
+            ticketRepository.save(ticket);
+        }
+    }
+
+    // websocket
+    private void notifyTicketStatus(Ticket ticket, ReservationStatus status) {
+        messagingTemplate.convertAndSendToUser(
+                String.valueOf(ticket.getUserId()),
+                "/queue/ticket-status",
+                new TicketStatusResponseDTO(ticket.getReservationNumber(), status)
+        );
+    }
+
     private Festival getFestivalOrThrow(String festivalId) {
         return festivalRepository.findByFestivalId(festivalId)
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
diff --git a/src/main/java/com/mnms/booking/service/EmailService.java b/src/main/java/com/mnms/booking/service/EmailService.java
index 50cf912..88210b4 100644
--- a/src/main/java/com/mnms/booking/service/EmailService.java
+++ b/src/main/java/com/mnms/booking/service/EmailService.java
@@ -1,24 +1,64 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.response.BookingUserResponseDTO;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
 import org.springframework.mail.SimpleMailMessage;
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.time.format.DateTimeFormatter;
 
 @Service
 @RequiredArgsConstructor
 public class EmailService {
     private final JavaMailSender mailSender;
 
+    public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO user) {
+        try (InputStream is = getClass().getClassLoader()
+                .getResourceAsStream("templates/email/ticket-confirmation.txt")) {
+
+            if (is == null) {
+                throw new BusinessException(ErrorCode.TICKET_EMAIL_TEMPLATE_NOT_FOUND);
+            }
+
+            String template = new String(is.readAllBytes(), StandardCharsets.UTF_8);
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy년MM월dd일 a h시");
+
+            String content = String.format(
+                    template,
+                    user.getName(),
+                    ticket.getReservationNumber(),
+                    ticket.getFestival().getFname(),
+                    ticket.getPerformanceDate().format(formatter),
+                    ticket.getFestival().getFcltynm(),
+                    ticket.getFestival().getTicketPrice() * ticket.getSelectedTicketCount(),
+                    ticket.getDeliveryMethod() == TicketType.MOBILE ? "모바일" : "지류"
+            );
+
+            String subject = String.format("[예매확인] %s 티켓", ticket.getFestival().getFname());
+            sendEmail(user.getEmail(), subject, content);
+
+        } catch (IOException e) {
+            throw new BusinessException(ErrorCode.TICKET_EMAIL_TEMPLATE_NOT_FOUND);
+        }
+    }
+
+
     public void sendEmail(String to, String subject, String text) {
         SimpleMailMessage message = new SimpleMailMessage();
         message.setTo(to);           // 수신자
         message.setSubject(subject); // 제목
         message.setText(text);       // 내용
-        message.setFrom("your_email@gmail.com"); // 발신자 (설정 가능)
+        message.setFrom("Tekcit"); // 발신자
 
         mailSender.send(message);
     }

From 363ef927e19c02a380041e47c67bac9ba99491aa Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 13:06:23 +0900
Subject: [PATCH 098/149] =?UTF-8?q?MNMS-462=20Refactor:=20BookingCommandSe?=
 =?UTF-8?q?rvice=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

BookingStatusService 생성
---
 .../service/BookingCommandService.java        | 205 ++----------------
 .../booking/service/BookingStatusService.java | 192 ++++++++++++++++
 .../mnms/booking/service/EmailService.java    |   4 +-
 3 files changed, 212 insertions(+), 189 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/BookingStatusService.java

diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index cfbd912..e635e6a 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -9,59 +9,35 @@
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
-import com.mnms.booking.repository.FestivalRepository;
-import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
-import org.springframework.messaging.simp.SimpMessagingTemplate;
-import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.time.format.DateTimeFormatter;
-import java.time.format.TextStyle;
-import java.time.temporal.ChronoUnit;
-import java.util.*;
-import java.util.stream.IntStream;
-
 
 @Service
 @RequiredArgsConstructor
 @Transactional(readOnly = true)
 public class BookingCommandService {
-
-    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
-    private static final int TEMP_RESERVATION_TTL_MINUTES = 30; // 가예매 유지 시간
-
     private final TicketRepository ticketRepository;
-    private final QrCodeRepository qrCodeRepository;
-    private final FestivalRepository festivalRepository;
-
-    private final QrCodeService qrCodeService;
     private final EmailService emailService;
-
-    private final ThreadPoolTaskScheduler scheduler;
-    private final SimpMessagingTemplate messagingTemplate;
     private final CommonUtils commonUtils;
     private final UserApiClient userApiClient;
+    private final BookingStatusService bookingStatusService;
 
     /// 1차: 가예매 - 임시 예약
     @Transactional
     public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
-        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        Festival festival = bookingStatusService.getFestivalOrThrow(request.getFestivalId());
         LocalDateTime performanceDate = request.getPerformanceDate();
 
-        validatePerformanceDate(festival, performanceDate);
-        validateScheduleExists(festival, performanceDate);
-        validateUserReservationLimit(userId, request, festival);
+        bookingStatusService.validatePerformanceDate(festival, performanceDate);
+        bookingStatusService.validateScheduleExists(festival, performanceDate);
+        bookingStatusService.validateUserReservationLimit(userId, request, festival);
 
         Ticket ticket = Ticket.builder()
                 .festival(festival)
@@ -76,7 +52,7 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
         ticketRepository.save(ticket);
 
         // TTL 스케줄링: 일정 시간 지나면 자동 삭제
-        scheduleTempReservationExpiration(ticket.getReservationNumber());
+        bookingStatusService.scheduleTempReservationExpiration(ticket.getReservationNumber());
 
         return ticket.getReservationNumber();
     }
@@ -84,12 +60,12 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
     /// 2차: 가예매 - 배송 방법 선택
     @Transactional
     public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long userId) {
-        Ticket ticket = getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
-        TicketType type = parseDeliveryMethod(request.getDeliveryMethod());
+        Ticket ticket = bookingStatusService.getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
+        TicketType type = bookingStatusService.parseDeliveryMethod(request.getDeliveryMethod());
         ticket.setDeliveryMethod(type);
         if(TicketType.PAPER.equals(type)){
             ticket.setAddress(request.getAddress());
-            ticket.setDeliveryDate(calculateDeliveryDate(ticket, type));
+            ticket.setDeliveryDate(bookingStatusService.calculateDeliveryDate(ticket, type));
         }
         ticketRepository.save(ticket);
     }
@@ -97,55 +73,34 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
     /// 3차: 가예매 - 예약 - QR생성
     @Transactional
     public void reserveTicket(BookingRequestDTO request, Long userId) {
-        Festival festival = getFestivalOrThrow(request.getFestivalId());
+        Festival festival = bookingStatusService.getFestivalOrThrow(request.getFestivalId());
         Long selectedTicketCount = ticketRepository.findSelectedTicketCountByReservationNumber(request.getReservationNumber());
 
-        validateCapacity(festival, request, selectedTicketCount);
+        bookingStatusService.validateCapacity(festival, request, selectedTicketCount);
 
-        Ticket ticket = getTicketByReservationNumberOrThrow(request.getReservationNumber());
+        Ticket ticket = bookingStatusService.getTicketByReservationNumberOrThrow(request.getReservationNumber());
         ticket.setReservationStatus(ReservationStatus.PAYMENT_IN_PROGRESS);
-        ensureDeliveryStepCompleted(ticket);
+        bookingStatusService.ensureDeliveryStepCompleted(ticket);
 
-        regenerateQrCodes(ticket, userId, festival);
+        bookingStatusService.regenerateQrCodes(ticket, userId, festival);
 
         ticketRepository.save(ticket);
     }
 
-    private void validateCapacity(Festival festival, BookingRequestDTO request, Long selectedTicketCount) {
-        int totalCount = ticketRepository.getTotalSelectedTicketCount(
-                request.getFestivalId(),
-                request.getPerformanceDate(),
-                List.of(ReservationStatus.CONFIRMED, ReservationStatus.PAYMENT_IN_PROGRESS)
-        );
-
-        if (totalCount + selectedTicketCount > festival.getAvailableNOP()) {
-            throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVALIABLE_PEOPLE);
-        }
-    }
-
-    private void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
-        ticket.getQrCodes().clear();
-        ticket.getQrCodes().addAll(
-                IntStream.range(0, ticket.getSelectedTicketCount())
-                        .mapToObj(i -> createAndSaveQrCode(userId, festival, ticket))
-                        .toList()
-        );
-    }
-
     /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
     @Transactional
     public void confirmTicket(String reservationNumber, boolean paymentStatus) {
-        Ticket ticket = getTicketByReservationNumberOrThrow(reservationNumber);
-        ReservationStatus newStatus = determineReservationStatus(paymentStatus);
+        Ticket ticket = bookingStatusService.getTicketByReservationNumberOrThrow(reservationNumber);
+        ReservationStatus newStatus = bookingStatusService.determineReservationStatus(paymentStatus);
 
         // 결제 상태 변경
-        updateTicketStatusIfNecessary(ticket, newStatus);
+        bookingStatusService.updateTicketStatusIfNecessary(ticket, newStatus);
 
         BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
         emailService.sendTicketConfirmationEmail(ticket, user);
 
         // websocket
-        notifyTicketStatus(ticket, newStatus);
+        bookingStatusService.notifyTicketStatus(ticket, newStatus);
     }
 
     ///  예매 취소
@@ -170,129 +125,7 @@ public void cancelBooking(String reservationNumber, boolean paymentStatus) {
         ticketRepository.save(ticket);
     }
 
-    /// schedule 점검
-    private void scheduleTempReservationExpiration(String reservationNumber) {
-        scheduler.schedule(() -> {
-            ticketRepository.findByReservationNumber(reservationNumber)
-                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
-                    .ifPresent(ticketRepository::delete);
-        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
-    }
-
-    /// 검증
-    private void validatePerformanceDate(Festival festival, LocalDateTime performanceDate) {
-        LocalDate date = performanceDate.toLocalDate();
-        if (date.isBefore(festival.getFdfrom()) || date.isAfter(festival.getFdto())) {
-            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
-        }
-    }
-
-    private void validateScheduleExists(Festival festival, LocalDateTime performanceDate) {
-        String dayOfWeek = performanceDate.getDayOfWeek()
-                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
-                .toUpperCase();
-
-        boolean exists = festival.getSchedules().stream()
-                .anyMatch(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek)
-                        && LocalTime.parse(s.getTime(), TIME_FORMATTER).equals(performanceDate.toLocalTime()));
-
-        if (!exists) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
-    }
-
-    private void validateUserReservationLimit(Long userId, BookingSelectRequestDTO request, Festival festival) {
-        int selectTicketCount = request.getSelectedTicketCount();
-        if (festival.getMaxPurchase() < selectTicketCount){
-            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
-        }
-
-        LocalDateTime startDate = request.getPerformanceDate();
-        LocalDateTime endDate = startDate.plusSeconds(1);
-
-        Long alreadyReserved = ticketRepository.sumSelectedTicketCount(
-                userId, festival.getFestivalId(), startDate, endDate);
-        if (alreadyReserved + selectTicketCount > festival.getMaxPurchase()) {
-            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
-        }
-    }
-
-    private void ensureDeliveryStepCompleted(Ticket ticket) {
-        if (ticket.getDeliveryMethod() == null && ticket.getDeliveryDate() == null) {
-            throw new BusinessException(ErrorCode.TICKET_DELIVERY_NOT_COMPLETED);
-        }
-    }
-
-    /// 기타
-    private ReservationStatus determineReservationStatus(boolean paymentStatus) {
-        return paymentStatus ? ReservationStatus.CONFIRMED : ReservationStatus.CANCELED;
-    }
-
-    private void updateTicketStatusIfNecessary(Ticket ticket, ReservationStatus newStatus) {
-        if (ticket.getReservationStatus() != ReservationStatus.CONFIRMED
-                && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
-            ticket.setReservationStatus(newStatus);
-            ticketRepository.save(ticket);
-        }
-    }
-
-    // websocket
-    private void notifyTicketStatus(Ticket ticket, ReservationStatus status) {
-        messagingTemplate.convertAndSendToUser(
-                String.valueOf(ticket.getUserId()),
-                "/queue/ticket-status",
-                new TicketStatusResponseDTO(ticket.getReservationNumber(), status)
-        );
-    }
-
-    private Festival getFestivalOrThrow(String festivalId) {
-        return festivalRepository.findByFestivalId(festivalId)
-                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
-    }
-
-    private Ticket getTicketOrThrow(String festivalId, Long userId, String reservationNumber) {
-        return ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(festivalId, userId, reservationNumber)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-    }
-
-    private Ticket getTicketByReservationNumberOrThrow(String reservationNumber) {
-        return ticketRepository.findByReservationNumber(reservationNumber)
-                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-    }
-
-    private TicketType parseDeliveryMethod(String method) {
-        if (method == null) throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
-        try {
-            return TicketType.valueOf(method.toUpperCase());
-        } catch (IllegalArgumentException e) {
-            throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
-        }
-    }
-
-    /// deliveryDate 생성
-    private LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMethod) {
-        if (ticket.getPerformanceDate() == null) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
-
-        if (deliveryMethod == TicketType.PAPER) {
-            LocalDateTime deliveryDate = ticket.getPerformanceDate().minusDays(14);
-            return deliveryDate.isAfter(LocalDateTime.now())
-                    ? deliveryDate
-                    : LocalDateTime.now().plusDays(1);
-        }
-        return null; // 모바일 티켓
-    }
-
-    /// Qr정보 생성
-    private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
-        // 중복 없는 QR 코드 ID 생성
-        String qrCodeId;
-        do {
-            qrCodeId = qrCodeService.generateQrCodeId();
-        } while (qrCodeRepository.existsByQrCodeId(qrCodeId));
-
-        QrCode qrCode = QrResponseDTO.create(userId, qrCodeId, festival, ticket).toEntity();
-        qrCodeRepository.save(qrCode);
-        return qrCode;
-    }
-
+    // websocket 손실 방지 확인
     public ReservationStatus checkStatus(String reservationNumber) {
         return ticketRepository.findReservationStatusByReservationNumber(reservationNumber);
     }
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
new file mode 100644
index 0000000..75c00ed
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -0,0 +1,192 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectRequestDTO;
+import com.mnms.booking.dto.response.QrResponseDTO;
+import com.mnms.booking.dto.response.TicketStatusResponseDTO;
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.QrCode;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.FestivalRepository;
+import com.mnms.booking.repository.QrCodeRepository;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.TextStyle;
+import java.time.temporal.ChronoUnit;
+import java.util.List;
+import java.util.Locale;
+import java.util.stream.IntStream;
+
+@Service
+@RequiredArgsConstructor
+@Transactional(readOnly = true)
+public class BookingStatusService {
+
+    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
+    private static final int TEMP_RESERVATION_TTL_MINUTES = 20; // 가예매 유지 시간
+
+    private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
+    private final FestivalRepository festivalRepository;
+    private final QrCodeService qrCodeService;
+    private final ThreadPoolTaskScheduler scheduler;
+    private final SimpMessagingTemplate messagingTemplate;
+
+    /// schedule 점검
+    public void scheduleTempReservationExpiration(String reservationNumber) {
+        scheduler.schedule(() -> {
+            ticketRepository.findByReservationNumber(reservationNumber)
+                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
+                    .ifPresent(ticketRepository::delete);
+        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
+    }
+
+    /// 검증
+    public void validateCapacity(Festival festival, BookingRequestDTO request, Long selectedTicketCount) {
+        int totalCount = ticketRepository.getTotalSelectedTicketCount(
+                request.getFestivalId(),
+                request.getPerformanceDate(),
+                List.of(ReservationStatus.CONFIRMED, ReservationStatus.PAYMENT_IN_PROGRESS)
+        );
+
+        if (totalCount + selectedTicketCount > festival.getAvailableNOP()) {
+            throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVALIABLE_PEOPLE);
+        }
+    }
+
+    public void validatePerformanceDate(Festival festival, LocalDateTime performanceDate) {
+        LocalDate date = performanceDate.toLocalDate();
+        if (date.isBefore(festival.getFdfrom()) || date.isAfter(festival.getFdto())) {
+            throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+        }
+    }
+
+    public void validateScheduleExists(Festival festival, LocalDateTime performanceDate) {
+        String dayOfWeek = performanceDate.getDayOfWeek()
+                .getDisplayName(TextStyle.SHORT, Locale.ENGLISH)
+                .toUpperCase();
+
+        boolean exists = festival.getSchedules().stream()
+                .anyMatch(s -> s.getDayOfWeek().equalsIgnoreCase(dayOfWeek)
+                        && LocalTime.parse(s.getTime(), TIME_FORMATTER).equals(performanceDate.toLocalTime()));
+
+        if (!exists) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_TIME);
+    }
+
+    public void validateUserReservationLimit(Long userId, BookingSelectRequestDTO request, Festival festival) {
+        int selectTicketCount = request.getSelectedTicketCount();
+        if (festival.getMaxPurchase() < selectTicketCount){
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+
+        LocalDateTime startDate = request.getPerformanceDate();
+        LocalDateTime endDate = startDate.plusSeconds(1);
+
+        Long alreadyReserved = ticketRepository.sumSelectedTicketCount(
+                userId, festival.getFestivalId(), startDate, endDate);
+        if (alreadyReserved + selectTicketCount > festival.getMaxPurchase()) {
+            throw new BusinessException(ErrorCode.TICKET_ALREADY_RESERVED);
+        }
+    }
+
+    public void ensureDeliveryStepCompleted(Ticket ticket) {
+        if (ticket.getDeliveryMethod() == null && ticket.getDeliveryDate() == null) {
+            throw new BusinessException(ErrorCode.TICKET_DELIVERY_NOT_COMPLETED);
+        }
+    }
+
+    /// 기타
+    public void regenerateQrCodes(Ticket ticket, Long userId, Festival festival) {
+        ticket.getQrCodes().clear();
+        ticket.getQrCodes().addAll(
+                IntStream.range(0, ticket.getSelectedTicketCount())
+                        .mapToObj(i -> createAndSaveQrCode(userId, festival, ticket))
+                        .toList()
+        );
+    }
+
+    public ReservationStatus determineReservationStatus(boolean paymentStatus) {
+        return paymentStatus ? ReservationStatus.CONFIRMED : ReservationStatus.CANCELED;
+    }
+
+    public void updateTicketStatusIfNecessary(Ticket ticket, ReservationStatus newStatus) {
+        if (ticket.getReservationStatus() != ReservationStatus.CONFIRMED
+                && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
+            ticket.setReservationStatus(newStatus);
+            ticketRepository.save(ticket);
+        }
+    }
+
+    // websocket
+    public void notifyTicketStatus(Ticket ticket, ReservationStatus status) {
+        messagingTemplate.convertAndSendToUser(
+                String.valueOf(ticket.getUserId()),
+                "/queue/ticket-status",
+                new TicketStatusResponseDTO(ticket.getReservationNumber(), status)
+        );
+    }
+
+    public Festival getFestivalOrThrow(String festivalId) {
+        return festivalRepository.findByFestivalId(festivalId)
+                .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
+    }
+
+    public Ticket getTicketOrThrow(String festivalId, Long userId, String reservationNumber) {
+        return ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(festivalId, userId, reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    public Ticket getTicketByReservationNumberOrThrow(String reservationNumber) {
+        return ticketRepository.findByReservationNumber(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
+
+    public TicketType parseDeliveryMethod(String method) {
+        if (method == null) throw new BusinessException(ErrorCode.FESTIVAL_DELIVERY_INVALID);
+        try {
+            return TicketType.valueOf(method.toUpperCase());
+        } catch (IllegalArgumentException e) {
+            throw new BusinessException(ErrorCode.TICKET_INVALID_DELIVERY_METHOD);
+        }
+    }
+
+    /// deliveryDate 생성
+    public LocalDateTime calculateDeliveryDate(Ticket ticket, TicketType deliveryMethod) {
+        if (ticket.getPerformanceDate() == null) throw new BusinessException(ErrorCode.FESTIVAL_INVALID_DATE);
+
+        if (deliveryMethod == TicketType.PAPER) {
+            LocalDateTime deliveryDate = ticket.getPerformanceDate().minusDays(14);
+            return deliveryDate.isAfter(LocalDateTime.now())
+                    ? deliveryDate
+                    : LocalDateTime.now().plusDays(1);
+        }
+        return null; // 모바일 티켓
+    }
+
+    /// Qr정보 생성
+    private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket) {
+        // 중복 없는 QR 코드 ID 생성
+        String qrCodeId;
+        do {
+            qrCodeId = qrCodeService.generateQrCodeId();
+        } while (qrCodeRepository.existsByQrCodeId(qrCodeId));
+
+        QrCode qrCode = QrResponseDTO.create(userId, qrCodeId, festival, ticket).toEntity();
+        qrCodeRepository.save(qrCode);
+        return qrCode;
+    }
+}
diff --git a/src/main/java/com/mnms/booking/service/EmailService.java b/src/main/java/com/mnms/booking/service/EmailService.java
index 88210b4..b501baf 100644
--- a/src/main/java/com/mnms/booking/service/EmailService.java
+++ b/src/main/java/com/mnms/booking/service/EmailService.java
@@ -52,13 +52,11 @@ public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO us
         }
     }
 
-
     public void sendEmail(String to, String subject, String text) {
         SimpleMailMessage message = new SimpleMailMessage();
-        message.setTo(to);           // 수신자
+        message.setTo("");           // 수신자
         message.setSubject(subject); // 제목
         message.setText(text);       // 내용
-        message.setFrom("Tekcit"); // 발신자
 
         mailSender.send(message);
     }

From 73e793f8cde3761c98e49909e94452a4dfae7d70 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 13:35:37 +0900
Subject: [PATCH 099/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20application-prod=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-prod.properties | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 52e06d2..a184554 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -48,6 +48,20 @@ springdoc.override-with-generic-response=false
 # user api
 base.service.url=${BASE_API}
 user.base.service.url=${USER_BASE_API}
-user.service.url=${USER_INFO_API}
+user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
-booking.user.service.url=${BOOKING_USER_INFO_API}
+user.service.booking.url=${BOOKING_USER_INFO_API}
+
+# mail
+spring.mail.host=smtp.gmail.com
+spring.mail.port=587
+spring.mail.username=${MAIL_USERNAME}
+spring.mail.password=${MAIL_PASSWORD}
+
+spring.mail.properties.mail.smtp.auth=true
+spring.mail.properties.mail.smtp.starttls.enable=true
+spring.mail.properties.mail.smtp.starttls.required=true
+spring.mail.properties.mail.smtp.connectiontimeout=5000
+spring.mail.properties.mail.smtp.timeout=5000
+spring.mail.properties.mail.smtp.writetimeout=5000
+spring.mail.default-encoding=UTF-8
\ No newline at end of file

From ecbfc4cdea09c813836b307788cf50b4c645a9a4 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 4 Sep 2025 17:06:28 +0900
Subject: [PATCH 100/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20payment=20kafka=20=EC=BD=94=EB=93=9C?=
 =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20application-dev,=20prod=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/exception/ErrorCode.java |  4 ++-
 .../kafka/dto/PaymentSuccessEventDTO.java     |  2 +-
 .../kafka/listener/PaymentListener.java       | 36 ++++++-------------
 src/main/resources/application-dev.properties |  3 +-
 .../resources/application-prod.properties     |  2 --
 5 files changed, 15 insertions(+), 32 deletions(-)

diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 6cdd8dd..7d761e1 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -68,8 +68,10 @@ public enum ErrorCode {
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
-    STATISTICS_NOT_FOUND("ST002", "해당 페스티벌의 통계 정보를 찾을 수 없습니다.", HttpStatus.NOT_FOUND);
+    STATISTICS_NOT_FOUND("ST002", "해당 페스티벌의 통계 정보를 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
 
+    // PAYMENT
+    PAYMENT_RESPONSE_ERROR("P001", "결제 응답이 실패하였습니다.", HttpStatus.BAD_REQUEST);
 
     private final String code;        // A001, A002 등
     private final String message;     // 사용자에게 보여줄 메시지
diff --git a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
index e9ecb00..4cb10cc 100644
--- a/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
+++ b/src/main/java/com/mnms/booking/kafka/dto/PaymentSuccessEventDTO.java
@@ -10,7 +10,7 @@
 @NoArgsConstructor
 @AllArgsConstructor
 public class PaymentSuccessEventDTO {
-    private String method;
+    private String method; // payment, cancel, transfer
     private String reservationNumber;
     private  boolean success;
 }
diff --git a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
index 4885867..f5a0854 100644
--- a/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
+++ b/src/main/java/com/mnms/booking/kafka/listener/PaymentListener.java
@@ -1,20 +1,19 @@
 package com.mnms.booking.kafka.listener;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.kafka.dto.PaymentSuccessEventDTO;
 import com.mnms.booking.service.BookingCommandService;
 import com.mnms.booking.service.TransferCompletionService;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.kafka.annotation.KafkaListener;
 import org.springframework.stereotype.Service;
 
 @Service
 @RequiredArgsConstructor
-@Slf4j
 public class PaymentListener {
 
     private final BookingCommandService bookingCommandService;
@@ -28,28 +27,13 @@ public void consumePaymentSuccess(String message) throws Exception {
         objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
 
         PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
-        bookingCommandService.confirmTicket(event.getReservationNumber(), event.isSuccess());
-    }
-
-    @KafkaListener(topics = "${app.kafka.topic.payment-cancel-event}", groupId = "booking-service-group")
-    public void consumeRefundSuccess(String message) throws JsonProcessingException {
-        ObjectMapper objectMapper = new ObjectMapper();
-
-        objectMapper.registerModule(new JavaTimeModule());
-        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-
-        PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
-        bookingCommandService.cancelBooking(event.getReservationNumber(), event.isSuccess());
-    }
-
-    @KafkaListener(topics = "${app.kafka.topic.transfer-payment-event}", groupId = "booking-service-group")
-    public void consumeTransferSuccess(String message) throws JsonProcessingException {
-        ObjectMapper objectMapper = new ObjectMapper();
-
-        objectMapper.registerModule(new JavaTimeModule());
-        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
-
-        PaymentSuccessEventDTO event = objectMapper.readValue(message, PaymentSuccessEventDTO.class);
-        transferCompletionService.updateOthersTicket(event.getReservationNumber(), event.isSuccess());
+        String method = event.getMethod();
+
+        switch (method) {
+            case "payment" -> bookingCommandService.confirmTicket(event.getReservationNumber(), event.isSuccess());
+            case "cancel" -> bookingCommandService.cancelBooking(event.getReservationNumber(), event.isSuccess());
+            case "transfer" -> transferCompletionService.updateOthersTicket(event.getReservationNumber(), event.isSuccess());
+            default -> throw new BusinessException(ErrorCode.PAYMENT_RESPONSE_ERROR);
+        }
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 1b08b27..b45a807 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -27,8 +27,7 @@ spring.data.redis.port=${REDIS_PORT}
 ## kafka
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
-app.kafka.topic.payment-cancel-event=payment-cancel-events
-app.kafka.topic.transfer-payment-event=payment-transfer-status-events
+
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index a184554..bd81ee5 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -23,8 +23,6 @@ spring.data.redis.port=${REDIS_PORT}
 ## kafka
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
-app.kafka.topic.payment-cancel-event=payment-cancel-events
-app.kafka.topic.transfer-payment-event=payment-transfer-status-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest

From 57128fc30df18322936049825c13c29084332b4e Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 5 Sep 2025 13:10:47 +0900
Subject: [PATCH 101/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20email=20=EC=88=98=EC=8B=A0=EC=9E=90=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/service/EmailService.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/EmailService.java b/src/main/java/com/mnms/booking/service/EmailService.java
index b501baf..a5f55e9 100644
--- a/src/main/java/com/mnms/booking/service/EmailService.java
+++ b/src/main/java/com/mnms/booking/service/EmailService.java
@@ -54,7 +54,7 @@ public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO us
 
     public void sendEmail(String to, String subject, String text) {
         SimpleMailMessage message = new SimpleMailMessage();
-        message.setTo("");           // 수신자
+        message.setTo(to);           // 수신자
         message.setSubject(subject); // 제목
         message.setText(text);       // 내용
 

From 88271ed8e9147458bf09e13e3d749d7032e428fb Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 5 Sep 2025 13:47:55 +0900
Subject: [PATCH 102/149] feat(booking): expose Prometheus metrics for scraping
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- add micrometer-registry-prometheus & actuator
- expose /actuator/prometheus (health/info 포함)
- allow unauthenticated access to actuator metrics (if security enabled)
- add default 'application' metrics tag
---
 build.gradle                                   | 4 ++++
 src/main/resources/application-dev.properties  | 4 ++++
 src/main/resources/application-prod.properties | 6 +++++-
 src/main/resources/application-test.properties | 6 +++++-
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/build.gradle b/build.gradle
index 30b7acf..4aea295 100644
--- a/build.gradle
+++ b/build.gradle
@@ -86,6 +86,10 @@ dependencies {
 
 	//Mail
 	implementation 'org.springframework.boot:spring-boot-starter-mail'
+
+	// prometheus
+	implementation 'org.springframework.boot:spring-boot-starter-actuator'
+  	implementation 'io.micrometer:micrometer-registry-prometheus'
 }
 
 tasks.named('test') {
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 1b08b27..7f64412 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -75,3 +75,7 @@ spring.mail.properties.mail.smtp.connectiontimeout=5000
 spring.mail.properties.mail.smtp.timeout=5000
 spring.mail.properties.mail.smtp.writetimeout=5000
 spring.mail.default-encoding=UTF-8
+
+management.endpoints.web.exposure.include=health,info,prometheus
+management.endpoint.health.show-details=always
+management.metrics.tags.application=${spring.application.name:booking-service}
\ No newline at end of file
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index bd81ee5..9aa05c9 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -62,4 +62,8 @@ spring.mail.properties.mail.smtp.starttls.required=true
 spring.mail.properties.mail.smtp.connectiontimeout=5000
 spring.mail.properties.mail.smtp.timeout=5000
 spring.mail.properties.mail.smtp.writetimeout=5000
-spring.mail.default-encoding=UTF-8
\ No newline at end of file
+spring.mail.default-encoding=UTF-8
+
+management.endpoints.web.exposure.include=health,info,prometheus
+management.endpoint.health.show-details=always
+management.metrics.tags.application=${spring.application.name:booking-service}
\ No newline at end of file
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 405d35d..c952ed5 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -53,4 +53,8 @@ springdoc.override-with-generic-response=false
 
 # user api
 user.service.url=${USER_INFO_API}
-booking.user.servicel.url=${BOOKING_USER_INFO_API}
\ No newline at end of file
+booking.user.servicel.url=${BOOKING_USER_INFO_API}
+
+management.endpoints.web.exposure.include=health,info,prometheus
+management.endpoint.health.show-details=always
+management.metrics.tags.application=${spring.application.name:booking-service}
\ No newline at end of file

From d513d65ad92bccaeb7a631ffff430b65fc0565cb Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 5 Sep 2025 16:08:37 +0900
Subject: [PATCH 103/149] =?UTF-8?q?feat:=20tomcat=20=EB=B0=8F=20=EB=B9=A0?=
 =?UTF-8?q?=EC=A7=84=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties | 72 ++++++++++---------
 1 file changed, 39 insertions(+), 33 deletions(-)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 7f64412..652aba6 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -1,35 +1,29 @@
 myboot.name=Dev Env
 
-#log level
-logging.level.root=INFO
-#logging.level.c.mnms.booking.config.RedisConfig=DEBUG
-#logging.level.com.basic.myspringboot=debug
+# ===== 이름(메트릭 application 라벨) =====
+spring.application.name=booking
 
+# ===== 로그 =====
+logging.level.root=INFO
 logging.level.org.springframework.security=DEBUG
+logging.level.com.mnms.booking.service=DEBUG
 
-#maria db info
+# ===== DB =====
 spring.datasource.url=${DB_URL}
 spring.datasource.username=${DB_USERNAME}
 spring.datasource.password=${DB_PASSWORD}
 spring.datasource.driverClassName=org.mariadb.jdbc.Driver
 
-# hibernate info
+# ===== JPA =====
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
-# redis 설정 - 로컬 설정
-#spring.data.redis.host=127.0.0.1
-spring.data.redis.host=${SERVER_URL}
-spring.data.redis.port=${REDIS_PORT}
-#spring.redis.password=your_password
-
-## kafka
-app.kafka.topic.festival-event=festival-topic
-app.kafka.topic.payment-event= payment-status-events
-app.kafka.topic.payment-cancel-event=payment-cancel-events
-app.kafka.topic.transfer-payment-event=payment-transfer-status-events
+# ===== Redis =====
+spring.redis.host=${REDIS_HOST:127.0.0.1}
+spring.redis.port=${REDIS_PORT:6379}
 
+# ===== Kafka =====
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
 spring.kafka.consumer.properties.spring.json.trusted.packages=*
@@ -37,37 +31,31 @@ spring.kafka.consumer.properties.spring.json.use.type.headers=false
 spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 
-# kafka 사용 X
-#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration
+# Topic
+app.kafka.topic.festival-event=festival-topic
+app.kafka.topic.payment-event=payment-status-events
+app.kafka.topic.payment-cancel-event=payment-cancel-events
+app.kafka.topic.transfer-payment-event=payment-transfer-status-events
 
-# jwt
+# ===== JWT =====
 jwt.public-pem-path=classpath:keys/public.pem
 jwt.issuer=festival-user-service
 
+# ===== 외부 설정/URL =====
 spring.config.import=optional:file:.env[.properties]
 
-# swagger
-springdoc.api-docs.enabled=true
-springdoc.swagger-ui.enabled=true
-springdoc.swagger-ui.path=/swagger-ui.html
-springdoc.override-with-generic-response=false
-
-# user api
+# user API
 base.service.url=${BASE_API}
 user.base.service.url=${USER_BASE_API}
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}
 
-logging.level.com.mnms.booking.service=DEBUG
-
-
-# mail
+# ===== Mail =====
 spring.mail.host=smtp.gmail.com
 spring.mail.port=587
 spring.mail.username=${MAIL_USERNAME}
 spring.mail.password=${MAIL_PASSWORD}
-
 spring.mail.properties.mail.smtp.auth=true
 spring.mail.properties.mail.smtp.starttls.enable=true
 spring.mail.properties.mail.smtp.starttls.required=true
@@ -76,6 +64,24 @@ spring.mail.properties.mail.smtp.timeout=5000
 spring.mail.properties.mail.smtp.writetimeout=5000
 spring.mail.default-encoding=UTF-8
 
+# ===== Swagger =====
+springdoc.api-docs.enabled=true
+springdoc.swagger-ui.enabled=true
+springdoc.swagger-ui.path=/swagger-ui.html
+springdoc.override-with-generic-response=false
+
+# ===== Actuator/Prometheus & 메트릭 히스토그램 =====
 management.endpoints.web.exposure.include=health,info,prometheus
 management.endpoint.health.show-details=always
-management.metrics.tags.application=${spring.application.name:booking-service}
\ No newline at end of file
+management.endpoint.health.probes.enabled=true
+management.metrics.tags.application=${spring.application.name}
+
+# HTTP 서버 지연 히스토그램(p95 계산용)
+management.metrics.distribution.percentiles-histogram.http.server.requests=true
+
+# Hikari 커넥션 획득 지연 히스토그램(p95)
+management.metrics.distribution.percentiles-histogram.hikaricp.connections.acquire=true
+management.metrics.distribution.sla.hikaricp.connections.acquire=5ms,10ms,20ms,50ms,100ms,200ms,500ms
+
+# Tomcat 메트릭(MBean) 활성화(스레드, 커넥션 등)
+server.tomcat.mbeanregistry.enabled=true
\ No newline at end of file

From 6c89ff55d5fa1eeead2c4b526310490de79227a0 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 5 Sep 2025 16:58:47 +0900
Subject: [PATCH 104/149] =?UTF-8?q?feat:=20tomcat=20=EB=B0=8F=20=EB=B9=A0?=
 =?UTF-8?q?=EC=A7=84=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 652aba6..17093c1 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -44,9 +44,11 @@ jwt.issuer=festival-user-service
 # ===== 외부 설정/URL =====
 spring.config.import=optional:file:.env[.properties]
 
-# user API
-base.service.url=${BASE_API}
-user.base.service.url=${USER_BASE_API}
+# Base API (게이트웨이 기본값 제공)
+base.service.url=${BASE_API:http://gateway:10000}
+
+# user API (내부 DNS 기본값 제공)
+user.base.service.url=${USER_BASE_API:http://user:8080}
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}

From f27c9bc71cacdf33f78e19a6e9689737613da0d9 Mon Sep 17 00:00:00 2001
From: V4N1LL4 
Date: Fri, 5 Sep 2025 17:40:17 +0900
Subject: [PATCH 105/149] =?UTF-8?q?chore:=20booking=20redis=20redis=20host?=
 =?UTF-8?q?=20=EB=A7=A4=EC=B9=AD=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 17093c1..7524495 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -20,7 +20,7 @@ spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
 # ===== Redis =====
-spring.redis.host=${REDIS_HOST:127.0.0.1}
+spring.redis.host=${SERVER_URL:127.0.0.1}
 spring.redis.port=${REDIS_PORT:6379}
 
 # ===== Kafka =====

From 3b270f597062fb0937455651e342201457fbb7d7 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Sat, 6 Sep 2025 17:10:32 +0900
Subject: [PATCH 106/149] =?UTF-8?q?hotfix:=20=EA=B8=B4=EA=B8=89=20?=
 =?UTF-8?q?=ED=8C=A8=EC=B9=98=20-=20applicaton-dev,prod=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties  | 7 +++----
 src/main/resources/application-prod.properties | 1 -
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 7524495..bfafde5 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -20,8 +20,8 @@ spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
 # ===== Redis =====
-spring.redis.host=${SERVER_URL:127.0.0.1}
-spring.redis.port=${REDIS_PORT:6379}
+spring.data.redis.host=${SERVER_URL}
+spring.data.redis.port=${REDIS_PORT}
 
 # ===== Kafka =====
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
@@ -45,10 +45,9 @@ jwt.issuer=festival-user-service
 spring.config.import=optional:file:.env[.properties]
 
 # Base API (게이트웨이 기본값 제공)
-base.service.url=${BASE_API:http://gateway:10000}
+base.service.url=${BASE_API:http://localhost:10000}
 
 # user API (내부 DNS 기본값 제공)
-user.base.service.url=${USER_BASE_API:http://user:8080}
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index 9aa05c9..a0848a5 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -45,7 +45,6 @@ springdoc.override-with-generic-response=false
 
 # user api
 base.service.url=${BASE_API}
-user.base.service.url=${USER_BASE_API}
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}

From ddbf7999ea98eee203570e14fddf20d4978f96da Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Sun, 7 Sep 2025 11:10:19 +0900
Subject: [PATCH 107/149] =?UTF-8?q?MNMS-620=20featix:=20=E3=85=A0booking?=
 =?UTF-8?q?=20=EC=9B=90=EB=B3=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties | 18 ++++++-------
 .../resources/application-prod.properties     | 27 +++++++++++++++----
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index bfafde5..c59dcef 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -1,9 +1,9 @@
 myboot.name=Dev Env
 
-# ===== 이름(메트릭 application 라벨) =====
+# ===== 이름(메트릭 application 라벨) =====
 spring.application.name=booking
 
-# ===== 로그 =====
+# ===== 로그 =====
 logging.level.root=INFO
 logging.level.org.springframework.security=DEBUG
 logging.level.com.mnms.booking.service=DEBUG
@@ -41,13 +41,13 @@ app.kafka.topic.transfer-payment-event=payment-transfer-status-events
 jwt.public-pem-path=classpath:keys/public.pem
 jwt.issuer=festival-user-service
 
-# ===== 외부 설정/URL =====
+# ===== 외부 설정/URL =====
 spring.config.import=optional:file:.env[.properties]
 
-# Base API (게이트웨이 기본값 제공)
+# Base API (게이트웨이 기본값 제공)
 base.service.url=${BASE_API:http://localhost:10000}
 
-# user API (내부 DNS 기본값 제공)
+# user API (내부 DNS 기본값 제공)
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}
@@ -71,18 +71,18 @@ springdoc.swagger-ui.enabled=true
 springdoc.swagger-ui.path=/swagger-ui.html
 springdoc.override-with-generic-response=false
 
-# ===== Actuator/Prometheus & 메트릭 히스토그램 =====
+# ===== Actuator/Prometheus & 메트릭 히스토그램 =====
 management.endpoints.web.exposure.include=health,info,prometheus
 management.endpoint.health.show-details=always
 management.endpoint.health.probes.enabled=true
 management.metrics.tags.application=${spring.application.name}
 
-# HTTP 서버 지연 히스토그램(p95 계산용)
+# HTTP 서버 지연 히스토그램(p95 계산용)
 management.metrics.distribution.percentiles-histogram.http.server.requests=true
 
-# Hikari 커넥션 획득 지연 히스토그램(p95)
+# Hikari 커넥션 획득 지연 히스토그램(p95)
 management.metrics.distribution.percentiles-histogram.hikaricp.connections.acquire=true
 management.metrics.distribution.sla.hikaricp.connections.acquire=5ms,10ms,20ms,50ms,100ms,200ms,500ms
 
-# Tomcat 메트릭(MBean) 활성화(스레드, 커넥션 등)
+# Tomcat 메트릭(MBean) 활성화(스레드, 커넥션 등)
 server.tomcat.mbeanregistry.enabled=true
\ No newline at end of file
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index a0848a5..ee67dc5 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -1,9 +1,9 @@
-myboot.name=Dev Env
+myboot.name=Prod Env
 
 #log level
 logging.level.root=INFO
-logging.level.org.springframework.security=INFO
-logging.level.com.mnms.booking.service=INFO
+logging.level.com.mnms.booking.service=DEBUG
+logging.level.org.springframework.security=DEBUG
 
 #maria db info
 spring.datasource.url=${DB_URL}
@@ -16,13 +16,17 @@ spring.jpa.hibernate.ddl-auto=update
 spring.jpa.show-sql=true
 spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect
 
-# redis 설정
+# redis 설정 - 로컬 설정
+#spring.data.redis.host=127.0.0.1
 spring.data.redis.host=${REDIS_SERVER_URL}
 spring.data.redis.port=${REDIS_PORT}
+#spring.redis.password=your_password
 
 ## kafka
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event= payment-status-events
+app.kafka.topic.payment-cancel-event=payment-cancel-events
+app.kafka.topic.transfer-payment-event=payment-transfer-status-events
 
 spring.kafka.bootstrap-servers=${KAFKA_SERVERS}
 spring.kafka.consumer.auto-offset-reset=earliest
@@ -45,6 +49,7 @@ springdoc.override-with-generic-response=false
 
 # user api
 base.service.url=${BASE_API}
+user.base.service.url=${USER_BASE_API}
 user.service.email.url=${USER_EMAIL_INFO_API}
 user.service.stats.url=${USER_STATS_LIST_API}
 user.service.booking.url=${BOOKING_USER_INFO_API}
@@ -63,6 +68,18 @@ spring.mail.properties.mail.smtp.timeout=5000
 spring.mail.properties.mail.smtp.writetimeout=5000
 spring.mail.default-encoding=UTF-8
 
+# ===== Actuator/Prometheus & 메트릭 히스토그램 =====
 management.endpoints.web.exposure.include=health,info,prometheus
 management.endpoint.health.show-details=always
-management.metrics.tags.application=${spring.application.name:booking-service}
\ No newline at end of file
+management.endpoint.health.probes.enabled=true
+management.metrics.tags.application=${spring.application.name:booking}
+
+# HTTP 서버 지연 히스토그램(p95 계산용)
+management.metrics.distribution.percentiles-histogram.http.server.requests=true
+
+# Hikari 커넥션 획득 지연 히스토그램(p95)
+management.metrics.distribution.percentiles-histogram.hikaricp.connections.acquire=true
+management.metrics.distribution.sla.hikaricp.connections.acquire=5ms,10ms,20ms,50ms,100ms,200ms,500ms
+
+# Tomcat 메트릭(MBean) 활성화(스레드, 커넥션 등)
+server.tomcat.mbeanregistry.enabled=true
\ No newline at end of file

From 6adf6f63bebc58ba4a6dc6fb9bc6886465714ab9 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 9 Sep 2025 11:25:53 +0900
Subject: [PATCH 108/149] =?UTF-8?q?hotfix:=20websocket=20gateway=EC=99=80?=
 =?UTF-8?q?=20=EC=84=9C=EB=B2=84=20cors=20=EC=A4=91=EB=B3=B5=20=ED=97=A4?=
 =?UTF-8?q?=EB=8D=94=20=EB=AC=B8=EC=A0=9C=EB=A1=9C=20=EC=84=9C=EB=B2=84?=
 =?UTF-8?q?=EC=97=90=EC=84=9C=20cors=20=EB=B9=84=ED=99=9C=EC=84=B1?=
 =?UTF-8?q?=ED=99=94?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/config/WebSocketConfig.java  | 1 -
 src/main/java/com/mnms/booking/security/SecurityConfig.java | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index 7331acd..3586522 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -23,7 +23,6 @@ public void configureMessageBroker(MessageBrokerRegistry config) {
     public void registerStompEndpoints(StompEndpointRegistry registry) {
         // WebSocket 연결을 위한 endpoint 설정
         registry.addEndpoint("/ws")
-                .setAllowedOriginPatterns("*")
                 .withSockJS();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 96a1090..76b4148 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -24,6 +24,7 @@ public SecurityConfig(HeaderAuthenticationFilter headerAuthFilter) {
     SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
         return http
                 .csrf(AbstractHttpConfigurer::disable)
+                .cors(AbstractHttpConfigurer::disable) // gateway CORS 중복 방지
                 .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
                         .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()

From 46a60f20055eec3bb05312b98d34192b9db6540d Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 9 Sep 2025 12:45:27 +0900
Subject: [PATCH 109/149] =?UTF-8?q?hotfix:=20websocket=20=EA=B2=BD?=
 =?UTF-8?q?=EB=A1=9C=20auth=20=ED=97=88=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/security/SecurityConfig.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 76b4148..3d9c6e1 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -27,6 +27,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                 .cors(AbstractHttpConfigurer::disable) // gateway CORS 중복 방지
                 .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
+                        .requestMatchers("/ws/**").permitAll()
                         .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
                         .requestMatchers(
                                 "/public/**",

From b7bc15bd0c4d9c060128c99e0fbd0694a4a57afb Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 10 Sep 2025 09:25:57 +0900
Subject: [PATCH 110/149] =?UTF-8?q?hotfix:=20websocket=20origin=20?=
 =?UTF-8?q?=ED=97=88=EC=9A=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/config/WebSocketConfig.java  |  1 +
 .../controller/WebSocketAdminController.java  | 27 +++++++++++++++++++
 .../mnms/booking/security/SecurityConfig.java |  3 ++-
 3 files changed, 30 insertions(+), 1 deletion(-)
 create mode 100644 src/main/java/com/mnms/booking/controller/WebSocketAdminController.java

diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index 3586522..7331acd 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -23,6 +23,7 @@ public void configureMessageBroker(MessageBrokerRegistry config) {
     public void registerStompEndpoints(StompEndpointRegistry registry) {
         // WebSocket 연결을 위한 endpoint 설정
         registry.addEndpoint("/ws")
+                .setAllowedOriginPatterns("*")
                 .withSockJS();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/controller/WebSocketAdminController.java b/src/main/java/com/mnms/booking/controller/WebSocketAdminController.java
new file mode 100644
index 0000000..24cfe3d
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/WebSocketAdminController.java
@@ -0,0 +1,27 @@
+package com.mnms.booking.controller;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.messaging.simp.user.SimpUser;
+import org.springframework.messaging.simp.user.SimpUserRegistry;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/api/ws")
+@RequiredArgsConstructor
+public class WebSocketAdminController {
+
+    private final SimpUserRegistry simpUserRegistry;
+
+    // 현재 WebSocket에 연결된 사용자 확인
+    @GetMapping("/users")
+    public Set connectedUsers() {
+        return simpUserRegistry.getUsers().stream()
+                .map(SimpUser::getName)
+                .collect(Collectors.toSet());
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 3d9c6e1..8d5f960 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -38,7 +38,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                                 "/api/host/**",
                                 "/api/booking/confirm",
                                 "/api/transfer/**",
-                                "/api/transfer/**"
+                                "/api/transfer/**",
+                                "/api/ws/**"
                         ).permitAll() // 하위 경로 포함 허용
                         .anyRequest().permitAll()
                 )

From 6f65499faba4b255b2e2ed91d58a99db9b35925a Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 10 Sep 2025 17:46:59 +0900
Subject: [PATCH 111/149] =?UTF-8?q?MNMS-632=20Chore:=20swagger=20=EC=97=90?=
 =?UTF-8?q?=EB=9F=AC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B6=94=EA=B0=80=20?=
 =?UTF-8?q?=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java |  43 +-
 .../booking/controller/CaptchaController.java |  19 +-
 .../booking/controller/HostController.java    |  17 +-
 .../booking/controller/QrCodeController.java  |  13 +-
 .../controller/StatisticsController.java      |  19 +-
 .../booking/controller/TicketController.java  |  24 +-
 .../controller/TransferController.java        |  48 +-
 .../booking/controller/WaitingController.java |  25 +-
 .../com/mnms/booking/exception/ErrorCode.java |   5 +-
 .../exception/global/ErrorResponse.java       |   6 +-
 .../booking/repository/TicketRepository.java  |   2 +-
 .../service/BookingCommandService.java        |   2 +-
 .../booking/service/BookingStatusService.java |   2 +-
 .../mnms/booking/service/CaptchaService.java  |   1 -
 .../service/StatisticsQueryService.java       |   3 +-
 .../specification/BookingSpecification.java   | 285 ++++++++++
 .../specification/CaptchaSpecification.java   | 120 +++++
 .../specification/HostSpecification.java      | 186 +++++++
 .../specification/QrCodeSpecification.java    | 121 +++++
 .../StatisticsSpecification.java              | 180 +++++++
 .../specification/TicketSpecification.java    | 136 +++++
 .../specification/TransferSpecification.java  | 487 ++++++++++++++++++
 .../specification/WaitingSpecification.java   | 276 ++++++++++
 23 files changed, 1849 insertions(+), 171 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/specification/BookingSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/HostSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/TicketSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/TransferSpecification.java
 create mode 100644 src/main/java/com/mnms/booking/specification/WaitingSpecification.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index c63c75e..260960b 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -10,11 +10,10 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.BookingQueryService;
 import com.mnms.booking.service.BookingCommandService;
+import com.mnms.booking.specification.BookingSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
 import com.mnms.booking.util.UserApiClient;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpStatus;
@@ -25,8 +24,7 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
-@Tag(name = "예매 API", description = "예매 티켓 조회, 티켓 선택, 생성")
-public class BookingController {
+public class BookingController implements BookingSpecification {
 
     private final BookingCommandService bookingCommandService;
     private final BookingQueryService bookingQueryService;
@@ -34,17 +32,12 @@ public class BookingController {
     private final SecurityResponseUtil securityResponseUtil;
 
     /// GET : 페스티벌 예매 정보 조회
-    @PostMapping("/detail/phases/1")
-    @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId와 performanceDate(사용자가 선택한 날짜, 시간)으로 공연 상세 정보를 조회합니다." +
-                    "selectedTicketCount는 0으로 넣을 것!")
+    @Override
     public ResponseEntity> getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
         return ApiResponseUtil.success(bookingQueryService.getFestivalDetail(request));
     }
 
-    @PostMapping("/detail/phases/2")
-    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
-            description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
+    @Override
     public ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
@@ -54,10 +47,7 @@ public ResponseEntity> getFestivalBook
     }
 
     /// POST
-    @PostMapping("/selectDate")
-    @Operation(summary = "페스티벌 특정 페스티벌 날짜, 시간, 매수 선택",
-            description = "festivalId, performanceDate(선택한날짜,시간), selectedTicketCount(매수)를 입력하고 reservationNumber를 반환합니다."
-    )
+    @Override
     public ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
             Authentication authentication
@@ -65,10 +55,7 @@ public ResponseEntity> selectFestivalDate(
         return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, securityResponseUtil.requireUserId(authentication)));
     }
 
-    @PostMapping("/selectDeliveryMethod")
-    @Operation(summary = "페스티벌 특정 페스티벌 티켓 수령 방법, 주소 선택",
-            description = "festivalId, performanceDate(선택한날짜,시간), deliveryMethod(MOBILE or PAPER), address(String)"
-    )
+    @Override
     public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
             Authentication authentication
@@ -78,10 +65,7 @@ public ResponseEntity> selectFestivalDelivery(
     }
 
     /// POST : 3차 예매 완료 (결제 직전)
-    @PostMapping("/qr")
-    @Operation(summary = "페스티벌 예매 티켓 생성",
-            description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태입니다."
-    )
+    @Override
     public ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
@@ -91,26 +75,19 @@ public ResponseEntity> reserveTicket(
     }
 
     ///  Websocket 메시지 누락 방지 api요청
-    @GetMapping("reservation/status")
-    @Operation( summary = "예매 완료/취소 정보 조회",
-            description = "Websocket 메시지 누락 시, " +
-                    "예매 완료 혹은 취소 되었는지 확인합니다. ")
+    @Override
     public ResponseEntity> checkStatus(@RequestParam String reservationNumber){
         return ApiResponseUtil.success(bookingCommandService.checkStatus(reservationNumber));
     }
 
     ///  GET
-    @GetMapping("/user/info")
-    @Operation(summary = "예매자 정보 조회",
-            description = "예매 과정에서 예매자 정보를 조회합니다." +
-                    "예매자 role이 user인 사람만 조회 가능합니다. (email)"
-    )
+    @Override
     public ResponseEntity> getUserInfo(Authentication authentication) {
         return ApiResponseUtil.success(userApiClient.getUserInfoById(securityResponseUtil.requireUserId(authentication)));
     }
 
     ///  이메일 임시 테스트
-    @PostMapping("/email/test")
+    @Override
     public ResponseEntity confirmTicket(
             @RequestParam String reservationNumber,
             @RequestParam boolean paymentStatus) {
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
index a98d812..d9414e0 100644
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -3,9 +3,8 @@
 import com.mnms.booking.dto.response.CaptchaResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.CaptchaService;
+import com.mnms.booking.specification.CaptchaSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
@@ -20,27 +19,17 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/captcha")
-@Tag(name = "보안문자 API", description = "보안문자 생성 및 인증")
-public class CaptchaController {
+public class CaptchaController implements CaptchaSpecification{
 
     private final CaptchaService kaptchaService;
 
-    @GetMapping("/image")
-    @Operation(
-            summary = "보안문자 이미지 요청",
-            description = "새로운 보안문자 이미지를 생성하여 반환합니다."
-    )
+    @Override
     public ResponseEntity> getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
         kaptchaService.writeCaptchaImage(request.getSession(), response);
         return ApiResponseUtil.success(null, "보안문자 이미지가 생성 완료");
     }
 
-    @PostMapping("/verify")
-    @Operation(
-            summary = "보안문자 검증",
-            description = "사용자가 입력한 보안문자 값이 올바른지 검증합니다. " +
-                    "보안문자는 다섯 글자이며 대소문자 구분하지 않습니다. 만료시간은 3분이고, 불일치로 실패해도 만료시간 내에 입력하면 인증 가능합니다."
-    )
+    @Override
     public ResponseEntity> verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 87115b7..01c0eec 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -4,12 +4,10 @@
 import com.mnms.booking.dto.response.HostResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.HostService;
+import com.mnms.booking.specification.HostSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.security.core.Authentication;
@@ -18,27 +16,20 @@
 import java.util.List;
 
 @RestController
-@Slf4j
 @RequiredArgsConstructor
 @RequestMapping("/api/host")
-@Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
-public class HostController {
+public class HostController implements HostSpecification{
 
     private final SecurityResponseUtil securityResponseUtil;
     private final HostService hostService;
 
-    @PostMapping("/list")
-    @Operation(summary = "주최자 도메인에 예매자 리스트 제공",
-            description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId를 리스트로 제공합니다. front와 관련 없음"
-    )
+    @Override
     public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
 
     /// 주최자 측 예매자 조회
-    @PostMapping("/booking/list")
-    @Operation(summary = "예매자 정보 조회",
-            description = "예매자 정보 조회, 주최자 혹은 운영자로 로그인해야합니다.")
+    @Override
     @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
     public ResponseEntity>> getBookingInfo(@RequestParam String festivalId,
                                                                                  Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index 7427c8d..ccc16ab 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -3,10 +3,10 @@
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.QrCodeService;
+import com.mnms.booking.specification.QrCodeSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
 import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
@@ -21,16 +21,13 @@
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/qr")
-@Tag(name = "QR API", description = "QR 이미지 조회, 스캔, ")
-public class QrCodeController {
+public class QrCodeController implements QrCodeSpecification {
 
     private final QrCodeService qrCodeService;
     private final SecurityResponseUtil securityResponseUtil;
 
     /// Qrcode 이미지 조회
-    @GetMapping(value = "/image/{qrCodeId}", produces = MediaType.IMAGE_PNG_VALUE)
-    @Operation(summary = "QR 코드 이미지 조회",
-            description = "qrCodeId로 QR 코드 이미지를 PNG 형식으로 반환합니다.")
+    @Override
     public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
         QrCode qrCode = qrCodeService.getQrCodeByCode(qrCodeId);
         String qrCodeText = qrCode.getQrCodeId();
@@ -67,9 +64,7 @@ public ResponseEntity> getQrCodeImages(@RequestParam List q
 
 
     /// 페스티벌 주최자 QR 스캔
-    @PostMapping(value = "/validate/{qrCodeId}")
-    @Operation(summary = "QR 코드 스캔 및 유효성 검사",
-            description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
+    @Override
     public ResponseEntity> validateAndUseQrCode(
             @PathVariable String qrCodeId,
             Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/StatisticsController.java b/src/main/java/com/mnms/booking/controller/StatisticsController.java
index 0aeadd9..8ff71f3 100644
--- a/src/main/java/com/mnms/booking/controller/StatisticsController.java
+++ b/src/main/java/com/mnms/booking/controller/StatisticsController.java
@@ -7,8 +7,8 @@
 import com.mnms.booking.service.StatisticsQueryService;
 import com.mnms.booking.service.StatisticsUserService;
 import com.mnms.booking.service.StatisticsQrCodeService;
+import com.mnms.booking.specification.StatisticsSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
-import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import org.springframework.format.annotation.DateTimeFormat;
@@ -23,22 +23,19 @@
 @RequestMapping("/api/statistics")
 @RequiredArgsConstructor
 @Tag(name = "통계 API", description = "공연 별 예매자의 정보를 통해 성별/나이, 입장 인원 상황을 확인 가능")
-public class StatisticsController {
+public class StatisticsController implements StatisticsSpecification {
 
     private final StatisticsUserService statisticsUserService;
     private final StatisticsQrCodeService statisticsQrCodeService;
     private final StatisticsQueryService statisticsQueryService;
 
-    @GetMapping("/users/{festivalId}")
-    @Operation(summary = "feestivalId별 예매자의 성별/나이 통계 조회", description = "특정 페스티벌의 예매자 통계를 조회합니다.")
+    @Override
     public ResponseEntity> getFestivalUserStatistics(@PathVariable String festivalId) {
         StatisticsUserResponseDTO statistics = statisticsUserService.getFestivalUserStatistics(festivalId);
         return ApiResponseUtil.success(statistics, "예매자 통계 정보가 성공적으로 조회되었습니다.");
     }
 
-    @GetMapping("/schedules/{festivalId}")
-    @Operation(summary = "공연의 모든 유효 공연 날짜/시간 목록 조회",
-            description = "주최자가 입장 통계를 조회하기 전, 해당 페스티벌의 유효한(예매 내역이 있는) 모든 공연 날짜와 시간 목록을 가져옵니다.")
+    @Override
     public ResponseEntity>> getPerformanceDatesForFestival(
             @PathVariable String festivalId,
             Authentication authentication) {
@@ -50,13 +47,11 @@ public ResponseEntity>> getPerformanceDatesF
         return ApiResponseUtil.success(performanceDates, "공연 날짜 목록이 성공적으로 조회되었습니다.");
     }
 
-    @GetMapping("/enter/{festivalId}")
-    @Operation(summary = "공연 날짜별 입장 통계", description = "예매자 및 주최자가 자신의 공연 날짜별 현장 QR 입장 통계를 조회합니다.")
+    @Override
     public ResponseEntity> getPerformanceEnterStatistics(
             @PathVariable String festivalId,
             @RequestParam("performanceDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime performanceDate,
             Authentication authentication) {
-
         String userId = authentication.getName();
         boolean isHost = authentication.getAuthorities().stream()
                 .anyMatch(a -> a.getAuthority().equals("ROLE_HOST"));
@@ -68,9 +63,7 @@ public ResponseEntity> getPerforman
         return ApiResponseUtil.success(statistics, "공연 입장 통계 정보가 성공적으로 조회되었습니다.");
     }
 
-    @GetMapping("/booking/{festivalId}")
-    @Operation(summary = "공연별 예매자 수 / 수용 인원 요약 조회",
-            description = "주최자가 자신의 페스티벌에 대한 각 공연(날짜/시간)별 예매 현황과 총 수용 인원을 요약하여 조회합니다.")
+    @Override
     public ResponseEntity>> getBookingSummary(
             @PathVariable String festivalId,
             Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index 795d189..f09a919 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -4,50 +4,34 @@
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.TicketService;
+import com.mnms.booking.specification.TicketSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
-
-@Slf4j
 @RestController
 @RequiredArgsConstructor
 @RequestMapping("/api/ticket")
-@Tag(name = "예매 내역 API", description = "예매 내역 조회")
-public class TicketController {
+public class TicketController implements TicketSpecification {
 
     private final TicketService ticketService;
     private final SecurityResponseUtil securityResponseUtil;
 
-    @GetMapping
-    @Operation(summary = "예매한 티켓 정보 조회",
-            description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
-    )
+    @Override
     public ResponseEntity>> getUserTickets(Authentication authentication) {
         List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(tickets);
     }
 
-    @GetMapping("/detail")
-    @Operation(summary = "예매한 티켓 정보 디테일 조회",
-            description = "예매자가 예매 완료한 티켓 정보를 조회합니다. " +
-                    "ex : /api/ticket/detail?reservationNumber=T24CBD629 조회"
-    )
+    @Override
     public ResponseEntity> getUserTicketDetail(@RequestParam String reservationNumber,
                                                                                         Authentication authentication) {
         TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication), securityResponseUtil.requireName(authentication));
         return ApiResponseUtil.success(ticket);
     }
-
-
-
-
 }
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index f6c8c17..30230a4 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -8,16 +8,14 @@
 import com.mnms.booking.dto.response.TicketResponseDTO;
 import com.mnms.booking.dto.response.TicketTransferResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
-import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.OcrParserService;
 import com.mnms.booking.service.OcrService;
 import com.mnms.booking.service.TransferCompletionService;
 import com.mnms.booking.service.TransferService;
+import com.mnms.booking.specification.TransferSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
 import org.springframework.http.ResponseEntity;
@@ -31,18 +29,14 @@
 @RestController
 @RequestMapping("/api/transfer")
 @RequiredArgsConstructor
-@Tag(name = "양도 API", description = "양도 및 OCR, Ticket 재생성")
-public class TransferController {
+public class TransferController implements TransferSpecification {
     private final OcrService ocrService;
     private final TransferService transferService;
     private final SecurityResponseUtil securityResponseUtil;
     private final TransferCompletionService transferCompletionService;
 
     ///  양도할 수 있는 티켓 조회
-    @GetMapping("/transferor")
-    @Operation(summary = "양도 가능한 티켓 정보 조회",
-            description = "사용자가 양도 가능한 티켓을 조회할 수 있습니다. (status : 양도 받은 티켓 양도 불가능)"
-    )
+    @Override
     public ResponseEntity>> getUserTickets(Authentication authentication) {
         List tickets = transferService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(tickets);
@@ -50,10 +44,7 @@ public ResponseEntity>> getUserTickets(A
 
 
     ///  가족관계증명서 인증
-    @PostMapping("/extract")
-    @Operation(summary = "가족 간 양도 진행 인증 시도",
-            description = "가족관계증명서 PDF를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답을 보냅니다."
-    )
+    @Override
     public ResponseEntity> extractPersonAuth(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -65,10 +56,7 @@ public ResponseEntity> extractPersonAuth(
         return ApiResponseUtil.success(null,"가족관계증명서 인증이 완료되었습니다.");
     }
 
-    @PostMapping("/extract/result")
-    @Operation(summary = "가족 간 양도 진행 인증 시도",
-            description = "가족관계증명서 PDF를 첨부하고 양도자 및 양수자의 이름과 주민등록번호로 요청하고, 인증 완료 응답과 결과를 보냅니다."
-    )
+    @Override
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -83,10 +71,7 @@ public ResponseEntity>> extractPerso
 
 
     /// 양도 요청
-    @PostMapping("/request")
-    @Operation(summary = "양도 요청",
-            description = "양도자가 양도 요청 보내기"
-    )
+    @Override
     public ResponseEntity> requestTransfer(
             @RequestBody @Valid TicketTransferRequestDTO dto,
             Authentication authentication
@@ -96,20 +81,14 @@ public ResponseEntity> requestTransfer(
     }
 
     /// 양도 요청 받기 (조회)
-    @GetMapping("/watch")
-    @Operation(summary = "양도 요청 조회",
-            description = "양수자가 양도 요청을 조회합니다."
-    )
+    @Override
     public ResponseEntity>> watchTransfer(Authentication authentication){
         List response = transferService.watchTransfer(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(response);
     }
 
     /// 가족 간 양도 요청 승인
-    @PutMapping("/acceptance/family")
-    @Operation(summary = "가족 간 양도 요청 수락",
-            description = "가족 간 양도 요청 시, 양수자가 요청을 수락하면 양도가 완료되며 티켓과 QR 정보가 업데이트 됩니다."
-    )
+    @Override
     public ResponseEntity> responseTicketFamily(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
@@ -118,11 +97,7 @@ public ResponseEntity> responseTicketFamily(
     }
 
     /// 지인간 양도 요청 승인
-    @PutMapping("/acceptance/others")
-    @Operation(summary = "타인 간 양도 요청 완료",
-            description = "타인 간 양도 요청 시, 양수자가 요청을 수락하면 결제 요청이 넘어가게 됩니다. " +
-            "결제 완료 후 kafka 메시지 받으면 양도 완료됩니다."
-    )
+    @Override
     public ResponseEntity> responseTicketOthers(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
@@ -131,10 +106,7 @@ public ResponseEntity> responseTicket
     }
 
     ///  Websocket 메시지 누락 방지 api요청
-    @GetMapping("/reservation/status")
-    @Operation( summary = "양도 결제 완료 조회",
-            description = "Websocket 메시지 누락 시, " +
-                    "양도 결제 완료 혹은 실패를 확인합니다. ")
+    @Override
     public ResponseEntity> checkStatus(@RequestParam Long transferId){
         return ApiResponseUtil.success(transferService.checkStatus(transferId));
     }
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index f48523a..fa5c3a3 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -5,12 +5,10 @@
 import com.mnms.booking.service.FestivalService;
 import com.mnms.booking.service.WaitingNotificationService;
 import com.mnms.booking.service.WaitingQueueKeyGenerator;
+import com.mnms.booking.specification.WaitingSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
-import io.swagger.v3.oas.annotations.Hidden;
-import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -29,8 +27,7 @@
 @Slf4j
 @RequiredArgsConstructor
 @RequestMapping("/api/booking")
-@Tag(name = "대기열 API", description = "대기열 입장, 예매 화면 입장, 대기번호 조회(websocket), 대기열 퇴장")
-public class WaitingController {
+public class WaitingController implements WaitingSpecification {
 
     private final WaitingService waitingService;
     private final FestivalService festivalService;
@@ -42,7 +39,7 @@ public class WaitingController {
     private SimpMessagingTemplate messagingTemplate;
 
     /// 예매하기 버튼(front) 클릭 시 호출되는 API
-    @GetMapping("/enter")
+    @Override
     public ResponseEntity> enterBookingPage(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
@@ -61,13 +58,7 @@ public ResponseEntity> enterBookingPag
     }
 
     /// 예매 페이지 퇴장
-    @GetMapping("/release")
-    @Operation(
-            summary = "예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)",
-            description = "예매 페이지에 있던 사용자가 퇴장했을 때 실행됩니다. " +
-                    "(대기열에 있던 대기번호 1번 사용자는 스케쥴러에 의해 예매 페이지로 자동 입장 하게 되고, " +
-                    "대기열에 있던 모든 대기자의 대기번호가 변경됩니다.)"
-    )
+    @Override
     public ResponseEntity> releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
@@ -85,12 +76,7 @@ public ResponseEntity> releaseUser(
     }
 
     /// 대기열에서 퇴장
-    @Operation(
-            summary = "대기열 퇴장",
-            description = "대기 중인 사용자가 스스로 대기열에서 나갈 때 호출됩니다. " +
-                    "호출 시 해당 사용자는 대기열에서 제거됩니다."
-    )
-    @GetMapping("/exit")
+    @Override
     public ResponseEntity> exitWaitingUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
@@ -107,6 +93,7 @@ public ResponseEntity> exitWaitingUser(
         }
     }
 
+
     /**
      * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
      * 클라이언트가 /app/subscribe/waiting로 메시지를 보냄 (최초 구독 요청)
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 7d761e1..9095fed 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -1,7 +1,6 @@
 package com.mnms.booking.exception;
 
 import lombok.Getter;
-import org.springframework.boot.autoconfigure.graphql.GraphQlProperties;
 import org.springframework.http.HttpStatus;
 
 @Getter
@@ -19,9 +18,9 @@ public enum ErrorCode {
     FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
     FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
     FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
-    FESTIVAL_DELIVERY_INVALID("F004", "유효하지 않은 배송 방법입니다.", HttpStatus.BAD_REQUEST),
+    FESTIVAL_DELIVERY_INVALID("F004", "배송 방법 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
     FESTIVAL_MISMATCH("F005", "해당하는 QR의 페스티벌 주최자가 아닙니다.", HttpStatus.FORBIDDEN),
-    FESTIVAL_LIMIT_AVALIABLE_PEOPLE("F006", "해당 페스티벌 수용 인원이 초과되어 예매를 진행할 수 없습니다.", HttpStatus.CONFLICT),
+    FESTIVAL_LIMIT_AVAILABLE_PEOPLE("F006", "해당 페스티벌 수용 인원이 초과되어 예매를 진행할 수 없습니다.", HttpStatus.CONFLICT),
 
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
diff --git a/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
index 75c7602..5f1699a 100644
--- a/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
+++ b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
@@ -14,7 +14,7 @@
 @AllArgsConstructor
 @NoArgsConstructor
 public class ErrorResponse {
-    private boolean success;
-    private String errorCode;
-    private String errorMessage;
+    private boolean success = false;
+    private Object data = null;
+    private String message;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index aec002a..53ecf0f 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -61,7 +61,7 @@ List findDistinctUserIdsByFestivalIdAndPerformanceDateAndReservationStatus
     @Query("SELECT t.selectedTicketCount " +
             "FROM Ticket t " +
             "WHERE t.reservationNumber = :reservationNumber")
-    Long findSelectedTicketCountByReservationNumber(@Param("reservationNumber") String reservationNumber);
+    Long findTicketCountByReservationNumber(@Param("reservationNumber") String reservationNumber);
 
     @Query("SELECT COALESCE(SUM(t.selectedTicketCount), 0) " +
             "FROM Ticket t " +
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index e635e6a..b53c36c 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -74,7 +74,7 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
     @Transactional
     public void reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = bookingStatusService.getFestivalOrThrow(request.getFestivalId());
-        Long selectedTicketCount = ticketRepository.findSelectedTicketCountByReservationNumber(request.getReservationNumber());
+        Long selectedTicketCount = ticketRepository.findTicketCountByReservationNumber(request.getReservationNumber());
 
         bookingStatusService.validateCapacity(festival, request, selectedTicketCount);
 
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index 75c00ed..86c6ebc 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -64,7 +64,7 @@ public void validateCapacity(Festival festival, BookingRequestDTO request, Long
         );
 
         if (totalCount + selectedTicketCount > festival.getAvailableNOP()) {
-            throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVALIABLE_PEOPLE);
+            throw new BusinessException(ErrorCode.FESTIVAL_LIMIT_AVAILABLE_PEOPLE);
         }
     }
 
diff --git a/src/main/java/com/mnms/booking/service/CaptchaService.java b/src/main/java/com/mnms/booking/service/CaptchaService.java
index e9e9668..3608e77 100644
--- a/src/main/java/com/mnms/booking/service/CaptchaService.java
+++ b/src/main/java/com/mnms/booking/service/CaptchaService.java
@@ -6,7 +6,6 @@
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpSession;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
index 0292a00..41330ba 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
@@ -1,6 +1,7 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.response.StatisticsBookingDTO;
+import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.BusinessException;
@@ -49,7 +50,7 @@ public List getPerformanceDatesByFestivalId(String festivalId) {
 
     public List getBookingSummary(String festivalId) {
         int availableCapacity = festivalRepository.findByFestivalId(festivalId)
-                .map(festival -> festival.getAvailableNOP())
+                .map(Festival::getAvailableNOP)
                 .orElseThrow(() -> new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND));
 
         // 유효한 티켓을 가져오는 올바른 방법
diff --git a/src/main/java/com/mnms/booking/specification/BookingSpecification.java b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
new file mode 100644
index 0000000..f351e41
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
@@ -0,0 +1,285 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
+import com.mnms.booking.dto.request.BookingSelectRequestDTO;
+import com.mnms.booking.dto.response.BookingDetailResponseDTO;
+import com.mnms.booking.dto.response.BookingUserResponseDTO;
+import com.mnms.booking.dto.response.FestivalDetailResponseDTO;
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.validation.Valid;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+
+@Tag(name = "예매 API", description = "예매 티켓 조회, 티켓 선택, 생성")
+public interface BookingSpecification {
+
+    /// GET : 페스티벌 예매 정보 조회
+    @PostMapping("/detail/phases/1")
+    @Operation(summary = "1차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId와 performanceDate로 공연 상세 정보를 조회합니다. selectedTicketCount는 0으로 넣을 것!")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{\n" +
+                                    "  \"success\": true,\n" +
+                                    "  \"data\": {\n" +
+                                    "    \"festivalId\": \"PF272550\",\n" +
+                                    "    \"fname\": \"그 곳\",\n" +
+                                    "    \"performanceDate\": \"2025-09-07T15:00:00\",\n" +
+                                    "    \"posterFile\": \"http://www.kopis.or.kr/upload/pfmPoster/PF_PF272550_250825_154032.gif\",\n" +
+                                    "    \"ticketPrice\": 60000\n" +
+                                    "  },\n" +
+                                    "  \"message\": \"요청이 성공적으로 처리되었습니다.\"\n" +
+                                    "}"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{\n" +
+                                    "  \"success\": false,\n" +
+                                    "  \"data\": null,\n" +
+                                    "  \"message\": \"페스티벌을 찾을 수 없습니다.\"\n" +
+                                    "}"
+                    ))),
+            @ApiResponse(responseCode = "400", description = "선택한 날짜/시간이 잘못됨",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{\n" +
+                                    "  \"success\": false,\n" +
+                                    "  \"data\": null,\n" +
+                                    "  \"message\": \"선택한 날짜/시간이 잘못되었습니다.\"\n" +
+                                    "}"
+                    )))
+    })
+    ResponseEntity> getFestivalDetail(
+            @Valid @RequestBody BookingSelectRequestDTO request);
+
+    /// POST : 2차 예매 상세 조회
+    @PostMapping("/detail/phases/2")
+    @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
+            description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{\n" +
+                                    "  \"success\": true,\n" +
+                                    "  \"data\": {\n" +
+                                    "    \"reservationNumber\": \"TAEEDA779\",\n" +
+                                    "    \"userName\": \"삼길동\",\n" +
+                                    "    \"performanceDate\": \"2025-09-07T15:00:00\",\n" +
+                                    "    \"deliveryMethod\": \"MOBILE\",\n" +
+                                    "    \"address\": \"서울집\",\n" +
+                                    "    \"ticketPrice\": 60000\n" +
+                                    "  },\n" +
+                                    "  \"message\": \"조회 성공\"\n" +
+                                    "}"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌 또는 티켓을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌 또는 티켓을 찾을 수 없습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                    )))
+    })
+    ResponseEntity> getFestivalBookingDetail(
+            @Valid @RequestBody BookingRequestDTO request,
+            Authentication authentication
+    );
+
+    /// POST : 날짜 선택
+    @PostMapping("/selectDate")
+    @Operation(summary = "페스티벌 날짜, 시간, 매수 선택",
+            description = "festivalId, performanceDate, selectedTicketCount를 입력하고 reservationNumber 반환")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "임시 예약 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{ \"success\": true, \"data\": \"TAEEDA779\", \"message\": \"임시 예약 성공\" }"
+                    ))),
+            @ApiResponse(responseCode = "400", description = "유효하지 않은 날짜/시간 또는 티켓 수 초과",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"유효하지 않은 날짜/시간 또는 티켓 수 초과\" }"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌을 찾을 수 없습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "409", description = "예약 가능한 티켓 수를 초과",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"예약 가능한 티켓 수를 초과했습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                    )))
+    })
+    ResponseEntity> selectFestivalDate(
+            @Valid @RequestBody BookingSelectRequestDTO request,
+            Authentication authentication
+    );
+
+    /// POST : 배송 선택
+    @PostMapping("/selectDeliveryMethod")
+    @Operation(summary = "페스티벌 티켓 수령 방법, 주소 선택",
+            description = "festivalId, performanceDate, deliveryMethod(MOBILE or PAPER), address 선택")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "배송 방법 선택 완료",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{ \"success\": true, \"data\": null, \"message\": \"배송 방법 선택 완료\" }"
+                    ))),
+            @ApiResponse(responseCode = "400", description = "유효하지 않은 배송 방법/주소",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"유효하지 않은 배송 방법/주소\" }"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "티켓 또는 페스티벌을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓 또는 페스티벌을 찾을 수 없습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                    )))
+    })
+    ResponseEntity> selectFestivalDelivery(
+            @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
+            Authentication authentication
+    );
+
+    /// POST : 3차 예매 완료 (QR 생성)
+    @PostMapping("/qr")
+    @Operation(summary = "페스티벌 예매 티켓 생성",
+            description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "QR 생성 및 예약 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{ \"success\": true, \"data\": null, \"message\": \"QR 생성 및 예약 성공\" }"
+                    ))),
+            @ApiResponse(responseCode = "400", description = "배송 방법 선택하지 않거나 올바르지 않음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"배송 방법 선택하지 않았거나 올바르지 않습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "티켓 또는 페스티벌을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓 또는 페스티벌을 찾을 수 없습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "409", description = "페스티벌 수용 인원 초과",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌 수용 인원을 초과했습니다.\" }"
+                    )))
+    })
+    ResponseEntity> reserveTicket(
+            @Valid @RequestBody BookingRequestDTO request,
+            Authentication authentication
+    );
+
+    /// GET : WebSocket 메시지 누락 방지
+    @GetMapping("reservation/status")
+    @Operation(summary = "예매 완료/취소 정보 조회",
+            description = "WebSocket 메시지 누락 시 상태 확인")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{ \"success\": true, \"data\": \"CONFIRMED\", \"message\": \"조회 성공\" }"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓을 찾을 수 없습니다.\" }"
+                    )))
+    })
+    ResponseEntity> checkStatus(@RequestParam String reservationNumber);
+
+    /// GET : 예매자 정보 조회
+    @GetMapping("/user/info")
+    @Operation(summary = "예매자 정보 조회",
+            description = "예매자 role이 user인 사람만 조회 가능")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{\n" +
+                                    "  \"success\": true,\n" +
+                                    "  \"data\": {\n" +
+                                    "    \"userName\": \"삼길동\",\n" +
+                                    "    \"id\": 12\n" +
+                                    "  },\n" +
+                                    "  \"message\": \"조회 성공\"\n" +
+                                    "}"
+                    ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "403", description = "권한 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"권한이 없습니다.\" }"
+                    )))
+    })
+    ResponseEntity> getUserInfo(Authentication authentication);
+
+    /// POST : 이메일 임시 테스트
+    @PostMapping("/email/test")
+    @Operation(summary = "[테스트 진행X] 이메일 임시 테스트",
+            description = "예매 완료 후 이메일 전송 임시 테스트")
+    @ApiResponses({
+            @ApiResponse(responseCode = "200", description = "메일 발송 성공",
+                    content = @Content(schema = @Schema(
+                            implementation = SuccessResponse.class,
+                            example = "{ \"success\": true, \"data\": null, \"message\": \"메일 발송 성공\" }"
+                    ))),
+            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓을 찾을 수 없습니다.\" }"
+                    ))),
+            @ApiResponse(responseCode = "500", description = "메일 발송 실패",
+                    content = @Content(schema = @Schema(
+                            implementation = ErrorResponse.class,
+                            example = "{ \"success\": false, \"data\": null, \"message\": \"메일 발송 실패\" }"
+                    )))
+    })
+    ResponseEntity confirmTicket(
+            @RequestParam String reservationNumber,
+            @RequestParam boolean paymentStatus
+    );
+}
diff --git a/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java b/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
new file mode 100644
index 0000000..d7ed7e5
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
@@ -0,0 +1,120 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.response.CaptchaResponseDTO;
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+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.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpSession;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.io.IOException;
+
+@Tag(name = "보안문자 API", description = "보안문자 생성 및 인증")
+public interface CaptchaSpecification {
+
+    @GetMapping("/image")
+    @Operation(
+            summary = "보안문자 이미지 요청",
+            description = "새로운 보안문자 이미지를 생성하여 반환합니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "보안문자 생성 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    name = "성공 응답 예시",
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": null,
+                                      "message": "보안문자 이미지가 생성 완료"
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> getCaptchaImage(
+            @Parameter(hidden = true) HttpServletRequest request,
+            @Parameter(hidden = true) HttpServletResponse response
+    ) throws IOException;
+
+
+
+    @PostMapping("/verify")
+    @Operation(
+            summary = "보안문자 검증",
+            description = "사용자가 입력한 보안문자 값이 올바른지 검증합니다. " +
+                    "보안문자는 다섯 글자이며 대소문자 구분하지 않습니다. 만료시간은 3분이고, 불일치로 실패해도 만료시간 내에 입력하면 인증 가능합니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "보안문자 인증 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    name = "성공 응답 예시",
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": {
+                                        "success": true,
+                                        "remainingAttempts": 2
+                                      },
+                                      "message": "보안문자 인증 성공"
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "400",
+                    description = "보안문자 인증 실패",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    name = "실패 응답 예시",
+                                    value = """
+                                            [
+                                                {
+                                                    "success": false,
+                                                    "data": null,
+                                                    "message": "보안문자가 만료되었습니다."
+                                                },
+                                                {
+                                                    "success": false,
+                                                    "data": null,
+                                                    "message": "보안문자 불일치로 인증이 실패하였습니다."
+                                                }
+                                            ]
+                                            """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> verifyCaptcha(
+            @Parameter(description = "사용자가 입력한 보안문자 값", required = true, example = "aB12c")
+            @RequestParam("captcha") String captcha,
+
+            @Parameter(hidden = true)
+            HttpSession session
+    );
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/specification/HostSpecification.java b/src/main/java/com/mnms/booking/specification/HostSpecification.java
new file mode 100644
index 0000000..f3d5209
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/HostSpecification.java
@@ -0,0 +1,186 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.request.HostRequestDTO;
+import com.mnms.booking.dto.response.HostResponseDTO;
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+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.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
+public interface HostSpecification {
+
+    @PostMapping("/list")
+    @Operation(
+            summary = "주최자 도메인에 예매자 리스트 제공",
+            description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId 리스트를 반환합니다. (프론트와 직접 관련 없음)"
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": [101, 102, 103],
+                                      "message": "조회 성공"
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "404",
+                    description = "페스티벌을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                               "success": false,
+                                               "data": "FESTIVAL_NOT_FOUND",
+                                               "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "409",
+                    description = "사용자 API 호출 실패",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                               "success": false,
+                                               "data": "USER_API_ERROR",
+                                               "message": "예매자 정보를 가져오는데 실패했습니다."
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity>> getBookingsByOrganizer(
+            @Parameter(description = "주최자 요청 DTO", required = true)
+            @RequestBody HostRequestDTO hostRequestDTO
+    );
+
+    @PostMapping("/booking/list")
+    @Operation(
+            summary = "예매자 정보 조회",
+            description = "예매자 정보를 조회합니다. HOST 또는 ADMIN 권한이 필요합니다.",
+            security = @SecurityRequirement(name = "bearerAuth")
+    )
+    @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": [
+                                        {
+                                          "reservationNumber": "TAEEDA123",
+                                          "performanceDate": "2025-09-07T15:00:00",
+                                          "userId": 101,
+                                          "selectedTicketCount": 2,
+                                          "deliveryMethod": "MOBILE",
+                                          "address": "서울집",
+                                          "userName": "홍길동",
+                                          "userPhone": "010-1234-5678"
+                                        }
+                                      ],
+                                      "message": "조회 성공"
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "404",
+                    description = "페스티벌을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                               "success": false,
+                                               "data": "FESTIVAL_NOT_FOUND",
+                                               "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "403",
+                    description = "권한 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                               "success": false,
+                                               "data": "ACCESS_DENIED",
+                                               "message": "접근 권한이 없습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "409",
+                    description = "사용자 API 호출 실패 또는 알 수 없는 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                               "success": false,
+                                               "data": "USER_API_ERROR",
+                                               "message": "예매자 정보를 가져오는데 실패했습니다."
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity>> getBookingInfo(
+            @Parameter(description = "조회할 festivalId", example = "PF123456", required = true)
+            @RequestParam String festivalId,
+
+            @Parameter(hidden = true)
+            Authentication authentication
+    );
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java b/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
new file mode 100644
index 0000000..ebc705b
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
@@ -0,0 +1,121 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+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.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+
+@Tag(name = "QR API", description = "QR 이미지 조회, 스캔")
+public interface QrCodeSpecification {
+
+    @GetMapping(value = "/image/{qrCodeId}", produces = "image/png")
+    @Operation(summary = "QR 코드 이미지 조회", description = "qrCodeId로 QR 코드 이미지를 PNG 형식으로 반환합니다.")
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "조회 성공",
+                    content = @Content(mediaType = "image/png")
+            ),
+            @ApiResponse(
+                    responseCode = "409",
+                    description = "QR 코드를 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                            {
+                                               "success": false,
+                                               "data": "QR_CODE_ALREADY_USED",
+                                               "message": "이미 사용된 QR 코드입니다."
+                                            }
+                                            """
+                            )
+                    )
+            )
+    })
+    ResponseEntity getQrCodeImage(
+            @Parameter(description = "조회할 QR 코드 ID", example = "4b2f23d3019b727a3320f5a79ae98d27")
+            @PathVariable String qrCodeId
+    );
+
+    @PostMapping(value = "/validate/{qrCodeId}")
+    @Operation(summary = "QR 코드 스캔 및 유효성 검사", description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "QR 스캔 완료",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "410",
+                    description = "QR 코드가 유효하지 않거나 만료됨",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    name = "Expired QR",
+                                    value = """
+                                            {
+                                               "success": false,
+                                               "data": "QR_CODE_EXPIRED",
+                                               "message": "QR 코드의 만료일이 지났습니다."
+                                            }
+                                            """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "403",
+                    description = "주최자와 QR 코드 페스티벌 불일치",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                            {
+                                               "success": false,
+                                               "data": "FESTIVAL_MISMATCH",
+                                               "message": "해당하는 QR의 페스티벌 주최자가 아닙니다."
+                                            }
+                                            """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "409",
+                    description = "이미 사용된 QR 코드",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                            {
+                                               "success": false,
+                                               "data": "QR_CODE_ALREADY_USED",
+                                               "message": "QR 코드가 이미 사용되었습니다."
+                                            }
+                                            """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> validateAndUseQrCode(
+            @PathVariable String qrCodeId,
+            Authentication authentication
+    );
+}
diff --git a/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java b/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
new file mode 100644
index 0000000..a695058
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
@@ -0,0 +1,180 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.response.StatisticsBookingDTO;
+import com.mnms.booking.dto.response.StatisticsQrCodeResponseDTO;
+import com.mnms.booking.dto.response.StatisticsUserResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.GetMapping;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Tag(name = "통계 API", description = "공연 별 예매자의 정보를 통해 성별/나이, 입장 인원 상황을 확인 가능")
+public interface StatisticsSpecification {
+
+    @GetMapping("/users/{festivalId}")
+    @Operation(summary = "festivalId별 예매자 성별/나이 통계 조회",
+            description = "특정 페스티벌의 예매자 통계를 조회합니다.")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(implementation = StatisticsUserResponseDTO.class))),
+            @ApiResponse(responseCode = "500", description = "User MSA 조회 실패",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_API_ERROR",
+                                      "message": "사용자 통계 정보 조회에 실패했습니다."
+                                    }
+                                    """
+                            )
+                    ))
+    })
+    ResponseEntity> getFestivalUserStatistics(String festivalId);
+
+
+
+    @GetMapping("/schedules/{festivalId}")
+    @Operation(summary = "공연 날짜/시간 목록 조회",
+            description = "주최자가 입장 통계를 조회하기 전, 해당 페스티벌의 유효 공연 날짜/시간 목록 조회")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(implementation = List.class))),
+            @ApiResponse(responseCode = "404", description = "페스티벌 없음",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "FESTIVAL_NOT_FOUND",
+                                      "message": "해당 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    ))
+    })
+    ResponseEntity>> getPerformanceDatesForFestival(
+            String festivalId,
+            Authentication authentication
+    );
+
+
+
+    @GetMapping("/enter/{festivalId}")
+    @Operation(summary = "공연 날짜별 입장 통계",
+            description = "예매자 및 주최자가 공연 날짜별 현장 QR 입장 통계를 조회합니다.")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(implementation = StatisticsQrCodeResponseDTO.class))),
+            @ApiResponse(responseCode = "403", description = "권한 없음",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "STATISTICS_ACCESS_DENIED",
+                                      "message": "통계 조회 권한이 없습니다."
+                                    }
+                                    """
+                            )
+                    )),
+            @ApiResponse(responseCode = "404", description = "페스티벌 없음",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "FESTIVAL_NOT_FOUND",
+                                      "message": "해당 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )),
+            @ApiResponse(responseCode = "400", description = "유효하지 않은 사용자 ID",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_INVALID",
+                                      "message": "유효하지 않은 사용자 ID입니다."
+                                    }
+                                    """
+                            )
+                    ))
+    })
+    ResponseEntity> getPerformanceEnterStatistics(
+            String festivalId,
+            @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime performanceDate,
+            Authentication authentication
+    );
+
+
+
+    @GetMapping("/booking/{festivalId}")
+    @Operation(summary = "공연별 예매자 수 / 수용 인원 요약 조회",
+            description = "주최자가 자신의 페스티벌 공연별 예매 현황과 총 수용 인원을 요약 조회")
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(schema = @Schema(implementation = List.class))),
+            @ApiResponse(responseCode = "403", description = "권한 없음",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "STATISTICS_ACCESS_DENIED",
+                                      "message": "통계 조회 권한이 없습니다."
+                                    }
+                                    """
+                            )
+                    )),
+            @ApiResponse(responseCode = "404", description = "페스티벌 없음",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "FESTIVAL_NOT_FOUND",
+                                      "message": "해당 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )),
+            @ApiResponse(responseCode = "400", description = "유효하지 않은 사용자 ID",
+                    content = @Content(
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_INVALID",
+                                      "message": "유효하지 않은 사용자 ID입니다."
+                                    }
+                                    """
+                            )
+                    ))
+    })
+    ResponseEntity>> getBookingSummary(
+            String festivalId,
+            Authentication authentication
+    );
+}
diff --git a/src/main/java/com/mnms/booking/specification/TicketSpecification.java b/src/main/java/com/mnms/booking/specification/TicketSpecification.java
new file mode 100644
index 0000000..8ce2b5c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/TicketSpecification.java
@@ -0,0 +1,136 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.response.TicketDetailResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.exception.global.SuccessResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+
+@Tag(name = "예매 내역 API", description = "예매 내역 조회")
+public interface TicketSpecification {
+
+    @GetMapping
+    @Operation(summary = "예매한 티켓 정보 조회",
+            description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": [
+                                        {
+                                          "reservationNumber": "T24CBD629",
+                                          "festivalId": "PF272550",
+                                          "fname": "그 곳",
+                                          "performanceDate": "2025-09-07T15:00:00",
+                                          "ticketPrice": 60000,
+                                          "deliveryMethod": "MOBILE",
+                                          "status": "CONFIRMED"
+                                        }
+                                      ],
+                                      "message": "요청이 성공적으로 처리되었습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "TICKET_NOT_FOUND",
+                                      "message": "해당하는 티켓을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity>> getUserTickets(Authentication authentication);
+
+    @GetMapping("/detail")
+    @Operation(summary = "예매한 티켓 정보 디테일 조회",
+            description = "예매자가 예매 완료한 티켓 정보를 조회합니다. ex : /api/ticket/detail?reservationNumber=T24CBD629 조회"
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": {
+                                        "reservationNumber": "T24CBD629",
+                                        "festivalId": "PF272550",
+                                        "fname": "그 곳",
+                                        "performanceDate": "2025-09-07T15:00:00",
+                                        "ticketPrice": 60000,
+                                        "deliveryMethod": "MOBILE",
+                                        "status": "CONFIRMED",
+                                        "address": "서울집",
+                                        "userName": "삼길동"
+                                      },
+                                      "message": "요청이 성공적으로 처리되었습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "TICKET_NOT_FOUND",
+                                      "message": "해당하는 티켓을 찾을 수 없습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "401", description = "권한 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_UNAUTHORIZED_ACCESS",
+                                      "message": "잘못된 사용자 예매내역 입니다."
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> getUserTicketDetail(
+            @RequestParam String reservationNumber,
+            Authentication authentication
+    );
+}
diff --git a/src/main/java/com/mnms/booking/specification/TransferSpecification.java b/src/main/java/com/mnms/booking/specification/TransferSpecification.java
new file mode 100644
index 0000000..a20a136
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/TransferSpecification.java
@@ -0,0 +1,487 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.request.TicketTransferRequestDTO;
+import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
+import com.mnms.booking.dto.response.PersonInfoResponseDTO;
+import com.mnms.booking.dto.response.TicketResponseDTO;
+import com.mnms.booking.dto.response.TicketTransferResponseDTO;
+import com.mnms.booking.dto.response.TransferOthersResponseDTO;
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.*;
+
+import org.springframework.web.multipart.MultipartFile;
+import java.io.IOException;
+import java.util.List;
+
+@Tag(name = "양도 API", description = "양도 및 OCR, Ticket 재생성")
+public interface TransferSpecification {
+
+    @GetMapping("/transferor")
+    @Operation(summary = "양도 가능한 티켓 정보 조회",
+            description = "사용자가 양도 가능한 티켓을 조회할 수 있습니다. (status : 양도 받은 티켓 양도 불가능)"
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": true,
+                                      "data": [
+                                        {
+                                          "reservationNumber": "T24CBD629",
+                                          "festivalId": "PF272550",
+                                          "fname": "그 곳",
+                                          "performanceDate": "2025-09-07T15:00:00",
+                                          "ticketPrice": 60000,
+                                          "deliveryMethod": "MOBILE",
+                                          "status": "CONFIRMED"
+                                        }
+                                      ],
+                                      "message": "요청이 성공적으로 처리되었습니다."
+                                    }
+                                    """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "TICKET_NOT_FOUND",
+                                      "message": "예매 티켓이 존재하지 않습니다."
+                                    }
+                                    """
+                            )
+                    )
+            )
+    })
+    ResponseEntity>> getUserTickets(Authentication authentication);
+
+
+    @ApiResponse(responseCode = "406", description = "유효하지 않은 파일 첨부",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                    {
+                                      "success": false,
+                                      "data": "TRANSFER_NOT_VALID_FILE_TYPE",
+                                      "message": "유효하지 않은 파일 확장자입니다."
+                                    }
+                                    """
+                            )
+                    )
+    )
+    @PostMapping("/extract")
+    @Operation(summary = "가족 간 양도 인증 시도",
+            description = "가족관계증명서 PDF와 양도자/양수자 정보로 인증을 시도합니다."
+    )
+    ResponseEntity> extractPersonAuth(
+            @RequestPart("file") MultipartFile file,
+            @RequestPart("targetInfo") String targetInfoJson
+    ) throws IOException;
+
+
+
+    @PostMapping("/extract/result")
+    @Operation(summary = "가족 간 양도 인증 결과 조회",
+            description = "인증 완료 후 양도 대상 정보와 함께 반환합니다."
+    )
+    @ApiResponse(responseCode = "406", description = "유효하지 않은 파일 첨부",
+            content = @Content(
+                    mediaType = "application/json",
+                    schema = @Schema(implementation = ErrorResponse.class),
+                    examples = @ExampleObject(
+                            value = """
+                                    {
+                                      "success": false,
+                                      "data": "TRANSFER_NOT_VALID_FILE_TYPE",
+                                      "message": "유효하지 않은 파일 확장자입니다."
+                                    }
+                                    """
+                    )
+            )
+    )
+    ResponseEntity>> extractPersonInfo(
+            @RequestPart("file") MultipartFile file,
+            @RequestPart("targetInfo") String targetInfoJson
+    ) throws IOException;
+
+
+
+    @PostMapping("/request")
+    @Operation(summary = "양도 요청",
+            description = "양도자가 양도 요청을 보냅니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "요청 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "해당하는 티켓을 찾을 수 없습니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "409", description = "이미 양도 요청 존재",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TRANSFER_ALREADY_EXIST_REQUEST",
+                                  "message": "진행되고 있는 양도 거래가 존재하거나, 양도 1회 진행한 티켓입니다. 양도는 1회로 제한됩니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "403", description = "권한 없음 (티켓 소유자 불일치)",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_USER_NOT_SAME",
+                                  "message": "사용자가 티켓 소유자가 아닙니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "500", description = "알 수 없는 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "INTERNAL_SERVER_ERROR",
+                                  "message": "알 수 없는 오류가 발생했습니다."
+                                }
+                                """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> requestTransfer(
+            @RequestBody TicketTransferRequestDTO dto,
+            Authentication authentication
+    );
+
+
+    @GetMapping("/watch")
+    @Operation(summary = "양도 요청 조회",
+            description = "양수자가 자신에게 온 양도 요청을 조회합니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "조회 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "양도 요청이 존재하지 않음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TRANSFER_NOT_EXIST",
+                                  "message": "양도 요청이 존재하지 않습니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "해당하는 티켓을 찾을 수 없습니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "페스티벌 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(responseCode = "500", description = "알 수 없는 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "INTERNAL_SERVER_ERROR",
+                                  "message": "알 수 없는 오류가 발생했습니다."
+                                }
+                                """
+                            )
+                    )
+            )
+    })
+    ResponseEntity>> watchTransfer(Authentication authentication);
+
+
+
+    @PutMapping("/acceptance/family")
+    @Operation(
+            summary = "가족 간 양도 요청 수락",
+            description = "양수자가 요청을 수락하면 티켓과 QR 정보가 업데이트 됩니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "요청 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(responseCode = "400", description = "양도 타입 또는 양수자 매칭 실패",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_MATCH_TYPE",
+                                          "message": "양도 타입이 맞지 않습니다."
+                                        }
+                                        """
+                                    ),
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_MATCH_RECEIVER",
+                                          "message": "양도 승인하는 양수자가 맞지 않습니다."
+                                        }
+                                        """
+                                    )
+                            }
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓 또는 양도 요청 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_EXIST",
+                                          "message": "양도 요청이 존재하지 않습니다."
+                                        }
+                                        """
+                                    ),
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TICKET_NOT_FOUND",
+                                          "message": "해당하는 티켓을 찾을 수 없습니다."
+                                        }
+                                        """
+                                    )
+                            }
+                    )
+            ),
+            @ApiResponse(responseCode = "409", description = "티켓 상태 문제",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TICKET_EXPIRED",
+                                          "message": "티켓의 유효기간이 만료되었습니다."
+                                        }
+                                        """
+                                    ),
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TICKET_CANCELED",
+                                          "message": "취소된 티켓입니다."
+                                        }
+                                        """
+                                    )
+                            }
+                    )
+            ),
+            @ApiResponse(responseCode = "500", description = "알 수 없는 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "INTERNAL_SERVER_ERROR",
+                                  "message": "알 수 없는 오류가 발생했습니다."
+                                }
+                                """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> responseTicketFamily(
+            @RequestBody UpdateTicketRequestDTO request,
+            Authentication authentication
+    );
+
+
+
+    @PutMapping("/acceptance/others")
+    @Operation(summary = "타인 간 양도 요청 완료",
+            description = "양수자가 요청을 수락하면 결제 진행 후 양도 완료됩니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(responseCode = "200", description = "요청 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(responseCode = "400", description = "양도 타입 또는 양수자 매칭 실패",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_MATCH_TYPE",
+                                          "message": "양도 타입이 맞지 않습니다."
+                                        }
+                                        """
+                                    ),
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_MATCH_RECEIVER",
+                                          "message": "양도 승인하는 양수자가 맞지 않습니다."
+                                        }
+                                        """
+                                    )
+                            }
+                    )
+            ),
+            @ApiResponse(responseCode = "404", description = "티켓 또는 양도 요청 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TRANSFER_NOT_EXIST",
+                                          "message": "양도 요청이 존재하지 않습니다."
+                                        }
+                                        """
+                                    ),
+                                    @ExampleObject(
+                                            value = """
+                                        {
+                                          "success": false,
+                                          "data": "TICKET_NOT_FOUND",
+                                          "message": "해당하는 티켓을 찾을 수 없습니다."
+                                        }
+                                        """
+                                    )
+                            }
+                    )
+            ),
+            @ApiResponse(responseCode = "500", description = "알 수 없는 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "INTERNAL_SERVER_ERROR",
+                                  "message": "알 수 없는 오류가 발생했습니다."
+                                }
+                                """
+                            )
+                    )
+            )
+    })
+    ResponseEntity> responseTicketOthers(
+            @RequestBody UpdateTicketRequestDTO request,
+            Authentication authentication
+    );
+
+
+    @GetMapping("/reservation/status")
+    @Operation(summary = "양도 결제 완료 조회",
+            description = "Websocket 메시지 누락 시 양도 완료 여부 확인"
+    )
+    ResponseEntity> checkStatus(@RequestParam Long transferId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/specification/WaitingSpecification.java b/src/main/java/com/mnms/booking/specification/WaitingSpecification.java
new file mode 100644
index 0000000..e07c85a
--- /dev/null
+++ b/src/main/java/com/mnms/booking/specification/WaitingSpecification.java
@@ -0,0 +1,276 @@
+package com.mnms.booking.specification;
+
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
+import com.mnms.booking.exception.global.ErrorResponse;
+import com.mnms.booking.exception.global.SuccessResponse;
+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.ExampleObject;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.Authentication;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.time.LocalDateTime;
+
+@Tag(name = "대기열 API", description = "대기열 입장, 예매 화면 입장, 대기번호 조회")
+public interface WaitingSpecification {
+
+        @GetMapping("/enter")
+        @Operation(
+                summary = "예매 페이지 입장 요청",
+                description = "사용자가 예매 페이지에 입장하거나 대기열에 등록됩니다. " +
+                        "즉시 입장이 가능하면 waitingNumber는 0, 대기열 입장 시 1 이상의 대기번호 반환."
+        )
+        @ApiResponses(value = {
+                @ApiResponse(
+                        responseCode = "200",
+                        description = "대기열 입장 성공 또는 예매 페이지 바로 입장",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = SuccessResponse.class)
+                        )
+                ),
+                @ApiResponse(
+                        responseCode = "404",
+                        description = "페스티벌이 존재하지 않거나 대기열에서 사용자 조회 실패",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = ErrorResponse.class),
+                                examples = {
+                                        @ExampleObject(
+                                                name = "FESTIVAL_NOT_FOUND",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "FESTIVAL_NOT_FOUND",
+                                      "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                    }
+                                    """
+                                        ),
+                                        @ExampleObject(
+                                                name = "USER_NOT_FOUND_IN_WAITING",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_NOT_FOUND_IN_WAITING",
+                                      "message": "대기열에서 사용자를 찾을 수 없습니다."
+                                    }
+                                    """
+                                        )
+                                }
+                        )
+                ),
+                @ApiResponse(
+                        responseCode = "500",
+                        description = "예약 또는 대기열 입장 실패",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = ErrorResponse.class),
+                                examples = {
+                                        @ExampleObject(
+                                                name = "FAILED_TO_ENTER_BOOKING",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "FAILED_TO_ENTER_BOOKING",
+                                      "message": "예매 진입 처리에 실패했습니다."
+                                    }
+                                    """
+                                        ),
+                                        @ExampleObject(
+                                                name = "FAILED_TO_ENTER_QUEUE",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "FAILED_TO_ENTER_QUEUE",
+                                      "message": "대기열 진입에 실패했습니다."
+                                    }
+                                    """
+                                        ),
+                                        @ExampleObject(
+                                                name = "REDIS_CONNECTION_FAILED",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "REDIS_CONNECTION_FAILED",
+                                      "message": "Redis 서버 연결에 실패했습니다."
+                                    }
+                                    """
+                                        ),
+                                        @ExampleObject(
+                                                name = "FAILED_TO_EXECUTE_SCRIPT",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "FAILED_TO_EXECUTE_SCRIPT",
+                                      "message": "Redis 스크립트 실행에 실패했습니다."
+                                    }
+                                    """
+                                        ),
+                                        @ExampleObject(
+                                                name = "REDIS_PUBLISH_FAILED",
+                                                value = """
+                                    {
+                                      "success": false,
+                                      "data": "REDIS_PUBLISH_FAILED",
+                                      "message": "Redis Pub/Sub 발행 실패"
+                                    }
+                                    """
+                                        )
+                                }
+                        )
+                )
+        })
+        ResponseEntity> enterBookingPage(
+                @RequestParam String festivalId,
+                @RequestParam LocalDateTime reservationDate,
+                @Parameter(hidden = true) Authentication authentication
+        );
+
+
+
+        @GetMapping("/release")
+        @Operation(
+                summary = "예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)",
+                description = "예매 페이지에 있던 사용자가 퇴장했을 때 실행됩니다. " +
+                        "대기열에 있던 대기번호 1번 사용자는 스케쥴러에 의해 예매 페이지로 자동 입장하며, " +
+                        "대기열에 있던 모든 대기자의 대기번호가 변경됩니다."
+        )
+        @ApiResponses(value = {
+                @ApiResponse(responseCode = "200", description = "사용자 퇴장 성공",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = SuccessResponse.class)
+                        )
+                ),
+                @ApiResponse(responseCode = "404", description = "예매 사용자 목록에 없음",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = SuccessResponse.class),
+                                examples = @ExampleObject(
+                                        value = """
+                                    {
+                                      "success": false,
+                                      "data": "USER_NOT_FOUND_IN_BOOKING",
+                                      "message": "사용자가 예매 페이지에 존재하지 않습니다."
+                                    }
+                                    """
+                                )
+                        )
+                ),
+                @ApiResponse(responseCode = "500", description = "서버 오류",
+                        content = @Content(
+                                mediaType = "application/json",
+                                schema = @Schema(implementation = SuccessResponse.class),
+                                examples = @ExampleObject(
+                                        value = """
+                                    {
+                                      "success": false,
+                                      "data": "INTERNAL_SERVER_ERROR",
+                                      "message": "서버 오류로 인해 사용자를 처리하지 못했습니다."
+                                    }
+                                    """
+                                )
+                        )
+                )
+        })
+        ResponseEntity> releaseUser(
+                @RequestParam String festivalId,
+                @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime reservationDate,
+                @Parameter(hidden = true) Authentication authentication
+        );
+
+
+
+
+    @Operation(
+            summary = "대기열 퇴장",
+            description = "대기 중인 사용자가 스스로 대기열에서 나갈 때 호출됩니다. " +
+                    "호출 시 해당 사용자는 대기열에서 제거되고, 남은 대기자에게 알림이 전송됩니다."
+    )
+    @ApiResponses(value = {
+            @ApiResponse(
+                    responseCode = "200",
+                    description = "사용자 퇴장 성공",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = SuccessResponse.class)
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "404",
+                    description = "대기열에 사용자 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "USER_NOT_FOUND_IN_WAITING",
+                                  "message": "해당 사용자는 대기열 목록에 없습니다."
+                                }
+                                """
+                            )
+                    )
+            ),
+            @ApiResponse(
+                    responseCode = "500",
+                    description = "서버 오류",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = {
+                                    @ExampleObject(
+                                            name = "INTERNAL_SERVER_ERROR",
+                                            value = """
+                                {
+                                  "success": false,
+                                  "data": "INTERNAL_SERVER_ERROR",
+                                  "message": "서버 오류로 인해 사용자를 처리하지 못했습니다."
+                                }
+                                """
+                                    ),
+                                    @ExampleObject(
+                                            name = "REDIS_CONNECTION_FAILED",
+                                            value = """
+                                {
+                                  "success": false,
+                                  "data": "REDIS_CONNECTION_FAILED",
+                                  "message": "대기열 정보를 처리하는 중 Redis 연결에 실패했습니다."
+                                }
+                                """
+                                    ),
+                                    @ExampleObject(
+                                            name = "REDIS_PUBLISH_FAILED",
+                                            value = """
+                                {
+                                  "success": false,
+                                  "data": "REDIS_PUBLISH_FAILED",
+                                  "message": "Redis Pub/Sub 발행 실패"
+                                }
+                                """
+                                    )
+                            }
+                    )
+            )
+    })
+    @GetMapping("/exit")
+    ResponseEntity> exitWaitingUser(
+            @Parameter(description = "페스티벌 ID", required = true, example = "festival-001")
+            @RequestParam String festivalId,
+
+            @Parameter(description = "예매 날짜 및 시간", required = true, example = "2025-09-10T18:30:00")
+            @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime reservationDate,
+
+            @Parameter(hidden = true)
+            Authentication authentication
+    );
+}

From 8e7cc2d6107035b695116ce0ef3ad3ef481c9f49 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 11 Sep 2025 13:19:41 +0900
Subject: [PATCH 112/149] =?UTF-8?q?MNMS-632=20Fix:=20Swagger=20=EC=98=A4?=
 =?UTF-8?q?=EB=A5=98=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95=20?=
 =?UTF-8?q?=EB=B0=8F=20=EC=A4=91=EB=B3=B5=20=EC=98=88=EB=A7=A4=20=EC=A7=84?=
 =?UTF-8?q?=ED=96=89=20=EB=B0=A9=EC=A7=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

BookingController Swagger 오류 메시지 수정 및 보완
가예매 중에 추가적 가예매 진행 시, 이전 모든 가예매 데이터 삭제
---
 build.gradle                                  |   1 +
 .../com/mnms/booking/exception/ErrorCode.java |   6 +-
 .../exception/global/ErrorResponse.java       |  15 +-
 .../global/GlobalExceptionHandler.java        |   8 +
 .../booking/repository/TicketRepository.java  |  26 +-
 .../security/HeaderAuthenticationFilter.java  |  74 ++-
 .../service/BookingCommandService.java        |   3 +-
 .../booking/service/BookingStatusService.java |   8 +-
 .../com/mnms/booking/service/HostService.java |   4 +-
 .../service/StatisticsQueryService.java       |   2 +-
 .../specification/BookingSpecification.java   | 457 ++++++++++++------
 .../specification/HostSpecification.java      |  11 +-
 12 files changed, 423 insertions(+), 192 deletions(-)

diff --git a/build.gradle b/build.gradle
index 4aea295..57baa6a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -35,6 +35,7 @@ dependencies {
 	compileOnly 'org.projectlombok:lombok'
 	annotationProcessor 'org.projectlombok:lombok'
 
+
 	// security
 	implementation 'org.springframework.boot:spring-boot-starter-security'
 	implementation 'org.springframework.boot:spring-boot-starter-oauth2-resource-server'
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 9095fed..21fba55 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -16,15 +16,15 @@ public enum ErrorCode {
 
     // FESTIVAL
     FESTIVAL_NOT_FOUND("F001","입력 ID에 해당하는 페스티벌을 찾을 수 없습니다.",HttpStatus.NOT_FOUND),
-    FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
-    FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    FESTIVAL_INVALID_DATE("F002", "해당 날짜의 페스티벌을 찾을 수 없습니다.", HttpStatus.BAD_REQUEST),
+    FESTIVAL_INVALID_TIME("F003", "해당 시간의 페스티벌을 찾을 수 없습니다.", HttpStatus.BAD_REQUEST),
     FESTIVAL_DELIVERY_INVALID("F004", "배송 방법 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
     FESTIVAL_MISMATCH("F005", "해당하는 QR의 페스티벌 주최자가 아닙니다.", HttpStatus.FORBIDDEN),
     FESTIVAL_LIMIT_AVAILABLE_PEOPLE("F006", "해당 페스티벌 수용 인원이 초과되어 예매를 진행할 수 없습니다.", HttpStatus.CONFLICT),
 
     // TICKET
     TICKET_ALREADY_RESERVED("T001", "예약 가능한 티켓 수를 초과하였습니다.", HttpStatus.CONFLICT),
-    TICKET_NOT_FOUND("T002", "해당하는 티켓을 찾을 수 없습니다.", HttpStatus.NOT_FOUND),
+    TICKET_NOT_FOUND("T002", "예매 정보가 만료되어 존재하지 않습니다.", HttpStatus.NOT_FOUND),
     TICKET_INVALID_DELIVERY_METHOD("T003", "수령 방법이 올바르지 않습니다.", HttpStatus.BAD_REQUEST),
     TICKET_DELIVERY_NOT_COMPLETED("T004", "티켓 수령 방법이 선택되지 않았습니다.", HttpStatus.BAD_REQUEST),
     TICKET_FAIL_CANCEL("T005", "티켓 취소가 실패했습니다.", HttpStatus.CONFLICT),
diff --git a/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
index 5f1699a..0c00cb4 100644
--- a/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
+++ b/src/main/java/com/mnms/booking/exception/global/ErrorResponse.java
@@ -1,20 +1,17 @@
 package com.mnms.booking.exception.global;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.mnms.booking.exception.BusinessException;
+
 import lombok.AllArgsConstructor;
+import lombok.Builder;
 import lombok.Data;
-import lombok.Getter;
 import lombok.NoArgsConstructor;
-import org.springframework.http.HttpStatus;
-
-import java.time.LocalDateTime;
 
 @Data
-@AllArgsConstructor
 @NoArgsConstructor
+@AllArgsConstructor
+@Builder
 public class ErrorResponse {
-    private boolean success = false;
-    private Object data = null;
+    private boolean success;
+    private Object data;
     private String message;
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
index 81d6d8b..c67ebed 100644
--- a/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
+++ b/src/main/java/com/mnms/booking/exception/global/GlobalExceptionHandler.java
@@ -10,6 +10,8 @@
 import org.springframework.web.bind.annotation.RestControllerAdvice;
 import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
 
+import java.nio.file.AccessDeniedException;
+
 
 @RestControllerAdvice
 public class GlobalExceptionHandler {
@@ -24,6 +26,12 @@ public ResponseEntity handleBusinessException(BusinessException e
         return new ResponseEntity<>(response, errorCode.getStatus());
     }
 
+    @ExceptionHandler(AccessDeniedException.class)
+    public ResponseEntity handleAccessDenied(AccessDeniedException ex) {
+        ErrorResponse response = new ErrorResponse(false, "AUTHORIZATION_ERROR", "접근 권한이 없습니다.");
+        return new ResponseEntity<>(response, HttpStatus.FORBIDDEN);
+    }
+
     /**
      * @Valid 검증 실패 (DTO 바인딩 오류 등)
      */
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index 53ecf0f..d9bb7b4 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -33,7 +33,7 @@ Long sumSelectedTicketCount(
     @Query("SELECT t " +
             "FROM Ticket t " +
             "WHERE t.festival.festivalId = :festivalId AND t.userId = :userId AND t.reservationNumber = :reservationNumber")
-    Optional findByFestivalIdAndUserIdAndReservationNumber(
+    Optional findByIdAndReservationNumber(
             @Param("festivalId") String festivalId,
             @Param("userId") Long userId,
             @Param("reservationNumber") String reservationNumber
@@ -47,7 +47,7 @@ Optional findByFestivalIdAndUserIdAndReservationNumber(
             "WHERE t.festival.festivalId = :festivalId " +
             "AND t.performanceDate = :performanceDate " +
             "AND t.reservationStatus = :reservationStatus")
-    List findDistinctUserIdsByFestivalIdAndPerformanceDateAndReservationStatus(
+    List findDistinctUserIds(
             @Param("festivalId") String festivalId,
             @Param("performanceDate") LocalDateTime performanceDate,
             @Param("reservationStatus") ReservationStatus reservationStatus);
@@ -78,7 +78,7 @@ int getTotalSelectedTicketCount(@Param("festivalId") String festivalId,
     @Query("SELECT t FROM Ticket t " +
             "WHERE t.festival.festivalId = :festivalId " +
             "AND t.reservationStatus = :status")
-    List findByFestivalIdAndReservationStatus(@Param("festivalId") String festivalId,
+    List findByIdAndReservationStatus(@Param("festivalId") String festivalId,
                                                       @Param("status") ReservationStatus status);
 
     Optional> findByUserId(Long userId);
@@ -89,10 +89,10 @@ List findByFestivalIdAndReservationStatus(@Param("festivalId") String fe
 
     // 특정 festivalId에 대한 유효한 공연 날짜-시간을 모두 조회
     @Query("SELECT DISTINCT t.performanceDate FROM Ticket t WHERE t.festival.festivalId = :festivalId")
-    List findDistinctPerformanceDateByFestivalId(@Param("festivalId") String festivalId);
+    List findDistinctPerformanceDate(@Param("festivalId") String festivalId);
 
     @Query("SELECT t.reservationStatus FROM Ticket t WHERE t.reservationNumber = :reservationNumber")
-    ReservationStatus findReservationStatusByReservationNumber(@Param("reservationNumber") String reservationNumber);
+    ReservationStatus findReservationStatusByRN(@Param("reservationNumber") String reservationNumber);
 
     List findByUserIdAndReservationStatus(Long userId, ReservationStatus status);
 
@@ -105,5 +105,21 @@ List findByFestivalIdAndReservationStatus(@Param("festivalId") String fe
             "GROUP BY t.performanceDate, t.festival.availableNOP")
     List findBookedSummary(@Param("festivalId") String festivalId, @Param("status") ReservationStatus status);
 
+
+    @Query("""
+        SELECT t
+        FROM Ticket t
+        JOIN t.festival f
+        WHERE f.id = :festivalId
+          AND t.performanceDate = :performanceDate
+          AND t.userId = :userId
+          AND t.reservationStatus = :reservationStatus
+    """)
+    List findTempReservedTickets(
+            @Param("festivalId") Long festivalId,
+            @Param("performanceDate") LocalDateTime performanceDate,
+            @Param("userId") Long userId,
+            @Param("reservationStatus") ReservationStatus reservationStatus
+    );
 }
 
diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index ede95f9..72bcb8e 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -1,23 +1,28 @@
 package com.mnms.booking.security;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.exception.global.ErrorResponse;
 import jakarta.servlet.FilterChain;
 import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.authentication.AnonymousAuthenticationToken;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
 import org.springframework.web.filter.OncePerRequestFilter;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
+import java.util.Base64;
 import java.util.List;
 import java.util.stream.Collectors;
 
 @Component
+@Slf4j
 public class HeaderAuthenticationFilter extends OncePerRequestFilter {
 
     @Override
@@ -34,33 +39,45 @@ protected void doFilterInternal(
             return;
         }
 
-        // 게이트웨이가 붙여주는 헤더 (✅ userId 사용)
+        // 게이트웨이가 붙여주는 헤더
         final String userIdHeader = trimToNull(request.getHeader("X-User-Id"));
-        final String rolesHdr     = trimToNull(request.getHeader("X-User-Role"));
+        final String rolesHdr = trimToNull(request.getHeader("X-User-Role"));
         final String userNameHeader = trimToNull(request.getHeader("X-User-Name"));
-        String userName = "";
-        if(userNameHeader != null) {
-            userName = new String(
-                    java.util.Base64.getUrlDecoder().decode(userNameHeader),
-                    java.nio.charset.StandardCharsets.UTF_8
-            );
-        }
-        Authentication current = SecurityContextHolder.getContext().getAuthentication();
+
+        Authentication current = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
         boolean isAnonymous = (current instanceof AnonymousAuthenticationToken);
         boolean canSetAuth = (current == null) || isAnonymous;
 
-        if (canSetAuth && userIdHeader != null && rolesHdr != null) {
-            // userId는 숫자여야 하므로 안전하게 파싱
+        if (canSetAuth) {
+            // 헤더가 없으면 401
+            if (userIdHeader == null || rolesHdr == null) {
+                sendUnauthorized(response, "X-User-Id 또는 X-User-Role 헤더가 없습니다.");
+                return;
+            }
+
+            // userId 파싱
             final Long userId;
             try {
                 userId = Long.valueOf(userIdHeader);
             } catch (NumberFormatException e) {
-                // 잘못된 헤더면 인증 세팅 없이 통과
-                logger.warn("[HeaderAuth] invalid X-User-Id: " + userIdHeader);
-                chain.doFilter(request, response);
+                sendUnauthorized(response, "X-User-Id가 숫자가 아닙니다.");
                 return;
             }
 
+            // userName 디코딩
+            String userName = "";
+            if (userNameHeader != null) {
+                try {
+                    userName = new String(
+                            Base64.getUrlDecoder().decode(userNameHeader),
+                            StandardCharsets.UTF_8
+                    );
+                } catch (IllegalArgumentException e) {
+                    log.warn("[HeaderAuth] userName 디코딩 실패: {}", userNameHeader);
+                }
+            }
+
+            // 권한 세팅
             List authorities = Arrays.stream(rolesHdr.split(","))
                     .map(String::trim)
                     .filter(s -> !s.isEmpty())
@@ -69,22 +86,35 @@ protected void doFilterInternal(
                     .map(SimpleGrantedAuthority::new)
                     .collect(Collectors.toList());
 
-            logger.info("[HeaderAuth] userId=" + userId + ", rolesHeader=" + rolesHdr
-                    + " -> authorities=" + authorities);
+            log.info("[HeaderAuth] userId={}, roles={} -> authorities={}", userId, rolesHdr, authorities);
 
-            // principal = userId(String) → Controller에서 Long.parseLong(principal.getName()) 가능
+            // 인증 정보 세팅
             UsernamePasswordAuthenticationToken auth =
                     new UsernamePasswordAuthenticationToken(String.valueOf(userId), null, authorities);
-            auth.setDetails(new com.mnms.booking.security.AuthDetails(request, userName));
-            SecurityContextHolder.getContext().setAuthentication(auth);
+            auth.setDetails(new AuthDetails(request, userName));
+            org.springframework.security.core.context.SecurityContextHolder.getContext().setAuthentication(auth);
         }
 
         chain.doFilter(request, response);
     }
 
+    // 401 응답 직접 처리
+    private void sendUnauthorized(HttpServletResponse response, String message) throws IOException {
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        response.setContentType("application/json;charset=UTF-8");
+
+        ErrorResponse error = ErrorResponse.builder()
+                .success(false)
+                .data("UNAUTHORIZED")
+                .message(message)
+                .build();
+        String body = new ObjectMapper().writeValueAsString(error);
+        response.getWriter().write(body);
+    }
+
     private static String trimToNull(String s) {
         if (s == null) return null;
         String t = s.trim();
         return t.isEmpty() ? null : t;
     }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index b53c36c..651ec90 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -37,6 +37,7 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
 
         bookingStatusService.validatePerformanceDate(festival, performanceDate);
         bookingStatusService.validateScheduleExists(festival, performanceDate);
+        bookingStatusService.recreateHold(festival, performanceDate, userId); // 가예매 상태인 티켓 모두 삭제
         bookingStatusService.validateUserReservationLimit(userId, request, festival);
 
         Ticket ticket = Ticket.builder()
@@ -127,6 +128,6 @@ public void cancelBooking(String reservationNumber, boolean paymentStatus) {
 
     // websocket 손실 방지 확인
     public ReservationStatus checkStatus(String reservationNumber) {
-        return ticketRepository.findReservationStatusByReservationNumber(reservationNumber);
+        return ticketRepository.findReservationStatusByRN(reservationNumber);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index 86c6ebc..50c6b06 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -146,7 +146,7 @@ public Festival getFestivalOrThrow(String festivalId) {
     }
 
     public Ticket getTicketOrThrow(String festivalId, Long userId, String reservationNumber) {
-        return ticketRepository.findByFestivalIdAndUserIdAndReservationNumber(festivalId, userId, reservationNumber)
+        return ticketRepository.findByIdAndReservationNumber(festivalId, userId, reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
     }
 
@@ -189,4 +189,10 @@ private QrCode createAndSaveQrCode(Long userId, Festival festival, Ticket ticket
         qrCodeRepository.save(qrCode);
         return qrCode;
     }
+
+    ///  예매 시도 시, 가예매 상태 모두 지우기
+    public void recreateHold(Festival festival, LocalDateTime performanceDate, Long userId) {
+        List tempReservedTickets = ticketRepository.findTempReservedTickets(festival.getId(), performanceDate, userId, ReservationStatus.TEMP_RESERVED);
+        ticketRepository.deleteAllInBatch(tempReservedTickets);
+    }
 }
diff --git a/src/main/java/com/mnms/booking/service/HostService.java b/src/main/java/com/mnms/booking/service/HostService.java
index c0599b0..0d14eb7 100644
--- a/src/main/java/com/mnms/booking/service/HostService.java
+++ b/src/main/java/com/mnms/booking/service/HostService.java
@@ -33,7 +33,7 @@ public class HostService {
 
     public List getBookingsByOrganizer(HostRequestDTO request) {
         return ticketRepository
-                .findDistinctUserIdsByFestivalIdAndPerformanceDateAndReservationStatus(
+                .findDistinctUserIds(
                         request.getFestivalId(),
                         request.getPerformanceDate(),
                         ReservationStatus.CONFIRMED
@@ -55,7 +55,7 @@ public List getBookingInfoByHost(String festivalId, Long hostUs
             throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
         }
 
-        List tickets = new ArrayList<>(ticketRepository.findByFestivalIdAndReservationStatus(festival.getFestivalId(), ReservationStatus.CONFIRMED));
+        List tickets = new ArrayList<>(ticketRepository.findByIdAndReservationStatus(festival.getFestivalId(), ReservationStatus.CONFIRMED));
 
         if (tickets.isEmpty()) {
             return Collections.emptyList();
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
index 41330ba..ef6a22a 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQueryService.java
@@ -41,7 +41,7 @@ public void validateHostOrAdminAccess(String festivalId, String userId, boolean
     }
 
     public List getPerformanceDatesByFestivalId(String festivalId) {
-        List performanceDates = ticketRepository.findDistinctPerformanceDateByFestivalId(festivalId);
+        List performanceDates = ticketRepository.findDistinctPerformanceDate(festivalId);
         if (performanceDates.isEmpty()) {
             throw new BusinessException(ErrorCode.FESTIVAL_NOT_FOUND);
         }
diff --git a/src/main/java/com/mnms/booking/specification/BookingSpecification.java b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
index f351e41..040ab69 100644
--- a/src/main/java/com/mnms/booking/specification/BookingSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
@@ -11,6 +11,7 @@
 import com.mnms.booking.exception.global.SuccessResponse;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.ExampleObject;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 import io.swagger.v3.oas.annotations.responses.ApiResponses;
@@ -34,37 +35,35 @@ public interface BookingSpecification {
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "조회 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{\n" +
-                                    "  \"success\": true,\n" +
-                                    "  \"data\": {\n" +
-                                    "    \"festivalId\": \"PF272550\",\n" +
-                                    "    \"fname\": \"그 곳\",\n" +
-                                    "    \"performanceDate\": \"2025-09-07T15:00:00\",\n" +
-                                    "    \"posterFile\": \"http://www.kopis.or.kr/upload/pfmPoster/PF_PF272550_250825_154032.gif\",\n" +
-                                    "    \"ticketPrice\": 60000\n" +
-                                    "  },\n" +
-                                    "  \"message\": \"요청이 성공적으로 처리되었습니다.\"\n" +
-                                    "}"
+                            implementation = SuccessResponse.class
                     ))),
             @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{\n" +
-                                    "  \"success\": false,\n" +
-                                    "  \"data\": null,\n" +
-                                    "  \"message\": \"페스티벌을 찾을 수 없습니다.\"\n" +
-                                    "}"
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
                     ))),
             @ApiResponse(responseCode = "400", description = "선택한 날짜/시간이 잘못됨",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{\n" +
-                                    "  \"success\": false,\n" +
-                                    "  \"data\": null,\n" +
-                                    "  \"message\": \"선택한 날짜/시간이 잘못되었습니다.\"\n" +
-                                    "}"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_INVALID_DATE / FESTIVAL_INVALID_TIME",
+                                  "message": "해당 날짜/시간의 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            )))
+
     })
     ResponseEntity> getFestivalDetail(
             @Valid @RequestBody BookingSelectRequestDTO request);
@@ -76,30 +75,47 @@ ResponseEntity> getFestivalDetail(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "조회 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{\n" +
-                                    "  \"success\": true,\n" +
-                                    "  \"data\": {\n" +
-                                    "    \"reservationNumber\": \"TAEEDA779\",\n" +
-                                    "    \"userName\": \"삼길동\",\n" +
-                                    "    \"performanceDate\": \"2025-09-07T15:00:00\",\n" +
-                                    "    \"deliveryMethod\": \"MOBILE\",\n" +
-                                    "    \"address\": \"서울집\",\n" +
-                                    "    \"ticketPrice\": 60000\n" +
-                                    "  },\n" +
-                                    "  \"message\": \"조회 성공\"\n" +
-                                    "}"
-                    ))),
-            @ApiResponse(responseCode = "404", description = "페스티벌 또는 티켓을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌 또는 티켓을 찾을 수 없습니다.\" }"
+                            implementation = SuccessResponse.class
                     ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            ))),
             @ApiResponse(responseCode = "401", description = "인증 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "UNAUTHORIZED",
+                                  "message": "X-User-Id 또는 X-User-Role 헤더가 없습니다. OR X-User-Id가 숫자가 아닙니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
@@ -113,29 +129,73 @@ ResponseEntity> getFestivalBookingDeta
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "임시 예약 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{ \"success\": true, \"data\": \"TAEEDA779\", \"message\": \"임시 예약 성공\" }"
-                    ))),
-            @ApiResponse(responseCode = "400", description = "유효하지 않은 날짜/시간 또는 티켓 수 초과",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"유효하지 않은 날짜/시간 또는 티켓 수 초과\" }"
+                            implementation = SuccessResponse.class
                     ))),
             @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌을 찾을 수 없습니다.\" }"
-                    ))),
-            @ApiResponse(responseCode = "409", description = "예약 가능한 티켓 수를 초과",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"예약 가능한 티켓 수를 초과했습니다.\" }"
-                    ))),
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "400", description = "페스티벌 해당 날짜 또는 시간 불일치",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_INVALID_DATE OR FESTIVAL_INVALID_TIME",
+                                  "message": "해당 날짜/시간의 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "409", description = "예약 가능한 티켓 수 초과",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_ALREADY_RESERVED",
+                                  "message": "예약 가능한 티켓 수를 초과하였습니다."
+                                }
+                                """
+                            ))),
             @ApiResponse(responseCode = "401", description = "인증 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "UNAUTHORIZED",
+                                  "message": "X-User-Id 또는 X-User-Role 헤더가 없습니다. OR X-User-Id가 숫자가 아닙니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
@@ -149,24 +209,86 @@ ResponseEntity> selectFestivalDate(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "배송 방법 선택 완료",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{ \"success\": true, \"data\": null, \"message\": \"배송 방법 선택 완료\" }"
-                    ))),
-            @ApiResponse(responseCode = "400", description = "유효하지 않은 배송 방법/주소",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"유효하지 않은 배송 방법/주소\" }"
-                    ))),
-            @ApiResponse(responseCode = "404", description = "티켓 또는 페스티벌을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓 또는 페스티벌을 찾을 수 없습니다.\" }"
+                            implementation = SuccessResponse.class
                     ))),
+            @ApiResponse(responseCode = "400", description = "배송 방법 미선택",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_DELIVERY_INVALID",
+                                  "message": "배송 방법 선택되지 않았습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "400", description = "수령 방법",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_INVALID_DELIVERY_METHOD",
+                                  "message": "수령 방법이 올바르지 않습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "400", description = "페스티벌 해당 날짜 불일치",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_INVALID_DATE",
+                                  "message": "해당 날짜/시간의 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
             @ApiResponse(responseCode = "401", description = "인증 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "UNAUTHORIZED",
+                                  "message": "X-User-Id 또는 X-User-Role 헤더가 없습니다. OR X-User-Id가 숫자가 아닙니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
@@ -180,29 +302,60 @@ ResponseEntity> selectFestivalDelivery(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "QR 생성 및 예약 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{ \"success\": true, \"data\": null, \"message\": \"QR 생성 및 예약 성공\" }"
-                    ))),
-            @ApiResponse(responseCode = "400", description = "배송 방법 선택하지 않거나 올바르지 않음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"배송 방법 선택하지 않았거나 올바르지 않습니다.\" }"
-                    ))),
-            @ApiResponse(responseCode = "404", description = "티켓 또는 페스티벌을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓 또는 페스티벌을 찾을 수 없습니다.\" }"
-                    ))),
-            @ApiResponse(responseCode = "401", description = "인증 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
+                            implementation = SuccessResponse.class
                     ))),
+            @ApiResponse(responseCode = "404", description = "페스티벌을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_NOT_FOUND",
+                                  "message": "입력 ID에 해당하는 페스티벌을 찾을 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            ))),
             @ApiResponse(responseCode = "409", description = "페스티벌 수용 인원 초과",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"페스티벌 수용 인원을 초과했습니다.\" }"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "FESTIVAL_LIMIT_AVAILABLE_PEOPLE",
+                                  "message": "해당 페스티벌 수용 인원이 초과되어 예매를 진행할 수 없습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "401", description = "인증 실패",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "UNAUTHORIZED",
+                                  "message": "X-User-Id 또는 X-User-Role 헤더가 없습니다. OR X-User-Id가 숫자가 아닙니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
@@ -216,14 +369,21 @@ ResponseEntity> reserveTicket(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "조회 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{ \"success\": true, \"data\": \"CONFIRMED\", \"message\": \"조회 성공\" }"
+                            implementation = SuccessResponse.class
                     ))),
-            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓을 찾을 수 없습니다.\" }"
-                    )))
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> checkStatus(@RequestParam String reservationNumber);
 
@@ -234,29 +394,25 @@ ResponseEntity> reserveTicket(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "조회 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{\n" +
-                                    "  \"success\": true,\n" +
-                                    "  \"data\": {\n" +
-                                    "    \"userName\": \"삼길동\",\n" +
-                                    "    \"id\": 12\n" +
-                                    "  },\n" +
-                                    "  \"message\": \"조회 성공\"\n" +
-                                    "}"
+                            implementation = SuccessResponse.class
                     ))),
             @ApiResponse(responseCode = "401", description = "인증 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"인증에 실패했습니다.\" }"
-                    ))),
-            @ApiResponse(responseCode = "403", description = "권한 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"권한이 없습니다.\" }"
-                    )))
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "UNAUTHORIZED",
+                                  "message": "X-User-Id 또는 X-User-Role 헤더가 없습니다. OR X-User-Id가 숫자가 아닙니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity> getUserInfo(Authentication authentication);
 
+
     /// POST : 이메일 임시 테스트
     @PostMapping("/email/test")
     @Operation(summary = "[테스트 진행X] 이메일 임시 테스트",
@@ -264,19 +420,34 @@ ResponseEntity> reserveTicket(
     @ApiResponses({
             @ApiResponse(responseCode = "200", description = "메일 발송 성공",
                     content = @Content(schema = @Schema(
-                            implementation = SuccessResponse.class,
-                            example = "{ \"success\": true, \"data\": null, \"message\": \"메일 발송 성공\" }"
-                    ))),
-            @ApiResponse(responseCode = "404", description = "티켓을 찾을 수 없음",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"티켓을 찾을 수 없습니다.\" }"
+                            implementation = SuccessResponse.class
                     ))),
-            @ApiResponse(responseCode = "500", description = "메일 발송 실패",
-                    content = @Content(schema = @Schema(
-                            implementation = ErrorResponse.class,
-                            example = "{ \"success\": false, \"data\": null, \"message\": \"메일 발송 실패\" }"
-                    )))
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_NOT_FOUND",
+                                  "message": "예매 정보가 만료되어 존재하지 않습니다."
+                                }
+                                """
+                            ))),
+            @ApiResponse(responseCode = "404", description = "예매 중인 티켓을 찾을 수 없음",
+                    content = @Content(
+                            mediaType = "application/json",
+                            schema = @Schema(implementation = ErrorResponse.class),
+                            examples = @ExampleObject(
+                                    value = """
+                                {
+                                  "success": false,
+                                  "data": "TICKET_EMAIL_TEMPLATE_NOT_FOUND",
+                                  "message": "이메일 템플릿 오류로 이메일 전송에 실패하였습니다."
+                                }
+                                """
+                            )))
     })
     ResponseEntity confirmTicket(
             @RequestParam String reservationNumber,
diff --git a/src/main/java/com/mnms/booking/specification/HostSpecification.java b/src/main/java/com/mnms/booking/specification/HostSpecification.java
index f3d5209..f61e26c 100644
--- a/src/main/java/com/mnms/booking/specification/HostSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/HostSpecification.java
@@ -149,11 +149,12 @@ ResponseEntity>> getBookingsByOrganizer(
                             schema = @Schema(implementation = ErrorResponse.class),
                             examples = @ExampleObject(
                                     value = """
-                                    {
-                                               "success": false,
-                                               "data": "ACCESS_DENIED",
-                                               "message": "접근 권한이 없습니다."
-                                    }
+                                            {
+                                                "timestamp": "2025-09-11T02:22:47.684+00:00",
+                                                "status": 403,
+                                                "error": "Forbidden",
+                                                "path": "/api/host/booking/list"
+                                            }
                                     """
                             )
                     )

From 09cd4834da4d33c90c9a26c4bf99c9428dbdb963 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 11 Sep 2025 14:09:17 +0900
Subject: [PATCH 113/149] =?UTF-8?q?MNMS-632=20Fix:=20ticket=5Fpick=20?=
 =?UTF-8?q?=EC=98=88=EB=A7=A4=EB=95=8C=20=EC=A1=B0=ED=9A=8C=20=EB=B0=98?=
 =?UTF-8?q?=ED=99=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ticket_pick - 예매 시, 지류, qr 선택 가능 범위
---
 .../com/mnms/booking/dto/response/BookingDetailResponseDTO.java | 2 ++
 src/main/java/com/mnms/booking/entity/Festival.java             | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
index 22e27a0..70dd5bd 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingDetailResponseDTO.java
@@ -18,6 +18,7 @@ public class BookingDetailResponseDTO {
     private LocalDateTime performanceDate;
     private int ticketCount;
     private Long sellerId;
+    private int ticketPick;
 
     public static BookingDetailResponseDTO fromEntities(Festival festival, Ticket ticket) {
         return BookingDetailResponseDTO.builder()
@@ -27,6 +28,7 @@ public static BookingDetailResponseDTO fromEntities(Festival festival, Ticket ti
                 .ticketPrice(festival.getTicketPrice())
                 .performanceDate(ticket.getPerformanceDate())
                 .ticketCount(ticket.getSelectedTicketCount())
+                .ticketPick(festival.getTicketPick())
                 .build();
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Festival.java b/src/main/java/com/mnms/booking/entity/Festival.java
index d5f461b..12c16b1 100644
--- a/src/main/java/com/mnms/booking/entity/Festival.java
+++ b/src/main/java/com/mnms/booking/entity/Festival.java
@@ -43,7 +43,7 @@ public class Festival {
     private String fcltynm; // 공연장 장소
 
     @Column(name = "ticket_pick")
-    private int ticketPick; // 티켓 배송 방법 (1=배송만, 2=qr만, 3=둘다)
+    private int ticketPick; // 티켓 배송 방법 (1=둘다, 2=qr만)
 
     @Column(name = "max_purchase")
     private int maxPurchase; // 1회 최대 구매 가능 수량 (1~4)

From cc2457b56576d7461e3e231bdd7d38c7105e6b44 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 11 Sep 2025 14:35:14 +0900
Subject: [PATCH 114/149] =?UTF-8?q?MNMS-632=20Fix:=20=EC=96=91=EB=8F=84=20?=
 =?UTF-8?q?=EA=B1=B0=EC=A0=88=20=EC=8B=9C=20=EC=A1=B0=EA=B1=B4=20=EC=88=98?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

양도 거절 시 양도 내역 삭제
거절당한 양도는 다시 양도 가능
---
 .../com/mnms/booking/service/TransferCompletionService.java     | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 4e6595d..0c61041 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -136,7 +136,7 @@ private void applyTicketAndQrUpdate(Transfer transfer, UpdateTicketRequestDTO re
 
     private boolean handleCancel(Transfer transfer, UpdateTicketRequestDTO request) {
         if (request.getTransferStatus() == TransferStatus.CANCELED) {
-            transfer.setStatus(TransferStatus.CANCELED);
+            transferRepository.delete(transfer);
             return true;
         }
         return false;

From ccbd789b1948f66966beac04e06ccfeddf07530e Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 11 Sep 2025 18:27:24 +0900
Subject: [PATCH 115/149] =?UTF-8?q?MNMS-632=20Fix/Feat:=20=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EA=B0=80=EC=98=88=EB=A7=A4=20=EC=9E=90=EB=8F=99=20?=
 =?UTF-8?q?=EC=82=AD=EC=A0=9C=20=EC=8A=A4=EC=BC=80=EC=A4=84=EB=9F=AC=20->?=
 =?UTF-8?q?=20Redis=EB=A1=9C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Redis event db 데이터 삭제 자동 실행
---
 build.gradle                                  |  3 ++
 .../com/mnms/booking/config/RedisConfig.java  | 46 +++++++++++++++----
 .../java/com/mnms/booking/entity/Ticket.java  |  3 ++
 .../service/BookingCommandService.java        | 18 ++++++--
 .../booking/service/BookingStatusService.java | 45 ++++++++++++++----
 .../service/KeyExpirationListener.java        | 28 +++++++++++
 .../service/TempReservationService.java       | 46 +++++++++++++++++++
 src/main/resources/application-dev.properties |  5 +-
 8 files changed, 172 insertions(+), 22 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/service/KeyExpirationListener.java
 create mode 100644 src/main/java/com/mnms/booking/service/TempReservationService.java

diff --git a/build.gradle b/build.gradle
index 57baa6a..17faa5e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -72,6 +72,9 @@ dependencies {
 	implementation 'org.springframework.boot:spring-boot-starter-json'
 	testImplementation 'org.springframework.kafka:spring-kafka-test'
 
+	// 역직렬화
+	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2'
+
 	// QR 생성
 	implementation 'com.google.zxing:core:3.5.2'
 	implementation 'com.google.zxing:javase:3.5.2'
diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index bcd391b..3561565 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.config;
 
+import com.mnms.booking.service.KeyExpirationListener;
 import com.mnms.booking.service.RedisMessageSubscriber;
 import jakarta.annotation.PostConstruct;
 import lombok.extern.slf4j.Slf4j;
@@ -10,9 +11,11 @@
 import org.springframework.data.redis.listener.PatternTopic;
 import org.springframework.data.redis.listener.RedisMessageListenerContainer;
 import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 import org.springframework.data.redis.core.StringRedisTemplate;
-
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 
 @Configuration
 @Slf4j
@@ -25,6 +28,7 @@ public void init() {
     }
 
     /// Redis Pub/Sub 메시지를 구독하고 처리할 컨테이너
+/*
     @Bean
     public RedisMessageListenerContainer redisMessageListenerContainer(
             RedisConnectionFactory connectionFactory,
@@ -38,9 +42,33 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
 
         // 구독 시작 시 로그 출력
         log.info("Subscribed to Redis channels with pattern: {}", patternTopic.getTopic());
+
+        return container;
+    }
+ */
+
+    @Bean
+    public RedisMessageListenerContainer redisMessageListenerContainer(
+            RedisConnectionFactory connectionFactory,
+            MessageListenerAdapter waitingNotificationListenerAdapter,
+            KeyExpirationListener keyExpirationListener
+    ) {
+        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
+        container.setConnectionFactory(connectionFactory);
+
+        // 기존 waiting_notification:* 구독
+        container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification:*"));
+        log.info("Subscribed to Redis channels with pattern: waiting_notification:*");
+
+        // Keyspace Notification (만료 이벤트) 구독
+        container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
+        log.info("Subscribed to Redis key expiration events");
+
         return container;
     }
 
+
+
     /// Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결)
     @Bean
     public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
@@ -56,18 +84,20 @@ public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connection
 
     // ZSet, Hash 등 일반적인 Redis 데이터 구조 관리에 사용될 RedisTemplate 설정 추가
     @Bean
-    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
-        RedisTemplate template = new RedisTemplate<>();
+    public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory, ObjectMapper objectMapper) {
+        RedisTemplate template = new RedisTemplate<>();
         template.setConnectionFactory(connectionFactory);
 
-        // 직렬화 설정
+        // ObjectMapper에 JavaTimeModule 등록
+        objectMapper.registerModule(new JavaTimeModule());
+        objectMapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+
+        // Key와 Value Serializer 설정
         template.setKeySerializer(new StringRedisSerializer());
-        template.setValueSerializer(new StringRedisSerializer());
-        template.setHashKeySerializer(new StringRedisSerializer());
-        template.setHashValueSerializer(new StringRedisSerializer());
+        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
 
-        // 초기화 메서드 호출 (설정 적용)
         template.afterPropertiesSet();
         return template;
     }
+
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 085878c..9c66e74 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -1,5 +1,6 @@
 package com.mnms.booking.entity;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import jakarta.persistence.*;
@@ -37,10 +38,12 @@ public class Ticket {
     private Long userId; // 예매자 id
 
     @Column(name = "reservation_date")
+    //@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
     private LocalDate reservationDate; // 예매를 수행한 날짜
 
     @Setter
     @Column(name = "delivery_date")
+
     private LocalDateTime deliveryDate; // 택배 날짜
 
     @Column(name = "performance_date")
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 651ec90..8efabe4 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -1,6 +1,6 @@
 package com.mnms.booking.service;
 
-import  com.mnms.booking.dto.request.BookingRequestDTO;
+import com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
 import com.mnms.booking.dto.response.*;
@@ -28,6 +28,7 @@ public class BookingCommandService {
     private final CommonUtils commonUtils;
     private final UserApiClient userApiClient;
     private final BookingStatusService bookingStatusService;
+    private final TempReservationService tempReservationService;
 
     /// 1차: 가예매 - 임시 예약
     @Transactional
@@ -51,10 +52,8 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .build();
 
         ticketRepository.save(ticket);
-
-        // TTL 스케줄링: 일정 시간 지나면 자동 삭제
-        bookingStatusService.scheduleTempReservationExpiration(ticket.getReservationNumber());
-
+        // ttl
+        tempReservationService.createTempReservation(ticket);
         return ticket.getReservationNumber();
     }
 
@@ -69,6 +68,9 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
             ticket.setDeliveryDate(bookingStatusService.calculateDeliveryDate(ticket, type));
         }
         ticketRepository.save(ticket);
+
+        // ttl
+        tempReservationService.refreshTempReservation(ticket.getReservationNumber());
     }
 
     /// 3차: 가예매 - 예약 - QR생성
@@ -86,6 +88,9 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
         bookingStatusService.regenerateQrCodes(ticket, userId, festival);
 
         ticketRepository.save(ticket);
+
+        // ttl
+        tempReservationService.refreshTempReservation(ticket.getReservationNumber());
     }
 
     /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
@@ -100,6 +105,9 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
         emailService.sendTicketConfirmationEmail(ticket, user);
 
+        // redis
+        tempReservationService.deleteTempReservation(ticket.getReservationNumber());
+
         // websocket
         bookingStatusService.notifyTicketStatus(ticket, newStatus);
     }
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index 50c6b06..63daa21 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -15,6 +15,7 @@
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
@@ -29,6 +30,8 @@
 import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Locale;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
 
 @Service
@@ -45,15 +48,41 @@ public class BookingStatusService {
     private final QrCodeService qrCodeService;
     private final ThreadPoolTaskScheduler scheduler;
     private final SimpMessagingTemplate messagingTemplate;
+//
+//    /// schedule 점검
+//    public void scheduleTempReservationExpiration(String reservationNumber) {
+//        scheduler.schedule(() -> {
+//            ticketRepository.findByReservationNumber(reservationNumber)
+//                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
+//                    .ifPresent(ticketRepository::delete);
+//        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
+//    }
+//
+//    /// redis를 통해 schedule 점검
+//    private final RedisTemplate redisTemplate;
+//    private static final String PREFIX = "TEMP_RESERVATION:"; // Key prefix
+//    private static final long TTL_MINUTES = 5;
+//
+//    public void createTempReservation(Ticket ticket) {
+//        String key = PREFIX + ticket.getReservationNumber();
+//        redisTemplate.opsForValue().set(
+//                key,
+//                ticket,
+//                TTL_MINUTES,
+//                TimeUnit.MINUTES
+//        );
+//    }
+//
+//    public Optional getTempReservation(String reservationNumber) {
+//        String key = PREFIX + reservationNumber;
+//        Ticket ticket = (Ticket) redisTemplate.opsForValue().get(key);
+//        return Optional.ofNullable(ticket);
+//    }
+//
+//    public void deleteTempReservation(String reservationNumber) {
+//        redisTemplate.delete(PREFIX + reservationNumber);
+//    }
 
-    /// schedule 점검
-    public void scheduleTempReservationExpiration(String reservationNumber) {
-        scheduler.schedule(() -> {
-            ticketRepository.findByReservationNumber(reservationNumber)
-                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
-                    .ifPresent(ticketRepository::delete);
-        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
-    }
 
     /// 검증
     public void validateCapacity(Festival festival, BookingRequestDTO request, Long selectedTicketCount) {
diff --git a/src/main/java/com/mnms/booking/service/KeyExpirationListener.java b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
new file mode 100644
index 0000000..e17934f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
@@ -0,0 +1,28 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.repository.TicketRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.connection.Message;
+import org.springframework.data.redis.connection.MessageListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class KeyExpirationListener implements MessageListener {
+
+    private final TicketRepository ticketRepository;
+
+    ///  ticket 가예매 스케줄러
+    @Override
+    public void onMessage(Message message, byte[] pattern) {
+        String key = message.toString();
+        if (key.startsWith("TEMP_RESERVATION:")) {
+            String reservationNumber = key.substring("TEMP_RESERVATION:".length());
+            
+            ticketRepository.findByReservationNumber(reservationNumber)
+                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
+                    .ifPresent(ticketRepository::delete);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
new file mode 100644
index 0000000..8ec635f
--- /dev/null
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -0,0 +1,46 @@
+package com.mnms.booking.service;
+
+import com.mnms.booking.entity.Ticket;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@RequiredArgsConstructor
+public class TempReservationService {
+
+    private final RedisTemplate redisTemplate;
+
+    private static final String PREFIX = "TEMP_RESERVATION:";
+    private static final long TTL_MINUTES = 1;
+
+    public void createTempReservation(Ticket ticket) {
+        String key = PREFIX + ticket.getReservationNumber();
+        redisTemplate.opsForValue().set(key, ticket, TTL_MINUTES, TimeUnit.MINUTES);
+    }
+
+    // 갱신
+    public void refreshTempReservation(String reservationNumber) {
+        String key = PREFIX + reservationNumber;
+        Boolean exists = redisTemplate.hasKey(key);
+
+        if (Boolean.TRUE.equals(exists)) {
+            redisTemplate.expire(key, TTL_MINUTES, TimeUnit.MINUTES);
+        }
+    }
+
+    // 조회
+    public Optional getTempReservation(String reservationNumber) {
+        String key = PREFIX + reservationNumber;
+        Ticket ticket = (Ticket) redisTemplate.opsForValue().get(key);
+        return Optional.ofNullable(ticket);
+    }
+
+    // 삭제
+    public void deleteTempReservation(String reservationNumber) {
+        redisTemplate.delete(PREFIX + reservationNumber);
+    }
+}
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index c59dcef..3cb5e3b 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -85,4 +85,7 @@ management.metrics.distribution.percentiles-histogram.hikaricp.connections.acqui
 management.metrics.distribution.sla.hikaricp.connections.acquire=5ms,10ms,20ms,50ms,100ms,200ms,500ms
 
 # Tomcat 메트릭(MBean) 활성화(스레드, 커넥션 등)
-server.tomcat.mbeanregistry.enabled=true
\ No newline at end of file
+server.tomcat.mbeanregistry.enabled=true
+
+
+spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
\ No newline at end of file

From 5b5ca5395da97323639efca68694d4d1929be9bd Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 10:12:48 +0900
Subject: [PATCH 116/149] =?UTF-8?q?MNMS-632=20Chore:=20=EC=A3=BC=EC=84=9D?=
 =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/config/RedisConfig.java  | 32 +++--------------
 .../service/BookingCommandService.java        | 10 +++---
 .../booking/service/BookingStatusService.java | 35 -------------------
 .../service/TempReservationService.java       |  3 ++
 4 files changed, 13 insertions(+), 67 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 3561565..31e84ba 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -28,25 +28,6 @@ public void init() {
     }
 
     /// Redis Pub/Sub 메시지를 구독하고 처리할 컨테이너
-/*
-    @Bean
-    public RedisMessageListenerContainer redisMessageListenerContainer(
-            RedisConnectionFactory connectionFactory,
-            MessageListenerAdapter listenerAdapter
-    ) {
-        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
-        container.setConnectionFactory(connectionFactory);
-
-        PatternTopic patternTopic = new PatternTopic("waiting_notification:*");
-        container.addMessageListener(listenerAdapter, patternTopic);
-
-        // 구독 시작 시 로그 출력
-        log.info("Subscribed to Redis channels with pattern: {}", patternTopic.getTopic());
-
-        return container;
-    }
- */
-
     @Bean
     public RedisMessageListenerContainer redisMessageListenerContainer(
             RedisConnectionFactory connectionFactory,
@@ -56,19 +37,17 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
         RedisMessageListenerContainer container = new RedisMessageListenerContainer();
         container.setConnectionFactory(connectionFactory);
 
-        // 기존 waiting_notification:* 구독
+        // waiting_notification:* 구독
         container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification:*"));
         log.info("Subscribed to Redis channels with pattern: waiting_notification:*");
 
-        // Keyspace Notification (만료 이벤트) 구독
+        // Keyspace Notification 구독 (예매 완료 이벤트)
         container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
         log.info("Subscribed to Redis key expiration events");
 
         return container;
     }
 
-
-
     /// Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결)
     @Bean
     public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
@@ -76,26 +55,23 @@ public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber)
         return new MessageListenerAdapter(subscriber, "onMessage");
     }
 
-    // Redis Pub/Sub 메시지를 발행하는 데 사용될 템플릿
+    /// Redis Pub/Sub 메시지를 발행하는 데 사용될 템플릿
     @Bean
     public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
         return new StringRedisTemplate(connectionFactory);
     }
 
-    // ZSet, Hash 등 일반적인 Redis 데이터 구조 관리에 사용될 RedisTemplate 설정 추가
+    /// ZSet, Hash 등 일반적인 Redis 데이터 구조 관리에 사용될 RedisTemplate 설정 추가
     @Bean
     public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory, ObjectMapper objectMapper) {
         RedisTemplate template = new RedisTemplate<>();
         template.setConnectionFactory(connectionFactory);
 
-        // ObjectMapper에 JavaTimeModule 등록
         objectMapper.registerModule(new JavaTimeModule());
         objectMapper.disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
 
-        // Key와 Value Serializer 설정
         template.setKeySerializer(new StringRedisSerializer());
         template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
-
         template.afterPropertiesSet();
         return template;
     }
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 8efabe4..d760470 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -52,7 +52,7 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .build();
 
         ticketRepository.save(ticket);
-        // ttl
+        // redis ttl
         tempReservationService.createTempReservation(ticket);
         return ticket.getReservationNumber();
     }
@@ -69,8 +69,9 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
         }
         ticketRepository.save(ticket);
 
-        // ttl
+        // redis ttl
         tempReservationService.refreshTempReservation(ticket.getReservationNumber());
+
     }
 
     /// 3차: 가예매 - 예약 - QR생성
@@ -89,10 +90,11 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
 
         ticketRepository.save(ticket);
 
-        // ttl
+        // redis ttl
         tempReservationService.refreshTempReservation(ticket.getReservationNumber());
     }
 
+
     /// 최종 완료 - status 변경 (payment에 kafka 메시지 구독)
     @Transactional
     public void confirmTicket(String reservationNumber, boolean paymentStatus) {
@@ -105,7 +107,7 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
         emailService.sendTicketConfirmationEmail(ticket, user);
 
-        // redis
+        // redis ttl
         tempReservationService.deleteTempReservation(ticket.getReservationNumber());
 
         // websocket
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index 63daa21..bde3757 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -48,41 +48,6 @@ public class BookingStatusService {
     private final QrCodeService qrCodeService;
     private final ThreadPoolTaskScheduler scheduler;
     private final SimpMessagingTemplate messagingTemplate;
-//
-//    /// schedule 점검
-//    public void scheduleTempReservationExpiration(String reservationNumber) {
-//        scheduler.schedule(() -> {
-//            ticketRepository.findByReservationNumber(reservationNumber)
-//                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
-//                    .ifPresent(ticketRepository::delete);
-//        }, Instant.now().plus(TEMP_RESERVATION_TTL_MINUTES, ChronoUnit.MINUTES));
-//    }
-//
-//    /// redis를 통해 schedule 점검
-//    private final RedisTemplate redisTemplate;
-//    private static final String PREFIX = "TEMP_RESERVATION:"; // Key prefix
-//    private static final long TTL_MINUTES = 5;
-//
-//    public void createTempReservation(Ticket ticket) {
-//        String key = PREFIX + ticket.getReservationNumber();
-//        redisTemplate.opsForValue().set(
-//                key,
-//                ticket,
-//                TTL_MINUTES,
-//                TimeUnit.MINUTES
-//        );
-//    }
-//
-//    public Optional getTempReservation(String reservationNumber) {
-//        String key = PREFIX + reservationNumber;
-//        Ticket ticket = (Ticket) redisTemplate.opsForValue().get(key);
-//        return Optional.ofNullable(ticket);
-//    }
-//
-//    public void deleteTempReservation(String reservationNumber) {
-//        redisTemplate.delete(PREFIX + reservationNumber);
-//    }
-
 
     /// 검증
     public void validateCapacity(Festival festival, BookingRequestDTO request, Long selectedTicketCount) {
diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index 8ec635f..7a59aa2 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -25,7 +25,10 @@ public void createTempReservation(Ticket ticket) {
     // 갱신
     public void refreshTempReservation(String reservationNumber) {
         String key = PREFIX + reservationNumber;
+
+        System.out.println("갱신하려는 key: " + key);
         Boolean exists = redisTemplate.hasKey(key);
+        System.out.println("exists? " + exists);
 
         if (Boolean.TRUE.equals(exists)) {
             redisTemplate.expire(key, TTL_MINUTES, TimeUnit.MINUTES);

From 281b923fffbe412de5cb1caf27b5badfb54b37de Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 10:36:50 +0900
Subject: [PATCH 117/149] =?UTF-8?q?=20swagger=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/security/SecurityConfig.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 8d5f960..5f2ff5d 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -28,7 +28,7 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                 .authorizeHttpRequests(auth -> auth
                         .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
                         .requestMatchers("/ws/**").permitAll()
-                        .requestMatchers("/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html").permitAll()
+                        .requestMatchers("/v3/api-docs/**", "/v3/api-docs","/swagger-ui/**", "/swagger-ui.html").permitAll()
                         .requestMatchers(
                                 "/public/**",
                                 "/h2-console/**",

From a4235435e774ccbcfb5f5d6f68e3cdc180681e82 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 11:15:31 +0900
Subject: [PATCH 118/149] =?UTF-8?q?header=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/security/HeaderAuthenticationFilter.java   | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index 72bcb8e..034e957 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -51,6 +51,12 @@ protected void doFilterInternal(
         if (canSetAuth) {
             // 헤더가 없으면 401
             if (userIdHeader == null || rolesHdr == null) {
+                if (uri.startsWith("/v3/api-docs")
+                        || uri.startsWith("/swagger-ui")
+                        || uri.equals("/swagger-ui.html")
+                        || uri.startsWith("/actuator")) {
+                    chain.doFilter(request, response);
+                }
                 sendUnauthorized(response, "X-User-Id 또는 X-User-Role 헤더가 없습니다.");
                 return;
             }

From e7452963f48aa116f64a444e90f7a186b4494fcc Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 11:16:29 +0900
Subject: [PATCH 119/149] =?UTF-8?q?he=20=EC=A4=91=EB=B3=B5=20=EB=B9=8C?=
 =?UTF-8?q?=EB=93=9C=20=EB=B6=80=EB=B6=84=20=EC=A0=9C=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .github/workflows/api-booking-docker-dispatch.yml | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 16f9249..0661111 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -23,14 +23,6 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
-      - uses: actions/setup-java@v3
-        with:
-          distribution: temurin
-          java-version: '17'
-
-      - run: chmod +x ./gradlew
-      - run: ./gradlew bootJar --no-daemon
-
       - name: ⏱️ Tag
         run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
 

From a7e09433a42f4862bb8d8ba42087be5de06e1e03 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 12:12:50 +0900
Subject: [PATCH 120/149] =?UTF-8?q?=20=EB=B9=8C=EB=93=9C=20=EC=8B=9C?=
 =?UTF-8?q?=EA=B0=84=20=EB=8B=A8=EC=B6=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../workflows/api-booking-docker-dispatch.yml |  8 +++++
 Dockerfile                                    | 30 +++++++++++--------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/.github/workflows/api-booking-docker-dispatch.yml b/.github/workflows/api-booking-docker-dispatch.yml
index 0661111..16f9249 100644
--- a/.github/workflows/api-booking-docker-dispatch.yml
+++ b/.github/workflows/api-booking-docker-dispatch.yml
@@ -23,6 +23,14 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
+      - uses: actions/setup-java@v3
+        with:
+          distribution: temurin
+          java-version: '17'
+
+      - run: chmod +x ./gradlew
+      - run: ./gradlew bootJar --no-daemon
+
       - name: ⏱️ Tag
         run: echo "TAG=v$(date -u +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
 
diff --git a/Dockerfile b/Dockerfile
index da18336..838322d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,16 +1,20 @@
-# -------- build stage --------
-FROM eclipse-temurin:17-jdk AS build
-WORKDIR /app
-COPY gradlew gradlew
-COPY gradle gradle
-COPY build.gradle settings.gradle ./
-COPY src src
-RUN chmod +x gradlew && ./gradlew bootJar --no-daemon
+# Debian/Ubuntu 계열 JRE (amd64/arm64 모두 제공)
+FROM eclipse-temurin:17-jre-jammy
+
+# spring 사용자/그룹 생성 (Debian 표준 명령)
+RUN groupadd -r spring \
+ && useradd -r -g spring -d /home/spring -s /usr/sbin/nologin spring \
+ && mkdir -p /app /home/spring
 
-# -------- run stage --------
-FROM eclipse-temurin:17-jre
 WORKDIR /app
-# 빌드 산출물 복사 (이름 모르면 * 로)
-COPY --from=build /app/build/libs/*.jar app.jar
+
+# 빌드 산출물 복사 (권한도 함께 설정)
+ARG JAR_FILE=build/libs/*.jar
+COPY --chown=spring:spring ${JAR_FILE} /app/app.jar
+
+# 비루트 실행
+USER spring
+
 EXPOSE 8080
-ENTRYPOINT ["java","-jar","/app/app.jar"]
\ No newline at end of file
+ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75"
+ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/app.jar"]
\ No newline at end of file

From 41fe6956810d769e290349373961da2e4bbecc58 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 12:59:18 +0900
Subject: [PATCH 121/149] =?UTF-8?q?swagger=20=C3=AC=C2=84docker=20=C2=A4?=
 =?UTF-8?q?=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/resources/application-dev.properties | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 3cb5e3b..70dd00f 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -70,6 +70,8 @@ springdoc.api-docs.enabled=true
 springdoc.swagger-ui.enabled=true
 springdoc.swagger-ui.path=/swagger-ui.html
 springdoc.override-with-generic-response=false
+springdoc.servers[0].url=${BASE_API:http://localhost:10000}
+springdoc.servers[0].description=API Gateway
 
 # ===== Actuator/Prometheus & 메트릭 히스토그램 =====
 management.endpoints.web.exposure.include=health,info,prometheus

From 7907dd76c53b6a612d0fba476c080636ec2ad3a0 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 14:15:46 +0900
Subject: [PATCH 122/149] =?UTF-8?q?header=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/security/HeaderAuthenticationFilter.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index 034e957..cccf868 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -54,13 +54,15 @@ protected void doFilterInternal(
                 if (uri.startsWith("/v3/api-docs")
                         || uri.startsWith("/swagger-ui")
                         || uri.equals("/swagger-ui.html")
-                        || uri.startsWith("/actuator")) {
+                        || uri.startsWith("/actuator")
+                        || uri.equals("/ws/info")) {
                     chain.doFilter(request, response);
                 }
                 sendUnauthorized(response, "X-User-Id 또는 X-User-Role 헤더가 없습니다.");
                 return;
             }
 
+
             // userId 파싱
             final Long userId;
             try {

From b5df21f45ab9f5b77a427565a23d755983ce9655 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Fri, 12 Sep 2025 14:31:50 +0900
Subject: [PATCH 123/149] =?UTF-8?q?ws=20=EC=98=A4=EB=A5=98=20=ED=95=B4?=
 =?UTF-8?q?=EA=B2=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/security/HeaderAuthenticationFilter.java  | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index cccf868..6d4ee28 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -55,8 +55,9 @@ protected void doFilterInternal(
                         || uri.startsWith("/swagger-ui")
                         || uri.equals("/swagger-ui.html")
                         || uri.startsWith("/actuator")
-                        || uri.equals("/ws/info")) {
+                        || uri.startsWith("/ws")) {
                     chain.doFilter(request, response);
+                    return;
                 }
                 sendUnauthorized(response, "X-User-Id 또는 X-User-Role 헤더가 없습니다.");
                 return;

From d6880456ab238b831150b5fc7e20fdd18a1b1bba Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Fri, 12 Sep 2025 14:49:14 +0900
Subject: [PATCH 124/149] =?UTF-8?q?Fix:=20=EC=98=88=EB=A7=A4=EC=9E=90=20?=
 =?UTF-8?q?=EB=AA=85=EB=8B=A8=20ADMIN=EB=8F=84=20=EC=A1=B0=ED=9A=8C=20?=
 =?UTF-8?q?=EA=B0=80=EB=8A=A5=ED=95=98=EA=B2=8C=20=EB=B2=84=EA=B7=B8=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95,=20api/host/list=20jwt=EC=9D=B8=EC=A6=9D=20?=
 =?UTF-8?q?=EC=97=86=EC=9D=B4=EB=8F=84=20=EA=B0=80=EB=8A=A5=ED=95=98?=
 =?UTF-8?q?=EA=B2=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/security/HeaderAuthenticationFilter.java | 3 ++-
 src/main/java/com/mnms/booking/security/SecurityConfig.java   | 4 ++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index 6d4ee28..f7a405f 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -55,7 +55,8 @@ protected void doFilterInternal(
                         || uri.startsWith("/swagger-ui")
                         || uri.equals("/swagger-ui.html")
                         || uri.startsWith("/actuator")
-                        || uri.startsWith("/ws")) {
+                        || uri.startsWith("/ws")
+                        || uri.startsWith("/api/host/list")) {
                     chain.doFilter(request, response);
                     return;
                 }
diff --git a/src/main/java/com/mnms/booking/security/SecurityConfig.java b/src/main/java/com/mnms/booking/security/SecurityConfig.java
index 5f2ff5d..01c1c68 100644
--- a/src/main/java/com/mnms/booking/security/SecurityConfig.java
+++ b/src/main/java/com/mnms/booking/security/SecurityConfig.java
@@ -26,7 +26,8 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                 .csrf(AbstractHttpConfigurer::disable)
                 .cors(AbstractHttpConfigurer::disable) // gateway CORS 중복 방지
                 .authorizeHttpRequests(auth -> auth
-                        .requestMatchers("/api/host/booking/list").hasRole("HOST") // HOST ROLE 설정
+                        .requestMatchers("/api/host/list").permitAll()
+                        .requestMatchers("/api/host/booking/list").hasAnyRole("HOST", "ADMIN")
                         .requestMatchers("/ws/**").permitAll()
                         .requestMatchers("/v3/api-docs/**", "/v3/api-docs","/swagger-ui/**", "/swagger-ui.html").permitAll()
                         .requestMatchers(
@@ -35,7 +36,6 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
                                 "/api/captcha/**",
                                 "/api/qr/**",
                                 "/api/booking/detail/phases/1",
-                                "/api/host/**",
                                 "/api/booking/confirm",
                                 "/api/transfer/**",
                                 "/api/transfer/**",

From 2b53de3009708739ba7aea9c178fede2d5a2a76b Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 15:24:15 +0900
Subject: [PATCH 125/149] =?UTF-8?q?MNMS-632=20Merge=20&=20Chore:=20?=
 =?UTF-8?q?=EA=B0=80=EC=98=88=EB=A7=A4=20bookingUsersKey=20=EC=82=AD?=
 =?UTF-8?q?=EC=A0=9C=20=EC=99=84=EB=A3=8C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Redis 가예매 자동 삭제 테스트 완료
userExitBookingPage 실행으로 해당하는 bookingUserKey 자동 삭제 테스트 완료
---
 .../com/mnms/booking/config/RedisConfig.java  |  1 +
 .../booking/repository/TicketRepository.java  |  3 +++
 .../service/BookingCommandService.java        |  1 -
 .../service/KeyExpirationListener.java        | 23 ++++++++++++++++++-
 .../service/WaitingQueueRedisService.java     |  4 ++++
 .../WaitingQueueSchedulingService.java        |  6 ++---
 .../mnms/booking/service/WaitingService.java  |  1 +
 7 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 31e84ba..73e76ed 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -43,6 +43,7 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
 
         // Keyspace Notification 구독 (예매 완료 이벤트)
         container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
+        container.addMessageListener(keyExpirationListener, new PatternTopic("waiting_notification:*"));
         log.info("Subscribed to Redis key expiration events");
 
         return container;
diff --git a/src/main/java/com/mnms/booking/repository/TicketRepository.java b/src/main/java/com/mnms/booking/repository/TicketRepository.java
index d9bb7b4..4c12834 100644
--- a/src/main/java/com/mnms/booking/repository/TicketRepository.java
+++ b/src/main/java/com/mnms/booking/repository/TicketRepository.java
@@ -121,5 +121,8 @@ List findTempReservedTickets(
             @Param("userId") Long userId,
             @Param("reservationStatus") ReservationStatus reservationStatus
     );
+
+    @Query("SELECT t FROM Ticket t JOIN FETCH t.festival WHERE t.reservationNumber = :reservationNumber")
+    Optional findByReservationNumberWithFestival(@Param("reservationNumber") String reservationNumber);
 }
 
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index d760470..1de12f8 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -71,7 +71,6 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
 
         // redis ttl
         tempReservationService.refreshTempReservation(ticket.getReservationNumber());
-
     }
 
     /// 3차: 가예매 - 예약 - QR생성
diff --git a/src/main/java/com/mnms/booking/service/KeyExpirationListener.java b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
index e17934f..5d387c3 100644
--- a/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
+++ b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
@@ -1,17 +1,23 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.ReservationStatus;
+import com.mnms.booking.exception.BusinessException;
+import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.connection.Message;
 import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.stereotype.Component;
 
+@Slf4j
 @Component
 @RequiredArgsConstructor
 public class KeyExpirationListener implements MessageListener {
 
     private final TicketRepository ticketRepository;
+    private final WaitingService waitingService;
 
     ///  ticket 가예매 스케줄러
     @Override
@@ -19,10 +25,25 @@ public void onMessage(Message message, byte[] pattern) {
         String key = message.toString();
         if (key.startsWith("TEMP_RESERVATION:")) {
             String reservationNumber = key.substring("TEMP_RESERVATION:".length());
-            
+
+            // 예매열 삭제
+            Ticket reservation = loadReservationMeta(reservationNumber);
+
+            waitingService.userExitBookingPage(
+                    reservation.getFestival().getFestivalId(),
+                    reservation.getPerformanceDate(),
+                    String.valueOf(reservation.getUserId())
+            );
+
+            // 티켓 가예매 삭제
             ticketRepository.findByReservationNumber(reservationNumber)
                     .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
                     .ifPresent(ticketRepository::delete);
         }
     }
+
+    private Ticket loadReservationMeta(String reservationNumber) {
+        return ticketRepository.findByReservationNumberWithFestival(reservationNumber)
+                .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index 1aa94e4..fce0d26 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.data.redis.RedisConnectionFailureException;
 import org.springframework.data.redis.RedisSystemException;
 import org.springframework.data.redis.core.RedisTemplate;
@@ -15,6 +16,7 @@
 import java.util.Set;
 
 @Service
+@Slf4j
 public class WaitingQueueRedisService {
 
     private final RedisTemplate redisTemplate;
@@ -120,6 +122,8 @@ public boolean removeBookingUser(String bookingUsersKey, String userId) {
         Long removed = redisTemplate.opsForSet().remove(bookingUsersKey, userId);
         return removed != null && removed > 0;
     }
+
+
     public Long getRank(String waitingQueueKey, String userId){
         return zSetOperations.rank(waitingQueueKey, userId);
     }
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index eba3dac..5a12f2c 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -33,14 +33,12 @@ public synchronized void startScheduler(String waitingQueueKey, String bookingUs
         log.info("Starting scheduler for queue: {}", waitingQueueKey);
         ScheduledFuture task = scheduler.scheduleWithFixedDelay(
                 () -> runSchedulerLogic(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP),
-                Duration.ofSeconds(5)
+                Duration.ofSeconds(10)
         );
         scheduledTasks.put(waitingQueueKey, task);
     }
 
-    /**
-     * 스케줄러 중지
-     */
+    /// 스케줄러 중지
     public synchronized void stopScheduler(String waitingQueueKey) {
         ScheduledFuture task = scheduledTasks.get(waitingQueueKey);
         if (task != null && !task.isCancelled()) {
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 5b7ec83..88c8d0a 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -35,6 +35,7 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
                 throw new BusinessException(ErrorCode.FAILED_TO_ENTER_QUEUE);
             }
             log.info("User {} added to waiting queue {}.", userId, waitingQueueKey);
+
             waitingQueueSchedulingService.startScheduler(waitingQueueKey, bookingUsersKey, notificationChannelKey, availableNOP);
             return waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
         }

From 3f53ce2e07ab327c1fa472544f0e3e47dbebfeea Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 17:10:51 +0900
Subject: [PATCH 126/149] =?UTF-8?q?MNMS-632=20Chore:=20websocket=20bean=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../service/TempReservationService.java       |   2 +-
 .../service/WaitingQueueKeyGenerator.java     |   2 +-
 .../WaitingQueueSchedulingService.java        |   3 +-
 src/main/resources/static/index.html          | 129 ------------------
 src/main/resources/static/test-websocket.html |  62 ---------
 5 files changed, 4 insertions(+), 194 deletions(-)
 delete mode 100644 src/main/resources/static/index.html
 delete mode 100644 src/main/resources/static/test-websocket.html

diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index 7a59aa2..5cf5a4c 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -15,7 +15,7 @@ public class TempReservationService {
     private final RedisTemplate redisTemplate;
 
     private static final String PREFIX = "TEMP_RESERVATION:";
-    private static final long TTL_MINUTES = 1;
+    private static final long TTL_MINUTES = 100;
 
     public void createTempReservation(Ticket ticket) {
         String key = PREFIX + ticket.getReservationNumber();
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java b/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java
index 8459b47..1105fab 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueKeyGenerator.java
@@ -24,6 +24,6 @@ public String getBookingUsersKey(String festivalId, LocalDateTime reservationDat
 
     public String getNotificationChannelKey(String festivalId, LocalDateTime reservationDate) {
         String dateStr = reservationDate.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
-        return NOTIFICATION_CHANNEL + ":" + festivalId + ":" + dateStr;
+        return NOTIFICATION_CHANNEL + "/" + festivalId + "/" + dateStr;
     }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index 5a12f2c..bf70b5a 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -22,7 +22,8 @@
 public class WaitingQueueSchedulingService {
     private final WaitingQueueRedisService waitingQueueRedisService;
     private final WaitingNotificationService waitingNotificationService;
-    private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+    //private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+    private final ThreadPoolTaskScheduler scheduler;
     private final Map> scheduledTasks = new ConcurrentHashMap<>();
 
     /// 스케줄러 시작 (중복 시작 방지)
diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html
deleted file mode 100644
index 0dda08f..0000000
--- a/src/main/resources/static/index.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/static/test-websocket.html b/src/main/resources/static/test-websocket.html
deleted file mode 100644
index 28d3b52..0000000
--- a/src/main/resources/static/test-websocket.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-  
-  WebSocket STOMP 테스트
-  
-  
-
-
-

WebSocket STOMP 테스트

- -
- - - -
- -

-
-
-
-

From c1c013692513222d68a5b8ac2653f4c1bb538bbc Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 17:12:02 +0900
Subject: [PATCH 127/149] =?UTF-8?q?MNMS-632=20Chore:=20websocket=20?=
 =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=82=AD=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/service/WaitingQueueSchedulingService.java  | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
index bf70b5a..25e3a31 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueSchedulingService.java
@@ -22,7 +22,6 @@
 public class WaitingQueueSchedulingService {
     private final WaitingQueueRedisService waitingQueueRedisService;
     private final WaitingNotificationService waitingNotificationService;
-    //private final ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
     private final ThreadPoolTaskScheduler scheduler;
     private final Map> scheduledTasks = new ConcurrentHashMap<>();
 

From 92ee68aeb8464bc5d4261b008cba6e98729cc3b7 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 17:43:27 +0900
Subject: [PATCH 128/149] =?UTF-8?q?MNMS-632=20Chore:=20websocket=20userId?=
 =?UTF-8?q?=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/service/WaitingNotificationService.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index e551c1d..0647118 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -44,7 +44,7 @@ private void publishWaitingNumber(String userId, long waitingNumber, String noti
         try {
             WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(waitingNumberDto);
-            stringRedisTemplate.convertAndSend(notificationChannelKey, message);
+            stringRedisTemplate.convertAndSend(notificationChannelKey + "/" + userId, message);
         } catch (JsonProcessingException e) {
             throw new BusinessException(ErrorCode.JSON_SERIALIZATION_FAILED);
         } catch (RedisConnectionFailureException e) {

From f565e8f102acfe6d6173b287acc3deddf3538165 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 22:20:26 +0900
Subject: [PATCH 129/149] =?UTF-8?q?MNMS-632=20Fix:=20=EC=9D=B4=EB=B2=A4?=
 =?UTF-8?q?=ED=8A=B8=20=EC=A4=91=EB=B3=B5=20=EA=B5=AC=EB=8F=85=20=EC=82=AD?=
 =?UTF-8?q?=EC=A0=9C=20=EB=B0=8F=20=EC=9D=B4=EC=A0=84=20=EC=88=98=EC=A0=95?=
 =?UTF-8?q?=20=EB=B3=B5=EA=B5=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

MNMS-632에서 websocket userId 처리 로직 내용 잘못 적용되어 복구함.
Issue: MNMS-632
---
 src/main/java/com/mnms/booking/config/RedisConfig.java        | 4 ++--
 .../com/mnms/booking/service/WaitingNotificationService.java  | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 73e76ed..55bf5e9 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -38,8 +38,8 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
         container.setConnectionFactory(connectionFactory);
 
         // waiting_notification:* 구독
-        container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification:*"));
-        log.info("Subscribed to Redis channels with pattern: waiting_notification:*");
+//        container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification:*"));
+//        log.info("Subscribed to Redis channels with pattern: waiting_notification:*");
 
         // Keyspace Notification 구독 (예매 완료 이벤트)
         container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index 0647118..bf4c273 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -44,7 +44,9 @@ private void publishWaitingNumber(String userId, long waitingNumber, String noti
         try {
             WaitingNumberResponseDTO waitingNumberDto = new WaitingNumberResponseDTO(userId, waitingNumber, false, null);
             String message = objectMapper.writeValueAsString(waitingNumberDto);
-            stringRedisTemplate.convertAndSend(notificationChannelKey + "/" + userId, message);
+
+            // message 발행
+            stringRedisTemplate.convertAndSend(notificationChannelKey, message);
         } catch (JsonProcessingException e) {
             throw new BusinessException(ErrorCode.JSON_SERIALIZATION_FAILED);
         } catch (RedisConnectionFailureException e) {

From 78ed9b69215f3ae616a2e3ade727b76af702e186 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 22:42:32 +0900
Subject: [PATCH 130/149] =?UTF-8?q?MNMS-632=20Chore:=20Swagger=20api?=
 =?UTF-8?q?=EB=A7=8C=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../booking/controller/BookingController.java | 21 +++++++-----
 .../booking/controller/CaptchaController.java |  4 +--
 .../booking/controller/HostController.java    |  4 +--
 .../booking/controller/QrCodeController.java  |  4 +--
 .../controller/StatisticsController.java      | 10 +++---
 .../booking/controller/TicketController.java  |  4 +--
 .../controller/TransferController.java        | 20 ++++++-----
 .../booking/controller/WaitingController.java |  6 ++--
 .../specification/BookingSpecification.java   |  7 ----
 .../specification/CaptchaSpecification.java   |  4 +--
 .../specification/HostSpecification.java      |  4 +--
 .../specification/QrCodeSpecification.java    |  5 +--
 .../StatisticsSpecification.java              |  4 ---
 .../specification/TicketSpecification.java    |  3 +-
 .../specification/TransferSpecification.java  | 34 +++++++++----------
 .../specification/WaitingSpecification.java   |  4 +--
 16 files changed, 64 insertions(+), 74 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/BookingController.java b/src/main/java/com/mnms/booking/controller/BookingController.java
index 260960b..523e3ad 100644
--- a/src/main/java/com/mnms/booking/controller/BookingController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingController.java
@@ -32,12 +32,13 @@ public class BookingController implements BookingSpecification {
     private final SecurityResponseUtil securityResponseUtil;
 
     /// GET : 페스티벌 예매 정보 조회
-    @Override
+    @PostMapping("/detail/phases/1")
     public ResponseEntity> getFestivalDetail(@Valid @RequestBody BookingSelectRequestDTO request) {
         return ApiResponseUtil.success(bookingQueryService.getFestivalDetail(request));
     }
 
-    @Override
+    /// POST : 2차 예매 상세 조회
+    @PostMapping("/detail/phases/2")
     public ResponseEntity> getFestivalBookingDetail(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
@@ -47,7 +48,7 @@ public ResponseEntity> getFestivalBook
     }
 
     /// POST
-    @Override
+    @PostMapping("/selectDate")
     public ResponseEntity> selectFestivalDate(
             @Valid @RequestBody BookingSelectRequestDTO request,
             Authentication authentication
@@ -55,7 +56,8 @@ public ResponseEntity> selectFestivalDate(
         return ApiResponseUtil.success(bookingCommandService.selectFestivalDate(request, securityResponseUtil.requireUserId(authentication)));
     }
 
-    @Override
+    /// POST : 배송 선택
+    @PostMapping("/selectDeliveryMethod")
     public ResponseEntity> selectFestivalDelivery(
             @Valid @RequestBody BookingSelectDeliveryRequestDTO request,
             Authentication authentication
@@ -65,7 +67,7 @@ public ResponseEntity> selectFestivalDelivery(
     }
 
     /// POST : 3차 예매 완료 (결제 직전)
-    @Override
+    @PostMapping("/qr")
     public ResponseEntity> reserveTicket(
             @Valid @RequestBody BookingRequestDTO request,
             Authentication authentication
@@ -75,19 +77,20 @@ public ResponseEntity> reserveTicket(
     }
 
     ///  Websocket 메시지 누락 방지 api요청
-    @Override
+    @GetMapping("reservation/status")
     public ResponseEntity> checkStatus(@RequestParam String reservationNumber){
         return ApiResponseUtil.success(bookingCommandService.checkStatus(reservationNumber));
     }
 
-    ///  GET
+    /// GET : 예매자 정보 조회
+    @GetMapping("/user/info")
     @Override
     public ResponseEntity> getUserInfo(Authentication authentication) {
         return ApiResponseUtil.success(userApiClient.getUserInfoById(securityResponseUtil.requireUserId(authentication)));
     }
 
-    ///  이메일 임시 테스트
-    @Override
+    /// POST : 이메일 임시 테스트
+    @PostMapping("/email/test")
     public ResponseEntity confirmTicket(
             @RequestParam String reservationNumber,
             @RequestParam boolean paymentStatus) {
diff --git a/src/main/java/com/mnms/booking/controller/CaptchaController.java b/src/main/java/com/mnms/booking/controller/CaptchaController.java
index d9414e0..25b810d 100644
--- a/src/main/java/com/mnms/booking/controller/CaptchaController.java
+++ b/src/main/java/com/mnms/booking/controller/CaptchaController.java
@@ -23,13 +23,13 @@ public class CaptchaController implements CaptchaSpecification{
 
     private final CaptchaService kaptchaService;
 
-    @Override
+    @GetMapping("/image")
     public ResponseEntity> getCaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
         kaptchaService.writeCaptchaImage(request.getSession(), response);
         return ApiResponseUtil.success(null, "보안문자 이미지가 생성 완료");
     }
 
-    @Override
+    @PostMapping("/verify")
     public ResponseEntity> verifyCaptcha(
             @RequestParam("captcha") String captcha,
             HttpSession session) {
diff --git a/src/main/java/com/mnms/booking/controller/HostController.java b/src/main/java/com/mnms/booking/controller/HostController.java
index 01c0eec..f9b988d 100644
--- a/src/main/java/com/mnms/booking/controller/HostController.java
+++ b/src/main/java/com/mnms/booking/controller/HostController.java
@@ -23,13 +23,13 @@ public class HostController implements HostSpecification{
     private final SecurityResponseUtil securityResponseUtil;
     private final HostService hostService;
 
-    @Override
+    @PostMapping("/list")
     public ResponseEntity>> getBookingsByOrganizer(@RequestBody HostRequestDTO hostRequestDTO) {
         return ApiResponseUtil.success(hostService.getBookingsByOrganizer(hostRequestDTO));
     }
 
     /// 주최자 측 예매자 조회
-    @Override
+    @PostMapping("/booking/list")
     @PreAuthorize("hasAnyRole('HOST', 'ADMIN')")
     public ResponseEntity>> getBookingInfo(@RequestParam String festivalId,
                                                                                  Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/QrCodeController.java b/src/main/java/com/mnms/booking/controller/QrCodeController.java
index ccc16ab..9449502 100644
--- a/src/main/java/com/mnms/booking/controller/QrCodeController.java
+++ b/src/main/java/com/mnms/booking/controller/QrCodeController.java
@@ -27,7 +27,7 @@ public class QrCodeController implements QrCodeSpecification {
     private final SecurityResponseUtil securityResponseUtil;
 
     /// Qrcode 이미지 조회
-    @Override
+    @GetMapping(value = "/image/{qrCodeId}", produces = "image/png")
     public ResponseEntity getQrCodeImage(@PathVariable String qrCodeId) {
         QrCode qrCode = qrCodeService.getQrCodeByCode(qrCodeId);
         String qrCodeText = qrCode.getQrCodeId();
@@ -64,7 +64,7 @@ public ResponseEntity> getQrCodeImages(@RequestParam List q
 
 
     /// 페스티벌 주최자 QR 스캔
-    @Override
+    @PostMapping(value = "/validate/{qrCodeId}")
     public ResponseEntity> validateAndUseQrCode(
             @PathVariable String qrCodeId,
             Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/StatisticsController.java b/src/main/java/com/mnms/booking/controller/StatisticsController.java
index 8ff71f3..07928a3 100644
--- a/src/main/java/com/mnms/booking/controller/StatisticsController.java
+++ b/src/main/java/com/mnms/booking/controller/StatisticsController.java
@@ -29,13 +29,14 @@ public class StatisticsController implements StatisticsSpecification {
     private final StatisticsQrCodeService statisticsQrCodeService;
     private final StatisticsQueryService statisticsQueryService;
 
-    @Override
+    @GetMapping("/users/{festivalId}")
     public ResponseEntity> getFestivalUserStatistics(@PathVariable String festivalId) {
         StatisticsUserResponseDTO statistics = statisticsUserService.getFestivalUserStatistics(festivalId);
         return ApiResponseUtil.success(statistics, "예매자 통계 정보가 성공적으로 조회되었습니다.");
     }
 
-    @Override
+
+    @GetMapping("/schedules/{festivalId}")
     public ResponseEntity>> getPerformanceDatesForFestival(
             @PathVariable String festivalId,
             Authentication authentication) {
@@ -47,7 +48,8 @@ public ResponseEntity>> getPerformanceDatesF
         return ApiResponseUtil.success(performanceDates, "공연 날짜 목록이 성공적으로 조회되었습니다.");
     }
 
-    @Override
+
+    @GetMapping("/enter/{festivalId}")
     public ResponseEntity> getPerformanceEnterStatistics(
             @PathVariable String festivalId,
             @RequestParam("performanceDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime performanceDate,
@@ -63,7 +65,7 @@ public ResponseEntity> getPerforman
         return ApiResponseUtil.success(statistics, "공연 입장 통계 정보가 성공적으로 조회되었습니다.");
     }
 
-    @Override
+    @GetMapping("/booking/{festivalId}")
     public ResponseEntity>> getBookingSummary(
             @PathVariable String festivalId,
             Authentication authentication) {
diff --git a/src/main/java/com/mnms/booking/controller/TicketController.java b/src/main/java/com/mnms/booking/controller/TicketController.java
index f09a919..df95f34 100644
--- a/src/main/java/com/mnms/booking/controller/TicketController.java
+++ b/src/main/java/com/mnms/booking/controller/TicketController.java
@@ -22,13 +22,13 @@ public class TicketController implements TicketSpecification {
     private final TicketService ticketService;
     private final SecurityResponseUtil securityResponseUtil;
 
-    @Override
+    @GetMapping
     public ResponseEntity>> getUserTickets(Authentication authentication) {
         List tickets = ticketService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(tickets);
     }
 
-    @Override
+    @GetMapping("/detail")
     public ResponseEntity> getUserTicketDetail(@RequestParam String reservationNumber,
                                                                                         Authentication authentication) {
         TicketDetailResponseDTO ticket = ticketService.getTicketDetailByUser(reservationNumber, securityResponseUtil.requireUserId(authentication), securityResponseUtil.requireName(authentication));
diff --git a/src/main/java/com/mnms/booking/controller/TransferController.java b/src/main/java/com/mnms/booking/controller/TransferController.java
index 30230a4..deb3c05 100644
--- a/src/main/java/com/mnms/booking/controller/TransferController.java
+++ b/src/main/java/com/mnms/booking/controller/TransferController.java
@@ -35,8 +35,8 @@ public class TransferController implements TransferSpecification {
     private final SecurityResponseUtil securityResponseUtil;
     private final TransferCompletionService transferCompletionService;
 
-    ///  양도할 수 있는 티켓 조회
-    @Override
+
+    @GetMapping("/transferor")
     public ResponseEntity>> getUserTickets(Authentication authentication) {
         List tickets = transferService.getTicketsByUser(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(tickets);
@@ -44,7 +44,7 @@ public ResponseEntity>> getUserTickets(A
 
 
     ///  가족관계증명서 인증
-    @Override
+    @PostMapping("/extract")
     public ResponseEntity> extractPersonAuth(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -56,7 +56,8 @@ public ResponseEntity> extractPersonAuth(
         return ApiResponseUtil.success(null,"가족관계증명서 인증이 완료되었습니다.");
     }
 
-    @Override
+
+    @PostMapping("/extract/result")
     public ResponseEntity>> extractPersonInfo(
             @RequestPart("file") MultipartFile file,
             @RequestPart("targetInfo") String targetInfoJson) throws IOException {
@@ -71,7 +72,7 @@ public ResponseEntity>> extractPerso
 
 
     /// 양도 요청
-    @Override
+    @PostMapping("/request")
     public ResponseEntity> requestTransfer(
             @RequestBody @Valid TicketTransferRequestDTO dto,
             Authentication authentication
@@ -81,14 +82,14 @@ public ResponseEntity> requestTransfer(
     }
 
     /// 양도 요청 받기 (조회)
-    @Override
+    @GetMapping("/watch")
     public ResponseEntity>> watchTransfer(Authentication authentication){
         List response = transferService.watchTransfer(securityResponseUtil.requireUserId(authentication));
         return ApiResponseUtil.success(response);
     }
 
     /// 가족 간 양도 요청 승인
-    @Override
+    @PutMapping("/acceptance/family")
     public ResponseEntity> responseTicketFamily(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
@@ -97,7 +98,7 @@ public ResponseEntity> responseTicketFamily(
     }
 
     /// 지인간 양도 요청 승인
-    @Override
+    @PutMapping("/acceptance/others")
     public ResponseEntity> responseTicketOthers(
             @RequestBody UpdateTicketRequestDTO request,
             Authentication authentication) {
@@ -105,8 +106,9 @@ public ResponseEntity> responseTicket
         return ApiResponseUtil.success(response);
     }
 
+
     ///  Websocket 메시지 누락 방지 api요청
-    @Override
+    @GetMapping("/reservation/status")
     public ResponseEntity> checkStatus(@RequestParam Long transferId){
         return ApiResponseUtil.success(transferService.checkStatus(transferId));
     }
diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index fa5c3a3..12b48be 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -39,7 +39,7 @@ public class WaitingController implements WaitingSpecification {
     private SimpMessagingTemplate messagingTemplate;
 
     /// 예매하기 버튼(front) 클릭 시 호출되는 API
-    @Override
+    @GetMapping("/enter")
     public ResponseEntity> enterBookingPage(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
@@ -58,7 +58,7 @@ public ResponseEntity> enterBookingPag
     }
 
     /// 예매 페이지 퇴장
-    @Override
+    @GetMapping("/release")
     public ResponseEntity> releaseUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
@@ -76,7 +76,7 @@ public ResponseEntity> releaseUser(
     }
 
     /// 대기열에서 퇴장
-    @Override
+    @GetMapping("/exit")
     public ResponseEntity> exitWaitingUser(
             @RequestParam String festivalId,
             @RequestParam LocalDateTime reservationDate,
diff --git a/src/main/java/com/mnms/booking/specification/BookingSpecification.java b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
index 040ab69..14d67be 100644
--- a/src/main/java/com/mnms/booking/specification/BookingSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/BookingSpecification.java
@@ -69,7 +69,6 @@ ResponseEntity> getFestivalDetail(
             @Valid @RequestBody BookingSelectRequestDTO request);
 
     /// POST : 2차 예매 상세 조회
-    @PostMapping("/detail/phases/2")
     @Operation(summary = "2차 : 예매 단계에서 선택한 예매 상세 조회",
             description = "festivalId, reservationNumber로 공연 및 예매자 상세 정보를 조회합니다.")
     @ApiResponses({
@@ -123,7 +122,6 @@ ResponseEntity> getFestivalBookingDeta
     );
 
     /// POST : 날짜 선택
-    @PostMapping("/selectDate")
     @Operation(summary = "페스티벌 날짜, 시간, 매수 선택",
             description = "festivalId, performanceDate, selectedTicketCount를 입력하고 reservationNumber 반환")
     @ApiResponses({
@@ -203,7 +201,6 @@ ResponseEntity> selectFestivalDate(
     );
 
     /// POST : 배송 선택
-    @PostMapping("/selectDeliveryMethod")
     @Operation(summary = "페스티벌 티켓 수령 방법, 주소 선택",
             description = "festivalId, performanceDate, deliveryMethod(MOBILE or PAPER), address 선택")
     @ApiResponses({
@@ -296,7 +293,6 @@ ResponseEntity> selectFestivalDelivery(
     );
 
     /// POST : 3차 예매 완료 (QR 생성)
-    @PostMapping("/qr")
     @Operation(summary = "페스티벌 예매 티켓 생성",
             description = "사용자가 특정 페스티벌 티켓을 예약하기 위한 마지막 가예매 상태")
     @ApiResponses({
@@ -363,7 +359,6 @@ ResponseEntity> reserveTicket(
     );
 
     /// GET : WebSocket 메시지 누락 방지
-    @GetMapping("reservation/status")
     @Operation(summary = "예매 완료/취소 정보 조회",
             description = "WebSocket 메시지 누락 시 상태 확인")
     @ApiResponses({
@@ -388,7 +383,6 @@ ResponseEntity> reserveTicket(
     ResponseEntity> checkStatus(@RequestParam String reservationNumber);
 
     /// GET : 예매자 정보 조회
-    @GetMapping("/user/info")
     @Operation(summary = "예매자 정보 조회",
             description = "예매자 role이 user인 사람만 조회 가능")
     @ApiResponses({
@@ -414,7 +408,6 @@ ResponseEntity> reserveTicket(
 
 
     /// POST : 이메일 임시 테스트
-    @PostMapping("/email/test")
     @Operation(summary = "[테스트 진행X] 이메일 임시 테스트",
             description = "예매 완료 후 이메일 전송 임시 테스트")
     @ApiResponses({
diff --git a/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java b/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
index d7ed7e5..4387c65 100644
--- a/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/CaptchaSpecification.java
@@ -24,7 +24,7 @@
 @Tag(name = "보안문자 API", description = "보안문자 생성 및 인증")
 public interface CaptchaSpecification {
 
-    @GetMapping("/image")
+
     @Operation(
             summary = "보안문자 이미지 요청",
             description = "새로운 보안문자 이미지를 생성하여 반환합니다."
@@ -55,8 +55,6 @@ ResponseEntity> getCaptchaImage(
     ) throws IOException;
 
 
-
-    @PostMapping("/verify")
     @Operation(
             summary = "보안문자 검증",
             description = "사용자가 입력한 보안문자 값이 올바른지 검증합니다. " +
diff --git a/src/main/java/com/mnms/booking/specification/HostSpecification.java b/src/main/java/com/mnms/booking/specification/HostSpecification.java
index f61e26c..12e2364 100644
--- a/src/main/java/com/mnms/booking/specification/HostSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/HostSpecification.java
@@ -25,7 +25,6 @@
 @Tag(name = "주최자 관련 API", description = "주최자 예매자 명단 조회, 주최자 도메인 데이터 제공 API")
 public interface HostSpecification {
 
-    @PostMapping("/list")
     @Operation(
             summary = "주최자 도메인에 예매자 리스트 제공",
             description = "주최자가 FestivalId와 PerformanceDate를 제공하면 해당하는 예매자 userId 리스트를 반환합니다. (프론트와 직접 관련 없음)"
@@ -88,7 +87,8 @@ ResponseEntity>> getBookingsByOrganizer(
             @RequestBody HostRequestDTO hostRequestDTO
     );
 
-    @PostMapping("/booking/list")
+
+
     @Operation(
             summary = "예매자 정보 조회",
             description = "예매자 정보를 조회합니다. HOST 또는 ADMIN 권한이 필요합니다.",
diff --git a/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java b/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
index ebc705b..5d28c73 100644
--- a/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/QrCodeSpecification.java
@@ -19,7 +19,7 @@
 @Tag(name = "QR API", description = "QR 이미지 조회, 스캔")
 public interface QrCodeSpecification {
 
-    @GetMapping(value = "/image/{qrCodeId}", produces = "image/png")
+
     @Operation(summary = "QR 코드 이미지 조회", description = "qrCodeId로 QR 코드 이미지를 PNG 형식으로 반환합니다.")
     @ApiResponses(value = {
             @ApiResponse(
@@ -50,7 +50,8 @@ ResponseEntity getQrCodeImage(
             @PathVariable String qrCodeId
     );
 
-    @PostMapping(value = "/validate/{qrCodeId}")
+
+
     @Operation(summary = "QR 코드 스캔 및 유효성 검사", description = "qrCodeId와 사용자 ID로 QR 코드 유효성 검사 후 QR 사용 처리합니다.")
     @ApiResponses(value = {
             @ApiResponse(
diff --git a/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java b/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
index a695058..07bb6fe 100644
--- a/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/StatisticsSpecification.java
@@ -22,7 +22,6 @@
 @Tag(name = "통계 API", description = "공연 별 예매자의 정보를 통해 성별/나이, 입장 인원 상황을 확인 가능")
 public interface StatisticsSpecification {
 
-    @GetMapping("/users/{festivalId}")
     @Operation(summary = "festivalId별 예매자 성별/나이 통계 조회",
             description = "특정 페스티벌의 예매자 통계를 조회합니다.")
     @ApiResponses(value = {
@@ -46,7 +45,6 @@ public interface StatisticsSpecification {
 
 
 
-    @GetMapping("/schedules/{festivalId}")
     @Operation(summary = "공연 날짜/시간 목록 조회",
             description = "주최자가 입장 통계를 조회하기 전, 해당 페스티벌의 유효 공연 날짜/시간 목록 조회")
     @ApiResponses(value = {
@@ -73,7 +71,6 @@ ResponseEntity>> getPerformanceDatesForFesti
 
 
 
-    @GetMapping("/enter/{festivalId}")
     @Operation(summary = "공연 날짜별 입장 통계",
             description = "예매자 및 주최자가 공연 날짜별 현장 QR 입장 통계를 조회합니다.")
     @ApiResponses(value = {
@@ -127,7 +124,6 @@ ResponseEntity> getPerformanceEnter
 
 
 
-    @GetMapping("/booking/{festivalId}")
     @Operation(summary = "공연별 예매자 수 / 수용 인원 요약 조회",
             description = "주최자가 자신의 페스티벌 공연별 예매 현황과 총 수용 인원을 요약 조회")
     @ApiResponses(value = {
diff --git a/src/main/java/com/mnms/booking/specification/TicketSpecification.java b/src/main/java/com/mnms/booking/specification/TicketSpecification.java
index 8ce2b5c..f93c1e7 100644
--- a/src/main/java/com/mnms/booking/specification/TicketSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/TicketSpecification.java
@@ -20,7 +20,6 @@
 @Tag(name = "예매 내역 API", description = "예매 내역 조회")
 public interface TicketSpecification {
 
-    @GetMapping
     @Operation(summary = "예매한 티켓 정보 조회",
             description = "예매자가 예매 완료한 전체 티켓 리스트를 조회합니다. (status : 완료, 취소한 티켓 조회 가능)"
     )
@@ -68,7 +67,7 @@ public interface TicketSpecification {
     })
     ResponseEntity>> getUserTickets(Authentication authentication);
 
-    @GetMapping("/detail")
+
     @Operation(summary = "예매한 티켓 정보 디테일 조회",
             description = "예매자가 예매 완료한 티켓 정보를 조회합니다. ex : /api/ticket/detail?reservationNumber=T24CBD629 조회"
     )
diff --git a/src/main/java/com/mnms/booking/specification/TransferSpecification.java b/src/main/java/com/mnms/booking/specification/TransferSpecification.java
index a20a136..8b8bc26 100644
--- a/src/main/java/com/mnms/booking/specification/TransferSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/TransferSpecification.java
@@ -26,7 +26,7 @@
 @Tag(name = "양도 API", description = "양도 및 OCR, Ticket 재생성")
 public interface TransferSpecification {
 
-    @GetMapping("/transferor")
+    ///  양도할 수 있는 티켓 조회
     @Operation(summary = "양도 가능한 티켓 정보 조회",
             description = "사용자가 양도 가능한 티켓을 조회할 수 있습니다. (status : 양도 받은 티켓 양도 불가능)"
     )
@@ -75,24 +75,25 @@ public interface TransferSpecification {
     ResponseEntity>> getUserTickets(Authentication authentication);
 
 
+
+    ///  가족관계증명서 인증
+    @Operation(summary = "가족 간 양도 인증 시도",
+            description = "가족관계증명서 PDF와 양도자/양수자 정보로 인증을 시도합니다."
+    )
     @ApiResponse(responseCode = "406", description = "유효하지 않은 파일 첨부",
-                    content = @Content(
-                            mediaType = "application/json",
-                            schema = @Schema(implementation = ErrorResponse.class),
-                            examples = @ExampleObject(
-                                    value = """
+            content = @Content(
+                    mediaType = "application/json",
+                    schema = @Schema(implementation = ErrorResponse.class),
+                    examples = @ExampleObject(
+                            value = """
                                     {
                                       "success": false,
                                       "data": "TRANSFER_NOT_VALID_FILE_TYPE",
                                       "message": "유효하지 않은 파일 확장자입니다."
                                     }
                                     """
-                            )
                     )
-    )
-    @PostMapping("/extract")
-    @Operation(summary = "가족 간 양도 인증 시도",
-            description = "가족관계증명서 PDF와 양도자/양수자 정보로 인증을 시도합니다."
+            )
     )
     ResponseEntity> extractPersonAuth(
             @RequestPart("file") MultipartFile file,
@@ -101,7 +102,6 @@ ResponseEntity> extractPersonAuth(
 
 
 
-    @PostMapping("/extract/result")
     @Operation(summary = "가족 간 양도 인증 결과 조회",
             description = "인증 완료 후 양도 대상 정보와 함께 반환합니다."
     )
@@ -127,7 +127,6 @@ ResponseEntity>> extractPersonInfo(
 
 
 
-    @PostMapping("/request")
     @Operation(summary = "양도 요청",
             description = "양도자가 양도 요청을 보냅니다."
     )
@@ -205,7 +204,7 @@ ResponseEntity> requestTransfer(
     );
 
 
-    @GetMapping("/watch")
+
     @Operation(summary = "양도 요청 조회",
             description = "양수자가 자신에게 온 양도 요청을 조회합니다."
     )
@@ -281,7 +280,7 @@ ResponseEntity> requestTransfer(
 
 
 
-    @PutMapping("/acceptance/family")
+    /// 가족 간 양도 요청 승인
     @Operation(
             summary = "가족 간 양도 요청 수락",
             description = "양수자가 요청을 수락하면 티켓과 QR 정보가 업데이트 됩니다."
@@ -393,8 +392,7 @@ ResponseEntity> responseTicketFamily(
     );
 
 
-
-    @PutMapping("/acceptance/others")
+    /// 지인간 양도 요청 승인
     @Operation(summary = "타인 간 양도 요청 완료",
             description = "양수자가 요청을 수락하면 결제 진행 후 양도 완료됩니다."
     )
@@ -479,7 +477,7 @@ ResponseEntity> responseTicketOthers(
     );
 
 
-    @GetMapping("/reservation/status")
+    ///  Websocket 메시지 누락 방지 api요청
     @Operation(summary = "양도 결제 완료 조회",
             description = "Websocket 메시지 누락 시 양도 완료 여부 확인"
     )
diff --git a/src/main/java/com/mnms/booking/specification/WaitingSpecification.java b/src/main/java/com/mnms/booking/specification/WaitingSpecification.java
index e07c85a..df39932 100644
--- a/src/main/java/com/mnms/booking/specification/WaitingSpecification.java
+++ b/src/main/java/com/mnms/booking/specification/WaitingSpecification.java
@@ -22,7 +22,7 @@
 @Tag(name = "대기열 API", description = "대기열 입장, 예매 화면 입장, 대기번호 조회")
 public interface WaitingSpecification {
 
-        @GetMapping("/enter")
+
         @Operation(
                 summary = "예매 페이지 입장 요청",
                 description = "사용자가 예매 페이지에 입장하거나 대기열에 등록됩니다. " +
@@ -136,7 +136,6 @@ ResponseEntity> enterBookingPage(
 
 
 
-        @GetMapping("/release")
         @Operation(
                 summary = "예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)",
                 description = "예매 페이지에 있던 사용자가 퇴장했을 때 실행됩니다. " +
@@ -262,7 +261,6 @@ ResponseEntity> releaseUser(
                     )
             )
     })
-    @GetMapping("/exit")
     ResponseEntity> exitWaitingUser(
             @Parameter(description = "페스티벌 ID", required = true, example = "festival-001")
             @RequestParam String festivalId,

From e45317f4f4ecda9138f3265420f28815fba49060 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 12 Sep 2025 23:39:51 +0900
Subject: [PATCH 131/149] =?UTF-8?q?MNMS-632=20Fix:=20ttlMinutes=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

추후 ttlMinutes application.properties 변수값으로 받을것임
---
 .../booking/controller/WaitingController.java | 25 -------------------
 .../service/TempReservationService.java       | 14 +++++------
 src/main/resources/application-dev.properties |  3 +++
 3 files changed, 10 insertions(+), 32 deletions(-)

diff --git a/src/main/java/com/mnms/booking/controller/WaitingController.java b/src/main/java/com/mnms/booking/controller/WaitingController.java
index 12b48be..2e96fe7 100644
--- a/src/main/java/com/mnms/booking/controller/WaitingController.java
+++ b/src/main/java/com/mnms/booking/controller/WaitingController.java
@@ -3,8 +3,6 @@
 import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import com.mnms.booking.exception.global.SuccessResponse;
 import com.mnms.booking.service.FestivalService;
-import com.mnms.booking.service.WaitingNotificationService;
-import com.mnms.booking.service.WaitingQueueKeyGenerator;
 import com.mnms.booking.specification.WaitingSpecification;
 import com.mnms.booking.util.ApiResponseUtil;
 import com.mnms.booking.util.SecurityResponseUtil;
@@ -14,8 +12,6 @@
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
-import org.springframework.messaging.handler.annotation.Header;
-import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.security.core.Authentication;
 import org.springframework.web.bind.annotation.*;
@@ -31,8 +27,6 @@ public class WaitingController implements WaitingSpecification {
 
     private final WaitingService waitingService;
     private final FestivalService festivalService;
-    private final WaitingQueueKeyGenerator waitingQueueKeyGenerator;
-    private final WaitingNotificationService waitingNotificationService;
     private final SecurityResponseUtil securityResponseUtil;
 
     @Autowired
@@ -93,25 +87,6 @@ public ResponseEntity> exitWaitingUser(
         }
     }
 
-
-    /**
-     * WebSocket: 특정 사용자의 대기 순번 구독 엔드포인트
-     * 클라이언트가 /app/subscribe/waiting로 메시지를 보냄 (최초 구독 요청)
-     */
-    @MessageMapping("/subscribe/waiting")
-    public void subscribeWaitingQueue(
-            @Header("festivalId") String festivalId,
-            @Header("reservationDate") LocalDateTime reservationDate,
-            Authentication authentication) {
-        String userId = getUserId(authentication);
-        log.info("User {} subscribed to waiting queue updates.", userId);
-
-        String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
-        String notificationChannelKey = waitingQueueKeyGenerator.getNotificationChannelKey(festivalId, reservationDate);
-        waitingNotificationService.getAndPublishWaitingNumber(waitingQueueKey, notificationChannelKey, userId);
-    }
-
-
     public String getUserId(Authentication authentication) {
         return String.valueOf(securityResponseUtil.requireUserId(authentication));
     }
diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index 5cf5a4c..f7e8869 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.entity.Ticket;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -15,23 +16,22 @@ public class TempReservationService {
     private final RedisTemplate redisTemplate;
 
     private static final String PREFIX = "TEMP_RESERVATION:";
-    private static final long TTL_MINUTES = 100;
+    private static final long ttlMinutes = 2;
+
+//    @Value("${temp-reservation.ttl-minutes:3}")
+//    private long ttlMinutes;
 
     public void createTempReservation(Ticket ticket) {
         String key = PREFIX + ticket.getReservationNumber();
-        redisTemplate.opsForValue().set(key, ticket, TTL_MINUTES, TimeUnit.MINUTES);
+        redisTemplate.opsForValue().set(key, ticket, ttlMinutes, TimeUnit.MINUTES);
     }
 
     // 갱신
     public void refreshTempReservation(String reservationNumber) {
         String key = PREFIX + reservationNumber;
-
-        System.out.println("갱신하려는 key: " + key);
         Boolean exists = redisTemplate.hasKey(key);
-        System.out.println("exists? " + exists);
-
         if (Boolean.TRUE.equals(exists)) {
-            redisTemplate.expire(key, TTL_MINUTES, TimeUnit.MINUTES);
+            redisTemplate.expire(key, ttlMinutes, TimeUnit.MINUTES);
         }
     }
 
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 70dd00f..0dc0223 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -31,6 +31,9 @@ spring.kafka.consumer.properties.spring.json.use.type.headers=false
 spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 
+# 가예매 TTL
+#temp-reservation.ttl-minutes=3
+
 # Topic
 app.kafka.topic.festival-event=festival-topic
 app.kafka.topic.payment-event=payment-status-events

From 3f6804f0d52446609799940339c100bb79d7a3dc Mon Sep 17 00:00:00 2001
From: CECHERI <24cecheri@gmail.com>
Date: Mon, 15 Sep 2025 18:20:48 +0900
Subject: [PATCH 132/149] =?UTF-8?q?MNMS-679=20Bug:=20=EA=B3=B5=EC=97=B0=20?=
 =?UTF-8?q?=EB=B3=84=20=EC=98=88=EB=A7=A4=EC=9E=90=20=ED=86=B5=EA=B3=84=20?=
 =?UTF-8?q?=EB=B9=84=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=EC=9E=90=EB=8A=94=20?=
 =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EC=8B=A4=ED=8C=A8=20=EC=98=A4=EB=A5=98=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/security/HeaderAuthenticationFilter.java  | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
index f7a405f..be62d82 100644
--- a/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
+++ b/src/main/java/com/mnms/booking/security/HeaderAuthenticationFilter.java
@@ -56,7 +56,8 @@ protected void doFilterInternal(
                         || uri.equals("/swagger-ui.html")
                         || uri.startsWith("/actuator")
                         || uri.startsWith("/ws")
-                        || uri.startsWith("/api/host/list")) {
+                        || uri.startsWith("/api/host/list")
+                        || uri.startsWith("/api/statistics/users")) {
                     chain.doFilter(request, response);
                     return;
                 }

From 13ef6442416563ded1fb50552dbb2c0f1c9be364 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 15 Sep 2025 23:37:33 +0900
Subject: [PATCH 133/149] =?UTF-8?q?MNMS-632=20Fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

+ ticketPick추가
---
 .../com/mnms/booking/config/RedisConfig.java  |  9 +--
 .../mnms/booking/config/WebSocketConfig.java  | 53 ++++++++++++++++-
 .../response/TicketTransferResponseDTO.java   |  2 +
 .../security/StompConnectInterceptor.java     | 26 ++++++++
 .../mnms/booking/security/StompPrincipal.java | 16 +++++
 .../service/RedisMessageSubscriber.java       | 59 +++++++++++++++----
 .../service/WaitingNotificationService.java   |  4 +-
 .../mnms/booking/service/WaitingService.java  |  1 -
 .../templates/email/ticket-confirmation.txt   | 13 ----
 9 files changed, 152 insertions(+), 31 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
 create mode 100644 src/main/java/com/mnms/booking/security/StompPrincipal.java
 delete mode 100644 src/main/resources/templates/email/ticket-confirmation.txt

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 55bf5e9..5c84093 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -38,17 +38,18 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
         container.setConnectionFactory(connectionFactory);
 
         // waiting_notification:* 구독
-//        container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification:*"));
-//        log.info("Subscribed to Redis channels with pattern: waiting_notification:*");
+        container.addMessageListener(waitingNotificationListenerAdapter, new PatternTopic("waiting_notification/*"));
+        log.info("Subscribed to Redis channels with pattern: waiting_notification/*");
 
-        // Keyspace Notification 구독 (예매 완료 이벤트)
+        // Keyspace 구독 (예매 완료 이벤트)
         container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
-        container.addMessageListener(keyExpirationListener, new PatternTopic("waiting_notification:*"));
+        //container.addMessageListener(keyExpirationListener, new PatternTopic("waiting_notification:*"));
         log.info("Subscribed to Redis key expiration events");
 
         return container;
     }
 
+
     /// Redis 메시지를 받아 처리할 리스너 어댑터 (RedisMessageSubscriber와 연결)
     @Bean
     public MessageListenerAdapter listenerAdapter(RedisMessageSubscriber subscriber) {
diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index 7331acd..35bafab 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -1,15 +1,35 @@
 package com.mnms.booking.config;
 
+import com.mnms.booking.security.StompConnectInterceptor;
+import com.mnms.booking.security.StompPrincipal;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.messaging.simp.config.ChannelRegistration;
 import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.WebSocketSession;
 import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
 import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
 import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
+import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
+import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
+import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.UUID;
 
 @Configuration
 @EnableWebSocketMessageBroker
+@AllArgsConstructor
+@Slf4j
 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
+    private final StompConnectInterceptor stompConnectInterceptor;
+
     @Override
     public void configureMessageBroker(MessageBrokerRegistry config) {
         // 구독경로
@@ -19,11 +39,42 @@ public void configureMessageBroker(MessageBrokerRegistry config) {
         config.setUserDestinationPrefix("/user");
     }
 
+    @Override
+    public void configureClientInboundChannel(ChannelRegistration registration) {
+        registration.interceptors(stompConnectInterceptor);
+    }
+
+    // 이 방식은 그대로 유지
     @Override
     public void registerStompEndpoints(StompEndpointRegistry registry) {
-        // WebSocket 연결을 위한 endpoint 설정
         registry.addEndpoint("/ws")
+                .setHandshakeHandler(new DefaultHandshakeHandler() {
+                    @Override
+                    protected Principal determineUser(ServerHttpRequest request,
+                                                      WebSocketHandler wsHandler,
+                                                      Map attributes) {
+                        String userId = (String) attributes.get("userId");
+                        if (userId != null) {
+                            return new StompPrincipal(userId);
+                        }
+                        // userId가 없을 경우 익명 사용자 처리
+                        return new StompPrincipal("anonymous-" + UUID.randomUUID().toString());
+                    }
+                })
+                .addInterceptors(new HttpSessionHandshakeInterceptor())
                 .setAllowedOriginPatterns("*")
                 .withSockJS();
     }
+
+    // 디버깅용 : 추후 삭제
+    @Override
+    public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
+        registration.addDecoratorFactory(handler -> new WebSocketHandlerDecorator(handler) {
+            @Override
+            public void afterConnectionEstablished(WebSocketSession session) throws Exception {
+                super.afterConnectionEstablished(session);
+                log.info("WebSocket connection established: {}", session.getId());
+            }
+        });
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
index a081bc1..440721e 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketTransferResponseDTO.java
@@ -30,6 +30,7 @@ public class TicketTransferResponseDTO {
     private String posterFile;
     private String fcltynm;
     private int ticketPrice;
+    private int ticketPick;
 
     ///  TICKET
     private LocalDateTime performanceDate;
@@ -45,6 +46,7 @@ public static TicketTransferResponseDTO from(Transfer transfer, Ticket ticket, F
                 .createdAt(transfer.getCreatedAt())
                 .status(String.valueOf(transfer.getStatus()))
                 .fname(festival.getFname())
+                .ticketPick(festival.getTicketPick())
                 .posterFile(festival.getPosterFile())
                 .fcltynm(festival.getFcltynm())
                 .ticketPrice(festival.getTicketPrice())
diff --git a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
new file mode 100644
index 0000000..b8b345e
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
@@ -0,0 +1,26 @@
+package com.mnms.booking.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptor;
+import org.springframework.stereotype.Component;
+
+
+
+@Component
+@Slf4j
+public class StompConnectInterceptor implements ChannelInterceptor {
+    @Override
+    public Message preSend(Message message, MessageChannel channel) {
+        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+
+        // 추가 검증 목적
+        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
+            log.info("CONNECT intercepted for user: {}", accessor.getUser() != null ? accessor.getUser().getName() : "anonymous");
+        }
+        return message;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/StompPrincipal.java b/src/main/java/com/mnms/booking/security/StompPrincipal.java
new file mode 100644
index 0000000..f108631
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/StompPrincipal.java
@@ -0,0 +1,16 @@
+package com.mnms.booking.security;
+
+import java.security.Principal;
+
+public class StompPrincipal implements Principal {
+    private final String name;
+
+    public StompPrincipal(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 13624a5..7c724e5 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -1,14 +1,22 @@
 package com.mnms.booking.service;
 
-import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.mnms.booking.dto.response.WaitingNumberResponseDTO;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.messaging.simp.user.SimpSession;
+import org.springframework.messaging.simp.user.SimpUser;
+import org.springframework.messaging.simp.user.SimpUserRegistry;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-// MessageListener 인터페이스 구현
+import java.util.Collection;
+import java.util.Map;
+import java.util.Queue;
+import java.util.concurrent.*;
+
+
 @Service
 @Slf4j
 @RequiredArgsConstructor
@@ -17,23 +25,52 @@ public class RedisMessageSubscriber {
 
     private final SimpMessagingTemplate messagingTemplate; // WebSocket 메시지 전송
     private final ObjectMapper objectMapper; // JSON 파싱을 위한 ObjectMapper
+    private final SimpUserRegistry simpUserRegistry;
+
+
+    // 유저별 대기 메시지 큐
+    private final Map> pendingMessages = new ConcurrentHashMap<>();
+
 
-    // Redis로부터 메시지를 수신할 때 호출되는 메서드
+    // Redis로 메시지 수신할 때 호출됨
     public void onMessage(String message, String channel) {
-        // 채널 이름
-        log.info("channel name : {}", channel);
 
-        // message는 JSON 문자열 -> DTO로 변환
+        printConnectedUsers();
+
         try {
-            log.info("Received message from Redis channel: {}", message);
-            WaitingNumberResponseDTO dto = new ObjectMapper().readValue(message, WaitingNumberResponseDTO.class);
+            WaitingNumberResponseDTO dto = objectMapper.readValue(message, WaitingNumberResponseDTO.class);
+            log.info("Received message from Redis: {}", dto);
 
-            // userId 기준으로 메시지 전송
-            messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
-            log.info("Sent WebSocket message to user {}: {}", dto.getUserId(), dto.getWaitingNumber());
+            // 연결된 유저인지 확인
+            if (isUserConnected(dto.getUserId())) {
+                messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
+                log.info("Sent immediately to user {}", dto.getUserId());
+            } else {
+                log.info("User {} not connected, store for retry", dto.getUserId());
+                pendingMessages.computeIfAbsent(dto.getUserId(), k -> new ConcurrentLinkedQueue<>()).add(dto);
+            }
 
         } catch (Exception e) {
             log.error("예외 발생: {}", e.getMessage(), e);
         }
     }
+
+    private boolean isUserConnected(String userId) {
+        log.info("Sent immediately to simpUserRegistry user {}", simpUserRegistry.getUser(userId));
+        return simpUserRegistry.getUser(userId) != null;
+    }
+
+    // 디버깅용 : 추후 삭제
+    private void printConnectedUsers() {
+        Collection users = simpUserRegistry.getUsers();
+        log.info("Connected users count: {}", users.size());
+
+        for (SimpUser user : users) {
+            log.info("User name (Principal.name): {}", user.getName());
+            for (SimpSession session : user.getSessions()) {
+                log.info("  Session ID: {}", session.getId());
+                log.info("  Session Principal: {}", session.getUser().getName());
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index bf4c273..9779a9d 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -10,8 +10,8 @@
 import org.springframework.data.redis.RedisConnectionFailureException;
 import org.springframework.data.redis.RedisSystemException;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.stereotype.Service;
-
 import java.util.Set;
 
 @Service
@@ -22,6 +22,7 @@ public class WaitingNotificationService {
     private final StringRedisTemplate stringRedisTemplate;
     private final ObjectMapper objectMapper;
     private final WaitingQueueRedisService waitingQueueRedisService;
+    private final SimpMessagingTemplate messagingTemplate;
 
     /// 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
     public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {
@@ -47,6 +48,7 @@ private void publishWaitingNumber(String userId, long waitingNumber, String noti
 
             // message 발행
             stringRedisTemplate.convertAndSend(notificationChannelKey, message);
+
         } catch (JsonProcessingException e) {
             throw new BusinessException(ErrorCode.JSON_SERIALIZATION_FAILED);
         } catch (RedisConnectionFailureException e) {
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 88c8d0a..21d5d30 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -5,7 +5,6 @@
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
-
 import java.time.LocalDateTime;
 
 @Service
diff --git a/src/main/resources/templates/email/ticket-confirmation.txt b/src/main/resources/templates/email/ticket-confirmation.txt
deleted file mode 100644
index 59e75b3..0000000
--- a/src/main/resources/templates/email/ticket-confirmation.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-%s 님, 예매가 완료되었습니다.
-
-예매번호: %s
-공연명: %s
-공연일시: %s
-공연장: %s
-결제금액: %s원
-
-티켓 수령: %s (앱에서 확인 가능)
-입장 시 QR코드를 제시해 주세요.
-
-※ 취소 마감: 공연 전일 17시까지
-문의: 고객센터 1588-0000
\ No newline at end of file

From 93f52463f0434f32f11d6babb842cf87a39e5e3f Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 15 Sep 2025 23:59:50 +0900
Subject: [PATCH 134/149] =?UTF-8?q?MNMS-581=20Fix:=20=EC=98=88=EB=A7=A4=20?=
 =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EC=97=86=EC=9D=84=20=EB=95=8C=20NOTFOUND?=
 =?UTF-8?q?=EC=97=90=EC=84=9C=20200=20=EB=B9=88=20=EB=A6=AC=EC=8A=A4?=
 =?UTF-8?q?=ED=8A=B8=EB=A1=9C=20=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/service/TicketService.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index 5128f29..460f226 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -12,6 +12,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
@@ -34,7 +35,7 @@ public List getTicketsByUser(Long userId) {
         List tickets = ticketRepository.findByUserIdAndReservationStatusIn(userId, statuses);
 
         if(tickets.isEmpty()){
-            throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
+            return Collections.emptyList();
         }
         return tickets.stream()
                 .sorted(Comparator.comparing(Ticket::getReservationDate).reversed())

From f8f728be2020e7cfffddcc0d3a3a217b991c4cef Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 00:16:35 +0900
Subject: [PATCH 135/149] =?UTF-8?q?MNMS-581=20Fix:=20QR=20=EC=82=AC?=
 =?UTF-8?q?=EC=9A=A9=ED=96=88=EC=9D=84=20=EB=95=8C=20=EC=96=91=EB=8F=84=20?=
 =?UTF-8?q?=EB=B6=88=EA=B0=80=EB=8A=A5=20=ED=95=98=EB=8F=84=EB=A1=9D=20?=
 =?UTF-8?q?=EC=88=98=EC=A0=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/mnms/booking/repository/QrCodeRepository.java | 2 ++
 .../java/com/mnms/booking/service/TransferService.java     | 7 +++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index a537017..d38a672 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -21,6 +21,8 @@ public interface QrCodeRepository extends JpaRepository {
     // 특정 페스티벌의 특정 공연 날짜에 입장(used=true)한 인원 수를 집계
     @Query("SELECT COUNT(q) FROM QrCode q JOIN q.ticket t WHERE q.used = true AND t.festival.festivalId = :festivalId AND t.performanceDate = :performanceDate")
     int countAdmittedAttendees(@Param("festivalId") String festivalId, @Param("performanceDate") LocalDateTime performanceDate);;
+
+    boolean existsByTicketIdAndUsedTrue(Long ticketId);
 }
 
 
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 5c42486..73f103d 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -11,6 +11,7 @@
 import com.mnms.booking.enums.TransferType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.repository.TransferRepository;
 import jakarta.validation.Valid;
@@ -20,6 +21,7 @@
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
+import java.util.Collections;
 import java.util.List;
 
 @Service
@@ -30,19 +32,20 @@ public class TransferService {
 
     private final TicketRepository ticketRepository;
     private final TransferRepository transferRepository;
+    private final QrCodeRepository qrCodeRepository;
 
     ///  양도 가능한 티켓 조회
     public List getTicketsByUser(Long userId) {
 
         List tickets = ticketRepository.findByUserIdAndReservationStatus(userId, ReservationStatus.CONFIRMED);
         if(tickets.isEmpty()){
-            throw new BusinessException(ErrorCode.TICKET_NOT_FOUND);
+            return Collections.emptyList();
         }
-        log.info("tickets : {}", tickets);
 
         return tickets.stream()
                 .filter(ticket -> ticket.getPerformanceDate().isAfter(LocalDateTime.now()))
                 .filter(ticket -> !transferRepository.existsByTicketId(ticket.getId()))
+                .filter(ticket -> !qrCodeRepository.existsByTicketIdAndUsedTrue(ticket.getId()))
                 .map(ticket -> TicketResponseDTO.fromEntity(ticket, ticket.getFestival()))
                 .toList();
     }

From 72199710b706246307a879329d1c72f567d99b79 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 00:29:54 +0900
Subject: [PATCH 136/149] =?UTF-8?q?MNMS-581=20Chore:=20QR=20=EC=98=88?=
 =?UTF-8?q?=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=88=9C=EC=84=9C=EB=A7=8C=20?=
 =?UTF-8?q?=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/mnms/booking/service/QrCodeService.java | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/QrCodeService.java b/src/main/java/com/mnms/booking/service/QrCodeService.java
index 3730860..6d60185 100644
--- a/src/main/java/com/mnms/booking/service/QrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/QrCodeService.java
@@ -66,13 +66,8 @@ public void validateAndUseQrCode(Long userId, String qrCodeId) {
         QrCode qrCode = qrCodeRepository.findByQrCodeId(qrCodeId)
                 .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
 
-        // QR 코드에 연결된 티켓과 페스티벌 확인
-        Ticket ticket = qrCode.getTicket();
-        if (ticket == null || ticket.getFestival() == null) {
-            throw new BusinessException(ErrorCode.QR_CODE_INVALID);
-        }
-
         // 주최자 확인
+        Ticket ticket = qrCode.getTicket();
         if (!ticket.getFestival().getOrganizer().equals(userId)) {
             throw new BusinessException(ErrorCode.FESTIVAL_MISMATCH);
         }
@@ -87,6 +82,11 @@ public void validateAndUseQrCode(Long userId, String qrCodeId) {
             throw new BusinessException(ErrorCode.QR_CODE_ALREADY_USED);
         }
 
+        // QR 코드에 연결된 티켓과 페스티벌 확인
+        if (ticket == null || ticket.getFestival() == null) {
+            throw new BusinessException(ErrorCode.QR_CODE_INVALID);
+        }
+
         // QR 코드 사용 처리
         qrCode.markAsUsed();
     }

From 1db97acf3f1e7b6beb2682bcb5266eb92f92627c Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 10:51:47 +0900
Subject: [PATCH 137/149] =?UTF-8?q?MNMS-581=20Fix:=20websocket=20=EB=B3=80?=
 =?UTF-8?q?=EA=B2=BD=20=EC=82=AC=ED=95=AD=20=EC=9D=BC=EB=B6=80=20=EB=B3=B5?=
 =?UTF-8?q?=EA=B7=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mnms/booking/config/WebSocketConfig.java  | 50 -------------------
 .../security/StompConnectInterceptor.java     | 26 ----------
 .../mnms/booking/security/StompPrincipal.java | 16 ------
 .../service/RedisMessageSubscriber.java       |  2 +-
 .../service/WaitingNotificationService.java   |  1 -
 5 files changed, 1 insertion(+), 94 deletions(-)
 delete mode 100644 src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
 delete mode 100644 src/main/java/com/mnms/booking/security/StompPrincipal.java

diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index 35bafab..df86ba0 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -1,35 +1,17 @@
 package com.mnms.booking.config;
 
-import com.mnms.booking.security.StompConnectInterceptor;
-import com.mnms.booking.security.StompPrincipal;
-import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.messaging.simp.config.ChannelRegistration;
 import org.springframework.messaging.simp.config.MessageBrokerRegistry;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.WebSocketSession;
 import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
 import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
 import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
-import org.springframework.web.socket.config.annotation.WebSocketTransportRegistration;
-import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
-import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
-import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
-
-import java.security.Principal;
-import java.util.Map;
-import java.util.UUID;
 
 @Configuration
 @EnableWebSocketMessageBroker
-@AllArgsConstructor
 @Slf4j
 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
-    private final StompConnectInterceptor stompConnectInterceptor;
-
     @Override
     public void configureMessageBroker(MessageBrokerRegistry config) {
         // 구독경로
@@ -39,42 +21,10 @@ public void configureMessageBroker(MessageBrokerRegistry config) {
         config.setUserDestinationPrefix("/user");
     }
 
-    @Override
-    public void configureClientInboundChannel(ChannelRegistration registration) {
-        registration.interceptors(stompConnectInterceptor);
-    }
-
-    // 이 방식은 그대로 유지
     @Override
     public void registerStompEndpoints(StompEndpointRegistry registry) {
         registry.addEndpoint("/ws")
-                .setHandshakeHandler(new DefaultHandshakeHandler() {
-                    @Override
-                    protected Principal determineUser(ServerHttpRequest request,
-                                                      WebSocketHandler wsHandler,
-                                                      Map attributes) {
-                        String userId = (String) attributes.get("userId");
-                        if (userId != null) {
-                            return new StompPrincipal(userId);
-                        }
-                        // userId가 없을 경우 익명 사용자 처리
-                        return new StompPrincipal("anonymous-" + UUID.randomUUID().toString());
-                    }
-                })
-                .addInterceptors(new HttpSessionHandshakeInterceptor())
                 .setAllowedOriginPatterns("*")
                 .withSockJS();
     }
-
-    // 디버깅용 : 추후 삭제
-    @Override
-    public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
-        registration.addDecoratorFactory(handler -> new WebSocketHandlerDecorator(handler) {
-            @Override
-            public void afterConnectionEstablished(WebSocketSession session) throws Exception {
-                super.afterConnectionEstablished(session);
-                log.info("WebSocket connection established: {}", session.getId());
-            }
-        });
-    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
deleted file mode 100644
index b8b345e..0000000
--- a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.mnms.booking.security;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.simp.stomp.StompCommand;
-import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
-import org.springframework.messaging.support.ChannelInterceptor;
-import org.springframework.stereotype.Component;
-
-
-
-@Component
-@Slf4j
-public class StompConnectInterceptor implements ChannelInterceptor {
-    @Override
-    public Message preSend(Message message, MessageChannel channel) {
-        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
-
-        // 추가 검증 목적
-        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
-            log.info("CONNECT intercepted for user: {}", accessor.getUser() != null ? accessor.getUser().getName() : "anonymous");
-        }
-        return message;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/StompPrincipal.java b/src/main/java/com/mnms/booking/security/StompPrincipal.java
deleted file mode 100644
index f108631..0000000
--- a/src/main/java/com/mnms/booking/security/StompPrincipal.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.mnms.booking.security;
-
-import java.security.Principal;
-
-public class StompPrincipal implements Principal {
-    private final String name;
-
-    public StompPrincipal(String name) {
-        this.name = name;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 7c724e5..a4e341d 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -43,7 +43,7 @@ public void onMessage(String message, String channel) {
 
             // 연결된 유저인지 확인
             if (isUserConnected(dto.getUserId())) {
-                messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
+                messagingTemplate.convertAndSendToUser(String.valueOf(dto.getUserId()), "/queue/waitingNumbr", dto);
                 log.info("Sent immediately to user {}", dto.getUserId());
             } else {
                 log.info("User {} not connected, store for retry", dto.getUserId());
diff --git a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
index 9779a9d..8fb3142 100644
--- a/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingNotificationService.java
@@ -22,7 +22,6 @@ public class WaitingNotificationService {
     private final StringRedisTemplate stringRedisTemplate;
     private final ObjectMapper objectMapper;
     private final WaitingQueueRedisService waitingQueueRedisService;
-    private final SimpMessagingTemplate messagingTemplate;
 
     /// 사용자 대기 순번 조회 및 Redis Pub/Sub으로 발행
     public long getAndPublishWaitingNumber(String waitingQueueKey, String notificationChannelKey, String loginId) {

From 67953f3ce7f9466e2bc396106a507cddab8f415a Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 13:52:24 +0900
Subject: [PATCH 138/149] =?UTF-8?q?MNMS-691=20fix:=20=EB=8C=80=EA=B8=B0?=
 =?UTF-8?q?=EC=97=B4=20=EA=B8=B4=EA=B8=89=20commit?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../security/StompConnectInterceptor.java     | 31 +++++++++++++++++++
 .../mnms/booking/security/StompPrincipal.java | 17 ++++++++++
 .../service/RedisMessageSubscriber.java       |  2 +-
 .../booking/util/SecurityResponseUtil.java    |  2 --
 4 files changed, 49 insertions(+), 3 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
 create mode 100644 src/main/java/com/mnms/booking/security/StompPrincipal.java

diff --git a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
new file mode 100644
index 0000000..83cb508
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
@@ -0,0 +1,31 @@
+package com.mnms.booking.security;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
+import org.springframework.messaging.support.ChannelInterceptor;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class StompConnectInterceptor implements ChannelInterceptor {
+    @Override
+    public Message preSend(Message message, MessageChannel channel) {
+        log.info("Before STOMP Principal set for message {}", message);
+        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
+
+        if (StompCommand.CONNECT.equals(accessor.getCommand())) {
+            String userId = accessor.getFirstNativeHeader("userId");
+
+            // 여기서 STOMP 세션에 userId으로 등록
+            if (userId != null) {
+                // STOMP 세션에 Principal 세팅
+                accessor.setUser(new StompPrincipal(userId));
+                log.info("STOMP Principal set for userId: {}", userId);
+            }
+        }
+        return message;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/StompPrincipal.java b/src/main/java/com/mnms/booking/security/StompPrincipal.java
new file mode 100644
index 0000000..a766c31
--- /dev/null
+++ b/src/main/java/com/mnms/booking/security/StompPrincipal.java
@@ -0,0 +1,17 @@
+package com.mnms.booking.security;
+
+
+import java.security.Principal;
+
+public class StompPrincipal implements Principal {
+    private final String name;
+
+    public StompPrincipal(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index a4e341d..7c724e5 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -43,7 +43,7 @@ public void onMessage(String message, String channel) {
 
             // 연결된 유저인지 확인
             if (isUserConnected(dto.getUserId())) {
-                messagingTemplate.convertAndSendToUser(String.valueOf(dto.getUserId()), "/queue/waitingNumbr", dto);
+                messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
                 log.info("Sent immediately to user {}", dto.getUserId());
             } else {
                 log.info("User {} not connected, store for retry", dto.getUserId());
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
index 142765d..4ec6931 100644
--- a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -7,8 +7,6 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.oauth2.jwt.Jwt;
-import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
 import org.springframework.stereotype.Component;
 
 import java.util.List;

From 6350da1cb77859664c0fd150cfaf3a06813e66b4 Mon Sep 17 00:00:00 2001
From: rookies-dogun 
Date: Tue, 16 Sep 2025 16:04:58 +0900
Subject: [PATCH 139/149] MNMS-691 feat: add websocket

---
 .../mnms/booking/config/WebSocketConfig.java  | 10 +++++
 .../security/StompConnectInterceptor.java     | 37 +++++++++++++++----
 2 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index df86ba0..b14a8f9 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -1,7 +1,10 @@
 package com.mnms.booking.config;
 
+import com.mnms.booking.security.StompConnectInterceptor;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.ChannelRegistration;
 import org.springframework.messaging.simp.config.MessageBrokerRegistry;
 import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
 import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@@ -9,9 +12,11 @@
 
 @Configuration
 @EnableWebSocketMessageBroker
+@RequiredArgsConstructor
 @Slf4j
 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
+    private final StompConnectInterceptor  interceptors;
     @Override
     public void configureMessageBroker(MessageBrokerRegistry config) {
         // 구독경로
@@ -27,4 +32,9 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
                 .setAllowedOriginPatterns("*")
                 .withSockJS();
     }
+
+    @Override
+    public void configureClientInboundChannel(ChannelRegistration registration) {
+        registration.interceptors(interceptors);
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
index 83cb508..ec790b2 100644
--- a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
+++ b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
@@ -6,26 +6,49 @@
 import org.springframework.messaging.simp.stomp.StompCommand;
 import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
 import org.springframework.messaging.support.ChannelInterceptor;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.stereotype.Component;
+import org.springframework.security.core.Authentication;
+import java.security.Principal;
+import java.util.List;
 
 @Component
 @Slf4j
 public class StompConnectInterceptor implements ChannelInterceptor {
     @Override
     public Message preSend(Message message, MessageChannel channel) {
-        log.info("Before STOMP Principal set for message {}", message);
+        // STOMP 메시지 접근
         StompHeaderAccessor accessor = StompHeaderAccessor.wrap(message);
 
         if (StompCommand.CONNECT.equals(accessor.getCommand())) {
-            String userId = accessor.getFirstNativeHeader("userId");
+            String userId = accessor.getFirstNativeHeader("X-User-Id");
+            String userName = accessor.getFirstNativeHeader("X-User-Name");
+            String role = accessor.getFirstNativeHeader("X-User-Role");
 
-            // 여기서 STOMP 세션에 userId으로 등록
-            if (userId != null) {
-                // STOMP 세션에 Principal 세팅
-                accessor.setUser(new StompPrincipal(userId));
-                log.info("STOMP Principal set for userId: {}", userId);
+            log.info("[STOMP CONNECT] X-User-Id={}, X-User-Name={}, X-User-Role={}", userId, userName, role);
+
+            if (userId != null && role != null) {
+                Authentication auth = new UsernamePasswordAuthenticationToken(
+                        userId,
+                        null,
+                        List.of(new SimpleGrantedAuthority(role))
+                );
+
+                accessor.setUser(auth);
+                log.info("[STOMP CONNECT] Authentication 등록 완료: {}", auth);
             }
         }
+
+        Principal principal = accessor.getUser();
+        if (principal != null) {
+            Authentication auth = (Authentication) principal;
+            log.info("[STOMP MESSAGE] UserId={}, Roles={}", auth.getName(), auth.getAuthorities());
+        }
+
         return message;
     }
+
+
+
 }
\ No newline at end of file

From 0a7b4ae9379372cf6f2f1f5f3e2aa3fdbae26aaf Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 21:52:54 +0900
Subject: [PATCH 140/149] =?UTF-8?q?MNMS-691=20feat:=20websocket=20?=
 =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/config/WebSocketConfig.java   | 2 --
 .../com/mnms/booking/security/StompConnectInterceptor.java   | 3 ---
 .../java/com/mnms/booking/service/BookingCommandService.java | 1 +
 .../java/com/mnms/booking/service/BookingStatusService.java  | 2 +-
 .../com/mnms/booking/service/RedisMessageSubscriber.java     | 5 -----
 .../com/mnms/booking/service/TempReservationService.java     | 2 +-
 6 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/WebSocketConfig.java b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
index b14a8f9..ec88eee 100644
--- a/src/main/java/com/mnms/booking/config/WebSocketConfig.java
+++ b/src/main/java/com/mnms/booking/config/WebSocketConfig.java
@@ -2,7 +2,6 @@
 
 import com.mnms.booking.security.StompConnectInterceptor;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.messaging.simp.config.ChannelRegistration;
 import org.springframework.messaging.simp.config.MessageBrokerRegistry;
@@ -13,7 +12,6 @@
 @Configuration
 @EnableWebSocketMessageBroker
 @RequiredArgsConstructor
-@Slf4j
 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
 
     private final StompConnectInterceptor  interceptors;
diff --git a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
index ec790b2..c30b891 100644
--- a/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
+++ b/src/main/java/com/mnms/booking/security/StompConnectInterceptor.java
@@ -48,7 +48,4 @@ public Message preSend(Message message, MessageChannel channel) {
 
         return message;
     }
-
-
-
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 1de12f8..3c34616 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -13,6 +13,7 @@
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index bde3757..fad9a75 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -40,7 +40,7 @@
 public class BookingStatusService {
 
     private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
-    private static final int TEMP_RESERVATION_TTL_MINUTES = 20; // 가예매 유지 시간
+    private static final int TEMP_RESERVATION_TTL_MINUTES = 1; // 가예매 유지 시간
 
     private final TicketRepository ticketRepository;
     private final QrCodeRepository qrCodeRepository;
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 7c724e5..3ad8430 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -39,24 +39,19 @@ public void onMessage(String message, String channel) {
 
         try {
             WaitingNumberResponseDTO dto = objectMapper.readValue(message, WaitingNumberResponseDTO.class);
-            log.info("Received message from Redis: {}", dto);
 
             // 연결된 유저인지 확인
             if (isUserConnected(dto.getUserId())) {
                 messagingTemplate.convertAndSendToUser(dto.getUserId(), "/queue/waitingNumber", dto);
-                log.info("Sent immediately to user {}", dto.getUserId());
             } else {
-                log.info("User {} not connected, store for retry", dto.getUserId());
                 pendingMessages.computeIfAbsent(dto.getUserId(), k -> new ConcurrentLinkedQueue<>()).add(dto);
             }
-
         } catch (Exception e) {
             log.error("예외 발생: {}", e.getMessage(), e);
         }
     }
 
     private boolean isUserConnected(String userId) {
-        log.info("Sent immediately to simpUserRegistry user {}", simpUserRegistry.getUser(userId));
         return simpUserRegistry.getUser(userId) != null;
     }
 
diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index f7e8869..2e9656e 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -16,7 +16,7 @@ public class TempReservationService {
     private final RedisTemplate redisTemplate;
 
     private static final String PREFIX = "TEMP_RESERVATION:";
-    private static final long ttlMinutes = 2;
+    private static final long ttlMinutes = 1;
 
 //    @Value("${temp-reservation.ttl-minutes:3}")
 //    private long ttlMinutes;

From 91720a7ea7b41866f9926984e366986c8969a272 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Tue, 16 Sep 2025 22:40:40 +0900
Subject: [PATCH 141/149] =?UTF-8?q?MNMS-691=20fix:=20=EC=82=AD=EC=A0=9C?=
 =?UTF-8?q?=EB=90=9C=20email=20=ED=85=9C=ED=94=8C=EB=A6=BF=20=EC=B6=94?=
 =?UTF-8?q?=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../templates/email/ticket-confirmation.txt         | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 src/main/resources/templates/email/ticket-confirmation.txt

diff --git a/src/main/resources/templates/email/ticket-confirmation.txt b/src/main/resources/templates/email/ticket-confirmation.txt
new file mode 100644
index 0000000..59e75b3
--- /dev/null
+++ b/src/main/resources/templates/email/ticket-confirmation.txt
@@ -0,0 +1,13 @@
+%s 님, 예매가 완료되었습니다.
+
+예매번호: %s
+공연명: %s
+공연일시: %s
+공연장: %s
+결제금액: %s원
+
+티켓 수령: %s (앱에서 확인 가능)
+입장 시 QR코드를 제시해 주세요.
+
+※ 취소 마감: 공연 전일 17시까지
+문의: 고객센터 1588-0000
\ No newline at end of file

From 28d8ec5dc9f79a93e74ed17192d93b718e255539 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 17 Sep 2025 11:08:05 +0900
Subject: [PATCH 142/149] =?UTF-8?q?MNMS-691=20Feat:=20websocket=20front=20?=
 =?UTF-8?q?->=20back=20=ED=86=B5=EC=8B=A0=20controller=20=EC=9E=91?=
 =?UTF-8?q?=EC=84=B1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/BookingEventController.java    | 54 +++++++++++++++++++
 .../dto/request/LeaveQueueRequestDTO.java     | 14 +++++
 .../dto/response/TicketDetailResponseDTO.java |  6 ++-
 .../booking/repository/QrCodeRepository.java  |  1 +
 .../mnms/booking/service/TicketService.java   |  9 +++-
 5 files changed, 82 insertions(+), 2 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/controller/BookingEventController.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/LeaveQueueRequestDTO.java

diff --git a/src/main/java/com/mnms/booking/controller/BookingEventController.java b/src/main/java/com/mnms/booking/controller/BookingEventController.java
new file mode 100644
index 0000000..8060749
--- /dev/null
+++ b/src/main/java/com/mnms/booking/controller/BookingEventController.java
@@ -0,0 +1,54 @@
+package com.mnms.booking.controller;
+
+import com.mnms.booking.dto.request.LeaveQueueRequestDTO;
+import com.mnms.booking.service.WaitingService;
+import com.mnms.booking.util.ApiResponseUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpStatus;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.stereotype.Controller;
+
+import java.security.Principal;
+
+/// front -> back websocket 소통을 위한 controller입니다.
+
+@RequiredArgsConstructor
+@Slf4j
+@Controller
+public class BookingEventController {
+
+    private final WaitingService waitingService;
+
+    // /app/queue/waiting/leave로 front 메시지 보내기
+    // 대기열에서 나갈 때
+    @MessageMapping("/queue/waiting/leave")
+    public void leaveWaitingQueue(LeaveQueueRequestDTO request, Principal principal) {
+        try {
+            String userId = principal.getName();
+            boolean removed = waitingService.removeUserFromQueue(request.getFestivalId(), request.getReservationDate(), userId);
+            if (removed) {
+                log.info("대기하던 사용자가 대기열을 나갔습니다."); // 일단 테스트로 log 추가 - 추후 변경 예정
+            } else {
+                log.info("해당 사용자는 대기열 목록에 없습니다.");
+            }
+        } catch (Exception e) {
+            log.info("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+        }
+    }
+
+    // 예매 페이지에서 퇴장
+    @MessageMapping("/queue/reservation/leave")
+    public void leaveReservationQueue(LeaveQueueRequestDTO request) {
+        try {
+            boolean removed = waitingService.userExitBookingPage(request.getFestivalId(), request.getReservationDate(), request.getUserId());
+            if (removed) {
+                log.info("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
+            } else {
+                log.info("해당 사용자는 예매 사용자 목록에 없습니다.");
+            }
+        } catch (Exception e) {
+                log.info("서버 오류로 인해 사용자를 처리하지 못했습니다.");
+        }
+    }
+}
diff --git a/src/main/java/com/mnms/booking/dto/request/LeaveQueueRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/LeaveQueueRequestDTO.java
new file mode 100644
index 0000000..b4e8eea
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/LeaveQueueRequestDTO.java
@@ -0,0 +1,14 @@
+package com.mnms.booking.dto.request;
+
+import lombok.Data;
+import lombok.Getter;
+
+import java.time.LocalDateTime;
+
+@Data
+@Getter
+public class LeaveQueueRequestDTO {
+    private String festivalId;
+    private LocalDateTime reservationDate;
+    private String userId;
+}
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index 1eb7e7b..ffb2635 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -32,7 +32,10 @@ public class TicketDetailResponseDTO {
     private String fcltynm; // 장소
     private int ticketPrice; // 1매 티켓 가격
 
-    public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival, String userName) {
+    // qr
+    private boolean qrUsed;
+
+    public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festival, String userName, boolean qrUsed) {
         List qrIds = ticket.getQrCodes().stream()
                 .map(QrCode::getQrCodeId)
                 .toList();
@@ -45,6 +48,7 @@ public static TicketDetailResponseDTO fromEntity(Ticket ticket, Festival festiva
                 .deliveryMethod(ticket.getDeliveryMethod())
                 .address(ticket.getAddress())
                 .qrId(qrIds)
+                .qrUsed(qrUsed)
                 .festivalId(festival.getFestivalId())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index d38a672..db986d0 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -23,6 +23,7 @@ public interface QrCodeRepository extends JpaRepository {
     int countAdmittedAttendees(@Param("festivalId") String festivalId, @Param("performanceDate") LocalDateTime performanceDate);;
 
     boolean existsByTicketIdAndUsedTrue(Long ticketId);
+    boolean existsByTicket_IdAndUsedTrue(Long ticketId);
 }
 
 
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index 460f226..23fa29c 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -6,6 +6,7 @@
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -23,6 +24,7 @@
 public class TicketService {
 
     private final TicketRepository ticketRepository;
+    private final QrCodeRepository qrCodeRepository;
 
     // 예매 리스트 기본 조회
     public List getTicketsByUser(Long userId) {
@@ -48,9 +50,14 @@ public TicketDetailResponseDTO getTicketDetailByUser(String reservationNumber, L
         Ticket ticket = ticketRepository.findByUserIdAndReservationNumber(userId, reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
+        log.info("ticket id : {}", ticket.getId());
+        boolean qrUsed = qrCodeRepository.existsByTicket_IdAndUsedTrue(ticket.getId());
+
+        log.info("qr used : {}", qrUsed);
+
         if (!ticket.getUserId().equals(userId)) {
             throw new BusinessException(ErrorCode.USER_UNAUTHORIZED_ACCESS);
         }
-        return TicketDetailResponseDTO.fromEntity(ticket, ticket.getFestival(), userName);
+        return TicketDetailResponseDTO.fromEntity(ticket, ticket.getFestival(), userName, qrUsed);
     }
 }

From d08a59d5baca2d1f50eef150b91c76150d727d04 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Wed, 17 Sep 2025 17:04:46 +0900
Subject: [PATCH 143/149] =?UTF-8?q?MNMS-691=20Fix:=20=EA=B0=80=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20=EC=83=81=ED=83=9C=20=EC=88=98=EC=A0=95=20=EB=B0=8F?=
 =?UTF-8?q?=20websocket=20=EC=82=AD=EC=A0=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

가예매 1일 때 자동 삭제 안되는 오류 해결
예매 완료 websocket 코드 삭제
---
 .../com/mnms/booking/config/RedisConfig.java    |  1 -
 .../controller/BookingEventController.java      |  7 +++----
 .../java/com/mnms/booking/entity/Ticket.java    | 10 +++++++++-
 .../booking/repository/QrCodeRepository.java    |  3 ++-
 .../booking/service/BookingCommandService.java  |  5 +----
 .../booking/service/BookingStatusService.java   |  7 +------
 .../booking/service/KeyExpirationListener.java  | 17 ++++++++++++++++-
 .../booking/service/RedisMessageSubscriber.java |  1 -
 .../service/TransferCompletionService.java      | 14 ++++++++++----
 .../service/WaitingQueueRedisService.java       |  5 ++---
 .../mnms/booking/service/WaitingService.java    |  8 ++------
 11 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/src/main/java/com/mnms/booking/config/RedisConfig.java b/src/main/java/com/mnms/booking/config/RedisConfig.java
index 5c84093..9c11fb9 100644
--- a/src/main/java/com/mnms/booking/config/RedisConfig.java
+++ b/src/main/java/com/mnms/booking/config/RedisConfig.java
@@ -43,7 +43,6 @@ public RedisMessageListenerContainer redisMessageListenerContainer(
 
         // Keyspace 구독 (예매 완료 이벤트)
         container.addMessageListener(keyExpirationListener, new PatternTopic("__keyevent@0__:expired"));
-        //container.addMessageListener(keyExpirationListener, new PatternTopic("waiting_notification:*"));
         log.info("Subscribed to Redis key expiration events");
 
         return container;
diff --git a/src/main/java/com/mnms/booking/controller/BookingEventController.java b/src/main/java/com/mnms/booking/controller/BookingEventController.java
index 8060749..d149a58 100644
--- a/src/main/java/com/mnms/booking/controller/BookingEventController.java
+++ b/src/main/java/com/mnms/booking/controller/BookingEventController.java
@@ -2,10 +2,8 @@
 
 import com.mnms.booking.dto.request.LeaveQueueRequestDTO;
 import com.mnms.booking.service.WaitingService;
-import com.mnms.booking.util.ApiResponseUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.HttpStatus;
 import org.springframework.messaging.handler.annotation.MessageMapping;
 import org.springframework.stereotype.Controller;
 
@@ -39,9 +37,10 @@ public void leaveWaitingQueue(LeaveQueueRequestDTO request, Principal principal)
 
     // 예매 페이지에서 퇴장
     @MessageMapping("/queue/reservation/leave")
-    public void leaveReservationQueue(LeaveQueueRequestDTO request) {
+    public void leaveReservationQueue(LeaveQueueRequestDTO request, Principal principal) {
         try {
-            boolean removed = waitingService.userExitBookingPage(request.getFestivalId(), request.getReservationDate(), request.getUserId());
+            String userId = principal.getName();
+            boolean removed = waitingService.userExitBookingPage(request.getFestivalId(), request.getReservationDate(), userId);
             if (removed) {
                 log.info("사용자가 예매 페이지를 나갔고, 다음 대기자가 입장했습니다.");
             } else {
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 9c66e74..6910298 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -16,7 +16,6 @@
 @AllArgsConstructor
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 @Table(name = "ticket")
-@ToString
 public class Ticket {
 
     @Id
@@ -86,4 +85,13 @@ public boolean isCanceled() {
     public boolean isExpired() {
         return performanceDate.isBefore(LocalDateTime.now());
     }
+
+    @Override
+    public String toString() {
+        return "Ticket{" +
+                "id=" + id +
+                ", reservationNumber='" + reservationNumber + '\'' +
+                ", festival=" + (festival != null ? festival : "null") +
+                '}';
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index db986d0..ad959b9 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -16,7 +16,8 @@ public interface QrCodeRepository extends JpaRepository {
     // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByQrCodeId(String qrCodeId);
     Boolean existsByQrCodeId(String qrCodeId);
-    Optional> findByTicketId(Long ticketId);
+
+    List findByTicketId(Long ticketId);
 
     // 특정 페스티벌의 특정 공연 날짜에 입장(used=true)한 인원 수를 집계
     @Query("SELECT COUNT(q) FROM QrCode q JOIN q.ticket t WHERE q.used = true AND t.festival.festivalId = :festivalId AND t.performanceDate = :performanceDate")
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 3c34616..66c5b35 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -109,9 +109,6 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
 
         // redis ttl
         tempReservationService.deleteTempReservation(ticket.getReservationNumber());
-
-        // websocket
-        bookingStatusService.notifyTicketStatus(ticket, newStatus);
     }
 
     ///  예매 취소
@@ -136,7 +133,7 @@ public void cancelBooking(String reservationNumber, boolean paymentStatus) {
         ticketRepository.save(ticket);
     }
 
-    // websocket 손실 방지 확인
+    // 예매 완료 확인
     public ReservationStatus checkStatus(String reservationNumber) {
         return ticketRepository.findReservationStatusByRN(reservationNumber);
     }
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index fad9a75..413105e 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -15,23 +15,18 @@
 import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.messaging.simp.SimpMessagingTemplate;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
 import java.time.format.TextStyle;
-import java.time.temporal.ChronoUnit;
 import java.util.List;
 import java.util.Locale;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.IntStream;
 
 @Service
@@ -125,7 +120,7 @@ public void updateTicketStatusIfNecessary(Ticket ticket, ReservationStatus newSt
         }
     }
 
-    // websocket
+    // websocket -> 사용x
     public void notifyTicketStatus(Ticket ticket, ReservationStatus status) {
         messagingTemplate.convertAndSendToUser(
                 String.valueOf(ticket.getUserId()),
diff --git a/src/main/java/com/mnms/booking/service/KeyExpirationListener.java b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
index 5d387c3..99057d6 100644
--- a/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
+++ b/src/main/java/com/mnms/booking/service/KeyExpirationListener.java
@@ -1,9 +1,11 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
+import com.mnms.booking.repository.QrCodeRepository;
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -11,6 +13,8 @@
 import org.springframework.data.redis.connection.MessageListener;
 import org.springframework.stereotype.Component;
 
+import java.util.List;
+
 @Slf4j
 @Component
 @RequiredArgsConstructor
@@ -18,16 +22,20 @@ public class KeyExpirationListener implements MessageListener {
 
     private final TicketRepository ticketRepository;
     private final WaitingService waitingService;
+    private final QrCodeRepository qrCodeRepository;
 
     ///  ticket 가예매 스케줄러
     @Override
     public void onMessage(Message message, byte[] pattern) {
         String key = message.toString();
+        log.info("onMessage key : {}", key);
         if (key.startsWith("TEMP_RESERVATION:")) {
             String reservationNumber = key.substring("TEMP_RESERVATION:".length());
+            log.info("onMessage reservationNumber : {}", reservationNumber);
 
             // 예매열 삭제
             Ticket reservation = loadReservationMeta(reservationNumber);
+            log.info("onMessage reservation : {}", reservation);
 
             waitingService.userExitBookingPage(
                     reservation.getFestival().getFestivalId(),
@@ -35,9 +43,16 @@ public void onMessage(Message message, byte[] pattern) {
                     String.valueOf(reservation.getUserId())
             );
 
+            // qr 있으면 삭제
+            List qrCodes = qrCodeRepository.findByTicketId(reservation.getId());
+            if (!qrCodes.isEmpty()) {
+                qrCodeRepository.deleteAll(qrCodes);
+            }
+
             // 티켓 가예매 삭제
             ticketRepository.findByReservationNumber(reservationNumber)
-                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED)
+                    .filter(t -> t.getReservationStatus() == ReservationStatus.TEMP_RESERVED
+                            || t.getReservationStatus() == ReservationStatus.PAYMENT_IN_PROGRESS)
                     .ifPresent(ticketRepository::delete);
         }
     }
diff --git a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
index 3ad8430..99c608e 100644
--- a/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
+++ b/src/main/java/com/mnms/booking/service/RedisMessageSubscriber.java
@@ -34,7 +34,6 @@ public class RedisMessageSubscriber {
 
     // Redis로 메시지 수신할 때 호출됨
     public void onMessage(String message, String channel) {
-
         printConnectedUsers();
 
         try {
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 0c61041..3f9c034 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -8,6 +8,7 @@
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
+import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
@@ -110,12 +111,14 @@ public void updateOthersTicket(String reservationNumber, boolean paymentStatus)
                     .build();
             applyTicketAndQrUpdate(transfer, request, transfer.getReceiverId(), false);
         }
+    }
 
-        // WebSocket 전송
+    // WebSocket 전송 -> 사용X (기존 결제에서 kafka 구독 메시지 받았을 때 사용)
+    private void notifyTicketStatus(Ticket ticket, TransferStatus status) {
         messagingTemplate.convertAndSendToUser(
                 String.valueOf(ticket.getUserId()),
                 "/queue/transfer-status",
-                new TransferStatusResponseDTO(ticket.getReservationNumber(), newStatus)
+                new TransferStatusResponseDTO(ticket.getReservationNumber(), status)
         );
     }
 
@@ -194,8 +197,11 @@ private void updateTicketInfo(Ticket ticket, UpdateTicketRequestDTO request, Lon
 
     /// qr 정보 업데이트
     private void updateQrCodes(Ticket ticket, UpdateTicketRequestDTO request,  Long receiverId) {
-        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId())
-                .orElseThrow(() -> new BusinessException(ErrorCode.QR_CODE_NOT_FOUND));
+        List existingQrs = qrCodeRepository.findByTicketId(ticket.getId());
+
+        if (existingQrs.isEmpty()) {
+                throw new BusinessException(ErrorCode.QR_CODE_NOT_FOUND);
+        }
 
         existingQrs.forEach(qr -> {
             qr.setQrCodeId(qrCodeService.generateQrCodeId());
diff --git a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
index fce0d26..127d52c 100644
--- a/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingQueueRedisService.java
@@ -118,9 +118,8 @@ public void addBookingUser(String bookingUsersKey, String userId) {
         redisTemplate.expire(bookingUsersKey, Duration.ofDays(2));
     }
 
-    public boolean removeBookingUser(String bookingUsersKey, String userId) {
-        Long removed = redisTemplate.opsForSet().remove(bookingUsersKey, userId);
-        return removed != null && removed > 0;
+    public void removeBookingUser(String bookingUsersKey, String userId) {
+        redisTemplate.opsForSet().remove(bookingUsersKey, userId);
     }
 
 
diff --git a/src/main/java/com/mnms/booking/service/WaitingService.java b/src/main/java/com/mnms/booking/service/WaitingService.java
index 21d5d30..844938c 100644
--- a/src/main/java/com/mnms/booking/service/WaitingService.java
+++ b/src/main/java/com/mnms/booking/service/WaitingService.java
@@ -41,14 +41,10 @@ public long enterWaitingQueue(String festivalId, LocalDateTime reservationDate,
     }
 
     /// 예매 페이지에서 사용자 퇴장 처리 (예매 완료 또는 타임아웃)
-    public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId){
+    public boolean userExitBookingPage(String festivalId, LocalDateTime reservationDate, String userId) {
         String bookingUsersKey = waitingQueueKeyGenerator.getBookingUsersKey(festivalId, reservationDate);
         String waitingQueueKey = waitingQueueKeyGenerator.getWaitingQueueKey(festivalId, reservationDate);
-        boolean removed = waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
-
-        if(!removed){
-            throw new BusinessException(ErrorCode.USER_NOT_FOUND_IN_BOOKING);
-        }
+        waitingQueueRedisService.removeBookingUser(bookingUsersKey, userId);
 
         log.info("User {} exited booking page and removed from booking user set.", userId);
 

From e41467a0a79c71339bfb0f2cf4d715a472f138d8 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 18 Sep 2025 10:22:51 +0900
Subject: [PATCH 144/149] =?UTF-8?q?MNMS-598=20Feat:=20Ticket=20reservation?=
 =?UTF-8?q?=5Fdate=20type=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

LocalDate -> LocalDateTime으로 변경
Ticket list 조회 시 QR USED 추가 (매수 2개 이상 예매 가능함. QR 1개라도 사용하면 TRUE)
---
 .../booking/dto/request/BookingCancelRequestDTO.java   | 10 ----------
 .../mnms/booking/dto/response/BookingResponseDTO.java  |  3 +--
 .../mnms/booking/dto/response/TicketResponseDTO.java   |  2 +-
 src/main/java/com/mnms/booking/entity/Ticket.java      |  6 ++----
 .../com/mnms/booking/repository/QrCodeRepository.java  |  4 ----
 .../mnms/booking/service/BookingCommandService.java    |  5 +----
 .../java/com/mnms/booking/service/TicketService.java   |  4 ----
 .../booking/service/TransferCompletionService.java     |  6 ++----
 .../java/com/mnms/booking/service/TransferService.java |  4 +---
 9 files changed, 8 insertions(+), 36 deletions(-)
 delete mode 100644 src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java

diff --git a/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java
deleted file mode 100644
index 5121889..0000000
--- a/src/main/java/com/mnms/booking/dto/request/BookingCancelRequestDTO.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.mnms.booking.dto.request;
-
-import lombok.Getter;
-import lombok.Setter;
-
-@Getter
-@Setter
-public class BookingCancelRequestDTO {
-    private String reservationNumber;
-}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
index f62c899..79e9f17 100644
--- a/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/BookingResponseDTO.java
@@ -6,7 +6,6 @@
 import com.mnms.booking.enums.TicketType;
 import lombok.*;
 
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -23,7 +22,7 @@ public class BookingResponseDTO {
     private TicketType deliveryMethod;
     private LocalDateTime deliveryDate;
     private Long userId;
-    private LocalDate reservationDate;
+    private LocalDateTime reservationDate;
     private List qrCodes;
     private Festival festival;
 
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index 89a9410..fa67da9 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -23,7 +23,7 @@ public class TicketResponseDTO {
     private LocalDateTime performanceDate; // 공연 일시
     private int selectedTicketCount; // 매수
     private TicketType deliveryMethod; // 티켓 수령 방법
-    private LocalDate reservationDate; // 예매를 수행한 날짜
+    private LocalDateTime reservationDate; // 예매를 수행한 날짜
     private ReservationStatus reservationStatus; // 예매상태
 
     // festival
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 6910298..56ce453 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -1,12 +1,10 @@
 package com.mnms.booking.entity;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import jakarta.persistence.*;
 import lombok.*;
 import jakarta.persistence.Id;
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
@@ -38,7 +36,7 @@ public class Ticket {
 
     @Column(name = "reservation_date")
     //@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
-    private LocalDate reservationDate; // 예매를 수행한 날짜
+    private LocalDateTime reservationDate; // 예매를 수행한 날짜
 
     @Setter
     @Column(name = "delivery_date")
@@ -68,7 +66,7 @@ public class Ticket {
     public void updateTicketInfo(String reservationNumber,
                                  TicketType deliveryMethod,
                                  Long userId,
-                                 LocalDate reservationDate,
+                                 LocalDateTime reservationDate,
                                  String address) {
 
         this.reservationNumber = reservationNumber;
diff --git a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
index ad959b9..379fad9 100644
--- a/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
+++ b/src/main/java/com/mnms/booking/repository/QrCodeRepository.java
@@ -1,19 +1,16 @@
 package com.mnms.booking.repository;
 
 import com.mnms.booking.entity.QrCode;
-import com.mnms.booking.entity.Ticket;
 import io.lettuce.core.dynamic.annotation.Param;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
-
 import java.time.LocalDateTime;
 import java.util.List;
 import java.util.Optional;
 
 @Repository
 public interface QrCodeRepository extends JpaRepository {
-    // 필요한 커스텀 쿼리가 있으면 여기에 추가 작성 가능
     Optional findByQrCodeId(String qrCodeId);
     Boolean existsByQrCodeId(String qrCodeId);
 
@@ -23,7 +20,6 @@ public interface QrCodeRepository extends JpaRepository {
     @Query("SELECT COUNT(q) FROM QrCode q JOIN q.ticket t WHERE q.used = true AND t.festival.festivalId = :festivalId AND t.performanceDate = :performanceDate")
     int countAdmittedAttendees(@Param("festivalId") String festivalId, @Param("performanceDate") LocalDateTime performanceDate);;
 
-    boolean existsByTicketIdAndUsedTrue(Long ticketId);
     boolean existsByTicket_IdAndUsedTrue(Long ticketId);
 }
 
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 66c5b35..3e01832 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -13,11 +13,8 @@
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
-import java.time.LocalDate;
 import java.time.LocalDateTime;
 
 @Service
@@ -49,7 +46,7 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .selectedTicketCount(request.getSelectedTicketCount())
                 .performanceDate(performanceDate)
                 .reservationStatus(ReservationStatus.TEMP_RESERVED)
-                .reservationDate(LocalDate.now())
+                .reservationDate(LocalDateTime.now())
                 .build();
 
         ticketRepository.save(ticket);
diff --git a/src/main/java/com/mnms/booking/service/TicketService.java b/src/main/java/com/mnms/booking/service/TicketService.java
index 23fa29c..9be6ce6 100644
--- a/src/main/java/com/mnms/booking/service/TicketService.java
+++ b/src/main/java/com/mnms/booking/service/TicketService.java
@@ -49,12 +49,8 @@ public List getTicketsByUser(Long userId) {
     public TicketDetailResponseDTO getTicketDetailByUser(String reservationNumber, Long userId, String userName) {
         Ticket ticket = ticketRepository.findByUserIdAndReservationNumber(userId, reservationNumber)
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
-
-        log.info("ticket id : {}", ticket.getId());
         boolean qrUsed = qrCodeRepository.existsByTicket_IdAndUsedTrue(ticket.getId());
 
-        log.info("qr used : {}", qrUsed);
-
         if (!ticket.getUserId().equals(userId)) {
             throw new BusinessException(ErrorCode.USER_UNAUTHORIZED_ACCESS);
         }
diff --git a/src/main/java/com/mnms/booking/service/TransferCompletionService.java b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
index 3f9c034..9863f9f 100644
--- a/src/main/java/com/mnms/booking/service/TransferCompletionService.java
+++ b/src/main/java/com/mnms/booking/service/TransferCompletionService.java
@@ -1,14 +1,12 @@
 package com.mnms.booking.service;
 
 import com.mnms.booking.dto.request.UpdateTicketRequestDTO;
-import com.mnms.booking.dto.response.TicketStatusResponseDTO;
 import com.mnms.booking.dto.response.TransferOthersResponseDTO;
 import com.mnms.booking.dto.response.TransferStatusResponseDTO;
 import com.mnms.booking.entity.Festival;
 import com.mnms.booking.entity.QrCode;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.entity.Transfer;
-import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.enums.TransferStatus;
 import com.mnms.booking.enums.TransferType;
@@ -23,7 +21,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.util.List;
 
 ///  양도 수락
@@ -190,7 +188,7 @@ private void updateTicketInfo(Ticket ticket, UpdateTicketRequestDTO request, Lon
                 commonUtils.generateReservationNumber(),
                 deliveryMethod,
                 receiverId,
-                LocalDate.now(),
+                LocalDateTime.now(),
                 request.getAddress()
         );
     }
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 73f103d..fd3502e 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -16,7 +16,6 @@
 import com.mnms.booking.repository.TransferRepository;
 import jakarta.validation.Valid;
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -26,7 +25,6 @@
 
 @Service
 @RequiredArgsConstructor
-@Slf4j
 @Transactional(readOnly = true)
 public class TransferService {
 
@@ -45,7 +43,7 @@ public List getTicketsByUser(Long userId) {
         return tickets.stream()
                 .filter(ticket -> ticket.getPerformanceDate().isAfter(LocalDateTime.now()))
                 .filter(ticket -> !transferRepository.existsByTicketId(ticket.getId()))
-                .filter(ticket -> !qrCodeRepository.existsByTicketIdAndUsedTrue(ticket.getId()))
+                .filter(ticket -> !qrCodeRepository.existsByTicket_IdAndUsedTrue(ticket.getId()))
                 .map(ticket -> TicketResponseDTO.fromEntity(ticket, ticket.getFestival()))
                 .toList();
     }

From 72ea19a562bb5cf7345984d7c7c5bcaa8f9190f7 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 18 Sep 2025 13:55:38 +0900
Subject: [PATCH 145/149] =?UTF-8?q?MNMS-598=20Fix:=20=EA=B0=80=EC=A1=B1?=
 =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EC=A6=9D=EB=AA=85=EC=84=9C=20=EA=B3=B5?=
 =?UTF-8?q?=EA=B2=A9=20=EB=B0=A9=EC=A7=80=20=EB=B0=8F=20=EC=A7=80=EC=9D=B8?=
 =?UTF-8?q?=20=EC=96=91=EB=8F=84=20=EA=B8=88=EC=A7=80=20=EC=A1=B0=EA=B1=B4?=
 =?UTF-8?q?=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Path Traversal 공격 방지 - 가족관계 증명서 경로 조작 방지
othersTransferAvailable - 예매 후 15분 후에 지인 양도 금지
---
 .../booking/dto/response/TicketResponseDTO.java   |  4 ++++
 src/main/java/com/mnms/booking/entity/Ticket.java |  2 +-
 .../com/mnms/booking/exception/ErrorCode.java     |  2 ++
 .../booking/service/BookingCommandService.java    |  1 -
 .../booking/service/BookingStatusService.java     |  1 +
 .../java/com/mnms/booking/service/OcrService.java | 15 ++++++++++++++-
 .../com/mnms/booking/service/TransferService.java |  1 +
 7 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index fa67da9..5dde834 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -26,6 +26,9 @@ public class TicketResponseDTO {
     private LocalDateTime reservationDate; // 예매를 수행한 날짜
     private ReservationStatus reservationStatus; // 예매상태
 
+    // 추가
+    private boolean othersTransferAvailable; // 지인 양도 가능 유무
+
     // festival
     private String festivalId; // festivalId
     private String posterFile;
@@ -45,6 +48,7 @@ public static TicketResponseDTO fromEntity(Ticket ticket, Festival festival) {
                 .posterFile(festival.getPosterFile())
                 .fname(festival.getFname())
                 .fcltynm(festival.getFcltynm())
+                .othersTransferAvailable(LocalDateTime.now().isBefore(ticket.getReservationDate().plusMinutes(15)))
                 .build();
     }
 }
diff --git a/src/main/java/com/mnms/booking/entity/Ticket.java b/src/main/java/com/mnms/booking/entity/Ticket.java
index 56ce453..a3904ea 100644
--- a/src/main/java/com/mnms/booking/entity/Ticket.java
+++ b/src/main/java/com/mnms/booking/entity/Ticket.java
@@ -34,8 +34,8 @@ public class Ticket {
     @Column(name = "user_id")
     private Long userId; // 예매자 id
 
+    @Setter
     @Column(name = "reservation_date")
-    //@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
     private LocalDateTime reservationDate; // 예매를 수행한 날짜
 
     @Setter
diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 21fba55..88ec180 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -64,6 +64,8 @@ public enum ErrorCode {
     TRANSFER_NOT_MATCH_TYPE("TR006", "양도 타입이 맞지 않습니다.", HttpStatus.BAD_REQUEST),
     TRANSFER_NOT_MATCH_SENDER("TR007", "양도자의 티켓과 매칭되지 않습니다.", HttpStatus.CONFLICT),
     TRANSFER_ALREADY_EXIST_REQUEST("T008", "진행되고 있는 양도 거래가 존재하거나, 양도 1회 진행한 티켓입니다. 양도는 1회로 제한됩니다.", HttpStatus.CONFLICT),
+    TRANSFER_NOT_HAVE_FILE_NAME("T009", "파일 이름이 없습니다.", HttpStatus.NOT_FOUND),
+    TRANSFER_DETECT_FILE_PATH_SECURITY("T010", "잘못된 파일 경로 또는 서버 파일 경로를 조작 공격이 감지되었습니다.", HttpStatus.UNPROCESSABLE_ENTITY),
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 3e01832..4190b71 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -46,7 +46,6 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .selectedTicketCount(request.getSelectedTicketCount())
                 .performanceDate(performanceDate)
                 .reservationStatus(ReservationStatus.TEMP_RESERVED)
-                .reservationDate(LocalDateTime.now())
                 .build();
 
         ticketRepository.save(ticket);
diff --git a/src/main/java/com/mnms/booking/service/BookingStatusService.java b/src/main/java/com/mnms/booking/service/BookingStatusService.java
index 413105e..9070237 100644
--- a/src/main/java/com/mnms/booking/service/BookingStatusService.java
+++ b/src/main/java/com/mnms/booking/service/BookingStatusService.java
@@ -116,6 +116,7 @@ public void updateTicketStatusIfNecessary(Ticket ticket, ReservationStatus newSt
         if (ticket.getReservationStatus() != ReservationStatus.CONFIRMED
                 && ticket.getReservationStatus() != ReservationStatus.CANCELED) {
             ticket.setReservationStatus(newStatus);
+            ticket.setReservationDate(LocalDateTime.now());
             ticketRepository.save(ticket);
         }
     }
diff --git a/src/main/java/com/mnms/booking/service/OcrService.java b/src/main/java/com/mnms/booking/service/OcrService.java
index 9a9b466..f0e6084 100644
--- a/src/main/java/com/mnms/booking/service/OcrService.java
+++ b/src/main/java/com/mnms/booking/service/OcrService.java
@@ -13,6 +13,7 @@
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
+import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestClient;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -35,7 +36,19 @@ public class OcrService {
 
     public String callOcr(MultipartFile image){
         try {
-            String extension = getExtension(image.getOriginalFilename());
+            String imageName = image.getOriginalFilename();
+
+            if (imageName == null || imageName.isBlank()) {
+                throw new BusinessException(ErrorCode.TRANSFER_NOT_HAVE_FILE_NAME);
+            }
+
+            // Path Traversal 공격 성공
+            String filename = StringUtils.cleanPath(imageName);
+            if (filename.contains("..")) {
+                throw new BusinessException(ErrorCode.TRANSFER_DETECT_FILE_PATH_SECURITY);
+            }
+
+            String extension = getExtension(imageName);
             if (!"pdf".equalsIgnoreCase(extension)) {
                 throw new BusinessException(ErrorCode.TRANSFER_NOT_VALID_FILE_TYPE);
             }
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index fd3502e..6d98287 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -19,6 +19,7 @@
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.time.Duration;
 import java.time.LocalDateTime;
 import java.util.Collections;
 import java.util.List;

From bd3f7067068c1e06a8df4c1889381a79f0b45217 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 18 Sep 2025 15:19:03 +0900
Subject: [PATCH 146/149] =?UTF-8?q?MNMS-598=20Fix:=20=EC=A7=80=EC=9D=B8=20?=
 =?UTF-8?q?=EC=96=91=EB=8F=84=20=EC=9A=94=EC=B2=AD=20=EC=8B=9C,=20?=
 =?UTF-8?q?=EC=98=88=EB=A7=A4=20=ED=9B=84=2015=EB=B6=84=20=EC=A0=9C?=
 =?UTF-8?q?=ED=95=9C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/main/java/com/mnms/booking/exception/ErrorCode.java     | 1 +
 src/main/java/com/mnms/booking/service/TransferService.java | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/src/main/java/com/mnms/booking/exception/ErrorCode.java b/src/main/java/com/mnms/booking/exception/ErrorCode.java
index 88ec180..c1d0f20 100644
--- a/src/main/java/com/mnms/booking/exception/ErrorCode.java
+++ b/src/main/java/com/mnms/booking/exception/ErrorCode.java
@@ -66,6 +66,7 @@ public enum ErrorCode {
     TRANSFER_ALREADY_EXIST_REQUEST("T008", "진행되고 있는 양도 거래가 존재하거나, 양도 1회 진행한 티켓입니다. 양도는 1회로 제한됩니다.", HttpStatus.CONFLICT),
     TRANSFER_NOT_HAVE_FILE_NAME("T009", "파일 이름이 없습니다.", HttpStatus.NOT_FOUND),
     TRANSFER_DETECT_FILE_PATH_SECURITY("T010", "잘못된 파일 경로 또는 서버 파일 경로를 조작 공격이 감지되었습니다.", HttpStatus.UNPROCESSABLE_ENTITY),
+    TRANSFER_OTHERS_NOT_ALLOWED("T011", "예매 완료 후 15분이 초과되어 지인 양도가 불가능합니다.", HttpStatus.CONFLICT),
 
     // STATISTICS (통계 관련 에러 코드 추가)
     STATISTICS_ACCESS_DENIED("ST001", "통계 정보에 접근할 권한이 없습니다.", HttpStatus.FORBIDDEN),
diff --git a/src/main/java/com/mnms/booking/service/TransferService.java b/src/main/java/com/mnms/booking/service/TransferService.java
index 6d98287..66af852 100644
--- a/src/main/java/com/mnms/booking/service/TransferService.java
+++ b/src/main/java/com/mnms/booking/service/TransferService.java
@@ -56,6 +56,11 @@ public void requestTransfer(@Valid TicketTransferRequestDTO dto, Long userId) {
         Ticket ticket = ticketRepository.findByReservationNumber(dto.getReservationNumber())
                 .orElseThrow(() -> new BusinessException(ErrorCode.TICKET_NOT_FOUND));
 
+        // 예매 15분 확인 후 지인간 양도 불가능
+        if(dto.getTransferType().equals("OTHERS") && Duration.between(ticket.getReservationDate(), LocalDateTime.now()).toMinutes() > 15){
+            throw new BusinessException(ErrorCode.TRANSFER_OTHERS_NOT_ALLOWED);
+        }
+
         if(transferRepository.existsByTicket_Id(ticket.getId())){
             throw new BusinessException(ErrorCode.TRANSFER_ALREADY_EXIST_REQUEST);
         }

From 69fdbefe93ce6433bd560a576da75c73f321aa95 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Thu, 18 Sep 2025 17:20:07 +0900
Subject: [PATCH 147/149] =?UTF-8?q?MNMS-598=20Chore:=20=EA=B0=80=EC=98=88?=
 =?UTF-8?q?=EB=A7=A4=20ttl=20=EC=A1=B0=EC=A0=95=20=EB=B0=8F=20=EC=A3=BC?=
 =?UTF-8?q?=EC=84=9D=20=EB=B3=80=EA=B2=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../dto/response/TicketDetailResponseDTO.java  |  2 +-
 .../dto/response/TicketResponseDTO.java        |  5 +----
 .../booking/service/BookingCommandService.java | 18 +++++++++---------
 .../service/StatisticsQrCodeService.java       |  2 --
 .../service/TempReservationService.java        |  6 +++---
 .../booking/util/SecurityResponseUtil.java     |  4 ++--
 6 files changed, 16 insertions(+), 21 deletions(-)

diff --git a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
index ffb2635..8354ccc 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketDetailResponseDTO.java
@@ -8,7 +8,7 @@
 import lombok.Data;
 import java.time.LocalDateTime;
 import java.util.List;
-import java.util.stream.Collectors;
+
 
 @Data
 @Builder
diff --git a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
index 5dde834..1f95df8 100644
--- a/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
+++ b/src/main/java/com/mnms/booking/dto/response/TicketResponseDTO.java
@@ -6,10 +6,7 @@
 import com.mnms.booking.enums.TicketType;
 import lombok.Builder;
 import lombok.Data;
-
-import java.time.LocalDate;
 import java.time.LocalDateTime;
-import java.util.stream.Collectors;
 
 
 // 예매 내역 기본 조회
@@ -26,7 +23,7 @@ public class TicketResponseDTO {
     private LocalDateTime reservationDate; // 예매를 수행한 날짜
     private ReservationStatus reservationStatus; // 예매상태
 
-    // 추가
+    // 추가적 요소
     private boolean othersTransferAvailable; // 지인 양도 가능 유무
 
     // festival
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index 4190b71..c4cba4a 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -28,7 +28,7 @@ public class BookingCommandService {
     private final BookingStatusService bookingStatusService;
     private final TempReservationService tempReservationService;
 
-    /// 1차: 가예매 - 임시 예약
+    /// 1차: 가예매 - 임시 예약 (2차 예매하기 누르면 실행)
     @Transactional
     public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
         Festival festival = bookingStatusService.getFestivalOrThrow(request.getFestivalId());
@@ -49,12 +49,12 @@ public String selectFestivalDate(BookingSelectRequestDTO request, Long userId) {
                 .build();
 
         ticketRepository.save(ticket);
-        // redis ttl
+        // redis ttl : 1분 설정
         tempReservationService.createTempReservation(ticket);
         return ticket.getReservationNumber();
     }
 
-    /// 2차: 가예매 - 배송 방법 선택
+    /// 2차: 가예매 - 배송 방법 선택 (결제하기 누르면 실행)
     @Transactional
     public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long userId) {
         Ticket ticket = bookingStatusService.getTicketOrThrow(request.getFestivalId(), userId, request.getReservationNumber());
@@ -66,11 +66,11 @@ public void selectFestivalDelivery(BookingSelectDeliveryRequestDTO request, Long
         }
         ticketRepository.save(ticket);
 
-        // redis ttl
-        tempReservationService.refreshTempReservation(ticket.getReservationNumber());
+        // redis ttl : 5분 설정
+        tempReservationService.refreshTempReservation(ticket.getReservationNumber(), 5);
     }
 
-    /// 3차: 가예매 - 예약 - QR생성
+    /// 3차: 가예매 - 예약 - QR생성 (마지막 결제하기 눌렀을 때 실행)
     @Transactional
     public void reserveTicket(BookingRequestDTO request, Long userId) {
         Festival festival = bookingStatusService.getFestivalOrThrow(request.getFestivalId());
@@ -86,8 +86,8 @@ public void reserveTicket(BookingRequestDTO request, Long userId) {
 
         ticketRepository.save(ticket);
 
-        // redis ttl
-        tempReservationService.refreshTempReservation(ticket.getReservationNumber());
+        // redis ttl : 3분 설정 (예매 완료하면 ttl 바로 완료됨)
+        tempReservationService.refreshTempReservation(ticket.getReservationNumber(), 3);
     }
 
 
@@ -103,7 +103,7 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
         BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
         emailService.sendTicketConfirmationEmail(ticket, user);
 
-        // redis ttl
+        // redis ttl : ttl 삭제
         tempReservationService.deleteTempReservation(ticket.getReservationNumber());
     }
 
diff --git a/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
index 8a542d3..33dba6f 100644
--- a/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
+++ b/src/main/java/com/mnms/booking/service/StatisticsQrCodeService.java
@@ -9,8 +9,6 @@
 import com.mnms.booking.repository.TicketRepository;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import java.time.LocalDateTime;
 
 @Service
diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index 2e9656e..16648e7 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -2,7 +2,6 @@
 
 import com.mnms.booking.entity.Ticket;
 import lombok.RequiredArgsConstructor;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -21,13 +20,14 @@ public class TempReservationService {
 //    @Value("${temp-reservation.ttl-minutes:3}")
 //    private long ttlMinutes;
 
+    // 2차 예매하기 누르면 실행
     public void createTempReservation(Ticket ticket) {
         String key = PREFIX + ticket.getReservationNumber();
         redisTemplate.opsForValue().set(key, ticket, ttlMinutes, TimeUnit.MINUTES);
     }
 
-    // 갱신
-    public void refreshTempReservation(String reservationNumber) {
+    // 갱신 - refresh ttl 각자 설정
+    public void refreshTempReservation(String reservationNumber, long ttlMinutes) {
         String key = PREFIX + reservationNumber;
         Boolean exists = redisTemplate.hasKey(key);
         if (Boolean.TRUE.equals(exists)) {
diff --git a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
index 4ec6931..8c31a12 100644
--- a/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
+++ b/src/main/java/com/mnms/booking/util/SecurityResponseUtil.java
@@ -16,7 +16,7 @@
 @Slf4j
 @RequiredArgsConstructor
 public class SecurityResponseUtil {
-    // Authentication에서 userId 추출
+    // Authentication 에서 userId 추출
     public Long requireUserId(Authentication authentication) {
         try {
             return Long.parseLong(authentication.getName());
@@ -25,7 +25,7 @@ public Long requireUserId(Authentication authentication) {
         }
     }
 
-    // Authentication에서 name 추출
+    // Authentication 에서 name 추출
     public String requireName(Authentication authentication) {
         String userName = null;
         log.info("authentication : {}", authentication);

From 63517ee8400d01ca03736502f6d110a2dda2e0e3 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Fri, 19 Sep 2025 10:03:18 +0900
Subject: [PATCH 148/149] =?UTF-8?q?application.properties=20=EB=B3=80?=
 =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../com/mnms/booking/service/TempReservationService.java   | 7 +++----
 src/main/resources/application-dev.properties              | 3 ++-
 src/main/resources/application-prod.properties             | 2 ++
 src/main/resources/application-test.properties             | 3 +++
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/main/java/com/mnms/booking/service/TempReservationService.java b/src/main/java/com/mnms/booking/service/TempReservationService.java
index 16648e7..64d352e 100644
--- a/src/main/java/com/mnms/booking/service/TempReservationService.java
+++ b/src/main/java/com/mnms/booking/service/TempReservationService.java
@@ -2,6 +2,7 @@
 
 import com.mnms.booking.entity.Ticket;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -13,12 +14,10 @@
 public class TempReservationService {
 
     private final RedisTemplate redisTemplate;
-
     private static final String PREFIX = "TEMP_RESERVATION:";
-    private static final long ttlMinutes = 1;
 
-//    @Value("${temp-reservation.ttl-minutes:3}")
-//    private long ttlMinutes;
+    @Value("${temp-reservation.ttl-minutes:1}")
+    private long ttlMinutes;
 
     // 2차 예매하기 누르면 실행
     public void createTempReservation(Ticket ticket) {
diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties
index 0dc0223..c488206 100644
--- a/src/main/resources/application-dev.properties
+++ b/src/main/resources/application-dev.properties
@@ -32,7 +32,8 @@ spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.Str
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 
 # 가예매 TTL
-#temp-reservation.ttl-minutes=3
+temp-reservation.ttl-minutes=1
+
 
 # Topic
 app.kafka.topic.festival-event=festival-topic
diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties
index ee67dc5..ff2cdb7 100644
--- a/src/main/resources/application-prod.properties
+++ b/src/main/resources/application-prod.properties
@@ -35,6 +35,8 @@ spring.kafka.consumer.properties.spring.json.use.type.headers=false
 spring.kafka.consumer.key-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 spring.kafka.consumer.value-deserializer=org.apache.kafka.common.serialization.StringDeserializer
 
+# 가예매 TTL
+temp-reservation.ttl-minutes=1
 
 # jwt
 jwt.public-pem-path=classpath:keys/public.pem
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index c952ed5..230636a 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -24,6 +24,9 @@ spring.redis.host=127.0.0.1
 spring.redis.port=6379
 #spring.redis.password=your_password
 
+# 가예매 TTL
+temp-reservation.ttl-minutes=1
+
 # kafka
 app.kafka.topic.booking-event=booking-events
 app.kafka.topic.user-event= user-events

From 277d4888b851014c4671a6c8f5636e7f60ab37f2 Mon Sep 17 00:00:00 2001
From: 19013na <19013@naver.com>
Date: Mon, 22 Sep 2025 13:43:29 +0900
Subject: [PATCH 149/149] =?UTF-8?q?hotfix:=20=EC=98=88=EB=A7=A4=20?=
 =?UTF-8?q?=EC=99=84=EB=A3=8C=20=ED=9B=84=20email=20=EC=A0=84=EC=86=A1=20?=
 =?UTF-8?q?=EB=B9=84=EB=8F=99=EA=B8=B0=20=EC=B2=98=EB=A6=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 build.gradle                                  |  4 ++
 .../com/mnms/booking/config/AsyncConfig.java  | 26 ++++++++++++
 .../booking/dto/request/TicketRequestDTO.java | 40 +++++++++++++++++++
 .../booking/event/TicketConfirmedEvent.java   |  5 +++
 .../booking/event/TicketEventListener.java    | 37 +++++++++++++++++
 .../service/BookingCommandService.java        | 13 +++---
 .../mnms/booking/service/EmailService.java    | 21 ++++++++--
 7 files changed, 135 insertions(+), 11 deletions(-)
 create mode 100644 src/main/java/com/mnms/booking/config/AsyncConfig.java
 create mode 100644 src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
 create mode 100644 src/main/java/com/mnms/booking/event/TicketConfirmedEvent.java
 create mode 100644 src/main/java/com/mnms/booking/event/TicketEventListener.java

diff --git a/build.gradle b/build.gradle
index 17faa5e..e167d2c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -94,6 +94,10 @@ dependencies {
 	// prometheus
 	implementation 'org.springframework.boot:spring-boot-starter-actuator'
   	implementation 'io.micrometer:micrometer-registry-prometheus'
+
+	// email retry
+	implementation 'org.springframework.retry:spring-retry'
+	implementation 'org.springframework.boot:spring-boot-starter-aop'
 }
 
 tasks.named('test') {
diff --git a/src/main/java/com/mnms/booking/config/AsyncConfig.java b/src/main/java/com/mnms/booking/config/AsyncConfig.java
new file mode 100644
index 0000000..1118cf6
--- /dev/null
+++ b/src/main/java/com/mnms/booking/config/AsyncConfig.java
@@ -0,0 +1,26 @@
+package com.mnms.booking.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.retry.annotation.EnableRetry;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+@Configuration
+@EnableAsync
+@EnableRetry
+public class AsyncConfig {
+
+    @Bean(name = "taskExecutor")
+    public Executor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(5);
+        executor.setMaxPoolSize(10);
+        executor.setQueueCapacity(100);
+        executor.setThreadNamePrefix("Async-");
+        executor.initialize();
+        return executor;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
new file mode 100644
index 0000000..14cbebb
--- /dev/null
+++ b/src/main/java/com/mnms/booking/dto/request/TicketRequestDTO.java
@@ -0,0 +1,40 @@
+package com.mnms.booking.dto.request;
+
+import com.mnms.booking.entity.Festival;
+import com.mnms.booking.entity.Ticket;
+import com.mnms.booking.enums.TicketType;
+import lombok.Builder;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+public class TicketRequestDTO {
+
+    private Long userId;
+    private String reservationNumber;
+
+    private String fname;      // 페스티벌 이름
+    private LocalDateTime performanceDate; // 선택 날짜
+
+    private Festival festival;
+    private String festivalFacility;  // 공연장 장소
+    private int ticketPrice;
+    private int selectedTicketCount;  // 선택 매수
+    private TicketType deliveryMethod;
+
+    public static TicketRequestDTO fromEntity(Ticket ticket) {
+        return TicketRequestDTO.builder()
+                .userId(ticket.getUserId())
+                .reservationNumber(ticket.getReservationNumber())
+                .fname(ticket.getFestival().getFname())
+                .performanceDate(ticket.getPerformanceDate())
+                .festival(ticket.getFestival())
+                .festivalFacility(ticket.getFestival().getFcltynm())
+                .ticketPrice(ticket.getFestival().getTicketPrice())
+                .selectedTicketCount(ticket.getSelectedTicketCount())
+                .deliveryMethod(ticket.getDeliveryMethod())
+                .build();
+    }
+}
diff --git a/src/main/java/com/mnms/booking/event/TicketConfirmedEvent.java b/src/main/java/com/mnms/booking/event/TicketConfirmedEvent.java
new file mode 100644
index 0000000..ae25db5
--- /dev/null
+++ b/src/main/java/com/mnms/booking/event/TicketConfirmedEvent.java
@@ -0,0 +1,5 @@
+package com.mnms.booking.event;
+
+import com.mnms.booking.dto.request.TicketRequestDTO;
+
+public record TicketConfirmedEvent(TicketRequestDTO ticket) {}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/event/TicketEventListener.java b/src/main/java/com/mnms/booking/event/TicketEventListener.java
new file mode 100644
index 0000000..0eb443c
--- /dev/null
+++ b/src/main/java/com/mnms/booking/event/TicketEventListener.java
@@ -0,0 +1,37 @@
+package com.mnms.booking.event;
+
+import com.mnms.booking.dto.response.BookingUserResponseDTO;
+import com.mnms.booking.service.EmailService;
+import com.mnms.booking.service.TempReservationService;
+import com.mnms.booking.util.UserApiClient;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.event.TransactionPhase;
+import org.springframework.transaction.event.TransactionalEventListener;
+
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class TicketEventListener {
+
+    private final UserApiClient userApiClient;
+    private final EmailService emailService;
+    private final TempReservationService tempReservationService;
+
+    @Async
+    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
+    public void handleTicketConfirmed(TicketConfirmedEvent event) {
+        var ticketDto = event.ticket(); // TicketRequestDTO
+
+        try {
+            BookingUserResponseDTO user = userApiClient.getUserInfoById(ticketDto.getUserId());
+            tempReservationService.deleteTempReservation(ticketDto.getReservationNumber());
+            emailService.sendTicketConfirmationEmail(ticketDto, user);
+            log.info("티켓 확정 후 이메일 전송 완료: reservationNumber={}", ticketDto.getReservationNumber());
+        } catch (Exception e) {
+            log.error("티켓 확정 후 이메일 전송 실패: reservationNumber={}", ticketDto.getReservationNumber(), e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mnms/booking/service/BookingCommandService.java b/src/main/java/com/mnms/booking/service/BookingCommandService.java
index c4cba4a..cfcc1f3 100644
--- a/src/main/java/com/mnms/booking/service/BookingCommandService.java
+++ b/src/main/java/com/mnms/booking/service/BookingCommandService.java
@@ -3,16 +3,18 @@
 import com.mnms.booking.dto.request.BookingRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectDeliveryRequestDTO;
 import com.mnms.booking.dto.request.BookingSelectRequestDTO;
-import com.mnms.booking.dto.response.*;
+import com.mnms.booking.dto.request.TicketRequestDTO;
 import com.mnms.booking.entity.*;
 import com.mnms.booking.enums.ReservationStatus;
 import com.mnms.booking.enums.TicketType;
+import com.mnms.booking.event.TicketConfirmedEvent;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import com.mnms.booking.repository.TicketRepository;
 import com.mnms.booking.util.CommonUtils;
 import com.mnms.booking.util.UserApiClient;
 import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import java.time.LocalDateTime;
@@ -27,6 +29,8 @@ public class BookingCommandService {
     private final UserApiClient userApiClient;
     private final BookingStatusService bookingStatusService;
     private final TempReservationService tempReservationService;
+    private final ApplicationEventPublisher eventPublisher;
+
 
     /// 1차: 가예매 - 임시 예약 (2차 예매하기 누르면 실행)
     @Transactional
@@ -99,12 +103,7 @@ public void confirmTicket(String reservationNumber, boolean paymentStatus) {
 
         // 결제 상태 변경
         bookingStatusService.updateTicketStatusIfNecessary(ticket, newStatus);
-
-        BookingUserResponseDTO user = userApiClient.getUserInfoById(ticket.getUserId());
-        emailService.sendTicketConfirmationEmail(ticket, user);
-
-        // redis ttl : ttl 삭제
-        tempReservationService.deleteTempReservation(ticket.getReservationNumber());
+        eventPublisher.publishEvent(new TicketConfirmedEvent(TicketRequestDTO.fromEntity(ticket)));
     }
 
     ///  예매 취소
diff --git a/src/main/java/com/mnms/booking/service/EmailService.java b/src/main/java/com/mnms/booking/service/EmailService.java
index a5f55e9..1f68ca0 100644
--- a/src/main/java/com/mnms/booking/service/EmailService.java
+++ b/src/main/java/com/mnms/booking/service/EmailService.java
@@ -1,13 +1,18 @@
 package com.mnms.booking.service;
 
+import com.mnms.booking.dto.request.TicketRequestDTO;
 import com.mnms.booking.dto.response.BookingUserResponseDTO;
 import com.mnms.booking.entity.Ticket;
 import com.mnms.booking.enums.TicketType;
 import com.mnms.booking.exception.BusinessException;
 import com.mnms.booking.exception.ErrorCode;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.mail.SimpleMailMessage;
 import org.springframework.mail.javamail.JavaMailSender;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Recover;
+import org.springframework.retry.annotation.Retryable;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
@@ -18,11 +23,13 @@
 import java.time.format.DateTimeFormatter;
 
 @Service
+@Slf4j
 @RequiredArgsConstructor
 public class EmailService {
     private final JavaMailSender mailSender;
 
-    public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO user) {
+    @Retryable(retryFor = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 2000, multiplier = 2))
+    public void sendTicketConfirmationEmail(TicketRequestDTO ticket, BookingUserResponseDTO user) {
         try (InputStream is = getClass().getClassLoader()
                 .getResourceAsStream("templates/email/ticket-confirmation.txt")) {
 
@@ -37,10 +44,10 @@ public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO us
                     template,
                     user.getName(),
                     ticket.getReservationNumber(),
-                    ticket.getFestival().getFname(),
+                    ticket.getFname(),
                     ticket.getPerformanceDate().format(formatter),
-                    ticket.getFestival().getFcltynm(),
-                    ticket.getFestival().getTicketPrice() * ticket.getSelectedTicketCount(),
+                    ticket.getFestivalFacility(),
+                    ticket.getTicketPrice() * ticket.getSelectedTicketCount(),
                     ticket.getDeliveryMethod() == TicketType.MOBILE ? "모바일" : "지류"
             );
 
@@ -52,6 +59,12 @@ public void sendTicketConfirmationEmail(Ticket ticket, BookingUserResponseDTO us
         }
     }
 
+    @Recover
+    public void recover(Exception e, TicketRequestDTO ticketDto, BookingUserResponseDTO user) {
+        log.error("이메일 재시도 실패: 예약 번호 = {}, 사용자 이메일={}",
+                ticketDto.getReservationNumber(), user.getEmail(), e);
+    }
+
     public void sendEmail(String to, String subject, String text) {
         SimpleMailMessage message = new SimpleMailMessage();
         message.setTo(to);           // 수신자