Skip to content

Conversation

@CSE-Shaco
Copy link
Contributor

@CSE-Shaco CSE-Shaco commented Dec 19, 2025

๐Ÿ“Œ ์—ฐ๊ด€๋œ ์ด์Šˆ

ex) #์ด์Šˆ๋ฒˆํ˜ธ, #์ด์Šˆ๋ฒˆํ˜ธ

โœจ ์ž‘์—… ๋‚ด์šฉ

์ด๋ฒˆ PR์—์„œ ์ž‘์—…ํ•œ ๋‚ด์šฉ์„ ๊ฐ„๋žตํžˆ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”

๐Ÿ’ฌ ๋ฆฌ๋ทฐ ์š”๊ตฌ์‚ฌํ•ญ(์„ ํƒ)

Summary by CodeRabbit

๋ฆด๋ฆฌ์Šค ๋…ธํŠธ

  • ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ

    • ๋งˆ๋‹ˆ๋˜(๋น„๋ฐ€ ์„ ๋ฌผ ๊ตํ™˜) ์‹œ์Šคํ…œ ์ถ”๊ฐ€: ์„ธ์…˜ ๊ด€๋ฆฌ, CSV ๊ธฐ๋ฐ˜ ์ฐธ๊ฐ€์ž ๋“ฑ๋ก, ์•”ํ˜ธํ™”๋œ ์ •๋ณด ์กฐํšŒ ๊ธฐ๋Šฅ
    • ๊ด€๋ฆฌ์ž ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค: ์—ญํ•  ๋ฐ ํŒ€ ๋ณ€๊ฒฝ, ์‚ฌ์šฉ์ž ๊ฒ€์ƒ‰ ๋ฐ ์‚ญ์ œ ๊ธฐ๋Šฅ
    • ์ถœ์„ ํ˜„ํ™ฉ CSV ๋‚ด๋ณด๋‚ด๊ธฐ: ์š”์•ฝ ๋ณด๊ณ ์„œ ๋ฐ ์ „์ฒด ์ฐธ์„ ํ˜„ํ™ฉ ๋งคํŠธ๋ฆญ์Šค
  • ์ ‘๊ทผ ๊ถŒํ•œ ํ™•๋Œ€

    • ํŒ€ ๋ฆฌ๋”์™€ ์˜ค๊ฐ€๋‚˜์ด์ €๊ฐ€ ๋ชจ์ง‘ ๋ฐ ์ถœ์„ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์— ์ถ”๊ฐ€ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ๋ฒ„๊ทธ ์ˆ˜์ •

    • ๊ถŒํ•œ ๋ถ€์กฑ ์˜ค๋ฅ˜ ์ƒํƒœ ์ฝ”๋“œ ์ˆ˜์ • (403์œผ๋กœ ์ •์ •)

โœ๏ธ Tip: You can customize this high-level summary in your review settings.

pwc2002 and others added 30 commits August 31, 2025 00:34
[FIX] #209: ์ค‘๋ณต email ๊ฒ€์ฆ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ
[FEAT]: ์ฝ”์–ด ๋ฉค๋ฒ„ ๋ชจ์ง‘ ํผ ์ƒ์„ฑ ๋ฐ ํŒŒ์ผ ์—…๋กœ๋“œ api ์ถ”๊ฐ€
[FEAT]: ์ฝ”์–ด ๋ฆฌ์ฟ ๋ฅดํŠธ ์ง€์›์ž ์กฐํšŒ API ์ถ”๊ฐ€
- AuthController์— /auth/{role} ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€
  - ์š”์ฒญ๋œ role๊ณผ ํ† ํฐ ๋‚ด ์‚ฌ์šฉ์ž ๊ถŒํ•œ์„ ๋น„๊ตํ•˜์—ฌ ์ ‘๊ทผ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ํŒ๋‹จ
  - ์ƒ์œ„ ๊ถŒํ•œ ์‚ฌ์šฉ์ž๋Š” ํ•˜์œ„ ๊ถŒํ•œ ํŽ˜์ด์ง€ ์ ‘๊ทผ ํ—ˆ์šฉ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด 403 ๋ฐ˜ํ™˜
- UserRole enum์— ๊ถŒํ•œ ์ˆœ์„œ ๊ธฐ๋ฐ˜ ๋น„๊ต ๋กœ์ง ์ถ”๊ฐ€ (ordinal ๊ฐ’ ํ™œ์šฉ)
Feat: ๊ถŒํ•œ ๊ฒ€์ฆ ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€ ๋ฐ UserRole ๊ธฐ๋ฐ˜ ๋น„๊ต ๋กœ์ง ๊ฐœ์„ 
fix(core-attendance): Postgres unnest ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ โ€” ๋ฐฐ์—ด+์บ์ŠคํŒ… ์ ์šฉ
feat(core-attendance): refine controller endpoints & auth-aware team โ€ฆ
feat(core-attendance): ๋‚ ์งœ ์ƒ์„ฑ ๊ถŒํ•œ ์ฒดํฌ ์ถ”๊ฐ€
[FEAT] ์‚ฌ์šฉ์ž ๊ถŒํ•œ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ๋ฐ ์ธ์ฆ/๋ฆฌํฌ๋ฃจํŒ… ๊ถŒํ•œ ๊ตฌ์กฐ ๊ฐœ์„ 
feat(user-admin): ์‚ฌ์šฉ์ž ์‚ญ์ œ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€ (Controller ๋ฐ Service ๊ณ„์ธต)
fix(user-admin): User role ์ •๋ ฌ ์ ์šฉ pagination
fix(user-admin): ์‚ฌ์šฉ์ž ๋ชฉ๋ก ์ •๋ ฌ ๋ฐ ๊ถŒํ•œ๋ณ„ ์ ‘๊ทผ ๋กœ์ง ๊ฐœ์„ 
fix(manito): csv ํŒŒ์ผ ํŒŒ์‹ฑ ์˜ค๋ฅ˜ ์ˆ˜์ •
fix(manito): csv ํŒŒ์ผ ํŒŒ์‹ฑ ์˜ค๋ฅ˜ ์ˆ˜์ •
fix(manito): csv ํŒŒ์ผ ํŒŒ์‹ฑ ์˜ค๋ฅ˜ ์ˆ˜์ •
fix(manito): ๋ฏธ์ƒ ์˜ค๋ฅ˜ ์ˆ˜์ •์ค‘
fix(manito): ๋ฏธ์ƒ ์˜ค๋ฅ˜ ์ˆ˜์ •์ค‘
fix: ๋””๋ฒ„๊น… ์„ค์ • ๋ณ€๊ฒฝ
fix: ๋””๋ฒ„๊น… ์„ค์ • ๋ณ€๊ฒฝ
fix(manito): ํ•€ ์ •๊ทœํ™” ๋กœ์ง ์˜์กด์„ฑ ์ถ”๊ฐ€
fix(security-config): ๋งˆ๋‹ˆ๋˜ ํ™•์ธ ํŽ˜์ด์ง€ ํ•„ํ„ฐ๋ง
fix(manito): ํ•€ ํ™•์ธ ๋กœ๊ทธ
fix(manito): Lob ์‚ญ์ œ ๋ฐ Transactional ์ถ”๊ฐ€
fix(manito): unexpected token ํ•ด๊ฒฐ
fix(manito): UI/UX ๊ฐœ์„ ์— ๋”ฐ๋ฅธ ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ฐ˜์˜
@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

์›Œํฌ์Šค๋ฃจ

์ด PR์€ ๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ(์„ธ์…˜ ๋ฐ ์ฐธ์—ฌ์ž ๊ด€๋ฆฌ), ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ ๊ธฐ๋Šฅ, ์ธ์ฆยท์ธ๊ฐ€ ๊ฐ•ํ™”๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ถœ์„ ์‹œ์Šคํ…œ์—์„œ ORGANIZER/LEAD ์—ญํ•  ์ง€์›์„ ํ™•๋Œ€ํ•˜๊ณ , ๋ชจ์ง‘ ๋ชจ๋“ˆ์˜ ๊ถŒํ•œ์„ ์™„ํ™”ํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ์—ญํ•  ๊ณ„์ธต ๊ฒ€์ฆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋ณ€๊ฒฝ ์‚ฌํ•ญ

์‘์ง‘ / ํŒŒ์ผ(๋“ค) ๋ณ€๊ฒฝ ์š”์•ฝ
์ธ์ฆ & ๊ถŒํ•œ
src/main/java/inha/gdgoc/domain/auth/controller/AuthController.java, src/main/java/inha/gdgoc/global/config/jwt/TokenProvider.java
์ƒˆ๋กœ์šด checkRoleOrTeam ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€ (์—ญํ• /ํŒ€ ๊ฒ€์ฆ); ํ† ํฐ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ(generateSelfSignupToken, generateGoogleLoginToken) ์ถ”๊ฐ€; ๊ถŒํ•œ ๊ตฌ์„ฑ ๊ฐœ์„ 
๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ - ์ปจํŠธ๋กค๋Ÿฌ & DTO
src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java, src/main/java/inha/gdgoc/domain/manito/controller/ManitoVerifyController.java, src/main/java/inha/gdgoc/domain/manito/dto/request/*, src/main/java/inha/gdgoc/domain/manito/dto/response/*
์„ธ์…˜ ๊ด€๋ฆฌ(listSessions, createSession), CSV ์—…๋กœ๋“œ(uploadCsv, uploadEncrypted), ๋งˆ๋‹ˆ๋˜ ๊ฒ€์ฆ ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€; ์š”์ฒญ/์‘๋‹ต DTO ์ •์˜
๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ - ์—”ํ‹ฐํ‹ฐ & ์ €์žฅ์†Œ
src/main/java/inha/gdgoc/domain/manito/entity/ManitoSession.java, src/main/java/inha/gdgoc/domain/manito/entity/ManitoAssignment.java, src/main/java/inha/gdgoc/domain/manito/repository/*
ManitoSession, ManitoAssignment ์—”ํ‹ฐํ‹ฐ ์ •์˜; ์ €์žฅ์†Œ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ(findByCode, findBySession_CodeAndStudentId ๋“ฑ) ์ถ”๊ฐ€
๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ - ์„œ๋น„์Šค
src/main/java/inha/gdgoc/domain/manito/service/ManitoAdminService.java, src/main/java/inha/gdgoc/domain/manito/service/ManitoUserService.java, src/main/java/inha/gdgoc/domain/manito/service/ManitoPinPolicy.java
CSV ๊ธฐ๋ฐ˜ ์ฐธ์—ฌ์ž ์ž„ํฌํŠธ/ํ• ๋‹น, ์•”ํ˜ธํ™”๋œ ๋งˆ๋‹ˆ๋˜ ์ž„ํฌํŠธ, ์„ธ์…˜/์ฐธ์—ฌ์ž ๊ฒ€์ฆ ๋กœ์ง ๊ตฌํ˜„
์‚ฌ์šฉ์ž ๊ด€๋ฆฌ
src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java, src/main/java/inha/gdgoc/domain/user/service/UserAdminService.java, src/main/java/inha/gdgoc/domain/user/dto/request/*, src/main/java/inha/gdgoc/domain/user/dto/response/UserSummaryResponse.java, src/main/java/inha/gdgoc/domain/user/entity/User.java
์‚ฌ์šฉ์ž ๋ชฉ๋ก/ํ•„ํ„ฐ๋ง, ์—ญํ• /ํŒ€ ์—…๋ฐ์ดํŠธ, ์‚ฌ์šฉ์ž ์‚ญ์ œ ๊ธฐ๋Šฅ ์ถ”๊ฐ€; ๊ถŒํ•œ ๊ฒ€์ฆ ๋กœ์ง ํฌํ•จ
์‚ฌ์šฉ์ž ์—ญํ•  & ํŒ€ ์—ด๊ฑฐํ˜•
src/main/java/inha/gdgoc/domain/user/enums/UserRole.java, src/main/java/inha/gdgoc/domain/user/enums/TeamType.java, src/main/java/inha/gdgoc/domain/user/repository/UserRepository.java
UserRole.hasAtLeast(), rank() ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€; TeamType.HQ ์ƒ์ˆ˜ ์ถ”๊ฐ€; findSummaries ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฟผ๋ฆฌ ์ถ”๊ฐ€
์ถœ์„ ์‹œ์Šคํ…œ
src/main/java/inha/gdgoc/domain/core/attendance/controller/CoreAttendanceController.java, src/main/java/inha/gdgoc/domain/core/attendance/service/CoreAttendanceService.java, src/main/java/inha/gdgoc/domain/core/attendance/repository/AttendanceRecordRepository.java
์ถœ์„ ์Šค๋ƒ…์ƒท ์ €์žฅ ๋ฉ”์„œ๋“œ ๋ฆฌํŒฉํ† ๋ง; LEAD/ORGANIZER ์—ญํ•  ์ง€์› ํ™•๋Œ€; CSV ์ƒ์„ฑ ๋ฉ”์„œ๋“œ(buildSummaryCsv, buildFullMatrixCsv) ์ถ”๊ฐ€; ์ €์žฅ์†Œ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… ๋ณ€๊ฒฝ(List<Long> โ†’ Long[])
๋ชจ์ง‘ ์‹œ์Šคํ…œ
src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java, src/main/java/inha/gdgoc/domain/recruit/controller/RecruitMemberController.java
๋ชจ์ง‘์ž ์กฐํšŒ ์—”๋“œํฌ์ธํŠธ์—์„œ ADMIN ์ „์šฉ โ†’ LEAD/ORGANIZER/ADMIN ํ—ˆ์šฉ์œผ๋กœ ๋ณ€๊ฒฝ; ํŒ€ ๊ธฐ๋ฐ˜ HR ๊ถŒํ•œ ๊ฒ€์ฆ ์ถ”๊ฐ€
๋ณด์•ˆ & ์„ค์ •
src/main/java/inha/gdgoc/global/security/SecurityConfig.java, src/main/java/inha/gdgoc/global/exception/GlobalErrorCode.java, src/main/java/inha/gdgoc/global/exception/BusinessException.java, src/main/resources/application-prod.yml
/api/v1/manito/verify ๊ณต๊ฐœ ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€; FORBIDDEN_USER ์ƒํƒœ ์ฝ”๋“œ ์ˆ˜์ •(NOT_FOUND โ†’ FORBIDDEN); BusinessException ์ƒ์„ฑ์ž ์˜ค๋ฒ„๋กœ๋“œ; Hibernate ๋กœ๊น… ์ƒ์„ธ๋„ ์ƒํ–ฅ

์˜ˆ์ƒ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋…ธ๋ ฅ

๐ŸŽฏ 4 (๋ณต์žกํ•จ) | โฑ๏ธ ~50๋ถ„

์ฃผ์˜๊ฐ€ ํ•„์š”ํ•œ ์˜์—ญ:

  • ๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ ์„œ๋น„์Šค (ManitoAdminService.java): CSV ํŒŒ์‹ฑ, ๋™์  ๊ทธ๋ฃน ํฌ๊ธฐ ๊ณ„์‚ฐ, ์•”ํ˜ธํ™” ์ฒ˜๋ฆฌ ๋“ฑ ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
  • ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ ์„œ๋น„์Šค (UserAdminService.java): ์—ญํ•  ๊ณ„์ธต ๊ฒ€์ฆ, ๊ถŒํ•œ ๊ธฐ๋ฐ˜ ์กฐ๊ฑด ๋ถ„๊ธฐ, ํŒ€ ํ• ๋‹น ๊ทœ์น™
  • ์ถœ์„ ์„œ๋น„์Šค (CoreAttendanceService.java): CSV ์ƒ์„ฑ ๋กœ์ง ๋‘ ๊ฐ€์ง€(buildSummaryCsv, buildFullMatrixCsv), ORGANIZER ์—ญํ•  ์ถ”๊ฐ€
  • ์ €์žฅ์†Œ ์ฟผ๋ฆฌ ๋ณ€๊ฒฝ (AttendanceRecordRepository.java): ๋„ค์ดํ‹ฐ๋ธŒ SQL์˜ CAST ๋ฐ ๋ณ„์นญ ๋ณ€๊ฒฝ - PostgreSQL ํŠน์ • ๋™์ž‘ ๊ฒ€์ฆ ํ•„์š”
  • ๊ถŒํ•œ ํ‘œํ˜„์‹ (RecruitMemberController.java, CoreRecruitController.java): SpEL ๊ธฐ๋ฐ˜ ํŒ€ ๋น„๊ต ๋กœ์ง์˜ ์ •ํ™•์„ฑ ํ™•์ธ

๊ด€๋ จ ๊ฐ€๋Šฅ์„ฑ ์žˆ๋Š” PR

์ œ์•ˆ ๋ ˆ์ด๋ธ”

enhancement

์‹œ

๐Ÿฐ ๋งˆ๋‹ˆ๋˜ ์‹œ์Šคํ…œ์ด ๋‚˜ํƒ€๋‚˜๊ณ ,
์—ญํ• ๊ณผ ํŒ€์ด ์ถค์„ ์ถ”๋ฉฐ,
์ถœ์„๊ณผ ์‚ฌ์šฉ์ž๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ƒˆ ๊ธธ,
์ธ์ฆ์˜ ๋ฌธ์„ ํ™œ์ง ์—ด๊ณ ,
ํ•œ ๋ฐœ ๋” ๋‚˜์•„๊ฐ€๋Š” ์„œ๋ฒ„์˜ ์—ฌ์ •์ด๋ผ๋„ค! ๐ŸŽ‰

Pre-merge checks and finishing touches

โŒ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage โš ๏ธ Warning Docstring coverage is 34.34% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check โ“ Inconclusive PR ์ œ๋ชฉ 'Main'์€ ๋งค์šฐ ๋ชจํ˜ธํ•˜๊ณ  ๋ณ€๊ฒฝ์‚ฌํ•ญ์˜ ์‹ค์งˆ์ ์ธ ๋‚ด์šฉ์„ ์ „ํ˜€ ์„ค๋ช…ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. PR์˜ ์ฃผ์š” ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ฐ˜์˜ํ•˜๋Š” ๊ตฌ์ฒด์ ์ธ ์ œ๋ชฉ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์„ธ์š”. ์˜ˆ: 'feat: Add Manito admin features and user role management' ๋˜๋Š” ์œ ์‚ฌํ•œ ๋ช…ํ™•ํ•œ ์„ค๋ช…์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
โœ… Passed checks (1 passed)
Check name Status Explanation
Description Check โœ… Passed Check skipped - CodeRabbitโ€™s high-level summary is enabled.
โœจ Finishing touches
  • ๐Ÿ“ Generate docstrings
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch main

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link

CI status
โœ… Assemble ์„ฑ๊ณต
โœ… Test ์„ฑ๊ณต

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

๐Ÿงน Nitpick comments (12)
src/main/java/inha/gdgoc/domain/user/repository/UserRepository.java (1)

39-46: ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ฟผ๋ฆฌ๊ฐ€ ์ž˜ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

JPQL ์ƒ์„ฑ์ž ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•œ DTO ํ”„๋กœ์ ์…˜๊ณผ ์„ ํƒ์  ์ด๋ฆ„ ํ•„ํ„ฐ๋ง์ด ์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Line 44์˜ LIKE ํŒจํ„ด์— ์•ž์ชฝ ์™€์ผ๋“œ์นด๋“œ('%', :q, '%')๊ฐ€ ์žˆ์–ด ์ธ๋ฑ์Šค ํ™œ์šฉ์ด ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ํ…Œ์ด๋ธ”์ด ๋งค์šฐ ํฐ ๊ฒฝ์šฐ ์ „๋ฌธ ๊ฒ€์ƒ‰ ์†”๋ฃจ์…˜(Full-text search) ๊ณ ๋ ค๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/core/attendance/controller/CoreAttendanceController.java (1)

71-71: ์—ญํ•  ๊ฒ€์ฆ ๋กœ์ง ์ค‘๋ณต์„ ํ—ฌํผ ๋ฉ”์„œ๋“œ๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

me.getRole() == UserRole.LEAD && me.getTeam() != TeamType.HR ํŒจํ„ด์ด ์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ 6๋ฒˆ ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค (lines 71, 82, 95, 113, 120, 133). ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์œ„ํ•ด ํ—ฌํผ ๋ฉ”์„œ๋“œ๋กœ ์ถ”์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ํ—ฌํผ ๋ฉ”์„œ๋“œ ์ถ”์ถœ ์ œ์•ˆ
 /* ===== helpers ===== */
+private static boolean isLeadExceptHr(CustomUserDetails me) {
+    return me.getRole() == UserRole.LEAD && me.getTeam() != TeamType.HR;
+}
+
 private static TeamType requiredTeamFrom(CustomUserDetails me) {
     if (me.getTeam() == null) throw new IllegalArgumentException("LEAD ๊ถŒํ•œ ํ† ํฐ์— team ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.");
     return me.getTeam();
 }

์‚ฌ์šฉ ์˜ˆ์‹œ:

-List<TeamResponse> list = (me.getRole() == UserRole.LEAD && me.getTeam() != TeamType.HR) ? ...
+List<TeamResponse> list = isLeadExceptHr(me) ? ...
src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java (2)

6-6: ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” import๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

TeamType์ด import๋˜์—ˆ์ง€๋งŒ ์ด ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
-import inha.gdgoc.domain.user.enums.TeamType;

43-43: ๋ฉ”์‹œ์ง€ ์ƒ์ˆ˜ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ปจํŠธ๋กค๋Ÿฌ๋“ค(์˜ˆ: CoreAttendanceController, RecruitMemberController)์€ ๋ฉ”์‹œ์ง€ ํด๋ž˜์Šค์—์„œ ์ƒ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด UserAdminMessage ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

// ์˜ˆ์‹œ: UserAdminMessage.java
public class UserAdminMessage {
    public static final String USER_SUMMARY_LIST_RETRIEVED = "์‚ฌ์šฉ์ž ๋ชฉ๋ก ์กฐํšŒ ์„ฑ๊ณต";
    public static final String USER_ROLE_TEAM_UPDATED = "์‚ฌ์šฉ์ž ์—ญํ• /ํŒ€ ์ˆ˜์ • ์„ฑ๊ณต";
    public static final String USER_ROLE_UPDATED = "์‚ฌ์šฉ์ž ์—ญํ•  ์ˆ˜์ • ์„ฑ๊ณต";
    public static final String USER_DELETED = "์‚ฌ์šฉ์ž ์‚ญ์ œ ์„ฑ๊ณต";
}
src/main/java/inha/gdgoc/domain/manito/service/ManitoAdminService.java (2)

225-225: ๋ถˆํ•„์š”ํ•œ ๋ฌธ์ž์—ด ์ธ์ฝ”๋”ฉ/๋””์ฝ”๋”ฉ์„ ์ œ๊ฑฐํ•˜์„ธ์š”.

sb.toString()์€ ์ด๋ฏธ String์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ UTF-8๋กœ ๋ณ€ํ™˜ ํ›„ ๋‹ค์‹œ String์œผ๋กœ ๋งŒ๋“œ๋Š” ์ž‘์—…์€ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
-        return new String(sb.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+        return sb.toString();

193-195: ๋งˆ๋‹ˆ๋˜ ๋งค์นญ์— SecureRandom ์‚ฌ์šฉ์„ ๊ณ ๋ คํ•˜์„ธ์š”.

Collections.shuffle()์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ThreadLocalRandom์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ๋งˆ๋‹ˆ๋˜ ๋งค์นญ์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ์ด ์ค‘์š”ํ•˜๋‹ค๋ฉด SecureRandom์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์ฃผ์„์—๋„ ์–ธ๊ธ‰๋˜์–ด ์žˆ์œผ๋‹ˆ ๋ณด์•ˆ ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๊ฒฐ์ •ํ•˜์„ธ์š”.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
+import java.security.SecureRandom;
+
         List<ManitoAssignment> shuffled = new ArrayList<>(participants);
-        Collections.shuffle(shuffled); // ํ•„์š”ํ•˜๋ฉด SecureRandom ์‚ฌ์šฉํ•ด๋„ ๋จ
+        Collections.shuffle(shuffled, new SecureRandom());
src/main/java/inha/gdgoc/domain/user/service/UserAdminService.java (2)

166-169: @Transactional ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ save() ํ˜ธ์ถœ์€ ์„ ํƒ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

JPA dirty checking์ด ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ž๋™์œผ๋กœ ๋ฐ˜์˜ํ•˜๋ฏ€๋กœ, ๋ช…์‹œ์  save() ํ˜ธ์ถœ์ด ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ถˆํ•„์š”ํ•œ ํ˜ธ์ถœ์ž„์„ ์ธ์ง€ํ•˜์„ธ์š”.


44-52: UserRole enum๊ณผ CASE ๋ฌธ์ด ํ˜„์žฌ ๋™๊ธฐํ™”๋˜์–ด ์žˆ์ง€๋งŒ, ํ•˜๋“œ์ฝ”๋”ฉ๋œ ์—ญํ•  ๊ฐ’์œผ๋กœ ์ธํ•œ ์œ ์ง€๋ณด์ˆ˜ ์œ„ํ—˜์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

UserRole enum์˜ ๋ชจ๋“  ๊ฐ’(GUEST, MEMBER, CORE, LEAD, ORGANIZER, ADMIN)์ด CASE ๋ฌธ์˜ ๋ฌธ์ž์—ด๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ enum ์ƒ์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ์ด SQL ์ฟผ๋ฆฌ๊ฐ€ ๊นจ์งˆ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฏ€๋กœ, enum.name()์„ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์ƒ์ˆ˜๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฆฌํŒฉํ† ๋ง์„ ๊ณ ๋ คํ•˜์„ธ์š”.

src/main/java/inha/gdgoc/domain/auth/controller/AuthController.java (2)

127-127: ๋ฉ”์„œ๋“œ ์ด๋ฆ„ responseResponseEntity๊ฐ€ ์˜๋ฏธ๋ฅผ ๋ช…ํ™•ํžˆ ์ „๋‹ฌํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

sendPasswordResetCode ๋˜๋Š” requestPasswordReset๊ณผ ๊ฐ™์ด ๊ธฐ๋Šฅ์„ ๋ช…ํ™•ํžˆ ๋‚˜ํƒ€๋‚ด๋Š” ์ด๋ฆ„์œผ๋กœ ๋ณ€๊ฒฝํ•˜์„ธ์š”.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
-    public ResponseEntity<ApiResponse<Void, Void>> responseResponseEntity(@RequestBody SendingCodeRequest sendingCodeRequest) {
+    public ResponseEntity<ApiResponse<Void, Void>> requestPasswordResetCode(@RequestBody SendingCodeRequest sendingCodeRequest) {

171-175: ์ธ์ฆ ์‹คํŒจ ์‹œ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๋Š” ๋ฐฉ์‹์„ ๊ณ ๋ คํ•˜์„ธ์š”.

์ง์ ‘ ResponseEntity๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋Œ€์‹  AuthException์„ ๋˜์ง€๋ฉด ์ผ๊ด€๋œ ์—๋Ÿฌ ์‘๋‹ต ํ˜•์‹์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฐฉ์‹๋„ ๋™์ž‘ํ•˜์ง€๋งŒ, ๋‹ค๋ฅธ ์—”๋“œํฌ์ธํŠธ์™€์˜ ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ์˜ˆ์™ธ ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ณ ๋ คํ•ด ๋ณด์„ธ์š”.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
         // 1) ์ธ์ฆ ์ฒดํฌ
         if (me == null) {
-            return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
-                    .body(ApiResponse.error(GlobalErrorCode.UNAUTHORIZED_USER.getStatus()
-                            .value(), GlobalErrorCode.UNAUTHORIZED_USER.getMessage(), null));
+            throw new AuthException(UNAUTHORIZED_USER);
         }
src/main/java/inha/gdgoc/domain/core/attendance/service/CoreAttendanceService.java (2)

226-227: ๋ถˆํ•„์š”ํ•œ UTF-8 ์ธ์ฝ”๋”ฉ ๋ณ€ํ™˜์„ ์ œ๊ฑฐํ•˜์„ธ์š”.

sb.toString()์€ ์ด๋ฏธ ์˜ฌ๋ฐ”๋ฅธ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, UTF-8 ๋ฐ”์ดํŠธ๋กœ ๋ณ€ํ™˜ ํ›„ ๋‹ค์‹œ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ž‘์—…์€ ์‹ค์ œ๋กœ ์•„๋ฌด๋Ÿฐ ํšจ๊ณผ๊ฐ€ ์—†์œผ๋ฉฐ, sb.toString()๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ œ์•ˆํ•˜๋Š” ์ˆ˜์ •
-        return new String(sb.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+        return sb.toString();

229-302: ์ „์ฒด ์ถœ์„ ๋งคํŠธ๋ฆญ์Šค CSV ์ƒ์„ฑ ๋กœ์ง์„ ํ™•์ธํ•˜์„ธ์š”.

์ „๋ฐ˜์ ์ธ ๋กœ์ง์€ ์˜ฌ๋ฐ”๋ฅด๋‚˜, ๋‹ค์Œ ์‚ฌํ•ญ๋“ค์„ ํ™•์ธํ•ด์ฃผ์„ธ์š”:

  1. ๋ถˆํ•„์š”ํ•œ UTF-8 ๋ณ€ํ™˜ (301๋ฒˆ ๋ผ์ธ): buildSummaryCsv์™€ ๋™์ผํ•˜๊ฒŒ ๋ถˆํ•„์š”ํ•œ ์ธ์ฝ”๋”ฉ ๋ณ€ํ™˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. sb.toString()๋งŒ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  2. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹œ ์„ฑ๋Šฅ: ์‚ฌ์šฉ์ž ์ˆ˜์™€ ๋‚ ์งœ ์ˆ˜๊ฐ€ ๋งŽ์„ ๊ฒฝ์šฐ (์˜ˆ: ์‚ฌ์šฉ์ž 1000๋ช… ร— ๋‚ ์งœ 50๊ฐœ), ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰๊ณผ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 259-261๋ฒˆ ๋ผ์ธ์˜ ๋ฃจํ”„์—์„œ ๊ฐ ๋‚ ์งœ๋งˆ๋‹ค ๋ณ„๋„์˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋ฏ€๋กœ N+1 ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ œ์•ˆํ•˜๋Š” ์ˆ˜์ •

1. UTF-8 ๋ณ€ํ™˜ ์ œ๊ฑฐ:

-        return new String(sb.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+        return sb.toString();

2. ์„ฑ๋Šฅ ๊ฐœ์„  ๊ณ ๋ ค์‚ฌํ•ญ:

  • ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๋ฐฐ์น˜ ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ๋ชจ๋“  ๋‚ ์งœ์˜ ์ถœ์„ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜์„ธ์š”.
  • ์‚ฌ์šฉ์ž ์ˆ˜๊ฐ€ ๋งŽ์„ ๊ฒฝ์šฐ ํŽ˜์ด์ง€๋„ค์ด์…˜ ๋˜๋Š” ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์˜ CSV ์ƒ์„ฑ์„ ๊ณ ๋ คํ•˜์„ธ์š”.
๐Ÿ“œ Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 272e1df and ea45ed7.

๐Ÿ“’ Files selected for processing (34)
  • src/main/java/inha/gdgoc/domain/auth/controller/AuthController.java (8 hunks)
  • src/main/java/inha/gdgoc/domain/core/attendance/controller/CoreAttendanceController.java (5 hunks)
  • src/main/java/inha/gdgoc/domain/core/attendance/repository/AttendanceRecordRepository.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/core/attendance/service/CoreAttendanceService.java (6 hunks)
  • src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java (2 hunks)
  • src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/controller/ManitoVerifyController.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/controller/message/ManitoMessage.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/dto/request/ManitoSessionCreateRequest.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/dto/request/ManitoVerifyRequest.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/dto/response/ManitoSessionResponse.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/dto/response/ManitoVerifyResponse.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/entity/ManitoAssignment.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/entity/ManitoSession.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/repository/ManitoAssignmentRepository.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/repository/ManitoSessionRepository.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/service/ManitoAdminService.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/service/ManitoPinPolicy.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/manito/service/ManitoUserService.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/recruit/controller/RecruitMemberController.java (3 hunks)
  • src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/dto/request/UpdateRoleRequest.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/dto/request/UpdateUserRoleTeamRequest.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/dto/response/UserSummaryResponse.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/entity/User.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/enums/TeamType.java (2 hunks)
  • src/main/java/inha/gdgoc/domain/user/enums/UserRole.java (1 hunks)
  • src/main/java/inha/gdgoc/domain/user/repository/UserRepository.java (2 hunks)
  • src/main/java/inha/gdgoc/domain/user/service/UserAdminService.java (1 hunks)
  • src/main/java/inha/gdgoc/global/config/jwt/TokenProvider.java (5 hunks)
  • src/main/java/inha/gdgoc/global/exception/BusinessException.java (1 hunks)
  • src/main/java/inha/gdgoc/global/exception/GlobalErrorCode.java (1 hunks)
  • src/main/java/inha/gdgoc/global/security/SecurityConfig.java (1 hunks)
  • src/main/resources/application-prod.yml (1 hunks)
๐Ÿงฐ Additional context used
๐Ÿง  Learnings (2)
๐Ÿ“š Learning: 2025-08-30T10:43:25.889Z
Learnt from: kaswhy
Repo: GDGoCINHA/24-2_GDGoC_Server PR: 207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.889Z
Learning: The GDGoCINHA project has a consistent security architecture where public endpoints are handled in two layers: 1) SecurityConfig uses .permitAll() for paths like /api/v1/auth/**, /api/v1/game/**, /api/v1/apply/**, /api/v1/check/** and 2) TokenAuthenticationFilter excludes the same paths in shouldNotFilter(). This dual-layer approach is correct and intentional.

Applied to files:

  • src/main/java/inha/gdgoc/global/security/SecurityConfig.java
๐Ÿ“š Learning: 2025-08-30T10:43:25.889Z
Learnt from: kaswhy
Repo: GDGoCINHA/24-2_GDGoC_Server PR: 207
File: src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java:31-39
Timestamp: 2025-08-30T10:43:25.889Z
Learning: In the GDGoCINHA project, the following API paths are intentionally designed as public endpoints that should not require authentication: /api/v1/auth/, /api/v1/test/, /api/v1/game/, /api/v1/apply/, /api/v1/check/. These paths are correctly excluded from the TokenAuthenticationFilter in shouldNotFilter() method.

Applied to files:

  • src/main/java/inha/gdgoc/global/security/SecurityConfig.java
๐Ÿงฌ Code graph analysis (14)
src/main/java/inha/gdgoc/global/security/SecurityConfig.java (1)
src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java (1)
  • Override (24-47)
src/main/java/inha/gdgoc/global/exception/GlobalErrorCode.java (2)
src/main/java/inha/gdgoc/global/exception/GlobalExceptionHandler.java (1)
  • ExceptionHandler (116-126)
src/main/java/inha/gdgoc/global/exception/ErrorCode.java (1)
  • ErrorCode (5-10)
src/main/java/inha/gdgoc/domain/manito/controller/ManitoVerifyController.java (2)
src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java (1)
  • RestController (14-53)
src/main/java/inha/gdgoc/domain/user/controller/UserController.java (2)
  • RequestMapping (25-60)
  • PostMapping (43-50)
src/main/java/inha/gdgoc/domain/manito/dto/request/ManitoVerifyRequest.java (2)
src/main/java/inha/gdgoc/domain/core/attendance/dto/request/CreateDateRequest.java (1)
  • Getter (8-14)
src/main/java/inha/gdgoc/domain/core/recruit/dto/request/CoreRecruitApplicationRequest.java (2)
  • Builder (47-62)
  • Getter (10-63)
src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java (4)
src/main/java/inha/gdgoc/domain/user/controller/UserController.java (1)
  • RequestMapping (25-60)
src/main/java/inha/gdgoc/domain/game/controller/GameUserController.java (1)
  • RequestMapping (19-41)
src/main/java/inha/gdgoc/domain/study/controller/StudyController.java (1)
  • RequestMapping (38-108)
src/main/java/inha/gdgoc/domain/user/service/UserService.java (1)
  • Slf4j (23-83)
src/main/java/inha/gdgoc/domain/core/attendance/controller/CoreAttendanceController.java (2)
src/main/java/inha/gdgoc/domain/core/attendance/controller/message/CoreAttendanceMessage.java (1)
  • CoreAttendanceMessage (3-22)
src/main/java/inha/gdgoc/domain/core/attendance/dto/response/DaySummaryResponse.java (1)
  • Getter (19-27)
src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java (4)
src/main/java/inha/gdgoc/domain/manito/controller/ManitoVerifyController.java (1)
  • RestController (16-34)
src/main/java/inha/gdgoc/domain/resource/controller/FileUploadController.java (1)
  • RestController (16-34)
src/main/java/inha/gdgoc/domain/user/controller/UserController.java (1)
  • RequestMapping (25-60)
src/main/java/inha/gdgoc/domain/game/controller/GameUserController.java (1)
  • RequestMapping (19-41)
src/main/java/inha/gdgoc/domain/manito/repository/ManitoSessionRepository.java (5)
src/main/java/inha/gdgoc/domain/core/attendance/repository/MeetingRepository.java (1)
  • MeetingRepository (8-9)
src/main/java/inha/gdgoc/domain/recruit/repository/RecruitMemberRepository.java (2)
  • RecruitMemberRepository (8-12)
  • existsByStudentId (9-9)
src/main/java/inha/gdgoc/domain/recruit/repository/AnswerRepository.java (1)
  • AnswerRepository (9-15)
src/main/java/inha/gdgoc/domain/core/recruit/repository/CoreRecruitApplicationRepository.java (1)
  • CoreRecruitApplicationRepository (8-10)
src/main/java/inha/gdgoc/domain/user/service/UserService.java (1)
  • Slf4j (23-83)
src/main/java/inha/gdgoc/domain/manito/repository/ManitoAssignmentRepository.java (2)
src/main/java/inha/gdgoc/domain/recruit/repository/RecruitMemberRepository.java (1)
  • RecruitMemberRepository (8-12)
src/main/java/inha/gdgoc/domain/recruit/repository/AnswerRepository.java (1)
  • AnswerRepository (9-15)
src/main/java/inha/gdgoc/global/exception/BusinessException.java (4)
src/main/java/inha/gdgoc/domain/auth/exception/AuthException.java (2)
  • AuthException (8-10)
  • AuthException (6-11)
src/main/java/inha/gdgoc/domain/user/exception/UserException.java (2)
  • UserException (6-11)
  • UserException (8-10)
src/main/java/inha/gdgoc/domain/resource/exception/ResourceException.java (2)
  • ResourceException (8-10)
  • ResourceException (6-11)
src/main/java/inha/gdgoc/domain/study/exception/StudyException.java (2)
  • StudyException (6-11)
  • StudyException (8-10)
src/main/java/inha/gdgoc/domain/manito/entity/ManitoSession.java (1)
src/main/java/inha/gdgoc/domain/manito/entity/ManitoAssignment.java (1)
  • Entity (10-60)
src/main/java/inha/gdgoc/domain/manito/entity/ManitoAssignment.java (1)
src/main/java/inha/gdgoc/domain/manito/entity/ManitoSession.java (1)
  • Getter (10-41)
src/main/java/inha/gdgoc/domain/user/service/UserAdminService.java (1)
src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java (1)
  • RequiredArgsConstructor (22-80)
src/main/java/inha/gdgoc/domain/auth/controller/AuthController.java (4)
src/main/java/inha/gdgoc/global/config/jwt/TokenProvider.java (1)
  • RequiredArgsConstructor (22-127)
src/main/java/inha/gdgoc/domain/auth/service/AuthService.java (1)
  • Slf4j (27-138)
src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java (1)
  • Slf4j (17-98)
src/main/java/inha/gdgoc/domain/auth/controller/message/AuthMessage.java (1)
  • AuthMessage (3-11)
๐Ÿ”‡ Additional comments (41)
src/main/java/inha/gdgoc/domain/user/enums/TeamType.java (1)

8-8: LGTM!

์ƒˆ๋กœ์šด HQ ํŒ€ ํƒ€์ž…์ด ๊ธฐ์กด ํŒจํ„ด๊ณผ ์ผ๊ด€๋˜๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. enum ์ƒ์ˆ˜์™€ from() ๋ฉ”์„œ๋“œ ๋ชจ๋‘ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Also applies to: 22-22

src/main/java/inha/gdgoc/global/exception/BusinessException.java (1)

15-18: LGTM!

์ปค์Šคํ…€ ๋ฉ”์‹œ์ง€๋ฅผ ์ง€์›ํ•˜๋Š” ์ƒ์„ฑ์ž๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์ƒ์„ฑ์ž์™€ ํ•จ๊ป˜ ๋” ์œ ์—ฐํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/enums/UserRole.java (2)

18-21: LGTM!

๊ถŒํ•œ ๋น„๊ต ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. null ์ธ์ž์— ๋Œ€ํ•ด false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์€ "๊ถŒํ•œ ์—†์Œ"์„ ์˜๋ฏธํ•˜๋Š” ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ ๋™์ž‘์ž…๋‹ˆ๋‹ค.


26-35: LGTM!

๊ถŒํ•œ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค. enum ์ˆœ์„œ์™€ ๋ฌด๊ด€ํ•˜๊ฒŒ rank๋ฅผ ์ค‘์•™์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ์ข‹์€ ์„ค๊ณ„์ž…๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/global/exception/GlobalErrorCode.java (1)

17-17: LGTM! ์˜๋ฏธ์ƒ ์˜ฌ๋ฐ”๋ฅธ ์ˆ˜์ •์ž…๋‹ˆ๋‹ค.

FORBIDDEN_USER์˜ HTTP ์ƒํƒœ๋ฅผ 404์—์„œ 403์œผ๋กœ ๋ณ€๊ฒฝํ•œ ๊ฒƒ์€ ๊ถŒํ•œ ๋ถ€์กฑ ์˜ค๋ฅ˜์˜ ์˜๋ฏธ๋ฅผ ์ •ํ™•ํžˆ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋Š” API ์†Œ๋น„์ž ์ž…์žฅ์—์„œ breaking change์ด๋ฏ€๋กœ, API ๋ฌธ์„œ๋‚˜ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ์— ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/dto/request/UpdateUserRoleTeamRequest.java (1)

6-9: LGTM!

๋ถ€๋ถ„ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ DTO ์„ค๊ณ„๊ฐ€ ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค. null์„ "๋ณ€๊ฒฝ ์—†์Œ"์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜๋ฏธ๊ฐ€ ์ฃผ์„์œผ๋กœ ๋ช…ํ™•ํžˆ ํ‘œ์‹œ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ์ด ์˜๋ฏธ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€๋Š” User.java ๋ฆฌ๋ทฐ์—์„œ ํ™•์ธ ์š”์ฒญํ–ˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/entity/User.java (1)

134-135: serviceRole null ๊ฐ’ ์ฒ˜๋ฆฌ๋Š” ์•ˆ์ „ํ•จ

updateRoleAndTeam() ๋ฉ”์„œ๋“œ์—์„œ req.role()์ด null์ผ ๋•Œ ๊ธฐ์กด ์—ญํ• ์„ ์œ ์ง€ํ•˜๋Š” ๋กœ์ง์ด ์žˆ์–ด์„œ, changeRole()์—๋Š” ํ•ญ์ƒ null์ด ์•„๋‹Œ ๊ฐ’์ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. updateUserRoleWithRules() ๋ฉ”์„œ๋“œ๋„ newRole ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋ฐ›์€ ์œ ํšจํ•œ ์—ญํ• ๊ฐ’์„ ๊ฒ€์ฆ ํ›„ ์ „๋‹ฌํ•˜๋ฏ€๋กœ ๋ฌธ์ œ์—†์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/dto/request/UpdateRoleRequest.java (1)

6-8: LGTM!

@NotNull ๊ฒ€์ฆ์ด ํฌํ•จ๋œ ๊ฐ„๊ฒฐํ•œ record DTO์ž…๋‹ˆ๋‹ค. ์—ญํ•  ์—…๋ฐ์ดํŠธ ์š”์ฒญ์— ์ ํ•ฉํ•œ ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/dto/response/ManitoSessionResponse.java (1)

7-11: LGTM!

์ •์  ํŒฉํ† ๋ฆฌ ๋ฉ”์„œ๋“œ ํŒจํ„ด์„ ์‚ฌ์šฉํ•œ ๊น”๋”ํ•œ DTO ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. Instant๋ฅผ ์‚ฌ์šฉํ•œ ํƒ€์ž„์Šคํƒฌํ”„ ์ฒ˜๋ฆฌ๋„ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/dto/response/ManitoVerifyResponse.java (1)

7-11: LGTM!

๋ชฉ์ ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์„ค๋ช…ํ•˜๋Š” Javadoc๊ณผ ํ•จ๊ป˜ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ตฌํ˜„๋œ DTO์ž…๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/dto/response/UserSummaryResponse.java (1)

6-14: LGTM!

๊ด€๋ฆฌ์ž ์ปจํ…์ŠคํŠธ์—์„œ ์‚ฌ์šฉ์ž ์š”์•ฝ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•œ ์ ์ ˆํ•œ DTO ๊ตฌํ˜„์ž…๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ํ•„๋“œ๋“ค์ด ์ž˜ ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/repository/ManitoSessionRepository.java (1)

8-18: LGTM!

๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ Spring Data JPA ๊ทœ์น™์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ, ๋ฉ”์„œ๋“œ ๋„ค์ด๋ฐ๊ณผ ๋ฌธ์„œํ™”๊ฐ€ ๋ช…ํ™•ํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/service/ManitoUserService.java (1)

25-47: ๊ฒ€์ฆ ๋กœ์ง์ด ์ž˜ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ค์Œ์„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค:

  • ์„ธ์…˜ ๋ฐ ์ฐธ๊ฐ€์ž ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
  • PIN ์ •๊ทœํ™” ๋ฐ ๊ฒ€์ฆ
  • ์•”ํ˜ธํ™”๋œ ๋งˆ๋‹ˆ๋˜ ์ •๋ณด ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธ
  • ๋ช…ํ™•ํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ์ ์ ˆํ•œ ์—๋Ÿฌ ์ฝ”๋“œ ์‚ฌ์šฉ

ํŠธ๋žœ์žญ์…˜ ์„ค์ •๊ณผ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/global/config/jwt/TokenProvider.java (2)

29-38: ์ƒˆ๋กœ์šด ํ† ํฐ ์ƒ์„ฑ ๋ฉ”์„œ๋“œ๊ฐ€ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

generateSelfSignupToken๊ณผ generateGoogleLoginToken ๋ฉ”์„œ๋“œ๊ฐ€ ๊ธฐ์กด generateRefreshToken ํŒจํ„ด์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


63-77: ๊ถŒํ•œ ๊ตฌ์„ฑ ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ฐœ์„ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์—ญํ• (ROLE_)๊ณผ ํŒ€(TEAM_) ๊ถŒํ•œ์„ ๋ชจ๋‘ ํฌํ•จํ•˜๋„๋ก ๋ณ€๊ฒฝ๋˜์–ด ๋” ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ์  ํŒ€ ์ •๋ณด ์ฒ˜๋ฆฌ๋„ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/dto/request/ManitoSessionCreateRequest.java (1)

8-15: LGTM!

Record ๊ธฐ๋ฐ˜ DTO๊ฐ€ ๊ฐ„๊ฒฐํ•˜๊ณ  ๋ช…ํ™•ํ•˜๋ฉฐ, ๊ฒ€์ฆ ์ œ์•ฝ์กฐ๊ฑด์ด ์ ์ ˆํ•˜๊ฒŒ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/dto/request/ManitoVerifyRequest.java (1)

19-22: ๊ฒ€์ฆ ์ œ์•ฝ์กฐ๊ฑด์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

PIN ํ•„๋“œ์˜ ๊ฒ€์ฆ์ด ๋‹จ๊ณ„์ ์œผ๋กœ ๋ช…ํ™•ํ•œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. @Size์™€ @Pattern์˜ ์กฐํ•ฉ์ด ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋‚˜์€ ๊ฒ€์ฆ ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/repository/UserRepository.java (1)

48-48: Null ์•ˆ์ „์„ฑ ๊ฐœ์„ ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

@NotNull ์–ด๋…ธํ…Œ์ด์…˜ ์ถ”๊ฐ€๋กœ ๋ฉ”์„œ๋“œ ๊ณ„์•ฝ์ด ๋ช…ํ™•ํ•ด์กŒ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/core/attendance/repository/AttendanceRecordRepository.java (1)

29-36: ๋ฉ”์„œ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜ ๋ณ€๊ฒฝ์ด ์ ์ ˆํ•˜๊ฒŒ ๋ฐ˜์˜๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

PostgreSQL ํƒ€์ž… ์•ˆ์ „์„ฑ์„ ์œ„ํ•œ CAST(:userIds AS bigint[]) ์ถ”๊ฐ€์™€ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ณ€๊ฒฝ(List<Long> โ†’ Long[])์ด ๋ชจ๋‘ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. CoreAttendanceService์˜ ํ˜ธ์ถœ ์ง€์ ์—์„œ userIds.toArray(Long[]::new)์œผ๋กœ ์ •ํ™•ํžˆ ๋ณ€ํ™˜๋˜์–ด ๋ฉ”์„œ๋“œ์— ์ „๋‹ฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/controller/ManitoVerifyController.java (1)

23-33: ์ปจํŠธ๋กค๋Ÿฌ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

REST ์—”๋“œํฌ์ธํŠธ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•˜๊ณ , ๊ฒ€์ฆ ๋ฐ ์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. verifyAndGetAssignment ๋ฉ”์„œ๋“œ๊ฐ€ encryptedManitto์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ๊ฒ€์ฆํ•˜๋ฏ€๋กœ Line 27์€ ์•ˆ์ „ํ•˜๊ณ , name ํ•„๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ˆ˜์ค€์—์„œ nullable = false ์ œ์•ฝ์ด ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ Line 28์˜ getName()๋„ null์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์–ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/repository/ManitoAssignmentRepository.java (1)

10-28: LGTM!

๋‹ค๋ฅธ ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ๋“ค์€ Spring Data JPA ๋„ค์ด๋ฐ ์ปจ๋ฒค์…˜์„ ์ž˜ ๋”ฐ๋ฅด๊ณ  ์žˆ์œผ๋ฉฐ, Optional ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜์—ฌ null ์•ˆ์ „์„ฑ์„ ํ™•๋ณดํ–ˆ์Šต๋‹ˆ๋‹ค. findBySession_CodeAndStudentId๋ฅผ ํ†ตํ•ด ์„ธ์…˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์—†์ด ๋ฐ”๋กœ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ์ ๋„ ์ข‹์€ ์„ค๊ณ„์ž…๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/core/attendance/controller/CoreAttendanceController.java (2)

54-66: LGTM!

๋‚ ์งœ ์ƒ์„ฑ/์‚ญ์ œ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ORGANIZER/ADMIN ์—ญํ•  ์ œํ•œ์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๋ ˆ๋ฒจ์˜ @PreAuthorize๋ฅผ ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ์—์„œ ๋” ์ œํ•œ์ ์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๋Š” ํŒจํ„ด์€ Spring Security ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.


127-141: LGTM!

์ƒˆ๋กœ์šด summaryCsvAll ์—”๋“œํฌ์ธํŠธ๊ฐ€ ๊ธฐ์กด ํŒจํ„ด์„ ์ผ๊ด€๋˜๊ฒŒ ๋”ฐ๋ฅด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Content-Disposition ํ—ค๋” ์„ค์ •๊ณผ CSV ์‘๋‹ต ์ฒ˜๋ฆฌ๊ฐ€ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/recruit/controller/RecruitMemberController.java (1)

88-88: ๊ถŒํ•œ ํ‘œํ˜„์‹์˜ ๋…ผ๋ฆฌ์  ์˜๋„๋ฅผ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

ํ˜„์žฌ @PreAuthorize ํ‘œํ˜„์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•ด์„๋ฉ๋‹ˆ๋‹ค:

  • LEAD, ORGANIZER, ADMIN ์—ญํ•  ์ค‘ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ๋˜๋Š”
  • ์—ญํ• ์— ๊ด€๊ณ„์—†์ด HR ํŒ€์— ์†ํ•œ ๋ชจ๋“  ์‚ฌ์šฉ์ž

์ด๋กœ ์ธํ•ด HR ํŒ€์— ์†ํ•œ ์ผ๋ฐ˜ USER ์—ญํ• ์˜ ์‚ฌ์šฉ์ž๋„ ์ด ๋ฏผ๊ฐํ•œ ์—”๋“œํฌ์ธํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜๋„๋œ ๋™์ž‘์ด๋ผ๋ฉด ๋ฌด์‹œํ•˜์…”๋„ ๋˜์ง€๋งŒ, LEAD ์—ญํ• ์ด๋ฉด์„œ HR ํŒ€์ธ ๊ฒฝ์šฐ๋งŒ ํ—ˆ์šฉํ•˜๋ ค๋ฉด ํ‘œํ˜„์‹์„ ์ˆ˜์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์˜๋„๋œ ๋™์ž‘์ธ์ง€ ํ™•์ธํ•ด ์ฃผ์„ธ์š”:

  • ํ˜„์žฌ: HR ํŒ€์›์ด๋ฉด ์—ญํ•  ๋ฌด๊ด€ํ•˜๊ฒŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ๋Œ€์•ˆ: (hasRole('LEAD') and principal.team == T(...).HR) or hasAnyRole('ORGANIZER','ADMIN')
src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java (1)

59-59: HR ํŒ€ ๊ถŒํ•œ ํ‘œํ˜„์‹ ์˜๋„ ํ™•์ธ ํ•„์š”.

RecruitMemberController์™€ ๋™์ผํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. HR ํŒ€์— ์†ํ•œ ์ผ๋ฐ˜ USER ์—ญํ• ๋„ ์—ญํ•  ์ˆ˜์ • ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜๋„๋œ ๋™์ž‘์ธ์ง€ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java (1)

39-46: ํŒŒ์ผ ์—…๋กœ๋“œ ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ๊ฒ€์ฆ ์™„๋ฃŒ.

๋‹ค์Œ ์‚ฌํ•ญ๋“ค์ด ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค:

  1. ํŒŒ์ผ ํฌ๊ธฐ ์ œํ•œ: ๋ชจ๋“  ์„ค์ • ํŒŒ์ผ(dev, local, prod)์—์„œ max-file-size: 10MB, max-request-size: 12MB๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  2. CSV ํ˜•์‹ ๊ฒ€์ฆ: ManitoAdminService.importParticipantsCsv()์—์„œ ๋นˆ ํŒŒ์ผ ํ™•์ธ, ํ—ค๋” ํ˜•์‹ ๊ฒ€์ฆ, ํ•„์ˆ˜ ์ปฌ๋Ÿผ ๊ฒ€์ฆ, CSV ์ด์Šค์ผ€์ดํ”„ ์ฒ˜๋ฆฌ, ํ•„๋“œ ๊ฐ’ ๊ฒ€์ฆ์ด ๋ชจ๋‘ ์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

  3. ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ: CSV ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” BufferedReader๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ, CSV ๋‚ด๋ณด๋‚ด๊ธฐ๋Š” StringBuilder๋กœ ๋นŒ๋“œ๋˜์–ด ์ผ๋ฐ˜์ ์ธ ๋ฐ์ดํ„ฐ ๊ทœ๋ชจ์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/entity/ManitoSession.java (2)

10-14: ์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ๊ฐ€ ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

JPA ์—”ํ‹ฐํ‹ฐ๋กœ์„œ ์ ์ ˆํ•œ ์–ด๋…ธํ…Œ์ด์…˜ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค. @NoArgsConstructor(access = AccessLevel.PROTECTED)๋กœ JPA ํ”„๋ก์‹œ ์ƒ์„ฑ์„ ์ง€์›ํ•˜๋ฉด์„œ ์™ธ๋ถ€ ์ง์ ‘ ์ƒ์„ฑ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.


32-40: Builder ํŒจํ„ด๊ณผ ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

code๋Š” ๋ถˆ๋ณ€์œผ๋กœ ์œ ์ง€ํ•˜๊ณ  title๋งŒ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ ์„ค๊ณ„๊ฐ€ ์ข‹์Šต๋‹ˆ๋‹ค. ์„ธ์…˜ ์ฝ”๋“œ๋Š” ์‹๋ณ„์ž ์—ญํ• ์„ ํ•˜๋ฏ€๋กœ ์ƒ์„ฑ ํ›„ ๋ณ€๊ฒฝ์„ ๋ง‰๋Š” ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅธ ์ ‘๊ทผ์ž…๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/entity/ManitoAssignment.java (3)

10-14: ์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ์™€ ์ œ์•ฝ ์กฐ๊ฑด์ด ์ž˜ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์„ธ์…˜-ํ•™๋ฒˆ ์กฐํ•ฉ์— ๋Œ€ํ•œ ์œ ๋‹ˆํฌ ์ œ์•ฝ(uq_manito_assignment_per_student)๊ณผ ์ ์ ˆํ•œ ์ธ๋ฑ์Šค ์„ค์ •์œผ๋กœ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ๊ณผ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.


20-22: LAZY ํŽ˜์น˜ ์ „๋žต์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

ManyToOne ๊ด€๊ณ„์— FetchType.LAZY๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์„ธ์…˜ ๋ฐ์ดํ„ฐ ๋กœ๋”ฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.


49-59: ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ๋“ค์ด ๋„๋ฉ”์ธ ์บก์Аํ™”๋ฅผ ์ž˜ ์ง€ํ‚ต๋‹ˆ๋‹ค.

Setter ๋Œ€์‹  ๋ช…์‹œ์ ์ธ ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ(changePinHash, changeEncryptedManitto, changeName)๋ฅผ ์ œ๊ณตํ•˜์—ฌ ๋„๋ฉ”์ธ ๋กœ์ง์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ํ•ฉ๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/manito/service/ManitoAdminService.java (1)

59-87: ๊ทธ๋ฃน ํฌ๊ธฐ ๊ณ„์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

5~9๋ช… ๊ทธ๋ฃน์œผ๋กœ ๋ถ„ํ• ํ•˜๋Š” ๋กœ์ง์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ตœ์†Œ ์ธ์› ๊ฒ€์ฆ๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/user/service/UserAdminService.java (3)

97-102: ๊ถŒํ•œ ๊ฒ€์ฆ ๋กœ์ง์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘์ž๊ฐ€ ๋Œ€์ƒ์˜ ํ˜„์žฌ ์—ญํ• ๊ณผ ์ƒˆ ์—ญํ•  ๋ชจ๋‘๋ณด๋‹ค ์ƒ์œ„ ๊ถŒํ•œ์„ ๊ฐ€์ ธ์•ผ ํ•˜๋Š” ๊ฒ€์ฆ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


104-143: ์—ญํ• ๋ณ„ ๊ถŒํ•œ ๊ทœ์น™์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ADMIN, ORGANIZER, LEAD ๊ฐ๊ฐ์— ๋Œ€ํ•œ ๊ถŒํ•œ ์ œ์•ฝ์ด switch ํ‘œํ˜„์‹์œผ๋กœ ์ž˜ ์ •๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. HR-LEAD์˜ ํŒ€ ๋ณ€๊ฒฝ ์˜ˆ์™ธ ์ผ€์ด์Šค๋„ ์ ์ ˆํžˆ ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.


163-172: HR-CORE ์˜ˆ์™ธ ๊ฒฝ๋กœ๊ฐ€ ์ ์ ˆํžˆ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

HRํŒ€ CORE ๋ฉค๋ฒ„๊ฐ€ GUEST๋ฅผ MEMBER๋กœ ์Šน๊ฒฉํ•  ์ˆ˜ ์žˆ๋Š” ํŠน๋ณ„ ๊ถŒํ•œ์ด ๋ช…ํ™•ํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/auth/controller/AuthController.java (2)

168-198: ์—ญํ• /ํŒ€ ๊ฒ€์ฆ ์—”๋“œํฌ์ธํŠธ๊ฐ€ ์ž˜ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

UserRole.hasAtLeast๋ฅผ ์‚ฌ์šฉํ•œ ์—ญํ•  ๊ฒ€์ฆ๊ณผ ORGANIZER ์ด์ƒ์€ ํŒ€ ๊ฒ€์ฆ์„ ์šฐํšŒํ•˜๋Š” ๋กœ์ง์ด ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค. OR ์กฐ๊ฑด์œผ๋กœ ์ตœ์ข… ํŒ์ •ํ•˜๋Š” ๊ฒƒ๋„ ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค.


168-169: ์œ ํšจํ•˜์ง€ ์•Š์€ ์—ญํ•  ๊ฐ’์— ๋Œ€ํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋Š” ์ด๋ฏธ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

@PathVariable UserRole role์— ์ž˜๋ชป๋œ ๋ฌธ์ž์—ด์ด ์ „๋‹ฌ๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” MethodArgumentTypeMismatchException์€ GlobalExceptionHandler์—์„œ @ExceptionHandler(MethodArgumentTypeMismatchException.class) (72-84์ค„)๋กœ ์ด๋ฏธ ์ฒ˜๋ฆฌ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

src/main/java/inha/gdgoc/domain/core/attendance/service/CoreAttendanceService.java (4)

33-39: CSV ์ด์Šค์ผ€์ดํ”„ ๋กœ์ง์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

RFC 4180 CSV ํ‘œ์ค€์— ๋”ฐ๋ผ null ์ฒ˜๋ฆฌ, ํŠน์ˆ˜ ๋ฌธ์ž ๊ฐ์ง€, ๋”ฐ์˜ดํ‘œ ์ด์Šค์ผ€์ดํ•‘์ด ์ •ํ™•ํ•˜๊ฒŒ ๊ตฌํ˜„๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.


306-336: ํ—ฌํผ ๋ฉ”์„œ๋“œ ๋ฌธ์„œํ™”๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

Javadoc ์ฃผ์„ ์ถ”๊ฐ€์™€ ์ฝ”๋“œ ํฌ๋งทํŒ… ๊ฐœ์„ ์ด ์ ์ ˆํ•˜๊ฒŒ ์ด๋ฃจ์–ด์กŒ์Šต๋‹ˆ๋‹ค.


88-96: ํ”„๋กœ์ ํŠธ์˜ Java ๋ฒ„์ „์€ 17๋กœ ์„ค์ •๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

.toList() ๋ฉ”์„œ๋“œ๋Š” Java 16๋ถ€ํ„ฐ ๋„์ž…๋˜์—ˆ์œผ๋ฉฐ, ํ”„๋กœ์ ํŠธ๊ฐ€ Java 17์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋Š” ์—†์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ฝ”๋“œ๋Š” ์ตœ์‹  Java ๋ฌธ๋ฒ•์„ ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


76-76: UserRole.ORGANIZER ์ถ”๊ฐ€๋Š” ์ปจํŠธ๋กค๋Ÿฌ ๋ ˆ๋ฒจ์˜ ๊ธฐ์กด ๊ถŒํ•œ ๋ชจ๋ธ๊ณผ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค.

์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค ๋ ˆ๋ฒจ์˜ @PreAuthorize("hasAnyRole('LEAD','ORGANIZER','ADMIN')")์—์„œ ์ด๋ฏธ ORGANIZER ์—ญํ• ์ด ํ—ˆ๊ฐ€๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋”์šฑ์ด ์ปจํŠธ๋กค๋Ÿฌ ๋กœ์ง(line 71, 82, 113)์—์„œ ์ด๋“ค ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ๋Š” LEAD ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹ ๋•Œ(๋˜๋Š” HR ํŒ€์˜ LEAD์ผ ๋•Œ) ํ˜ธ์ถœ๋˜๋ฏ€๋กœ, ORGANIZER์™€ ADMIN์ด ์˜๋„๋œ ๋Œ€์ƒ์ž…๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๋ฉ”์„œ๋“œ์— UserRole.ORGANIZER๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ์กด ๊ถŒํ•œ ์ •์ฑ…๊ณผ ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ณ€๊ฒฝ์ž…๋‹ˆ๋‹ค.

security = { @SecurityRequirement(name = "BearerAuth") }
)
@PreAuthorize("hasRole('ADMIN')")
@PreAuthorize("hasAnyRole('LEAD', 'ORGANIZER', 'ADMIN')")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

# 1. CoreRecruitController.java ํŒŒ์ผ์˜ ์‹ค์ œ ๋‚ด์šฉ ํ™•์ธ (lines 50-100)
cat -n src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java | sed -n '50,100p'

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 2669


๐Ÿ Script executed:

# 2. CoreRecruitApplicationService ๋˜๋Š” ๊ด€๋ จ ์„œ๋น„์Šค์—์„œ ํ•„ํ„ฐ๋ง ๋กœ์ง ํ™•์ธ
fd -e java CoreRecruitApplicationService -o CoreRecruitService --exec wc -l {} \; | head -5

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 226


๐Ÿ Script executed:

# 3. ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค์—์„œ hasAnyRole ํŒจํ„ด ๊ฒ€์ƒ‰
rg -n "hasAnyRole.*LEAD.*ORGANIZER" --type=java

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 1814


๐Ÿ Script executed:

# 4. UserRole ๋˜๋Š” Role enum ์ •์˜ ํ™•์ธ
fd -e java | xargs grep -l "enum.*Role\|class.*Role" | head -5

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 455


๐Ÿ Script executed:

# 5. CoreRecruitController ํŒŒ์ผ์˜ ์ „์ฒด ๋ผ์ธ ์ˆ˜ ํ™•์ธ
wc -l src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 157


๐Ÿ Script executed:

# CoreRecruitApplicationService ํŒŒ์ผ ์ฐพ๊ธฐ ๋ฐ ๋‚ด์šฉ ํ™•์ธ
fd -e java -path "*/service/*" | xargs grep -l "CoreRecruitApplicationService\|findApplicantsPage\|getApplicantDetail" | head -3

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 239


๐Ÿ Script executed:

# CoreRecruitApplicationService์˜ findApplicantsPage ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ํ™•์ธ
rg -n "findApplicantsPage|getApplicantDetail" -A 10 --type=java -B 2

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 5190


๐Ÿ Script executed:

# CoreRecruitApplication ์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ ํ™•์ธ (ํŒ€ ์—ฐ๊ด€์„ฑ ์žˆ๋Š”์ง€)
fd -e java CoreRecruitApplication --type=java | xargs cat | head -100

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 242


๐Ÿ Script executed:

# RecruitMemberController์™€ ๋น„๊ตํ•˜๊ธฐ ์œ„ํ•ด ์œ ์‚ฌํ•œ ํ•„ํ„ฐ๋ง ํŒจํ„ด ํ™•์ธ
rg -n "TeamType.*HR.*principal.team" --type=java -B 5 -A 5 | head -30

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 3988


๐Ÿ Script executed:

# CoreRecruitApplication ์—”ํ‹ฐํ‹ฐ ๊ตฌ์กฐ ํ™•์ธ
find . -name "CoreRecruitApplication.java" -exec cat {} \;

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 2021


๐Ÿ Script executed:

# CoreRecruitApplicantDetailResponse์™€ CoreRecruitApplicantSummaryResponse ํ™•์ธ (์–ด๋–ค ๋ฐ์ดํ„ฐ ๋…ธ์ถœ๋˜๋Š”์ง€)
rg -n "class CoreRecruitApplicant.*Response" -A 15

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 53


๐Ÿ Script executed:

# CoreRecruitApplication์˜ repository ์ฟผ๋ฆฌ ๋ฉ”์„œ๋“œ ํ™•์ธ
rg -n "CoreRecruitApplicationRepository\|interface.*CoreRecruitApplication" -A 20

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 53


์ง€์›์ž ์กฐํšŒ ์—”๋“œํฌ์ธํŠธ์˜ ํ–‰ ์ˆ˜์ค€ ๋ณด์•ˆ ํ•„ํ„ฐ๋ง์ด ๋ˆ„๋ฝ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ ‘๊ทผ ๊ถŒํ•œ์ด ADMIN ์ „์šฉ์—์„œ LEAD, ORGANIZER, ADMIN์œผ๋กœ ํ™•๋Œ€๋˜์—ˆ์œผ๋‚˜, ์„œ๋น„์Šค ๊ณ„์ธต์—์„œ ํ–‰ ์ˆ˜์ค€ ํ•„ํ„ฐ๋ง์ด ์ „ํ˜€ ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

  • findApplicantsPage() (๋ผ์ธ 42-47): ์ด๋ฆ„ ๊ฒ€์ƒ‰๋งŒ ์ˆ˜ํ–‰, ํŒ€ ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ์—†์Œ
  • getApplicantDetail() (๋ผ์ธ 50-54): ์ง์ ‘ ID ์กฐํšŒ, ๊ถŒํ•œ ๊ฒ€์ฆ ์—†์Œ
  • CoreRecruitApplication ์—”ํ‹ฐํ‹ฐ๋Š” "team" ํ•„๋“œ๋ฅผ ๋ณด์œ ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์ง€์›์ž๊ฐ€ ํŒ€๋ณ„๋กœ ๋ฒ”์œ„๊ฐ€ ์ง€์ •๋˜์–ด์•ผ ํ•จ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค

ํ˜„์žฌ ์ƒํƒœ์—์„œ LEAD์™€ ORGANIZER ์—ญํ• ์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋Š” ๋ชจ๋“  ํŒ€์˜ ๋ชจ๋“  ์ง€์›์ž ์ •๋ณด(ํ•™๋ฒˆ, ์ „ํ™”๋ฒˆํ˜ธ, ์ด๋ฉ”์ผ, ์ง€์› ๋™๊ธฐ, ๊ฐ•์  ๋“ฑ ๋ฏผ๊ฐํ•œ ๊ฐœ์ธ์ •๋ณด)์— ์ œํ•œ ์—†์ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํŒ€๋ณ„ ๋˜๋Š” ์—ญํ•  ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ฅธ ํ•„ํ„ฐ๋ง ๋กœ์ง์„ ์„œ๋น„์Šค ๋˜๋Š” ์ €์žฅ์†Œ ๊ณ„์ธต์— ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
In
src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java
around lines 42-55, the controller was broadened to LEAD/ORGANIZER/ADMIN but did
not enforce row-level team filtering; update the service/repository layer to
apply team-based access control and modify findApplicantsPage() (lines ~42-47)
to add a team filter when the caller is LEAD or ORGANIZER (Admins bypass), and
modify getApplicantDetail() (lines ~50-54) to verify the current user's team(s)
against the applicant's team and return 403 (or throw AccessDenied) when not
allowed; obtain the caller's roles and team membership from SecurityContext (or
a CurrentUser service), push team-limited queries down to the repository (add
team constraint to the query or repository method), and add/adjust unit tests to
cover LEAD/ORGANIZER access to own-team applicants and denial for other-team
applicants.

security = { @SecurityRequirement(name = "BearerAuth") }
)
@PreAuthorize("hasRole('ADMIN')")
@PreAuthorize("hasAnyRole('LEAD', 'ORGANIZER', 'ADMIN')")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

find src -name "*CoreRecruitController*" -type f

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 153


๐Ÿ Script executed:

# Find the CoreRecruitController file
find . -name "CoreRecruitController.java" -type f 2>/dev/null | head -5

# Also search for any service methods related to applicant details
find . -name "*.java" -path "*/service/*" -type f 2>/dev/null | xargs grep -l "getApplicant" 2>/dev/null | head -10

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 245


๐Ÿ Script executed:

# Search for CoreRecruitController and getApplicantDetail method
find . -name "*.java" -type f | xargs grep -l "getApplicantDetail" 2>/dev/null | head -5

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 245


๐Ÿ Script executed:

# Check CoreRecruitController.java around line 92
cat -n ./src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java | sed -n '85,100p'

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 784


๐Ÿ Script executed:

# Check CoreRecruitApplicationService.java for getApplicantDetail method
grep -n "getApplicantDetail" ./src/main/java/inha/gdgoc/domain/core/recruit/service/CoreRecruitApplicationService.java -A 20

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 393


๐Ÿ Script executed:

# Also check if there's any filtering/authorization logic in the service
grep -n "teamId\|team\|authorization\|permission" ./src/main/java/inha/gdgoc/domain/core/recruit/service/CoreRecruitApplicationService.java

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 110


@PreAuthorize๋งŒ์œผ๋กœ๋Š” ๋ถˆ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๋ ˆ์ด์–ด์— ์ธ๊ฐ€ ๊ฒ€์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

getApplicantDetail ๋ฉ”์„œ๋“œ๊ฐ€ ID๋กœ ์กฐํšŒํ•œ ์ง€์›์ž์— ๋Œ€ํ•œ ์ ‘๊ทผ ๊ถŒํ•œ์„ ๊ฒ€์ฆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ตฌํ˜„:

  • repository.findById(id)๋กœ ๋ชจ๋“  ์ง€์›์ž ์กฐํšŒ ๊ฐ€๋Šฅ
  • ์š”์ฒญ์ž๊ฐ€ ํ•ด๋‹น ์ง€์›์ž์˜ ํŒ€์— ์†ํ•˜๋Š”์ง€ ํ™•์ธ ์•ˆ ํ•จ
  • ํŒ€ ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ๋กœ์ง ์—†์Œ

LEAD๋‚˜ ORGANIZER๊ฐ€ ์ž„์˜์˜ ID๋กœ ๋ชจ๋“  ์ง€์›์ž์˜ ์ƒ์„ธ ์ •๋ณด๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋Š” ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์ž…๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๋ ˆ์ด์–ด์—์„œ ์š”์ฒญ์ž์˜ ํŒ€๊ณผ ์ง€์›์ž ์†Œ์† ํŒ€์„ ๋น„๊ตํ•˜์—ฌ ์ ‘๊ทผ์„ ์ œํ•œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
In
src/main/java/inha/gdgoc/domain/core/recruit/controller/CoreRecruitController.java
around line 92, the controller uses @PreAuthorize but the service layer does not
verify that the requesting user belongs to the same team as the applicant;
update the service method that loads applicant details to perform an explicit
authorization check: fetch the applicant by id, fetch the requester (from
SecurityContextHolder or by passing principal/userId into the service), compare
their team ids (allow if same team or if requester has ADMIN role), and if not
authorized throw an AccessDeniedException (or your app's equivalent); ensure the
controller passes the principal or userId into the service and add unit tests
for same-team, admin, and forbidden cases.

Comment on lines +14 to +17
@RestController
@RequestMapping("/api/v1/admin/manito")
@RequiredArgsConstructor
public class ManitoAdminController {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๋ณด์•ˆ ์ทจ์•ฝ์ : ๊ด€๋ฆฌ์ž ์—”๋“œํฌ์ธํŠธ์— ์ธ์ฆ/์ธ๊ฐ€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ด ์ปจํŠธ๋กค๋Ÿฌ๋Š” /api/v1/admin/manito ๊ฒฝ๋กœ์— ์žˆ์œผ๋ฉฐ ๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ(์„ธ์…˜ ์ƒ์„ฑ, ์ฐธ๊ฐ€์ž ์—…๋กœ๋“œ ๋“ฑ)์„ ์ œ๊ณตํ•˜์ง€๋งŒ, @PreAuthorize ์–ด๋…ธํ…Œ์ด์…˜์ด ์—†์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฌ๋‚˜ ์ด ์—”๋“œํฌ์ธํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ์ทจ์•ฝ์ ์ž…๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ๊ด€๋ฆฌ์ž ์ปจํŠธ๋กค๋Ÿฌ๋“ค(UserAdminController, CoreAttendanceController)์€ ์ ์ ˆํ•œ ๊ถŒํ•œ ๊ฒ€์‚ฌ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
+import org.springframework.security.access.prepost.PreAuthorize;
+
 @RestController
 @RequestMapping("/api/v1/admin/manito")
 @RequiredArgsConstructor
+@PreAuthorize("hasAnyRole('ORGANIZER', 'ADMIN')")
 public class ManitoAdminController {
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@RestController
@RequestMapping("/api/v1/admin/manito")
@RequiredArgsConstructor
public class ManitoAdminController {
import org.springframework.security.access.prepost.PreAuthorize;
@RestController
@RequestMapping("/api/v1/admin/manito")
@RequiredArgsConstructor
@PreAuthorize("hasAnyRole('ORGANIZER', 'ADMIN')")
public class ManitoAdminController {
๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java
around lines 14 to 17, the controller exposing /api/v1/admin/manito lacks
authentication/authorization and must be restricted; add a class-level security
annotation (e.g., @PreAuthorize("hasRole('ADMIN')") or
@PreAuthorize("hasAuthority('ADMIN')") consistent with the project's convention)
or annotate each admin method similarly, ensure the necessary import and that
method security is enabled in the application (e.g., @EnableGlobalMethodSecurity
or equivalent), and mirror the same role/authority checks used in
UserAdminController/CoreAttendanceController so only authorized admin users can
access these endpoints.

Comment on lines +29 to +37
@PostMapping("/sessions")
public ResponseEntity<ApiResponse<ManitoSessionResponse, Void>> createSession(
@RequestBody ManitoSessionCreateRequest request
) {
ManitoSessionResponse body = manitoAdminService.createSession(request);
return ResponseEntity.ok(
ApiResponse.ok("์„ธ์…˜ ์ƒ์„ฑ ์„ฑ๊ณต", body)
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

์š”์ฒญ ๋ณธ๋ฌธ์— @Valid ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

ManitoSessionCreateRequest์— @NotBlank ๋“ฑ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ์„ ๊ฒฝ์šฐ, @Valid ์—†์ด๋Š” ๊ฒ€์ฆ์ด ์ˆ˜ํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
+import jakarta.validation.Valid;
+
     @PostMapping("/sessions")
     public ResponseEntity<ApiResponse<ManitoSessionResponse, Void>> createSession(
-            @RequestBody ManitoSessionCreateRequest request
+            @RequestBody @Valid ManitoSessionCreateRequest request
     ) {
๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@PostMapping("/sessions")
public ResponseEntity<ApiResponse<ManitoSessionResponse, Void>> createSession(
@RequestBody ManitoSessionCreateRequest request
) {
ManitoSessionResponse body = manitoAdminService.createSession(request);
return ResponseEntity.ok(
ApiResponse.ok("์„ธ์…˜ ์ƒ์„ฑ ์„ฑ๊ณต", body)
);
}
import jakarta.validation.Valid;
@PostMapping("/sessions")
public ResponseEntity<ApiResponse<ManitoSessionResponse, Void>> createSession(
@RequestBody @Valid ManitoSessionCreateRequest request
) {
ManitoSessionResponse body = manitoAdminService.createSession(request);
return ResponseEntity.ok(
ApiResponse.ok("์„ธ์…˜ ์ƒ์„ฑ ์„ฑ๊ณต", body)
);
}
๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/manito/controller/ManitoAdminController.java
around lines 29 to 37, the @RequestBody parameter is missing the @Valid
annotation so bean validation on ManitoSessionCreateRequest won't run; add the
@Valid annotation to the request parameter (e.g. public
ResponseEntity<ApiResponse<..., Void>> createSession(@Valid @RequestBody
ManitoSessionCreateRequest request)) and import the correct annotation
(jakarta.validation.Valid or javax.validation.Valid depending on project),
ensuring validation will be triggered.

Comment on lines +1 to +5
package inha.gdgoc.domain.manito.controller.message;

public class ManitoMessage {

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

๋นˆ ํด๋ž˜์Šค์˜ ๋ชฉ์ ์„ ๋ช…ํ™•ํžˆ ํ•ด์ฃผ์„ธ์š”.

์ด ํด๋ž˜์Šค๋Š” ๊ตฌํ˜„ ๋‚ด์šฉ์ด ์—†๋Š” ๋นˆ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค. ์˜๋„์ ์ธ ํ”Œ๋ ˆ์ด์Šคํ™€๋”์ธ์ง€, ์ถ”ํ›„ ๊ตฌํ˜„ ์˜ˆ์ •์ธ์ง€, ์•„๋‹ˆ๋ฉด ์‹ค์ˆ˜๋กœ ์ปค๋ฐ‹๋œ ๊ฒƒ์ธ์ง€ ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋Š” ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, ํ–ฅํ›„ ๊ตฌํ˜„์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ TODO ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

์ด ํด๋ž˜์Šค๋ฅผ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ์ด์Šˆ๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜, ๊ตฌํ˜„ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋„์™€๋“œ๋ฆด๊นŒ์š”?

๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/manito/controller/message/ManitoMessage.java
lines 1-5 there is an empty class with no implementation or comment; determine
its intended purpose and act accordingly: if it is a deliberate placeholder, add
a TODO comment describing the intended responsibilities, expected fields/methods
and a link or issue number, and annotate as @SuppressWarnings("unused") only if
referenced later; if it was committed accidentally and unused, delete the file
and remove any imports/usages; if implementation is pending, implement the
required fields/methods (or add an interface/record) consistent with other
message classes and update related tests; ensure commit message documents the
decision.

Comment on lines +264 to +269
assignmentRepository.flush();

ManitoAssignment reloaded = assignmentRepository.findBySessionAndStudentId(session, studentId)
.orElseThrow();

log.info("[MANITO] after save: studentId='{}', enc='{}'", reloaded.getStudentId(), reloaded.getEncryptedManitto());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸ  Major

๋ฃจํ”„ ๋‚ด์—์„œ flush() ํ˜ธ์ถœ์€ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์œ ๋ฐœํ•ฉ๋‹ˆ๋‹ค.

flush()์™€ ์žฌ์กฐํšŒ๊ฐ€ ๊ฐ ๋ ˆ์ฝ”๋“œ๋งˆ๋‹ค ์‹คํ–‰๋˜์–ด N+1 ๋ฌธ์ œ์™€ ์œ ์‚ฌํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋””๋ฒ„๊น… ๋ชฉ์ ์ด๋ผ๋ฉด ์ œ๊ฑฐํ•˜๊ณ , ํ•„์š”์‹œ ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ ์‹œ ํ•œ ๋ฒˆ๋งŒ ์ฒ˜๋ฆฌ๋˜๋„๋ก ํ•˜์„ธ์š”.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
                assignment.changeEncryptedManitto(encryptedManitto);
-
-                assignmentRepository.flush();
-
-                ManitoAssignment reloaded = assignmentRepository.findBySessionAndStudentId(session, studentId)
-                        .orElseThrow();
-
-                log.info("[MANITO] after save: studentId='{}', enc='{}'", reloaded.getStudentId(), reloaded.getEncryptedManitto());

Committable suggestion skipped: line range outside the PR's diff.

๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/manito/service/ManitoAdminService.java around
lines 264 to 269, the code calls assignmentRepository.flush() and then
re-queries each saved assignment inside a loop which causes per-record
flushing/reloads and significant performance degradation; remove the
per-iteration flush() and the immediate findBySessionAndStudentId(...) call,
instead rely on the managed entity state returned from the save operation (or
collect ids and perform a single bulk query after the loop) and perform a single
flush() (or let the transaction commit) after processing all records to avoid
N+1 behavior.

Comment on lines +22 to +27
try {
int asInt = Integer.parseInt(digits);
return String.format("%04d", asInt);
} catch (NumberFormatException e) {
throw new BusinessException(GlobalErrorCode.BAD_REQUEST, "PIN ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

4์ž๋ฆฌ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” PIN ์ž…๋ ฅ ์‹œ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘ ๋ฐœ์ƒ ๊ฐ€๋Šฅ

ํ˜„์žฌ ๊ตฌํ˜„์—์„œ "12345"์™€ ๊ฐ™์ด 4์ž๋ฆฌ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ์ˆซ์ž๊ฐ€ ์ž…๋ ฅ๋˜๋ฉด String.format("%04d", 12345)๋Š” "12345" (5์ž๋ฆฌ)๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” 4์ž๋ฆฌ PIN ์ •์ฑ…๊ณผ ๋งž์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ๋Œ€ ์ž๋ฆฟ์ˆ˜๋ฅผ ๊ฒ€์ฆํ•˜๊ฑฐ๋‚˜, ๋งˆ์ง€๋ง‰ 4์ž๋ฆฌ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ œ์•ˆ๋œ ์ˆ˜์ • ์‚ฌํ•ญ
         try {
             int asInt = Integer.parseInt(digits);
+            if (asInt > 9999) {
+                throw new BusinessException(GlobalErrorCode.BAD_REQUEST, "PIN์€ 4์ž๋ฆฌ ์ดํ•˜์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.");
+            }
             return String.format("%04d", asInt);
         } catch (NumberFormatException e) {
             throw new BusinessException(GlobalErrorCode.BAD_REQUEST, "PIN ํ˜•์‹์ด ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์Šต๋‹ˆ๋‹ค.");
         }
๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/manito/service/ManitoPinPolicy.java around
lines 22 to 27, the method currently parses the input and formats it which
allows inputs longer than 4 digits (e.g., "12345") to pass through; update the
validation to explicitly reject inputs longer than 4 characters (after trimming
and ensuring non-null) by throwing BusinessException with the same BAD_REQUEST
code, or alternatively decide to keep only the last 4 digits (pick one approach
consistently); implement the chosen behavior before parsing (check
digits.length() > 4 and throw or trim to last 4), keep existing
NumberFormatException handling for non-numeric input, and ensure leading zeros
are preserved by continuing to use String.format("%04d", parsedInt) for valid
4-or-fewer digit inputs.

Comment on lines +49 to +55
public ResponseEntity<ApiResponse<Void, Void>> updateRoleTeam(
@AuthenticationPrincipal CustomUserDetails me,
@PathVariable Long userId,
@RequestBody UpdateUserRoleTeamRequest req
) {
userAdminService.updateRoleAndTeam(me, userId, req);
return ResponseEntity.ok(ApiResponse.ok("USER_ROLE_TEAM_UPDATED"));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸก Minor

@Valid ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ˆ„๋ฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

updateUserRole ๋ฉ”์„œ๋“œ(line 64)์—๋Š” @Valid๊ฐ€ ์žˆ์ง€๋งŒ, updateRoleTeam ๋ฉ”์„œ๋“œ์˜ UpdateUserRoleTeamRequest์—๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋‘ ์—”๋“œํฌ์ธํŠธ ๋ชจ๋‘ ์š”์ฒญ ๋ณธ๋ฌธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.

๐Ÿ”Ž ์ˆ˜์ • ์ œ์•ˆ
     public ResponseEntity<ApiResponse<Void, Void>> updateRoleTeam(
             @AuthenticationPrincipal CustomUserDetails me,
             @PathVariable Long userId,
-            @RequestBody UpdateUserRoleTeamRequest req
+            @RequestBody @Valid UpdateUserRoleTeamRequest req
     ) {
๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/domain/user/controller/UserAdminController.java
around lines 49 to 55, the request body parameter for updateRoleTeam is missing
the @Valid annotation so the UpdateUserRoleTeamRequest won't be validated; add
the @Valid annotation to the @RequestBody parameter (and ensure the
javax.validation.Valid import is present) so the request is validated the same
way as updateUserRole.

Comment on lines +52 to +53
"/api/v1/fileupload",
"/api/v1/manito/verify")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐Ÿ”ด Critical

๐Ÿงฉ Analysis chain

๐Ÿ Script executed:

#!/bin/bash
# TokenAuthenticationFilter ํŒŒ์ผ ์œ„์น˜ ์ฐพ๊ธฐ
find . -name "TokenAuthenticationFilter.java" -type f

# shouldNotFilter ๋ฉ”์„œ๋“œ ๋‚ด์šฉ ํ™•์ธ
rg -A 20 "shouldNotFilter" src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java

# manito์™€ fileupload ๊ฒฝ๋กœ ํ™•์ธ
rg -n "manito|fileupload" src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 1081


๐Ÿ Script executed:

#!/bin/bash
# TokenAuthenticationFilter ์ „์ฒด ํŒŒ์ผ ์ฝ๊ธฐ
cat -n src/main/java/inha/gdgoc/global/security/TokenAuthenticationFilter.java

Repository: GDGoCINHA/24-2_GDGoC_Server

Length of output: 4264


TokenAuthenticationFilter์— ์ƒˆ ์—”๋“œํฌ์ธํŠธ ์ถ”๊ฐ€ ํ•„์ˆ˜

/api/v1/manito/verify์™€ /api/v1/fileupload ์—”๋“œํฌ์ธํŠธ๊ฐ€ SecurityConfig์˜ permitAll()์—๋Š” ์ถ”๊ฐ€๋˜์—ˆ์œผ๋‚˜, TokenAuthenticationFilter์˜ shouldNotFilter() ๋ฉ”์„œ๋“œ์—๋Š” ์ถ”๊ฐ€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ๋ณด์•ˆ ์•„ํ‚คํ…์ฒ˜ ํŒจํ„ด์— ๋”ฐ๋ฅด๋ฉด ์–‘์ชฝ ๋ชจ๋‘์—์„œ ์ฒ˜๋ฆฌ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ, TokenAuthenticationFilter 46ํ–‰ ๋‹ค์Œ์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•˜์„ธ์š”:

            || uri.startsWith("/api/v1/manito/verify")
            || uri.equals("/api/v1/fileupload");

ํ˜„์žฌ ์ƒํƒœ์—์„œ๋Š” ์ด ๊ฒฝ๋กœ๋“ค์ด SecurityConfig์—์„œ๋Š” ํ—ˆ์šฉ๋˜์ง€๋งŒ ํ•„ํ„ฐ์—์„œ๋Š” ์—ฌ์ „ํžˆ ์ธ์ฆ์„ ์‹œ๋„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿค– Prompt for AI Agents
In src/main/java/inha/gdgoc/global/security/SecurityConfig.java around lines
52-53, the two endpoints were added to permitAll() but not to
TokenAuthenticationFilter.shouldNotFilter; update TokenAuthenticationFilter
(after line 46) to include the additional exclusions by adding checks for
uri.startsWith("/api/v1/manito/verify") and uri.equals("/api/v1/fileupload") so
those paths are skipped by the filter (place them in the existing OR-chain in
shouldNotFilter()).

Comment on lines +53 to +54
org.hibernate.orm.jdbc.bind: trace
org.hibernate.type: trace
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

โš ๏ธ Potential issue | ๐ŸŸ  Major

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ trace ๋ ˆ๋ฒจ ๋กœ๊น…์€ ์œ„ํ—˜ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ Hibernate ๋กœ๊น…์„ trace ๋ ˆ๋ฒจ๋กœ ์„ค์ •ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค:

  1. ์„ฑ๋Šฅ ์ €ํ•˜: trace ๋กœ๊น…์€ ๋ฐฉ๋Œ€ํ•œ ์–‘์˜ ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ CPU, I/O, ๋””์Šคํฌ ๊ณต๊ฐ„์„ ๊ณผ๋„ํ•˜๊ฒŒ ์†Œ๋น„ํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ณด์•ˆ/์ปดํ”Œ๋ผ์ด์–ธ์Šค ์œ„ํ—˜: org.hibernate.orm.jdbc.bind: trace๋Š” SQL ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ”์ธ๋”ฉ์„ ๋กœ๊ทธ์— ๊ธฐ๋กํ•˜๋ฏ€๋กœ, ์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ, ๋น„๋ฐ€๋ฒˆํ˜ธ, ๊ฐœ์ธ์ •๋ณด ๋“ฑ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋กœ๊ทธ์— ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ์šด์˜ ๋ฆฌ์Šคํฌ: ๋กœ๊ทธ ๋ณผ๋ฅจ ๊ธ‰์ฆ์œผ๋กœ ๋””์Šคํฌ ๊ณต๊ฐ„ ๋ถ€์กฑ, ๋กœ๊ทธ ๋ถ„์„ ์–ด๋ ค์›€ ๋“ฑ์˜ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” INFO ๋˜๋Š” WARN ๋ ˆ๋ฒจ์„ ๊ถŒ์žฅํ•˜๋ฉฐ, ํ•„์š”์‹œ DEBUG๊นŒ์ง€๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”Ž ๊ถŒ์žฅ ์ˆ˜์ •์‚ฌํ•ญ

์˜ต์…˜ 1 (๊ถŒ์žฅ): ํ”„๋กœ๋•์…˜์—์„œ๋Š” ๋‚ฎ์€ ๋กœ๊ทธ ๋ ˆ๋ฒจ ์‚ฌ์šฉ

 logging:
   level:
     org.hibernate.SQL: debug
-    org.hibernate.orm.jdbc.bind: trace
-    org.hibernate.type: trace
+    org.hibernate.orm.jdbc.bind: off
+    org.hibernate.type: off

์˜ต์…˜ 2: ์ƒ์„ธ ๋กœ๊น…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ฐœ๋ฐœ/์Šคํ…Œ์ด์ง• ํ™˜๊ฒฝ์—์„œ๋งŒ ํ™œ์„ฑํ™”

ํ”„๋กœ๋•์…˜(application-prod.yml)์—์„œ๋Š” ์ œ๊ฑฐํ•˜๊ณ , ๊ฐœ๋ฐœ ํ™˜๊ฒฝ(application-dev.yml)์—์„œ๋งŒ trace ๋ ˆ๋ฒจ์„ ์‚ฌ์šฉํ•˜์„ธ์š”.

๐Ÿ“ Committable suggestion

โ€ผ๏ธ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
org.hibernate.orm.jdbc.bind: trace
org.hibernate.type: trace
org.hibernate.orm.jdbc.bind: off
org.hibernate.type: off
๐Ÿค– Prompt for AI Agents
src/main/resources/application-prod.yml around lines 53-54: the production
config currently sets org.hibernate.orm.jdbc.bind and org.hibernate.type to
trace which can leak sensitive data and degrade performance; change these two
entries to a safer level (e.g., INFO or WARN) or remove them entirely from
application-prod.yml and instead place trace-level settings only in
application-dev.yml/application-staging.yml; ensure no JDBC bind/parameter trace
logging remains enabled in production.

@CSE-Shaco CSE-Shaco merged commit 5a683d8 into develop Dec 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants