Repository navigation
[Feat/#146] 사물함 상태 일괄 변경 관리자 API 추가 - #148
Open
sangrae2325 wants to merge 12 commits into
Open
sangrae2325 wants to merge 12 commits into
sangrae2325 wants to merge 12 commits into
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
github-actions
Bot
requested review from
jjunh33,
leegain1,
tnals0924 and
xeoxxn
October 19, 2026 04:16
tnals0924
reviewed
Oct 23, 2026
sangrae2325
force-pushed
the
feat/#146-admin-locker-status
branch
from
October 27, 2026 10:01
5e96754 to
4eeecd7
Compare
sangrae2325
force-pushed
the
feat/#146-admin-locker-status
branch
from
October 27, 2026 10:36
4eeecd7 to
20cc543
Compare
sangrae2325
force-pushed
the
feat/#146-admin-locker-status
branch
from
October 27, 2026 11:18
20cc543 to
9654f0c
Compare
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 1개를 추가합니다.
#132(구역 조회)에 이어지는 사물함 관리자 API의 세 번째 작업입니다.
❓ 왜 해결해야 하나요?
사물함이 고장 나도 상태를 바꿀 방법이 DB 직접 수정뿐입니다.
LockerRepository에 사물함 쓰기 경로가 아예 없습니다 — 회차는 #119에서 뚫었지만 사물함은 조회만 있습니다.상태를
DISABLED로 내리면Locker.isSelectable이 false가 되어 학생 화면의 선택 가능 수와 칸 표시에서 빠집니다. 그게 이 기능의 목적입니다.⭐ 어떻게 해결했나요?
1. 도메인 —
Locker.changeStatus와LockerStatus.isUsable을 더합니다. 쓸 수 있는 상태를 허용 목록으로 두어, 상태가 늘어도 새 값이 자동으로 "쓸 수 없음"에 들어가게 했습니다.Locker.isSelectable과 이용 중 검사가 같은 메서드를 봅니다.2. 저장소 —
saveLockers(여러 건 저장),findLockersByIds,existsByPeriodIdsAndLockerIds를 추가합니다.3. 서비스 —
AdminLockerService.changeLockerStatus입니다.검증을 전부 먼저 하고 바꿉니다. "하나라도 안 되면 전체를 안 바꾼다"를
@Transactional에만 기대지 않았습니다 — 예외로 롤백하는 것보다 사전 검증이 의도가 분명하고 실패 사유도 정확해집니다.이용 중 검사는 쓸 수 없는 상태로 바꿀 때만 합니다.
AVAILABLE로 되돌리는 건 막을 이유가 없고 쿼리 2개를 아낍니다.이용 중 판정은 회차를 먼저 좁힙니다. 회차는 학기당 한두 건이라 전부 읽어도 되고, 그래야 신청 조회가
(회차, 사물함)유니크 인덱스를 탑니다. 사물함 식별자만으로 신청을 찾으면 탈 인덱스가 없어 이력 전체를 훑습니다.4. API — 기존
AdminLockerSectionController에@PatchMapping("/{sectionId}/lockers/status")를 더합니다. 관리자 "구역 관리" 탭 한 화면이 쓰는 API가 전부/sections/{sectionId}아래라 컨트롤러를 탭 단위로 맞췄습니다. 조회 컨트롤러에 쓰기가 섞이는 건AdminNoticeController·AdminLockerPeriodController선례가 있습니다.응답 본문은 없습니다. 바뀐 결과는 화면이 구역 상세를 다시 조회해 받습니다.
🧩 이 PR의 한계 & 트레이드오프
취소 → 사용 중지로 처리합니다AGENTS.md원칙에 따랐습니다⛓️ 기존 기능에 미치는 영향
LockerStatus.isUsable도입으로Locker.isSelectable내부 표현만 바뀌고 결과는 같습니다lockers.status컬럼이 이미 있습니다DISABLED로 내리면 학생 화면의 선택 가능 수와 칸 표시에서 빠집니다 — 의도한 동작입니다LockerJpaEntity에@DynamicUpdate를 붙여 상태 변경이is_deleted같은 다른 컬럼을 덮어쓰지 않습니다🔀 Edge Case & 실패 시나리오
lockerIds가 빈 배열INVALID_INPUT(400) + "사물함을 하나 이상 선택해 주세요."lockerStatus가 enum에 없는 값INVALID_INPUT(400) — Jackson이 못 읽어HttpMessageNotReadableExceptionsectionIdLOCKER_SECTION_NOT_FOUND(404) — 같은 경로의 구역 상세 조회와 같습니다LOCKER_NOT_IN_SECTION(400), 아무것도 안 바뀜lockerIds에 같은 id가 여러 번DISABLED로LOCKER_IN_USE(409), 아무것도 안 바뀜DISABLED로AVAILABLE로is_deleted = false로 걸러LOCKER_NOT_IN_SECTION📋 검토한 대안과 선택 이유
architecture.md:74도infrastructure:*가 비즈니스 규칙을 갖지 않는다고 합니다. 판정은 내 신청 내역 화면이 쓰는LockerApplicationStatus.from(period, today)를 그대로 재사용해서, "배정 중"의 기준이 바뀌어도 한 곳만 고치면 됩니다locker_applications에locker_id로 시작하는 인덱스가 없어 이력 전체를 훑습니다. 회차를 먼저 좁히면(회차, 사물함)유니크 인덱스를 타고 쿼리 수는 그대로 둘입니다LockerStatus(물리 상태)와 구역 상세가 주는 표시 상태(회차 기준)가 서로 다른 값이라 응답으로 칸을 다시 그리면 어긋납니다. 배정된 칸을AVAILABLE로 바꾸면 응답엔AVAILABLE이 오는데 화면은ASSIGNED로 그려야 합니다.Void로 두고 상세를 다시 조회하게 했습니다changeStatus가 바뀐 여부를 돌려주기: 바뀐 것만 저장하려 했는데,filter안에서 상태를 바꾸게 되어 스트림 규칙에 어긋납니다. 같은 트랜잭션에서 이미 영속성 컨텍스트에 올라와 있어 전부 넘겨도 값이 바뀐 행만 UPDATE됩니다LOCKER_NOT_IN_SECTION을 404로: "없는 사물함"으로 보면 404지만, 구역과 사물함의 조합이 틀린 요청이라 400으로 뒀습니다. 없는 구역은 404입니다LOCKER_NOT_FOUND를 따로 두기: 만들었다가 지웠습니다. 없는 사물함과 다른 구역 사물함을 운영 화면에서 가를 이유가 없어 던질 곳이 없습니다@Size(max = N): 구역마다 칸 수가 달라 숫자를 박으면 언젠가 틀립니다. 중복만 걷어내면 상한이 자연히 그 구역의 칸 수가 됩니다AdminLockerStatusController): 화면 단위로 묶는 쪽이/periods·/applications와 나란히 가서 기존 컨트롤러에 넣었습니다PUT: 전체 교체가 아니라 상태 한 필드만 바꿔서PATCH입니다💬 리뷰 포인트
[r]배정된 칸의 사용 중지를 막는 기준이 맞는지 봐주세요. 관리자 화면이 배정된 칸을 고를 수 없게 하고 있어 그에 맞췄고, 고장 난 칸은 #149의 신청 취소가 생긴 뒤취소 → 사용 중지로 처리할 생각입니다[c]이용 중 검사와 학생 신청의 경합은 막지 않았습니다. 비관적 락이 저장소에 없는 패턴이라 Swagger에 적어두는 선에서 멈췄는데, 이 선택이 괜찮은지 봐주세요[a]사용 종료일 당일까지는 사용 중으로 봅니다(isUsageEnded가today.isAfter(usageEndAt)). 운영 기준이 이게 맞는지