Repository navigation
사물함 신청 현황 조회·취소·수동 배정 관리자 API 추가 #149
Copy link
Copy link
Open
Labels
Description
어떤 기능인가요?
추가하려는 기능에 대해 간결하게 설명해주세요
운영진 콘솔에서 사물함 신청 현황을 보고, 잘못된 신청을 취소하고, 학생에게 사물함을 직접 배정하는 관리자 API를 추가한다. #146(상태 일괄 변경)에 이어지는 사물함 관리자 API의 네 번째 작업이다.
GET /v1/admin/lockers/applications— 회차 기준 신청 현황, 이름·학번 키워드 검색, 페이징DELETE /v1/admin/lockers/applications/{lockerApplicationId}— 신청 취소POST /v1/admin/lockers/applications— 수동 배정
지금은 누가 어느 칸을 썼는지 볼 방법도, 잘못 들어간 신청을 되돌릴 방법도 DB 직접 수정뿐이다.
핵심 제약은 locker_applications에 취소를 표현할 방법이 없다는 것이다. 지금 구조에서 취소는 곧 행 삭제라 이력이 남지 않고, 유니크 2개(회차+회원, 회차+사물함)가 취소된 신청까지 붙잡아 같은 학생·같은 칸에 다시 배정할 수 없다.
📝 작업 상세 내용
- V26 마이그레이션 —
locker_applications에is_canceled추가, 유니크 2개를 generated column 기반으로 교체해 취소된 신청이 재배정을 막지 않게 한다 -
LockerApplication에canceled와cancel()추가 — 이미 취소된 신청은 다시 취소할 수 없다 - 신청 현황 목록 조회 — 운영 회차 기준, 이름·학번 키워드 검색, 페이징.
MemberService.searchIdsByKeyword재사용 - 신청 취소 — 행은 남기고
is_canceled만 바꾼다. 사용 기간이 끝난 회차는 거부 - 수동 배정 —
memberId를 받고, 그 회차에 선택 가능한 칸인지 확인한다. 회원·사물함 중복은 유니크가 막는다 - 학생 조회에서 취소 건 제외 —
getApplicationsByMemberId에 필터 한 줄. 학생에게는 "미신청"으로 보인다 - 알림 —
LOCKER_ASSIGNED_BY_ADMIN·LOCKER_ASSIGNMENT_CANCELED신설(아웃박스) -
AdminLockerService에 세 동작 추가, 목록 조회와 납부자 확인은api:admin-api의 UseCase로 조합 -
LockerErrorCode보강,@ApiErrorCode로 문서화
📁 참고 자료 (선택)
- API 명세: 관리자 페이지(노션)
- 관리자 화면 구현: https://github.com/kmu-yed/stream-admin
- 선행: 사물함 운영 회차 관리자 API 추가 #119(운영 회차) → 사물함 신청 시 모집 기간 검증 추가 #128(신청 기간 검증) → 사물함 구역 목록·상세 관리자 API 추가 #132(구역 조회) → 사물함 상태 일괄 변경 관리자 API 추가 #146(상태 일괄 변경)
- 키워드 검색·페이징 선례:
AdminFeeSearchUseCase,AdminFeeController.searchFeeStatuses - 납부자 확인 선례:
RentalApplyUseCase의PayerService.validatePayer - 유니크 + generated column 선례: V1(
student_id), V16(phone_number), V20(period_year+semester) - 취소 알림 선례:
EventApplicationCanceled - V26으로 잡는다. main이 V19까지이고 사물함 스택(사물함 운영 회차 관리자 API 추가 #119~사물함 상태 일괄 변경 관리자 API 추가 #146)이 V20·V21, #139가 V22, #166이 V23~V25를 쓴다. 머지 순서가 바뀌면 다시 맞춘다
정한 것
- 취소해도 행은 남긴다. 운영진이 왜 비었는지 알아야 하고, 나중에 신청 이력을 볼 수도 있다. 대신 유니크 2개를
IF(is_canceled = 0, col, NULL) VIRTUAL형태로 바꿔 취소된 신청이 재배정을 막지 않게 한다 - 학생에게는 "미신청"으로 보인다. 명세의 배정 상태 뱃지가 미신청·배정완료·기간종료 셋뿐이라 취소 뱃지가 없다. 취소 건을 학생 응답에서 빼면 미신청으로 보이고, 기간이 남아 있으면 다시 신청할 수 있다. 표시용
LockerApplicationStatus와 [Feat/#72] 내 배정 사물함 조회 API 추가 #73(내 배정 사물함 조회)을 건드리지 않는다 - 컬럼은
status가 아니라is_canceled다. 승인 절차가 없어 신청이 곧 배정이라 값이 둘뿐이고, 저장소의 소프트 삭제 패턴과 모양이 같다. "기간종료"는 저장하지 않고 회차로 계산한다 - 수동 배정은
memberId를 받는다. 화면이 "학생회비 납부자 목록에서 이름 또는 학번으로 검색해 선택"하는 구조라, 검색은 #166이 만드는 납부자 목록 조회를 쓰고 배정 요청은 식별자만 받는다. 납부자인지는PayerService.validatePayer로 확인하며, 교차 도메인이라api:admin-api의 UseCase에서 조합한다 —core:domain:event는 회비를 모른다 - 수동 배정은 신청 기간 제약을 받지 않는다. 학생이 신청을 놓쳤거나 고장 난 칸을 옮겨줄 때 쓰는 기능이라 신청 기간이 끝난 뒤가 오히려 주 사용 시점이다. 사용 기간이 끝난 회차만 막는다
- 취소·수동 배정 모두 학생에게 알림을 보낸다. 본인이 하지 않은 변경이고, 화면이 조용히 바뀌므로 알림이 유일한 전달 수단이다. 기존
LOCKER_ASSIGNED("사물함을 신청했어요")는 학생이 직접 신청한 경우로 남긴다 - 운영진 전용 동작은
AdminLockerService에 둔다. #119에서 분리해둔 그대로다 - 응답에 학년은 넣지 않는다
이 이슈에서 다루지 않는 것
- 구역 배치(layout)·사진 교체 — 별도 이슈
- 학생이 직접 신청을 취소하는 기능 — 학생 앱은 신청만 한다
- 사물함 등록·삭제, 구역 등록·수정
Activity