Repository navigation
[Feat/#119] 사물함 운영 회차 관리자 API 추가 - #129
Open
sangrae2325 wants to merge 4 commits into
Open
sangrae2325 wants to merge 4 commits into
sangrae2325 wants to merge 4 commits into
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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. Comment |
github-actions
Bot
requested review from
jjunh33,
leegain1,
tnals0924 and
xeoxxn
October 16, 2026 10:13
sangrae2325
added this pull request to stack #131
October 16, 2026 10:29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#️⃣연관된 이슈
🎯 해결하려는 문제가 무엇인가요?
운영진 콘솔에서 사물함 운영 회차를 등록·수정·삭제하고 목록·상세를 조회하는 관리자 API를 추가합니다.
GET /v1/admin/lockers/periods— 목록 + 진행 중인 회차GET /v1/admin/lockers/periods/{lockerPeriodId}— 상세POST /v1/admin/lockers/periods— 등록PUT /v1/admin/lockers/periods/{lockerPeriodId}— 수정DELETE /v1/admin/lockers/periods/{lockerPeriodId}— 삭제❓ 왜 해결해야 하나요?
사물함 관리자 API가 하나도 없어서 회차를 만들 방법이 DB 직접 입력뿐입니다. 마이그레이션에 두 번 적혀 있는 제약이기도 합니다.
그리고
lockerPeriodId가 사물함 관리자 API 14개 중 5개의 입력이라(구역 목록·상세, 신청 현황) 회차가 없으면 나머지를 호출조차 할 수 없습니다.LockerRepository에 쓰기 메서드가 하나도 없어서, 이 PR이 사물함 쓰기 경로를 처음 뚫습니다.⭐ 어떻게 해결했나요?
welfare/notice/(#104) 구조를 그대로 따랐습니다. 커밋 4개로 나눴고 각각 단독으로 컴파일됩니다.LockerPeriod에create·update·calculateStatus·overlaps추가. 지금까지of만 있어 DB 복원 전용이었습니다LockerApplicationRepository.existsByPeriodLockerService에 5개admin-api에event/locker패키지 신설,core:domain:event의존 추가구현 메모:
year·semester만 받고2026-1학기형태로 조립합니다00:00:00~ 마감일23:59:59로 저장합니다periodStatus는 저장하지 않고 계산합니다 — 신청 시작 전UPCOMING, 사용 종료일 이후ENDED, 그 사이IN_PROGRESSactive_semester에 유니크를 걸고(flyway-migration.md3-4절)ConstraintViolationUtil로 409로 바꿉니다NoticeRepositoryImpl.delete([Feat/#103] 게시판(공지) 관리자 API 추가 #104) 패턴. 조회한 엔티티를 바로 바꿔 쿼리 하나로 끝내고,save(merge) 경로를 타지 않아 도메인이 삭제 상태를 들고 있지 않아도 됩니다...AndIsDeletedFalse로 바꿔서, 호출부를 빠뜨리면 컴파일이 깨지게 했습니다🧩 이 PR의 한계 & 트레이드오프
apply_end_at을 늘리는 방식이 됩니다. 이 판단이 틀렸다면 검증 한 줄로 되돌릴 수 있습니다locker_periods가 0건이고 prod 릴리스도 아직 없습니다. 운영 데이터가 생긴 뒤에 적용될 환경을 대비해 백필(name에서 연도·학기 파싱)과DEFAULT는 남겨뒀습니다. 행이 있는 환경에서는^[0-9]{4}-[12]학기$형식이 아닌 행이 둘 이상일 때 유니크 인덱스가'0-0'중복으로 실패하므로 적용 전 확인이 필요합니다AGENTS.md원칙에 따랐습니다⛓️ 기존 기능에 미치는 영향
is_deleted = 0이 붙습니다(existsPublishedPeriod,findPublishedPeriodById,findPublishedPeriodsByIds). 기존 행은 전부is_deleted = 0이라 동작 변화는 없습니다admin-api가core:domain:event에 의존하기 시작합니다. 방향은api → core라architecture.md3절과 맞고,ModularityTests.verify()·DomainImplAccessTests통과를 확인했습니다LockerPeriod.of시그니처가 7개 → 9개(연도·학기 추가)가 되어LockerPeriodJpaEntity와 테스트 2곳이 함께 바뀝니다LockerRepository·LockerApplicationRepository에 메서드가 5개 늘어 테스트 가짜 2곳에 스텁 10개가 추가됩니다🔀 Edge Case & 실패 시나리오
LOCKER_PERIOD_SEMESTER_DUPLICATED(409)LOCKER_PERIOD_OVERLAPPED(409)LOCKER_PERIOD_ALREADY_ENDED(409)LOCKER_PERIOD_APPLY_ALREADY_STARTED(409). 원래 값을 그대로 보내면 통과LOCKER_PERIOD_HAS_APPLICATIONS(409)LOCKER_PERIOD_NOT_FOUND(404)INVALID_LOCKER_PERIOD_RANGE(400)@Min/@Max가 먼저 막아INVALID_INPUT(400). 도메인에도 방어 코드를 뒀습니다currentPeriod가null📋 검토한 대안과 선택 이유
PATCH로: 명세는 PATCH지만 PUT으로 갔습니다(명세서도 함께 고칩니다). 관리자 프론트의updateSemester가 전체를 보내고,AdminNoticeController.updateNotice가@PutMapping이며, 저장소에Optional<T>필드나JsonNullable같은 부분 수정 장치가 없습니다. 장치 없는 PATCH는 이름만 PATCH입니다name에서 파싱: 상세 조회가 둘을 따로 내려줘야 해서 컬럼으로 뒀습니다. 파싱하면 문자열 처리가 도메인에 들어오고 중복 검사도 문자열 비교가 됩니다deleted_at으로:flyway-migration.md3-2절은deleted_at을 규정하지만, 마이그레이션 전체에deleted_at은 0건이고is_deleted가 19곳입니다. 여기만 다르면 조건절이 테이블마다 갈려서 코드 쪽에 맞췄습니다. (문서와 스키마를 맞추는 건 별도 이슈로 올리겠습니다)true로 고정했습니다DATETIME)과 사용(DATE)이 섞여 캐스팅이 들어옵니다. 회차 수가 적어 메모리 비교를 골랐습니다@RequireDepartment:/v1/admin/**ADMIN 인가는 SecurityConfig가 처리하고,AdminNoticeController([Feat/#103] 게시판(공지) 관리자 API 추가 #104)도 붙이지 않았습니다. 사물함 소관 부서가 정해지면 한 줄로 추가합니다💬 리뷰 포인트
[r]마이그레이션 번호. 지금origin/main이 V16이라 V17~V19를 알림 스택([Feat/#109] 회원 알림 설정 조회·수정 API 추가 #110·[Feat/#113] 아웃박스 릴레이 추가 #117·[Feat/#114] 알림 발송 공통 처리 추가 #118)에 비워두고 V20을 썼습니다. 이 PR이 먼저 머지되면 FlywayoutOfOrder=false때문에 나중에 오는 V17이 거부되므로 번호를 내려야 합니다[c]신청 마감일과 사용 시작일의 선후를 검증하지 않은 판단 — 추가 모집 때문인데, 운영상 맞는지 봐주세요[c]기간 겹침 검사를 메모리에서 하는 것 — 쿼리로 옮길 값이 있는지[a]목록 응답의currentPeriod를 응답 DTO에서 고르는 것(IN_PROGRESS첫 건)검증 범위
compileJava·compileTestJava,:core:domain:event:test,:infrastructure:db:test(Testcontainers — V20 적용과 엔티티 스키마 검증 포함),ModularityTests.verify()·DomainImplAccessTests통과했습니다.:bootstrap:test의RentalApplyConcurrencyTest2건은S3StorageConfig의 R2 엔드포인트 환경변수가 로컬에 없어 컨텍스트가 뜨지 않습니다. 이 브랜치와 무관한 기존 문제입니다.