Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions app.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.2.5)

2025-12-08T16:16:34.260+09:00 INFO 79230 --- [plango] [ main] plango.PlangoApplication : Starting PlangoApplication v0.0.1-SNAPSHOT using Java 21.0.6 with PID 79230 (/Users/katekwak1/BE/build/libs/plango-0.0.1-SNAPSHOT.jar started by katekwak1 in /Users/katekwak1/BE)
2025-12-08T16:16:34.261+09:00 INFO 79230 --- [plango] [ main] plango.PlangoApplication : The following 1 profile is active: "dev"
2025-12-08T16:16:35.430+09:00 INFO 79230 --- [plango] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-12-08T16:16:35.492+09:00 INFO 79230 --- [plango] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 57 ms. Found 15 JPA repository interfaces.
2025-12-08T16:16:36.151+09:00 INFO 79230 --- [plango] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 65028 (http)
2025-12-08T16:16:36.162+09:00 INFO 79230 --- [plango] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2025-12-08T16:16:36.163+09:00 INFO 79230 --- [plango] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.20]
2025-12-08T16:16:36.196+09:00 INFO 79230 --- [plango] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2025-12-08T16:16:36.197+09:00 INFO 79230 --- [plango] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1882 ms
2025-12-08T16:16:36.393+09:00 INFO 79230 --- [plango] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2025-12-08T16:16:36.600+09:00 INFO 79230 --- [plango] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@adc3344
2025-12-08T16:16:36.601+09:00 INFO 79230 --- [plango] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2025-12-08T16:16:36.646+09:00 INFO 79230 --- [plango] [ main] o.f.c.internal.license.VersionPrinter : Flyway Community Edition 9.22.3 by Redgate
2025-12-08T16:16:36.646+09:00 INFO 79230 --- [plango] [ main] o.f.c.internal.license.VersionPrinter : See release notes here: https://rd.gt/416ObMi
2025-12-08T16:16:36.646+09:00 INFO 79230 --- [plango] [ main] o.f.c.internal.license.VersionPrinter :
2025-12-08T16:16:36.703+09:00 INFO 79230 --- [plango] [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:mysql://localhost:3306/db25328 (MySQL 5.5)
2025-12-08T16:16:36.955+09:00 INFO 79230 --- [plango] [ main] o.f.core.internal.command.DbValidate : Successfully validated 28 migrations (execution time 00:00.105s)
2025-12-08T16:16:37.172+09:00 INFO 79230 --- [plango] [ main] o.f.core.internal.command.DbMigrate : Current version of schema `db25328`: 28
2025-12-08T16:16:37.179+09:00 INFO 79230 --- [plango] [ main] o.f.core.internal.command.DbMigrate : Schema `db25328` is up to date. No migration necessary.
2025-12-08T16:16:37.367+09:00 INFO 79230 --- [plango] [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-12-08T16:16:37.423+09:00 INFO 79230 --- [plango] [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.4.4.Final
2025-12-08T16:16:37.452+09:00 INFO 79230 --- [plango] [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2025-12-08T16:16:37.666+09:00 INFO 79230 --- [plango] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-12-08T16:16:37.732+09:00 WARN 79230 --- [plango] [ main] org.hibernate.dialect.Dialect : HHH000511: The 5.5.0 version for [org.hibernate.dialect.MySQLDialect] is no longer supported, hence certain features may not work properly. The minimum supported version is 8.0.0. Check the community dialects project for available legacy versions.
2025-12-08T16:16:37.736+09:00 WARN 79230 --- [plango] [ main] org.hibernate.orm.deprecation : HHH90000025: MySQLDialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default)
2025-12-08T16:16:38.664+09:00 INFO 79230 --- [plango] [ 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-12-08T16:16:39.160+09:00 INFO 79230 --- [plango] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-12-08T16:16:39.536+09:00 INFO 79230 --- [plango] [ main] o.s.d.j.r.query.QueryEnhancerFactory : Hibernate is in classpath; If applicable, HQL parser will be used.
2025-12-08T16:16:41.297+09:00 INFO 79230 --- [plango] [ main] p.auth.domain.service.KakaoAuthService : KakaoAuthService initialized.
2025-12-08T16:16:41.298+09:00 INFO 79230 --- [plango] [ main] p.auth.domain.service.KakaoAuthService : clientId = 6ecbd75cc6c1f3a8819f66e5698ee294
2025-12-08T16:16:41.299+09:00 INFO 79230 --- [plango] [ main] p.auth.domain.service.KakaoAuthService : redirectUri = http://ceprj2.gachon.ac.kr:65028/login/oauth2/code/kakao
2025-12-08T16:16:41.578+09:00 WARN 79230 --- [plango] [ 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-12-08T16:16:41.659+09:00 WARN 79230 --- [plango] [ main] .s.s.UserDetailsServiceAutoConfiguration :

Using generated security password: 4c5905e7-2d63-41f3-9924-2b207ec01089

This generated password is for development use only. Your security configuration must be updated before running your application in production.

2025-12-08T16:16:41.864+09:00 INFO 79230 --- [plango] [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 1 endpoint(s) beneath base path '/actuator'
2025-12-08T16:16:41.900+09:00 INFO 79230 --- [plango] [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter@3d150d83, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@3ed476a8, org.springframework.security.web.context.SecurityContextHolderFilter@53c25e43, org.springframework.security.web.header.HeaderWriterFilter@27477eb7, org.springframework.web.filter.CorsFilter@7d950a61, org.springframework.security.web.authentication.logout.LogoutFilter@49f09ccf, plango.global.config.JwtAuthenticationFilter@2d06acfd, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@10b648c0, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5f24bda8, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@1f33e4b5, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@386ad5cb, org.springframework.security.web.session.SessionManagementFilter@7c1e325d, org.springframework.security.web.access.ExceptionTranslationFilter@720c54c6, org.springframework.security.web.access.intercept.AuthorizationFilter@381f7b8e]
2025-12-08T16:16:42.236+09:00 INFO 79230 --- [plango] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 65028 (http) with context path ''
2025-12-08T16:16:42.237+09:00 INFO 79230 --- [plango] [ main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting...
2025-12-08T16:16:42.238+09:00 INFO 79230 --- [plango] [ main] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=true, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@30a9a7f3]]
2025-12-08T16:16:42.238+09:00 INFO 79230 --- [plango] [ main] o.s.m.s.b.SimpleBrokerMessageHandler : Started.
2025-12-08T16:16:42.251+09:00 INFO 79230 --- [plango] [ main] plango.PlangoApplication : Started PlangoApplication in 8.415 seconds (process running for 8.925)
2025-12-08T16:17:42.209+09:00 INFO 79230 --- [plango] [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-12-08T16:17:43.012+09:00 INFO 79230 --- [plango] [io-65028-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2025-12-08T16:17:43.012+09:00 INFO 79230 --- [plango] [io-65028-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2025-12-08T16:17:43.016+09:00 INFO 79230 --- [plango] [io-65028-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 4 ms
2025-12-08T16:17:44.730+09:00 INFO 79230 --- [plango] [io-65028-exec-8] o.springdoc.api.AbstractOpenApiResource : Init duration for springdoc-openapi is: 1333 ms
2025-12-08T16:47:42.310+09:00 INFO 79230 --- [plango] [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-12-08T17:17:42.347+09:00 INFO 79230 --- [plango] [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-12-08T17:45:16.124+09:00 INFO 79230 --- [plango] [ionShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler : Stopping...
2025-12-08T17:45:16.130+09:00 INFO 79230 --- [plango] [ionShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@30a9a7f3]]
2025-12-08T17:45:16.131+09:00 INFO 79230 --- [plango] [ionShutdownHook] o.s.m.s.b.SimpleBrokerMessageHandler : Stopped.
2025-12-08T17:45:16.299+09:00 INFO 79230 --- [plango] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2025-12-08T17:45:16.360+09:00 INFO 79230 --- [plango] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2025-12-08T17:45:16.368+09:00 INFO 79230 --- [plango] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package plango.admin.application.dto.response;

import lombok.Builder;
import java.util.Map;
import java.util.List;

public record AdminDashboardStatsResponse(
long totalMemberCount,
Expand All @@ -10,7 +12,9 @@ public record AdminDashboardStatsResponse(
long totalScheduleCount,
long todayNewScheduleCount,
long totalNoticeCount,
long totalInconvenienceReportCount
long totalInconvenienceReportCount,
Map<String, Long> loginMethodStats,
List<MonthlyRoomStatResponse> monthlyRoomStats
) {

@Builder
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package plango.admin.application.dto.response;

import lombok.Builder;

public record MonthlyRoomStatResponse(
String yearMonth, // 예: "2024-05"
long totalRoomCount
) {
@Builder
public MonthlyRoomStatResponse {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import plango.admin.application.dto.response.AdminDashboardStatsResponse;
import plango.admin.application.dto.response.MonthlyRoomStatResponse;
import plango.member.domain.entity.LoginType;
import plango.member.domain.repository.MemberRepository;
import plango.notice.domain.repository.NoticeRepository;
import plango.report.domain.repository.InconvenienceReportRepository;
Expand Down Expand Up @@ -43,9 +49,25 @@ public AdminDashboardStatsResponse execute() {
roomScheduleRepository.countByCreatedAtBetween(startOfToday, endOfToday);

long totalNoticeCount = noticeRepository.count();

long totalInconvenienceReportCount = inconvenienceReportRepository.count();

// 로그인 타입별 통계 (NORMAL / KAKAO)
Map<String, Long> loginMethodStats = memberRepository.countByLoginTypeGroup()
.stream()
.collect(Collectors.toMap(
row -> ((LoginType) row[0]).name(), // key: "NORMAL", "KAKAO"
row -> (Long) row[1] // value: count
));

// 최근 월별 방 생성 수 통계
List<MonthlyRoomStatResponse> monthlyRoomStats = roomRepository.countMonthlyRooms()
.stream()
.map(stat -> MonthlyRoomStatResponse.builder()
.yearMonth(stat.getYearMonth()) // "2024-10" 이런 값
.totalRoomCount(stat.getTotalRoomCount()) // 해당 월 방 개수
.build())
.toList();

return AdminDashboardStatsResponse.builder()
.totalMemberCount(totalMemberCount)
.todayNewMemberCount(todayNewMemberCount)
Expand All @@ -55,6 +77,8 @@ public AdminDashboardStatsResponse execute() {
.todayNewScheduleCount(todayNewScheduleCount)
.totalNoticeCount(totalNoticeCount)
.totalInconvenienceReportCount(totalInconvenienceReportCount)
.loginMethodStats(loginMethodStats)
.monthlyRoomStats(monthlyRoomStats)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.time.LocalDateTime;
import plango.member.domain.entity.Member;
import plango.member.domain.entity.LoginType;

Expand All @@ -27,7 +29,16 @@ List<Member> findByLoginIdContainingOrEmailContainingOrNicknameContaining(

long count();

long countByCreatedAtBetween(java.time.LocalDateTime start, java.time.LocalDateTime end);
long countByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

long countByLoginType(LoginType loginType);

@Query("""
SELECT m.loginType, COUNT(m)
FROM Member m
GROUP BY m.loginType
""")
List<Object[]> countByLoginTypeGroup();

boolean existsByLoginId(String loginId);

Expand Down
38 changes: 27 additions & 11 deletions src/main/java/plango/room/domain/repository/RoomRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,8 @@ public interface RoomRepository extends JpaRepository<Room, Long> {
// 전체 여행방 개수 조회
long count();

// 특정 기간 동안 생성된 여행방 수 조회
@Query("""
select count(r)
from Room r
where r.createdAt between :start and :end
""")
long countCreatedAtBetween(
@Param("start") LocalDate start,
@Param("end") LocalDate end
);

// 오늘 생성된 여행방 수 조회 등에 사용하는 메서드
// createdAt (LocalDateTime) 기준으로 카운트
long countByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

// 특정 시작일 기준으로 여행방 조회 (기존 메서드 유지)
Expand Down Expand Up @@ -60,4 +51,29 @@ List<Room> findByMemberIdAndKeyword(
@Param("memberId") Long memberId,
@Param("keyword") String keyword
);

// 연/월별 여행방 수 (필요하면 사용)
@Query("""
select count(r)
from Room r
where year(r.createdAt) = :year
and month(r.createdAt) = :month
""")
long countByYearAndMonth(@Param("year") int year, @Param("month") int month);

// 대시보드: 월별 여행방 수 통계용 프로젝션
interface MonthlyRoomStats {
String getYearMonth();
Long getTotalRoomCount();
}

// 대시보드: 월별 여행방 수 통계 조회
@Query(value = """
select DATE_FORMAT(r.created_at, '%Y-%m') as yearMonth,
count(r.id) as totalRoomCount
from room r
group by DATE_FORMAT(r.created_at, '%Y-%m')
order by DATE_FORMAT(r.created_at, '%Y-%m')
""", nativeQuery = true)
List<MonthlyRoomStats> countMonthlyRooms();
}