diff --git a/README.md b/README.md deleted file mode 100644 index 47016a10..00000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# issue-pr-template - -공통으로 사용하게 될 이슈, PR 템플릿 저장소 \ No newline at end of file diff --git a/query.md b/query.md deleted file mode 100644 index 73406725..00000000 --- a/query.md +++ /dev/null @@ -1,845 +0,0 @@ -## Auth - -**로그인** - -```sql --- 회원 - --- 이메일로 회원 조회 -SELECT - u.id -FROM - users u -WHERE - u.email = ? - LIMIT 1; - --- 연락처로 회원 조회 -SELECT - u.id -FROM - users u -WHERE - u.phone = ? - LIMIT 1; - --- 회원 추가 -INSERT INTO users ( - created_at, created_by, email, name, password, phone, region_code, - status, updated_at, updated_by, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? - ); - --- 회원 상태 이력 추가 -INSERT INTO user_status_history ( - created_at, created_by, reason, status, updated_at, updated_by, - user_id, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? - ); -``` - -### Payment - -**결제 승인 & 저장** - -```sql --- 결제 정보 추가 -INSERT INTO payment ( approved_at, method, order_id, payment_key, requested_at, reservation_id, status, total_amount, type, id -) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); - --- 결제 상세 정보 추가 -INSERT INTO payment_detail ( payment_id, supplied_amount, vat, id -) VALUES ( ?, ?, ?, ? -); --- 카드 결제 상세 정보 추가 -INSERT INTO payment_card_detail ( amount, approval_number, card_number, card_type, easypay_discount_amount, easypay_provider_code, installment_plan_months, is_interest_free, issuer_code, owner_type, id -) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**결제 취소** - -SQL - -```sql --- 예약 ID로 결제 정보 조회 -SELECT - p.id, - p.approved_at, - p.method, - p.order_id, - p.payment_key, - p.requested_at, - p.reservation_id, - p.status, - p.total_amount, - p.type -FROM - payment p -WHERE - p.reservation_id = ?; - --- 추가 --- 취소된 결제 정보 추가 -INSERT INTO canceled_payment ( - cancel_amount, cancel_reason, canceled_at, canceled_by, - card_discount_amount, easypay_discount_amount, payment_id, - requested_at, transfer_discount_amount, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -### Region - -**모든 시/도 조회** - -```sql -SELECT DISTINCT - r.sido_code, - r.sido_name -FROM - region r -ORDER BY - r.sido_name; -``` - -**시/군/구 조회** - -```sql -SELECT - r.sigungu_code, - r.sigungu_name -FROM - region r -WHERE - r.sido_code = ? -GROUP BY - r.sigungu_code, r.sigungu_name -ORDER BY - r.sigungu_name; -``` - -**지역 코드 조회** - -```sql -SELECT - r.code -FROM - region r -WHERE - r.sido_code = ? AND r.sigungu_code = ?; -``` - -### Reservation - -**Pending 예약 생성** - -```sql --- schedule 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- theme 조회 -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.id = ?; - --- 예약 추가 -INSERT INTO reservation ( - created_at, created_by, participant_count, requirement, - reserver_contact, reserver_name, schedule_id, status, - updated_at, updated_by, user_id, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**확정** - -```sql --- 예약 조회 -SELECT - r.id, r.created_at, r.created_by, r.participant_count, r.requirement, - r.reserver_contact, r.reserver_name, r.schedule_id, r.status, - r.updated_at, r.updated_by, r.user_id -FROM - reservation r -WHERE - r.id = ?; - --- 일정 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 예약 확정 -UPDATE - reservation -SET - participant_count = ?, requirement = ?, reserver_contact = ?, - reserver_name = ?, schedule_id = ?, status = ?, - updated_at = ?, updated_by = ?, user_id = ? -WHERE - id = ?; - --- Schedule 확정 -UPDATE - schedule -SET - date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, - updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**취소** - -```sql --- 예약 조회 -SELECT - r.id, r.created_at, r.created_by, r.participant_count, r.requirement, - r.reserver_contact, r.reserver_name, r.schedule_id, r.status, - r.updated_at, r.updated_by, r.user_id -FROM - reservation r -WHERE - r.id = ?; - --- 일정 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 취소 예약 추가 -INSERT INTO canceled_reservation ( - cancel_reason, canceled_at, canceled_by, - reservation_id, status, id -) VALUES ( - ?, ?, ?, ?, ?, ? -); - --- 예약 취소 -UPDATE - reservation -SET - participant_count = ?, requirement = ?, reserver_contact = ?, - reserver_name = ?, schedule_id = ?, status = ?, - updated_at = ?, updated_by = ?, user_id = ? -WHERE - id = ?; - --- 일정 활성화 -UPDATE - schedule -SET - date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, - updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**회원 예약 조회** - -```sql --- 예약 조회 -SELECT - r.id, r.created_at, r.created_by, r.participant_count, r.requirement, - r.reserver_contact, r.reserver_name, r.schedule_id, r.status, - r.updated_at, r.updated_by, r.user_id -FROM - reservation r -WHERE - r.user_id = ? AND r.status IN (?, ?); - --- 일정 조회 -> 각 예약별 1개씩(N개) -SELECT - s.id, - st.id AS store_id, - st.name AS store_name, - s.date, - s.time, - t.id AS theme_id, - t.name AS theme_name, - t.difficulty, - t.available_minutes, - s.status -FROM - schedule s - JOIN theme t ON t.id = s.theme_id - JOIN store st ON st.id = s.store_id -WHERE - s.id = ?; -``` - -**예약 상세 조회** - -```sql --- 예약 조회 -SELECT - r.id, r.created_at, r.created_by, r.participant_count, r.requirement, - r.reserver_contact, r.reserver_name, r.schedule_id, r.status, - r.updated_at, r.updated_by, r.user_id -FROM - reservation r -WHERE - r.id = ?; - --- 회원 연락처 정보 조회 -SELECT - u.id, u.created_at, u.created_by, u.email, u.name, u.password, - u.phone, u.region_code, u.status, u.updated_at, u.updated_by -FROM - users u -WHERE - u.id = ?; - --- 결제 정보 조회 -SELECT - p.id, p.approved_at, p.method, p.order_id, p.payment_key, - p.requested_at, p.reservation_id, p.status, p.total_amount, p.type -FROM - payment p -WHERE - p.reservation_id = ?; - --- 결제 상세 정보 조회 -SELECT - pd.id, - CASE - WHEN pbt.id IS NOT NULL THEN 1 -- bank_transfer - WHEN pcd.id IS NOT NULL THEN 2 -- card - WHEN pep.id IS NOT NULL THEN 3 -- easypay - WHEN pd.id IS NOT NULL THEN 0 -- etc - END AS payment_type, - pd.payment_id, pd.supplied_amount, pd.vat, - pbt.bank_code, pbt.settlement_status, - pcd.amount, pcd.approval_number, pcd.card_number, pcd.card_type, - pcd.easypay_discount_amount, pcd.easypay_provider_code, - pcd.installment_plan_months, pcd.is_interest_free, pcd.issuer_code, - pcd.owner_type, - pep.amount AS easypay_amount, - pep.discount_amount AS easypay_discount_amount, - pep.easypay_provider_code AS easypay_provider -FROM - payment_detail pd - LEFT JOIN payment_bank_transfer_detail pbt ON pd.id = pbt.id - LEFT JOIN payment_card_detail pcd ON pd.id = pcd.id - LEFT JOIN payment_easypay_prepaid_detail pep ON pd.id = pep.id -WHERE - pd.payment_id = ?; - --- 취소 결제 정보 조회 -SELECT - cp.id, cp.cancel_amount, cp.cancel_reason, cp.canceled_at, - cp.canceled_by, cp.card_discount_amount, cp.easypay_discount_amount, - cp.payment_id, cp.requested_at, cp.transfer_discount_amount -FROM - canceled_payment cp -WHERE - cp.payment_id = ?; -``` - -### Schedule - -**날짜, 시간, 테마로 조회** - -```sql -SELECT - s.id, - st.id AS store_id, - st.name AS store_name, - s.date, - s.time, - t.id AS theme_id, - t.name AS theme_name, - t.difficulty, - t.available_minutes, - s.status -FROM - schedule s - JOIN theme t ON t.id = s.theme_id AND (? IS NULL OR t.id = ?) - JOIN store st ON st.id = s.store_id AND st.id = ? -WHERE - s.date = ? -``` - -**감사 정보 조회** - -```sql --- 일정 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 작업자 조회(createdBy, updatedBy) -SELECT - a.id, a.account, a.created_at, a.created_by, a.name, a.password, - a.permission_level, a.phone, a.store_id, a.type, a.updated_at, - a.updated_by -FROM - admin a -WHERE - a.id = ?; -``` - -**일정 생성** - -```sql --- 날짜, 시간, 테마가 같은 일정 존재 여부 확인 -SELECT EXISTS ( - SELECT 1 - FROM schedule s - WHERE - s.store_id = ? - AND s.date = ? - AND s.theme_id = ? - AND s.time = ? -); - --- 시간이 겹치는 같은 날의 일정이 있는지 확인 -SELECT - s.id, - st.id AS store_id, - st.name AS store_name, - s.date, - s.time, - t.id AS theme_id, - t.name AS theme_name, - t.difficulty, - t.available_minutes, - s.status -FROM - schedule s - JOIN theme t ON t.id = s.theme_id AND (? IS NULL OR s.theme_id = ?) - JOIN store st ON st.id = s.store_id AND st.id = ? -WHERE - s.date = ? - --- 일정 추가 -INSERT INTO schedule ( - created_at, created_by, date, status, store_id, - theme_id, time, updated_at, updated_by, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**일정 수정** - -```sql --- 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 수정 -UPDATE - schedule -SET - date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, - updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**일정 삭제** - -```sql --- 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 삭제 -DELETE FROM schedule -WHERE id = ?; -``` - -**상태 → HOLD 변경** - -```sql --- 조회 -SELECT - s.id, s.created_at, s.created_by, s.date, s.status, s.store_id, - s.theme_id, s.time, s.updated_at, s.updated_by -FROM - schedule s -WHERE - s.id = ?; - --- 수정 -UPDATE - schedule -SET - date = ?, status = ?, store_id = ?, theme_id = ?, time = ?, - updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -### Store - -**매장 상세 조회** - -```sql --- 조회 -SELECT - s.id, s.address, s.business_reg_num, s.contact, s.created_at, - s.created_by, s.name, s.region_code, s.status, s.updated_at, - s.updated_by -FROM - store s -WHERE - s.id = ? AND s.status = 'ACTIVE'; - --- 지역 정보 조회 -SELECT - r.code, r.sido_code, r.sido_name, r.sigungu_code, r.sigungu_name -FROM - region r -WHERE - r.code = ?; - --- 감사 정보 조회(createdBy, updatedBy) -SELECT - a.id, a.account, a.created_at, a.created_by, a.name, a.password, - a.permission_level, a.phone, a.store_id, a.type, a.updated_at, - a.updated_by -FROM - admin a -WHERE - a.id = ?; -``` - -**매장 등록** - -```sql --- 이름 중복 확인 -SELECT s.id FROM store s WHERE s.name = ? LIMIT 1; - --- 연락처 중복 확인 -SELECT s.id FROM store s WHERE s.contact = ? LIMIT 1; - --- 주소 중복 확인 -SELECT s.id FROM store s WHERE s.address = ? LIMIT 1; - --- 사업자번호 중복 확인 -SELECT s.id FROM store s WHERE s.business_reg_num = ? LIMIT 1; - --- 추가 -INSERT INTO store ( - address, business_reg_num, contact, created_at, created_by, - name, region_code, status, updated_at, updated_by, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**매장 수정** - -```sql --- 조회 -SELECT - s.id, s.address, s.business_reg_num, s.contact, s.created_at, - s.created_by, s.name, s.region_code, s.status, s.updated_at, - s.updated_by -FROM - store s -WHERE - s.id = ? AND s.status = 'ACTIVE'; - --- 수정 -UPDATE - store -SET - address = ?, business_reg_num = ?, contact = ?, name = ?, - region_code = ?, status = ?, updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**비활성화(status = DISABLE)** - -```sql --- 조회 -SELECT - s.id, s.address, s.business_reg_num, s.contact, s.created_at, - s.created_by, s.name, s.region_code, s.status, s.updated_at, - s.updated_by -FROM - store s -WHERE - s.id = ? AND s.status = 'ACTIVE'; - --- 수정 -UPDATE - store -SET - address = ?, business_reg_num = ?, contact = ?, name = ?, - region_code = ?, status = ?, updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**모든 매장 조회** - -```sql -SELECT - s.id, s.address, s.business_reg_num, s.contact, s.created_at, - s.created_by, s.name, s.region_code, s.status, s.updated_at, - s.updated_by -FROM - store s -WHERE - s.status = 'ACTIVE' - AND (? IS NULL OR s.region_code LIKE ?); -``` - -**개별 매장 상세 조회** - -```sql -SELECT - s.id, s.address, s.business_reg_num, s.contact, s.created_at, - s.created_by, s.name, s.region_code, s.status, s.updated_at, - s.updated_by -FROM - store s -WHERE - s.id = ? AND s.status = 'ACTIVE'; -``` - -### Theme - -**생성** - -```sql --- 이름으로 조회 -SELECT - t.id -FROM - theme t -WHERE - t.name = ? -LIMIT 1; - --- 추가 -INSERT INTO theme ( - available_minutes, created_at, created_by, description, difficulty, - expected_minutes_from, expected_minutes_to, is_active, max_participants, - min_participants, name, price, thumbnail_url, updated_at, updated_by, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**Active인 모든 테마 조회** - -```sql -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.is_active = TRUE; -``` - -**테마 목록 조회** - -```sql -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t; -``` - -**감사 정보 포함 개별 테마 상세 조회** - -```sql -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.id = ?; -``` - -**개별 테마 조회** - -```sql -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.id = ?; -``` - -**삭제** - -```sql --- 조회 -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.id = ?; - --- 삭제 -DELETE FROM theme WHERE id = ?; -``` - -**수정** - -```sql --- 조회 -SELECT - t.id, t.available_minutes, t.created_at, t.created_by, t.description, - t.difficulty, t.expected_minutes_from, t.expected_minutes_to, - t.is_active, t.max_participants, t.min_participants, t.name, - t.price, t.thumbnail_url, t.updated_at, t.updated_by -FROM - theme t -WHERE - t.id = ?; - --- 수정 -UPDATE - theme -SET - available_minutes = ?, description = ?, difficulty = ?, - expected_minutes_from = ?, expected_minutes_to = ?, is_active = ?, - max_participants = ?, min_participants = ?, name = ?, price = ?, - thumbnail_url = ?, updated_at = ?, updated_by = ? -WHERE - id = ?; -``` - -**인기 테마 조회** - -```sql -SELECT - t.id, t.name, t.description, t.difficulty, t.thumbnail_url, t.price, - t.min_participants, t.max_participants, - t.available_minutes, t.expected_minutes_from, t.expected_minutes_to -FROM - theme t - JOIN ( - SELECT - s.theme_id, count(*) as reservation_count - FROM - schedule s - JOIN - reservation r ON s.id = r.schedule_id AND r.status = 'CONFIRMED' - WHERE - s.status = 'RESERVED' - AND (s.date BETWEEN :startFrom AND :endAt) - GROUP BY - s.theme_id - ORDER BY - reservation_count desc - LIMIT :count - ) ranked_themes ON t.id = ranked_themes.theme_id -``` - -### User - -**회원가입** - -```sql --- 이메일 중복 확인 -SELECT - u.id -FROM - users u -WHERE - u.email = ? -LIMIT 1; - --- 연락처 중복 확인 -SELECT - u.id -FROM - users u -WHERE - u.phone = ? -LIMIT 1; - --- 추가 -INSERT INTO users ( - created_at, created_by, email, name, password, phone, region_code, - status, updated_at, updated_by, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? -); - --- 상태 변경 이력 추가 -INSERT INTO user_status_history ( - created_at, created_by, reason, status, updated_at, updated_by, - user_id, id -) VALUES ( - ?, ?, ?, ?, ?, ?, ?, ? -); -``` - -**연락처 정보 조회** - -```sql -SELECT - u.id, u.created_at, u.created_by, u.email, u.name, u.password, - u.phone, u.region_code, u.status, u.updated_at, u.updated_by -FROM - users u -WHERE - u.id = ?; -``` \ No newline at end of file diff --git a/service/src/main/kotlin/com/sangdol/roomescape/RoomescapeApplication.kt b/service/src/main/kotlin/com/sangdol/roomescape/RoomescapeApplication.kt index b44858ca..9aecb8dd 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/RoomescapeApplication.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/RoomescapeApplication.kt @@ -4,9 +4,13 @@ import org.springframework.boot.Banner import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.cache.annotation.EnableCaching +import org.springframework.scheduling.annotation.EnableAsync +import org.springframework.scheduling.annotation.EnableScheduling import java.util.* +@EnableAsync @EnableCaching +@EnableScheduling @SpringBootApplication( scanBasePackages = ["com.sangdol.roomescape", "com.sangdol.common"] ) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/admin/business/AdminService.kt b/service/src/main/kotlin/com/sangdol/roomescape/admin/business/AdminService.kt index cb1c02fb..447e4ab1 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/admin/business/AdminService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/admin/business/AdminService.kt @@ -20,7 +20,7 @@ class AdminService( ) { @Transactional(readOnly = true) fun findCredentialsByAccount(account: String): AdminLoginCredentials { - log.info { "[findCredentialsByAccount] 관리자 조회 시작: account=${account}" } + log.debug { "[findCredentialsByAccount] 관리자 조회 시작: account=${account}" } return adminRepository.findByAccount(account) ?.let { @@ -28,14 +28,14 @@ class AdminService( it.toCredentials() } ?: run { - log.info { "[findCredentialsByAccount] 관리자 조회 실패: account=${account}" } + log.debug { "[findCredentialsByAccount] 관리자 조회 실패: account=${account}" } throw AdminException(AdminErrorCode.ADMIN_NOT_FOUND) } } @Transactional(readOnly = true) fun findOperatorOrUnknown(id: Long): Auditor { - log.info { "[findOperatorById] 작업자 정보 조회 시작: id=${id}" } + log.debug { "[findOperatorById] 작업자 정보 조회 시작: id=${id}" } return adminRepository.findByIdOrNull(id)?.let { admin -> Auditor(admin.id, admin.name).also { diff --git a/service/src/main/kotlin/com/sangdol/roomescape/auth/business/AuthService.kt b/service/src/main/kotlin/com/sangdol/roomescape/auth/business/AuthService.kt index 8938a1fd..c4a89425 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/auth/business/AuthService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/auth/business/AuthService.kt @@ -33,7 +33,7 @@ class AuthService( request: LoginRequest, context: LoginContext ): LoginSuccessResponse { - log.info { "[login] 로그인 시작: account=${request.account}, type=${request.principalType}, context=${context}" } + log.debug { "[login] 로그인 시작: account=${request.account}, type=${request.principalType}, context=${context}" } val (credentials, extraClaims) = getCredentials(request) val event = LoginHistoryEvent( @@ -56,10 +56,7 @@ class AuthService( } catch (e: Exception) { eventPublisher.publishEvent(event.onFailure()) when (e) { - is AuthException -> { - log.info { "[login] 로그인 실패: account = ${request.account}" } - throw e - } + is AuthException -> { throw e } else -> { log.warn { "[login] 로그인 실패: message=${e.message} account = ${request.account}" } @@ -74,7 +71,7 @@ class AuthService( credentials: LoginCredentials ) { if (credentials.password != request.password) { - log.info { "[login] 비밀번호 불일치로 인한 로그인 실패: account = ${request.account}" } + log.debug { "[login] 비밀번호 불일치로 인한 로그인 실패: account = ${request.account}" } throw AuthException(AuthErrorCode.LOGIN_FAILED) } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/auth/business/LoginHistoryEventListener.kt b/service/src/main/kotlin/com/sangdol/roomescape/auth/business/LoginHistoryEventListener.kt index 5a9f0ca1..bb6841dc 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/auth/business/LoginHistoryEventListener.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/auth/business/LoginHistoryEventListener.kt @@ -11,8 +11,6 @@ import jakarta.annotation.PreDestroy import org.springframework.beans.factory.annotation.Value import org.springframework.context.event.EventListener import org.springframework.scheduling.annotation.Async -import org.springframework.scheduling.annotation.EnableAsync -import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component import java.util.concurrent.ConcurrentLinkedQueue @@ -21,8 +19,6 @@ import java.util.concurrent.TimeUnit private val log: KLogger = KotlinLogging.logger {} @Component -@EnableAsync -@EnableScheduling class LoginHistoryEventListener( private val idGenerator: IDGenerator, private val loginHistoryRepository: LoginHistoryRepository, @@ -35,7 +31,7 @@ class LoginHistoryEventListener( @Async @EventListener(classes = [LoginHistoryEvent::class]) fun onLoginCompleted(event: LoginHistoryEvent) { - log.info { "[onLoginCompleted] 로그인 이력 저장 이벤트 수신: id=${event.id}, type=${event.type}" } + log.debug { "[onLoginCompleted] 로그인 이력 저장 이벤트 수신: id=${event.id}, type=${event.type}" } queue.add(event.toEntity(idGenerator.create())).also { log.info { "[onLoginCompleted] 로그인 이력 저장 이벤트 큐 저장 완료: id=${event.id}, type=${event.type}" } @@ -48,10 +44,10 @@ class LoginHistoryEventListener( @Scheduled(fixedRate = 30, timeUnit = TimeUnit.SECONDS) fun flushScheduled() { - log.info { "[flushScheduled] 큐에 저장된 로그인 이력 저장 시작: size=${queue.size}" } + log.debug { "[flushScheduled] 큐에 저장된 로그인 이력 저장 시작: size=${queue.size}" } if (queue.isEmpty()) { - log.info { "[flushScheduled] 큐에 있는 로그인 이력이 없음." } + log.debug { "[flushScheduled] 큐에 있는 로그인 이력이 없음." } return } flush() @@ -60,7 +56,7 @@ class LoginHistoryEventListener( @PreDestroy fun flushAll() { - log.info { "[flushAll] 애플리케이션 종료. 큐에 있는 모든 이력 저장 시작: size=${queue.size}" } + log.debug { "[flushAll] 애플리케이션 종료. 큐에 있는 모든 이력 저장 시작: size=${queue.size}" } while (!queue.isEmpty()) { flush() } @@ -68,10 +64,10 @@ class LoginHistoryEventListener( } private fun flush() { - log.info { "[flush] 큐에 저장된 로그인 이력 저장 시작: size=${queue.size}" } + log.debug { "[flush] 큐에 저장된 로그인 이력 저장 시작: size=${queue.size}" } if (queue.isEmpty()) { - log.info { "[flush] 큐에 있는 로그인 이력이 없음." } + log.debug { "[flush] 큐에 있는 로그인 이력이 없음." } return; } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/auth/infrastructure/jwt/JwtUtils.kt b/service/src/main/kotlin/com/sangdol/roomescape/auth/infrastructure/jwt/JwtUtils.kt index 28be6c61..ea8920ce 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/auth/infrastructure/jwt/JwtUtils.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/auth/infrastructure/jwt/JwtUtils.kt @@ -50,7 +50,7 @@ class JwtUtils( val claims = extractAllClaims(token) return claims.subject ?: run { - log.info { "[JwtUtils.extractSubject] subject를 찾을 수 없음.: token = ${token}" } + log.debug { "[JwtUtils.extractSubject] subject를 찾을 수 없음.: token = ${token}" } throw AuthException(AuthErrorCode.INVALID_TOKEN) } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderService.kt b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderService.kt index e77703f6..415d5236 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderService.kt @@ -32,7 +32,7 @@ class OrderService( fun confirm(reservationId: Long, paymentConfirmRequest: PaymentConfirmRequest) { val paymentKey = paymentConfirmRequest.paymentKey - log.info { "[confirm] 결제 및 예약 확정 시작: reservationId=${reservationId}, paymentKey=${paymentKey}" } + log.debug { "[confirm] 결제 및 예약 확정 시작: reservationId=${reservationId}, paymentKey=${paymentKey}" } try { transactionExecutionUtil.withNewTransaction(isReadOnly = false) { validateCanConfirm(reservationId) @@ -42,7 +42,7 @@ class OrderService( paymentService.requestConfirm(reservationId, paymentConfirmRequest) eventPublisher.publishEvent(ReservationConfirmEvent(reservationId)) - log.info { "[confirm] 결제 처리 및 예약 확정 이벤트 발행 완료" } + log.info { "[confirm] 결제 처리 및 예약 확정 이벤트 발행 완료: reservationId=${reservationId}, paymentKey=${paymentKey}" } } catch (e: Exception) { val errorCode: ErrorCode = if (e is RoomescapeException) { e.errorCode @@ -55,7 +55,7 @@ class OrderService( } private fun validateCanConfirm(reservationId: Long) { - log.info { "[validateAndMarkInProgress] 예약 확정 가능 여부 검증 시작: reservationId=${reservationId}" } + log.debug { "[validateAndMarkInProgress] 예약 확정 가능 여부 검증 시작: reservationId=${reservationId}" } val reservation: ReservationStateResponse = reservationService.findStatusWithLock(reservationId) val schedule: ScheduleStateResponse = scheduleService.findStateWithLock(reservation.scheduleId) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderValidator.kt b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderValidator.kt index b2d724b8..b5dda52f 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderValidator.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/order/business/OrderValidator.kt @@ -27,15 +27,12 @@ class OrderValidator { private fun validateReservationStatus(reservation: ReservationStateResponse) { when (reservation.status) { ReservationStatus.CONFIRMED -> { - log.info { "[validateCanConfirm] 이미 확정된 예약: id=${reservation.id}" } throw OrderException(OrderErrorCode.ORDER_ALREADY_CONFIRMED) } ReservationStatus.EXPIRED -> { - log.info { "[validateCanConfirm] 만료된 예약: id=${reservation.id}" } throw OrderException(OrderErrorCode.EXPIRED_RESERVATION) } ReservationStatus.CANCELED -> { - log.info { "[validateCanConfirm] 취소된 예약: id=${reservation.id}" } throw OrderException(OrderErrorCode.CANCELED_RESERVATION) } else -> {} @@ -44,14 +41,14 @@ class OrderValidator { private fun validateScheduleStatus(schedule: ScheduleStateResponse) { if (schedule.status != ScheduleStatus.HOLD) { - log.info { "[validateScheduleStatus] 일정 상태 오류: status=${schedule.status}" } + log.debug { "[validateScheduleStatus] 일정 상태 오류: status=${schedule.status}" } throw OrderException(OrderErrorCode.EXPIRED_RESERVATION) } val scheduleDateTime = LocalDateTime.of(schedule.date, schedule.startFrom) val nowDateTime = KoreaDateTime.now() if (scheduleDateTime.isBefore(nowDateTime)) { - log.info { "[validateScheduleStatus] 과거 시간인 일정으로 인한 실패: scheduleDateTime=${scheduleDateTime}(KST), now=${nowDateTime}(KST)" } + log.debug { "[validateScheduleStatus] 과거 시간인 일정으로 인한 실패: scheduleDateTime=${scheduleDateTime}(KST), now=${nowDateTime}(KST)" } throw OrderException(OrderErrorCode.PAST_SCHEDULE) } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/payment/business/PaymentService.kt b/service/src/main/kotlin/com/sangdol/roomescape/payment/business/PaymentService.kt index 3998f46e..11e840b1 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/payment/business/PaymentService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/payment/business/PaymentService.kt @@ -31,7 +31,7 @@ class PaymentService( private val eventPublisher: ApplicationEventPublisher ) { fun requestConfirm(reservationId: Long, request: PaymentConfirmRequest): PaymentGatewayResponse { - log.info { "[requestConfirm] 결제 요청 시작: paymentKey=${request.paymentKey}" } + log.debug { "[requestConfirm] 결제 요청 시작: paymentKey=${request.paymentKey}" } try { return paymentClient.confirm(request.paymentKey, request.orderId, request.amount).also { eventPublisher.publishEvent(it.toEvent(reservationId)) @@ -90,7 +90,7 @@ class PaymentService( @Transactional(readOnly = true) fun findDetailByReservationId(reservationId: Long): PaymentResponse? { - log.info { "[findDetailByReservationId] 예약 결제 정보 조회 시작: reservationId=$reservationId" } + log.debug { "[findDetailByReservationId] 예약 결제 정보 조회 시작: reservationId=$reservationId" } val payment: PaymentEntity? = findByReservationIdOrNull(reservationId) val paymentDetail: PaymentDetailEntity? = payment?.let { findDetailByPaymentIdOrNull(it.id) } @@ -99,11 +99,13 @@ class PaymentService( return payment?.toResponse( detail = paymentDetail?.toResponse(), cancel = cancelDetail?.toResponse() - ) + ).also { + log.info { "[findDetailByReservationId] 예약 결제 정보 조회 완료: reservationId=$reservationId" } + } } private fun findByReservationIdOrThrow(reservationId: Long): PaymentEntity { - log.info { "[findByReservationIdOrThrow] 결제 정보 조회 시작: reservationId=: $reservationId" } + log.debug { "[findByReservationIdOrThrow] 결제 정보 조회 시작: reservationId=: $reservationId" } return paymentRepository.findByReservationId(reservationId) ?.also { log.info { "[findByReservationIdOrThrow] 결제 정보 조회 완료: reservationId=$reservationId, paymentId=${it.id}" } } @@ -114,7 +116,7 @@ class PaymentService( } private fun findByReservationIdOrNull(reservationId: Long): PaymentEntity? { - log.info { "[findByReservationIdOrThrow] 결제 정보 조회 시작: reservationId=: $reservationId" } + log.debug { "[findByReservationIdOrThrow] 결제 정보 조회 시작: reservationId=: $reservationId" } return paymentRepository.findByReservationId(reservationId) .also { @@ -127,7 +129,7 @@ class PaymentService( } private fun findDetailByPaymentIdOrNull(paymentId: Long): PaymentDetailEntity? { - log.info { "[findDetailByPaymentIdOrThrow] 결제 상세 정보 조회 시작: paymentId=$paymentId" } + log.debug { "[findDetailByPaymentIdOrThrow] 결제 상세 정보 조회 시작: paymentId=$paymentId" } return paymentDetailRepository.findByPaymentId(paymentId).also { if (it != null) { @@ -139,7 +141,7 @@ class PaymentService( } private fun findCancelByPaymentIdOrNull(paymentId: Long): CanceledPaymentEntity? { - log.info { "[findDetailByReservationId] 취소 결제 정보 조회 시작: paymentId=${paymentId}" } + log.debug { "[findDetailByReservationId] 취소 결제 정보 조회 시작: paymentId=${paymentId}" } return canceledPaymentRepository.findByPaymentId(paymentId).also { if (it == null) { diff --git a/service/src/main/kotlin/com/sangdol/roomescape/payment/business/event/PaymentEventListener.kt b/service/src/main/kotlin/com/sangdol/roomescape/payment/business/event/PaymentEventListener.kt index 6ef93f0b..f6a35f5e 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/payment/business/event/PaymentEventListener.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/payment/business/event/PaymentEventListener.kt @@ -29,20 +29,16 @@ class PaymentEventListener( fun handlePaymentEvent(event: PaymentEvent) { val reservationId = event.reservationId - log.info { "[handlePaymentEvent] 결제 정보 저장 이벤트 수신: reservationId=${reservationId}, paymentKey=${event.paymentKey}" } + log.debug { "[handlePaymentEvent] 결제 정보 저장 이벤트 수신: reservationId=${reservationId}, paymentKey=${event.paymentKey}" } val paymentId = idGenerator.create() val paymentEntity: PaymentEntity = event.toEntity(paymentId) - paymentRepository.save(paymentEntity).also { - log.info { "[handlePaymentEvent] 결제 정보 저장 완료: paymentId=${paymentId}" } - } + paymentRepository.save(paymentEntity) val paymentDetailId = idGenerator.create() val paymentDetailEntity: PaymentDetailEntity = event.toDetailEntity(id = paymentDetailId, paymentId = paymentId) - paymentDetailRepository.save(paymentDetailEntity).also { - log.info { "[handlePaymentEvent] 결제 상세 저장 완료: paymentDetailId=${paymentDetailId}" } - } + paymentDetailRepository.save(paymentDetailEntity) - log.info { "[handlePaymentEvent] 결제 정보 저장 이벤트 처리 완료" } + log.info { "[handlePaymentEvent] 결제 정보 저장 이벤트 처리 완료: reservationId=${reservationId}, paymentId=${paymentId}, paymentDetailId=${paymentDetailId}" } } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/payment/infrastructure/client/TosspayClient.kt b/service/src/main/kotlin/com/sangdol/roomescape/payment/infrastructure/client/TosspayClient.kt index d769bb35..1a963d53 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/payment/infrastructure/client/TosspayClient.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/payment/infrastructure/client/TosspayClient.kt @@ -33,7 +33,7 @@ class TosspayClient( amount: Int, ): PaymentGatewayResponse { val startTime = System.currentTimeMillis() - log.info { "[TosspayClient.confirm] 결제 승인 요청: paymentKey=$paymentKey, orderId=$orderId, amount=$amount" } + log.debug { "[TosspayClient.confirm] 결제 승인 요청: paymentKey=$paymentKey, orderId=$orderId, amount=$amount" } return confirmClient.request(paymentKey, orderId, amount) .also { @@ -47,7 +47,7 @@ class TosspayClient( cancelReason: String ): PaymentGatewayCancelResponse { val startTime = System.currentTimeMillis() - log.info { "[TosspayClient.cancel] 결제 취소 요청: paymentKey=$paymentKey, amount=$amount, cancelReason=$cancelReason" } + log.debug { "[TosspayClient.cancel] 결제 취소 요청: paymentKey=$paymentKey, amount=$amount, cancelReason=$cancelReason" } return cancelClient.request(paymentKey, amount, cancelReason).also { log.info { "[TosspayClient.cancel] 결제 취소 완료: duration_ms=${System.currentTimeMillis() - startTime}ms, paymentKey=$paymentKey" } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/region/business/RegionService.kt b/service/src/main/kotlin/com/sangdol/roomescape/region/business/RegionService.kt index fe89cc63..58959ad1 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/region/business/RegionService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/region/business/RegionService.kt @@ -17,7 +17,7 @@ class RegionService( ) { @Transactional(readOnly = true) fun readAllSido(): SidoListResponse { - log.info { "[readAllSido] 모든 시/도 조회 시작" } + log.debug { "[readAllSido] 모든 시/도 조회 시작" } val result: List> = regionRepository.readAllSido() if (result.isEmpty()) { @@ -32,7 +32,7 @@ class RegionService( @Transactional(readOnly = true) fun findSigunguBySido(sidoCode: String): SigunguListResponse { - log.info { "[findSigunguBySido] 시/군/구 조회 시작: sidoCode=${sidoCode}" } + log.debug { "[findSigunguBySido] 시/군/구 조회 시작: sidoCode=${sidoCode}" } val result: List> = regionRepository.findAllSigunguBySido(sidoCode) if (result.isEmpty()) { @@ -47,7 +47,7 @@ class RegionService( @Transactional(readOnly = true) fun findRegionCode(sidoCode: String, sigunguCode: String): RegionCodeResponse { - log.info { "[findRegionCode] 지역 코드 조회 시작: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" } + log.debug { "[findRegionCode] 지역 코드 조회 시작: sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" } return regionRepository.findRegionCode(sidoCode, sigunguCode)?.let { log.info { "[findRegionCode] 지역 코드 조회 완료: code=${it} sidoCode=${sidoCode} / sigunguCode=${sigunguCode}" } @@ -60,7 +60,7 @@ class RegionService( @Transactional(readOnly = true) fun findRegionInfo(regionCode: String): RegionInfoResponse { - log.info { "[findRegionInfo] 지역 정보 조회 시작: regionCode=${regionCode}" } + log.debug { "[findRegionInfo] 지역 정보 조회 시작: regionCode=${regionCode}" } return regionRepository.findByCode(regionCode)?.let { log.info { "[findRegionInfo] 지역 정보 조회 완료: code=${it} regionCode=${regionCode}" } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt index 8496801d..c021a7eb 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationService.kt @@ -45,7 +45,7 @@ class ReservationService( user: CurrentUserContext, request: PendingReservationCreateRequest ): PendingReservationCreateResponse { - log.info { "[createPendingReservation] Pending 예약 생성 시작: schedule=${request.scheduleId}" } + log.debug { "[createPendingReservation] Pending 예약 생성 시작: schedule=${request.scheduleId}" } run { val schedule: ScheduleStateResponse = scheduleService.findStateWithLock(request.scheduleId) @@ -64,7 +64,7 @@ class ReservationService( @Transactional fun confirmReservation(id: Long) { - log.info { "[confirmReservation] Pending 예약 확정 시작: reservationId=${id}" } + log.debug { "[confirmReservation] Pending 예약 확정 시작: reservationId=${id}" } val reservation: ReservationEntity = findOrThrow(id) run { @@ -81,7 +81,7 @@ class ReservationService( @Transactional fun cancelReservation(user: CurrentUserContext, reservationId: Long, request: ReservationCancelRequest) { - log.info { "[cancelReservation] 예약 취소 시작: userId=${user.id}, reservationId=${reservationId}" } + log.debug { "[cancelReservation] 예약 취소 시작: userId=${user.id}, reservationId=${reservationId}" } val reservation: ReservationEntity = findOrThrow(reservationId) @@ -100,7 +100,7 @@ class ReservationService( @Transactional(readOnly = true) fun findAllUserReservationOverview(user: CurrentUserContext): ReservationOverviewListResponse { - log.info { "[findSummaryByMemberId] 예약 조회 시작: userId=${user.id}" } + log.debug { "[findSummaryByMemberId] 예약 조회 시작: userId=${user.id}" } val reservations: List = reservationRepository.findAllByUserIdAndStatusIsIn( userId = user.id, @@ -125,7 +125,7 @@ class ReservationService( @Transactional(readOnly = true) fun findDetailById(id: Long): ReservationAdditionalResponse { - log.info { "[findDetailById] 예약 상세 조회 시작: reservationId=${id}" } + log.debug { "[findDetailById] 예약 상세 조회 시작: reservationId=${id}" } val reservation: ReservationEntity = findOrThrow(id) val user: UserContactResponse = userService.findContactById(reservation.userId) @@ -141,7 +141,7 @@ class ReservationService( @Transactional(readOnly = true) fun findStatusWithLock(id: Long): ReservationStateResponse { - log.info { "[findStatusWithLock] 예약 LOCK + 상태 조회 시작: reservationId=${id}" } + log.debug { "[findStatusWithLock] 예약 LOCK + 상태 조회 시작: reservationId=${id}" } return reservationRepository.findByIdForUpdate(id)?.let { log.info { "[findStatusWithLock] 예약 LOCK + 상태 조회 완료: reservationId=${id}" } @@ -154,7 +154,7 @@ class ReservationService( @Transactional fun markInProgress(reservationId: Long) { - log.info { "[markInProgress] 예약 상태 ${ReservationStatus.PAYMENT_IN_PROGRESS} 변경 시작." } + log.debug { "[markInProgress] 예약 상태 ${ReservationStatus.PAYMENT_IN_PROGRESS} 변경 시작." } findOrThrow(reservationId).apply { this.status = ReservationStatus.PAYMENT_IN_PROGRESS @@ -164,7 +164,7 @@ class ReservationService( } private fun findOrThrow(id: Long): ReservationEntity { - log.info { "[findOrThrow] 예약 조회 시작: reservationId=${id}" } + log.debug { "[findOrThrow] 예약 조회 시작: reservationId=${id}" } return reservationRepository.findByIdOrNull(id) ?.also { log.info { "[findOrThrow] 예약 조회 완료: reservationId=${id}" } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationValidator.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationValidator.kt index f0993c21..da97b442 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationValidator.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/ReservationValidator.kt @@ -1,17 +1,15 @@ package com.sangdol.roomescape.reservation.business import com.sangdol.common.utils.KoreaDateTime -import com.sangdol.common.utils.toKoreaDateTime +import com.sangdol.roomescape.reservation.dto.PendingReservationCreateRequest import com.sangdol.roomescape.reservation.exception.ReservationErrorCode import com.sangdol.roomescape.reservation.exception.ReservationException -import com.sangdol.roomescape.reservation.dto.PendingReservationCreateRequest import com.sangdol.roomescape.schedule.dto.ScheduleStateResponse import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleStatus import com.sangdol.roomescape.theme.dto.ThemeInfoResponse import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KotlinLogging import org.springframework.stereotype.Component -import java.time.Instant import java.time.LocalDateTime private val log: KLogger = KotlinLogging.logger {} diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/event/ReservationEventListener.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/event/ReservationEventListener.kt index 60dad491..f7c6860c 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/event/ReservationEventListener.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/event/ReservationEventListener.kt @@ -22,7 +22,7 @@ class ReservationEventListener( fun handleReservationConfirmEvent(event: ReservationConfirmEvent) { val reservationId = event.reservationId - log.info { "[handleReservationConfirmEvent] 예약 확정 이벤트 수신: reservationId=${reservationId}" } + log.debug { "[handleReservationConfirmEvent] 예약 확정 이벤트 수신: reservationId=${reservationId}" } val modifiedRows = reservationRepository.confirmReservation(Instant.now(), reservationId) if (modifiedRows == 0) { diff --git a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/scheduler/IncompletedReservationScheduler.kt b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/scheduler/IncompletedReservationScheduler.kt index 6b596e41..4f5a98a5 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/scheduler/IncompletedReservationScheduler.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/reservation/business/scheduler/IncompletedReservationScheduler.kt @@ -5,7 +5,6 @@ import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleReposi import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleStatus import io.github.oshai.kotlinlogging.KLogger import io.github.oshai.kotlinlogging.KotlinLogging -import org.springframework.scheduling.annotation.EnableScheduling import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional @@ -15,7 +14,6 @@ import java.util.concurrent.TimeUnit private val log: KLogger = KotlinLogging.logger {} @Component -@EnableScheduling class IncompletedReservationScheduler( private val scheduleRepository: ScheduleRepository, private val reservationRepository: ReservationRepository @@ -24,10 +22,10 @@ class IncompletedReservationScheduler( @Scheduled(initialDelay = 1, fixedRate = 1, timeUnit = TimeUnit.MINUTES) @Transactional fun processExpiredHoldSchedule() { - log.info { "[processExpiredHoldSchedule] 만료 시간이 지난 ${ScheduleStatus.HOLD} 상태의 일정 재활성화 시작" } + log.debug { "[processExpiredHoldSchedule] 만료 시간이 지난 ${ScheduleStatus.HOLD} 상태의 일정 재활성화 시작" } val targets: List = scheduleRepository.findAllExpiredHeldSchedules(Instant.now()).also { - log.info { "[processExpiredHoldSchedule] ${it.size} 개의 일정 조회 완료" } + log.debug { "[processExpiredHoldSchedule] ${it.size} 개의 일정 조회 완료" } } scheduleRepository.releaseHeldSchedules(targets).also { @@ -38,7 +36,7 @@ class IncompletedReservationScheduler( @Scheduled(initialDelay = 1, fixedRate = 1, timeUnit = TimeUnit.MINUTES) @Transactional fun processExpiredReservation() { - log.info { "[processExpiredReservation] 결제되지 않은 예약 만료 처리 시작" } + log.debug { "[processExpiredReservation] 결제되지 않은 예약 만료 처리 시작" } val targets: List = reservationRepository.findAllExpiredReservation().also { log.info { "[processExpiredReservation] ${it.size} 개의 예약 조회 완료" } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/AdminScheduleService.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/AdminScheduleService.kt index cf400d8e..d6901b1b 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/AdminScheduleService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/AdminScheduleService.kt @@ -34,7 +34,7 @@ class AdminScheduleService( ) { @Transactional(readOnly = true) fun searchSchedules(storeId: Long, date: LocalDate?, themeId: Long?): AdminScheduleSummaryListResponse { - log.info { "[searchSchedules] 일정 검색 시작: storeId=$storeId, date=$date, themeId=$themeId" } + log.debug { "[searchSchedules] 일정 검색 시작: storeId=$storeId, date=$date, themeId=$themeId" } val searchDate = date ?: KoreaDate.today() @@ -44,14 +44,12 @@ class AdminScheduleService( .sortedBy { it.time } return schedules.toAdminSummaryResponse() - .also { - log.info { "[searchSchedules] ${it.schedules.size} 개의 일정 조회 완료" } - } + .also { log.info { "[searchSchedules] ${it.schedules.size} 개의 일정 조회 완료" } } } @Transactional(readOnly = true) fun findScheduleAudit(id: Long): AuditingInfo { - log.info { "[findDetail] 일정 감사 정보 조회 시작: id=$id" } + log.debug { "[findDetail] 일정 감사 정보 조회 시작: id=$id" } val schedule: ScheduleEntity = findOrThrow(id) @@ -64,7 +62,7 @@ class AdminScheduleService( @Transactional fun createSchedule(storeId: Long, request: ScheduleCreateRequest): ScheduleCreateResponse { - log.info { "[createSchedule] 일정 생성 시작: storeId=${storeId}, date=${request.date}, time=${request.time}, themeId=${request.themeId}" } + log.debug { "[createSchedule] 일정 생성 시작: storeId=${storeId}, date=${request.date}, time=${request.time}, themeId=${request.themeId}" } scheduleValidator.validateCanCreate(storeId, request) @@ -79,14 +77,12 @@ class AdminScheduleService( } return ScheduleCreateResponse(schedule.id) - .also { - log.info { "[createSchedule] 일정 생성 완료: id=${it.id}" } - } + .also { log.info { "[createSchedule] 일정 생성 완료: id=${it.id}" } } } @Transactional fun updateSchedule(id: Long, request: ScheduleUpdateRequest) { - log.info { "[updateSchedule] 일정 수정 시작: id=$id, request=${request}" } + log.debug { "[updateSchedule] 일정 수정 시작: id=$id, request=${request}" } if (request.isAllParamsNull()) { log.info { "[updateSchedule] 일정 변경 사항 없음: id=$id" } @@ -104,7 +100,7 @@ class AdminScheduleService( @Transactional fun deleteSchedule(id: Long) { - log.info { "[deleteSchedule] 일정 삭제 시작: id=$id" } + log.debug { "[deleteSchedule] 일정 삭제 시작: id=$id" } val schedule: ScheduleEntity = findOrThrow(id).also { scheduleValidator.validateCanDelete(it) @@ -116,7 +112,7 @@ class AdminScheduleService( } private fun findOrThrow(id: Long): ScheduleEntity { - log.info { "[findOrThrow] 일정 조회 시작: id=$id" } + log.debug { "[findOrThrow] 일정 조회 시작: id=$id" } return scheduleRepository.findByIdOrNull(id) ?.also { log.info { "[findOrThrow] 일정 조회 완료: id=$id" } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt index 0c7e1576..30536fe0 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt @@ -30,13 +30,12 @@ class ScheduleService( ) { @Transactional(readOnly = true) fun getStoreScheduleByDate(storeId: Long, date: LocalDate): ScheduleWithThemeListResponse { - log.info { "[getStoreScheduleByDate] 매장 일정 조회: storeId=${storeId}, date=$date" } + log.debug { "[getStoreScheduleByDate] 매장 일정 조회 시작: storeId=${storeId}, date=$date" } val currentDate: LocalDate = KoreaDate.today() val currentTime: LocalTime = KoreaTime.now() if (date.isBefore(currentDate)) { - log.warn { "[getStoreScheduleByDate] 이전 날짜 선택으로 인한 실패: date=${date}" } throw ScheduleException(ScheduleErrorCode.PAST_DATE_TIME) } @@ -44,6 +43,7 @@ class ScheduleService( scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date) .filter { it.date.isAfter(currentDate) || it.time.isAfter(currentTime) } + return schedules.toResponseWithTheme() .also { log.info { "[getStoreScheduleByDate] storeId=${storeId}, date=$date 인 ${it.schedules.size}개 일정 조회 완료" } @@ -52,7 +52,7 @@ class ScheduleService( @Transactional fun holdSchedule(id: Long) { - log.info { "[holdSchedule] 일정 Holding 시작: id=$id" } + log.debug { "[holdSchedule] 일정 Holding 시작: id=$id" } val schedule = findForUpdateOrThrow(id).also { scheduleValidator.validateCanHold(it) @@ -69,7 +69,7 @@ class ScheduleService( @Transactional(readOnly = true) fun findStateWithLock(id: Long): ScheduleStateResponse { - log.info { "[findDateTimeById] 일정 개요 조회 시작 : id=$id" } + log.debug { "[findDateTimeById] 일정 개요 조회 시작 : id=$id" } val schedule: ScheduleEntity = scheduleRepository.findByIdForUpdate(id) ?: run { @@ -95,7 +95,7 @@ class ScheduleService( @Transactional fun changeStatus(scheduleId: Long, currentStatus: ScheduleStatus, changeStatus: ScheduleStatus) { - log.info { "[reserveSchedule] 일정 상태 변경 시작: id=${scheduleId}, currentStatus=${currentStatus}, changeStatus=${changeStatus}" } + log.debug { "[reserveSchedule] 일정 상태 변경 시작: id=${scheduleId}, currentStatus=${currentStatus}, changeStatus=${changeStatus}" } scheduleRepository.changeStatus(scheduleId, currentStatus, changeStatus).also { log.info { "[reserveSchedule] 일정 상태 변경 완료: id=${scheduleId}, currentStatus=${currentStatus}, changeStatus=${changeStatus}" } @@ -103,7 +103,7 @@ class ScheduleService( } private fun findForUpdateOrThrow(id: Long): ScheduleEntity { - log.info { "[findForUpdateOrThrow] 일정 LOCK + 조회 시작: id=$id" } + log.debug { "[findForUpdateOrThrow] 일정 LOCK + 조회 시작: id=$id" } return scheduleRepository.findByIdForUpdate(id) ?.also { log.info { "[findForUpdateOrThrow] 일정 조회 완료: id=$id" } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleValidator.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleValidator.kt index 75deaa46..108dcc4e 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleValidator.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleValidator.kt @@ -59,7 +59,7 @@ class ScheduleValidator( private fun validateAlreadyExists(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime) { if (scheduleRepository.existsDuplicate(storeId, date, themeId, time)) { - log.info { + log.debug { "[validateAlreadyExists] 동일한 날짜, 테마, 시간 존재로 인한 실패: date=${date} / themeId=${themeId} / time=${time}" } throw ScheduleException(ScheduleErrorCode.SCHEDULE_ALREADY_EXISTS) @@ -71,7 +71,7 @@ class ScheduleValidator( val inputDateTime = LocalDateTime.of(date, time).truncatedTo(ChronoUnit.MINUTES) if (inputDateTime.isBefore(now)) { - log.info { + log.debug { "[validateDateTime] 이전 시간 선택으로 인한 실패: date=${date} / time=${time}" } throw ScheduleException(ScheduleErrorCode.PAST_DATE_TIME) @@ -82,7 +82,7 @@ class ScheduleValidator( scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date, themeId) .firstOrNull { it.containsTime(time) } ?.let { - log.info { "[validateTimeNotConflict] 시간이 겹치는 일정 존재: conflictSchedule(Id=${it.id}, time=${it.time}~${it.getEndAt()})" } + log.debug { "[validateTimeNotConflict] 시간이 겹치는 일정 존재: conflictSchedule(Id=${it.id}, time=${it.time}~${it.getEndAt()})" } throw ScheduleException(ScheduleErrorCode.SCHEDULE_TIME_CONFLICT) } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreService.kt b/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreService.kt index e82ce88e..e3114128 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreService.kt @@ -35,7 +35,7 @@ class StoreService( ) { @Transactional(readOnly = true) fun getDetail(id: Long): StoreDetailResponse { - log.info { "[getDetail] 매장 상세 조회 시작: id=${id}" } + log.debug { "[getDetail] 매장 상세 조회 시작: id=${id}" } val store: StoreEntity = findOrThrow(id) val region = regionService.findRegionInfo(store.regionCode) @@ -47,7 +47,7 @@ class StoreService( @Transactional fun register(request: StoreRegisterRequest): StoreRegisterResponse { - log.info { "[register] 매장 등록 시작: name=${request.name}" } + log.debug { "[register] 매장 등록 시작: name=${request.name}" } storeValidator.validateCanRegister(request) @@ -70,7 +70,7 @@ class StoreService( @Transactional fun update(id: Long, request: StoreUpdateRequest) { - log.info { "[update] 매장 수정 시작: id=${id}, request=${request}" } + log.debug { "[update] 매장 수정 시작: id=${id}, request=${request}" } storeValidator.validateCanUpdate(request) @@ -83,7 +83,7 @@ class StoreService( @Transactional fun disableById(id: Long) { - log.info { "[inactive] 매장 비활성화 시작: id=${id}" } + log.debug { "[inactive] 매장 비활성화 시작: id=${id}" } findOrThrow(id).apply { this.disable() @@ -94,7 +94,7 @@ class StoreService( @Transactional(readOnly = true) fun getAllActiveStores(sidoCode: String?, sigunguCode: String?): StoreNameListResponse { - log.info { "[getAllActiveStores] 전체 매장 조회 시작" } + log.debug { "[getAllActiveStores] 전체 매장 조회 시작" } val regionCode: String? = when { sidoCode == null && sigunguCode != null -> throw StoreException(StoreErrorCode.SIDO_CODE_REQUIRED) @@ -108,7 +108,7 @@ class StoreService( @Transactional(readOnly = true) fun findStoreInfo(id: Long): StoreInfoResponse { - log.info { "[findStoreInfo] 매장 정보 조회 시작: id=${id}" } + log.debug { "[findStoreInfo] 매장 정보 조회 시작: id=${id}" } val store: StoreEntity = findOrThrow(id) @@ -117,7 +117,7 @@ class StoreService( } private fun getAuditInfo(store: StoreEntity): AuditingInfo { - log.info { "[getAuditInfo] 감사 정보 조회 시작: storeId=${store.id}" } + log.debug { "[getAuditInfo] 감사 정보 조회 시작: storeId=${store.id}" } val createdBy = adminService.findOperatorOrUnknown(store.createdBy) val updatedBy = adminService.findOperatorOrUnknown(store.updatedBy) @@ -132,7 +132,7 @@ class StoreService( } private fun findOrThrow(id: Long): StoreEntity { - log.info { "[findOrThrow] 매장 조회 시작: id=${id}" } + log.debug { "[findOrThrow] 매장 조회 시작: id=${id}" } return storeRepository.findActiveStoreById(id) ?.also { diff --git a/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreValidator.kt b/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreValidator.kt index 3a9538e7..aad3eb8f 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreValidator.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/store/business/StoreValidator.kt @@ -31,21 +31,21 @@ class StoreValidator( private fun validateDuplicateNameExist(name: String) { if (storeRepository.existsByName(name)) { - log.info { "[StoreValidator.validateDuplicateNameExist] 이름 중복: name=${name}" } + log.debug { "[StoreValidator.validateDuplicateNameExist] 이름 중복: name=${name}" } throw StoreException(StoreErrorCode.STORE_NAME_DUPLICATED) } } private fun validateDuplicateContactExist(contact: String) { if (storeRepository.existsByContact(contact)) { - log.info { "[StoreValidator.validateDuplicateContact] 연락처 중복: contact=${contact}" } + log.debug { "[StoreValidator.validateDuplicateContact] 연락처 중복: contact=${contact}" } throw StoreException(StoreErrorCode.STORE_CONTACT_DUPLICATED) } } private fun validateDuplicateAddressExist(address: String) { if (storeRepository.existsByAddress(address)) { - log.info { "[StoreValidator.validateDuplicateAddress] 주소 중복: address=${address}" } + log.debug { "[StoreValidator.validateDuplicateAddress] 주소 중복: address=${address}" } throw StoreException(StoreErrorCode.STORE_ADDRESS_DUPLICATED) } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/theme/business/AdminThemeService.kt b/service/src/main/kotlin/com/sangdol/roomescape/theme/business/AdminThemeService.kt index 7496a2ae..a09eff60 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/theme/business/AdminThemeService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/theme/business/AdminThemeService.kt @@ -30,7 +30,7 @@ class AdminThemeService( ) { @Transactional(readOnly = true) fun findThemeSummaries(): ThemeSummaryListResponse { - log.info { "[findAdminThemes] 관리자 페이지에서의 테마 목록 조회 시작" } + log.debug { "[findAdminThemes] 관리자 페이지에서의 테마 목록 조회 시작" } return themeRepository.findAll() .toSummaryListResponse() @@ -39,7 +39,7 @@ class AdminThemeService( @Transactional(readOnly = true) fun findThemeDetail(id: Long): ThemeDetailResponse { - log.info { "[findAdminThemeDetail] 관리자 페이지에서의 테마 상세 정보 조회 시작: id=${id}" } + log.debug { "[findAdminThemeDetail] 관리자 페이지에서의 테마 상세 정보 조회 시작: id=${id}" } val theme: ThemeEntity = findOrThrow(id) @@ -53,7 +53,7 @@ class AdminThemeService( @Transactional(readOnly = true) fun findActiveThemes(): ThemeNameListResponse { - log.info { "[findActiveThemes] open 상태인 모든 테마 조회 시작" } + log.debug { "[findActiveThemes] open 상태인 모든 테마 조회 시작" } return themeRepository.findActiveThemes() .toNameListResponse() @@ -65,7 +65,7 @@ class AdminThemeService( @Transactional fun createTheme(request: ThemeCreateRequest): ThemeCreateResponse { - log.info { "[createTheme] 테마 생성 시작: name=${request.name}" } + log.debug { "[createTheme] 테마 생성 시작: name=${request.name}" } themeValidator.validateCanCreate(request) @@ -80,7 +80,7 @@ class AdminThemeService( @CacheEvict(cacheNames = ["theme-details"], key = "#id") @Transactional fun deleteTheme(id: Long) { - log.info { "[deleteTheme] 테마 삭제 시작: id=${id}" } + log.debug { "[deleteTheme] 테마 삭제 시작: id=${id}" } val theme: ThemeEntity = findOrThrow(id) @@ -92,7 +92,7 @@ class AdminThemeService( @CacheEvict(cacheNames = ["theme-details"], key = "#id") @Transactional fun updateTheme(id: Long, request: ThemeUpdateRequest) { - log.info { "[updateTheme] 테마 수정 시작: id=${id}, request=${request}" } + log.debug { "[updateTheme] 테마 수정 시작: id=${id}, request=${request}" } if (request.isAllParamsNull()) { log.info { "[updateTheme] 테마 변경 사항 없음: id=${id}" } @@ -121,7 +121,7 @@ class AdminThemeService( } private fun findOrThrow(id: Long): ThemeEntity { - log.info { "[findOrThrow] 테마 조회 시작: id=$id" } + log.debug { "[findOrThrow] 테마 조회 시작: id=$id" } return themeRepository.findByIdOrNull(id) ?.also { log.info { "[findOrThrow] 테마 조회 완료: id=$id" } } diff --git a/service/src/main/kotlin/com/sangdol/roomescape/theme/business/ThemeService.kt b/service/src/main/kotlin/com/sangdol/roomescape/theme/business/ThemeService.kt index 75824632..b2ae426d 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/theme/business/ThemeService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/theme/business/ThemeService.kt @@ -31,7 +31,7 @@ class ThemeService( @Cacheable(cacheNames = ["theme-details"], key="#id") @Transactional(readOnly = true) fun findInfoById(id: Long): ThemeInfoResponse { - log.info { "[findInfoById] 테마 조회 시작: id=$id" } + log.debug { "[findInfoById] 테마 조회 시작: id=$id" } val theme = themeRepository.findByIdOrNull(id)?.also { themeDetailQueryRequestCount.increment() @@ -46,7 +46,7 @@ class ThemeService( @Transactional(readOnly = true) fun findMostReservedThemeLastWeek(count: Int): ThemeInfoListResponse { - log.info { "[findMostReservedThemeLastWeek] 인기 테마 조회 시작: count=$count" } + log.debug { "[findMostReservedThemeLastWeek] 인기 테마 조회 시작: count=$count" } val previousWeekSunday = DateUtils.getSundayOfPreviousWeek(KoreaDate.today()) val previousWeekSaturday = previousWeekSunday.plusDays(6) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserService.kt b/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserService.kt index f51eced6..db6b4dfd 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserService.kt @@ -29,7 +29,7 @@ class UserService( ) { @Transactional(readOnly = true) fun findCredentialsByAccount(email: String): UserLoginCredentials { - log.info { "[findCredentialsByAccount] 회원 조회 시작: email=${email}" } + log.debug { "[findCredentialsByAccount] 회원 조회 시작: email=${email}" } return userRepository.findByEmail(email) ?.let { @@ -37,14 +37,13 @@ class UserService( it.toCredentials() } ?: run { - log.info { "[findCredentialsByAccount] 회원 조회 실패" } throw UserException(UserErrorCode.USER_NOT_FOUND) } } @Transactional(readOnly = true) fun findContactById(id: Long): UserContactResponse { - log.info { "[findContactById] 회원 연락 정보 조회 시작: id=${id}" } + log.debug { "[findContactById] 회원 연락 정보 조회 시작: id=${id}" } val user = findOrThrow(id) @@ -56,7 +55,7 @@ class UserService( @Transactional fun signup(request: UserCreateRequest): UserCreateResponse { - log.info { "[signup] 회원가입 시작: request:$request" } + log.debug { "[signup] 회원가입 시작: request:$request" } userValidator.validateCanSignup(request.email, request.phone) diff --git a/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserValidator.kt b/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserValidator.kt index ff7a4ec6..3b04f536 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserValidator.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/user/business/UserValidator.kt @@ -15,14 +15,14 @@ class UserValidator( ) { fun validateCanSignup(email: String, phone: String) { - log.info { "[UserValidator.validateCanSignup] 회원가입 가능 여부 검증 시작: email:$email / phone:$phone" } + log.debug { "[UserValidator.validateCanSignup] 회원가입 가능 여부 검증 시작: email:$email / phone:$phone" } if (userRepository.existsByEmail(email)) { - log.info { "[UserValidator.validateCanSignup] 중복된 이메일 입력으로 인한 실패: email:$email" } + log.debug { "[UserValidator.validateCanSignup] 중복된 이메일 입력으로 인한 실패: email:$email" } throw UserException(UserErrorCode.EMAIL_ALREADY_EXISTS) } if (userRepository.existsByPhone(phone)) { - log.info { "[UserValidator.validateCanSignup] 중복된 휴대폰 번호 입력으로 인한 실패: phone:$phone" } + log.debug { "[UserValidator.validateCanSignup] 중복된 휴대폰 번호 입력으로 인한 실패: phone:$phone" } throw UserException(UserErrorCode.PHONE_ALREADY_EXISTS) } }