MSG-500 feat: 관리자가 신청을 심사해 승인하면 행사가 지도에 실린다 - #245
Merged
Conversation
13450~13454는 스펙 표, 13455·13456은 목록 검증용. user 대역 1424·1425를 event 컨트롤러가 내지 않기 위한 신설이고 13440대는 MSG-502 예약이라 피했다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
관리자 상세와 신청자 상세가 같은 영역 그림을 보게 하기 위한 이동이고 로직 변경은 없다. 읽기 경로의 재검증(81칸 상한)은 제거됐다 — 저장 데이터는 접수 검증을 이미 통과했다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
13450 상수명 정정(SUBMISSION_STATUS_NOT_REVIEWABLE), 13455·13456 행 추가, M5의 1424·1425 재사용 근거 명시. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
FR-EVENT-17·18 신설, FR-EVENT-15는 유형별 분기 확정으로 재작성. M4 테스트가 인용할 ID를 소급 주석 없이 확보한다(MSG-390 교훈). Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
시더의 KST 변환·대표 격자 규칙을 public 승격해 재사용하고(복제 0), 무효화는 refreshLock 안에서 홀더를 비워 옛 결과 되채움을 차단한다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
셀 전개를 EventSubmissionCells 한 곳으로 모아 상세 칸 수와 승인 판정 격자가 같은 산술을 쓴다. 이미지 복사는 보상 등록이 복사보다 선행한다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
승인은 선검사, 전이와 승인 번호 한 문장 UPDATE, 재로드 후 등재 순서의 한 트랜잭션이다. 검증 19건. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
hidden_at IS NULL 술어로 첫 중지 시각을 보존하고, 활성·스탬프 판정·격자 역조회에 숨김 필터를 건다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
피드는 빈 목록이 아니라 미션 상세와 같은 404(12404)로 수렴한다. 진행도·방문 스팟·뱃지 지표에는 필터를 걸지 않는다(완료 기록 비회수). Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
탭 상태는 KST 오늘로 파생하고, 중지는 기록과 숨김 한 트랜잭션 뒤 커밋 성공 시에만 사유 메일을 보낸다(실패 시 emailSent=false). Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
트랜잭션 격리 클래스에선 롤백을 관찰할 수 없어 비트랜잭션 클래스에 편입했다. 시드 헬퍼를 픽스처로 추출. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
hide의 무효화 한 줄을 지우면 반드시 실패하는 형태다. 승인 쪽 기존 검증과 짝을 이뤄 D-12가 양방향으로 고정됐다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
전이 술어에 접수 시각 일치를 포함해 재제출 경합을 막고, 이메일 교체는 단일 컬럼 UPDATE라 동시 갱신을 되덮지 않는다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
승인은 전이와 이메일 교체 한 트랜잭션이고, 통지는 새 이메일로 커밋 후 발송한다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
검토 시점 가드와 동시 승인 경합, 커밋된 비밀번호 변경 생존까지 계약 단위로 덮는다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
승인(요청 행, users 행)과 탈퇴(users 삭제, CASCADE 요청 행)의 AB-BA 교차를 닫는다. 문장 순서 교체안은 1429/1409 우선순위가 흔들려 기각. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
작업 로그에 생성 SQL 실측, 예외 흐름 16행 표, afterCommit·잠금 순서·시퀀스 갭 등 런타임 동작과 MSG-502 인계 2건을 기록했다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
FR-USER-16과 FR-EVENT-18은 구현됨, FR-EVENT-15와 17은 참여형 잔여로 진행 중 유지. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
이메일 선검사를 전이 UPDATE 뒤로 옮겨 재승인은 0행 분기의 1428로 결정된다. 1409 거절 시 전이가 함께 롤백됨을 실커밋 테스트로 고정했다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
충돌 7파일 해소. SRS는 MSG-502가 선점한 FR-EVENT-17에 맞춰 중지를 18, 목록을 19로 재번호하고 테스트 주석과 문서 참조를 함께 옮겼다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
승인·중지·재시드가 같은 산술에 입력만 달리 넣는다. 재시드 합집합은 참여 위치 가시 격자로 한정해 시드 축소 시 옛 격자로 부풀지 않는다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
회차 잠금 아래 두 방향 겹침 검사 후 위치·참여 속성·커버 이미지를 반영하고 노출 영역을 넓힌다. 심사 상세에 참여 방식과 부모 이벤트를 싣는다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
동시 승인 직렬화, 숨긴 격자 재승인 거부, 시드 위치 불변까지 계약 단위로 덮는다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
|
Claude finished @s13121312's task in 4m 0s —— View job 리뷰 완료확인 범위: origin/develop 대비 마이그레이션(V51)·developCode 대역(13450 발견
코드 레벨(승인/반려/중지/이메일 심사 서비스, 리포지토리 쿼리, 엔티티, 마이그레이션, 잠금 순서, 숨김 필터 8+7곳)은 스펙·작업 로그의 서술과 실제 구현이 정확히 일치함을 확인했고, 병렬 브랜치 경합(마이그레이션 번호·developCode 대역)도 충돌 없음을 확인했습니다. 인라인 코멘트는 위 1건입니다. |
상호 배제는 양쪽이 다 잠가야 성립한다. 기동 시딩이 계약 밖이면 스테일 합집합이 방금 승인된 확장을 되쓰거나 시드 격자 삽입이 커밋 시점 500이 된다. Claude-Session: https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
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.
🎫 관련 티켓
작업 내용
GET /api/admin/event-submissions(상태 필터 + 탭 건수 3종), 상세는 위치 사각형·노출 영역1·신청 계정 정보에 참여형 전용 재료(참여 방식·부모 이벤트)까지 싣습니다APR-{연도}-{4자리}부여GET /api/admin/events(KST 파생 탭), 중지는 hidden_at 숨김 + 사용자 대면 전 경로 차단(칩·격자 선택·영상 피드·직링크·댓글·도움돼요) + 부모 회차 노출 영역 재계산 + 사유 메일. 이미 받은 스탬프·뱃지는 회수하지 않습니다13456·14271429 신설// 검증: FR-...주석으로 RTM 연결, 공백 0건)🤔 고민한 내용
승인 반영의 유형별 분기: 2026-08-29 정민 확정(PRD v2.2)에 따라 축제·팝업은 행사 도메인이 아니라 미션으로 등재합니다.
publish()의 switch에 default를 두지 않아, 유형이 늘면 컴파일 에러로 분기 누락이 드러납니다노출 중지 = 삭제가 아니라 숨김(hidden_at): 산출물 삭제는 스탬프 FK와 비회수 원칙에 충돌하고, 기간 소급은 저장값이 사실과 달라져 기각했습니다. 뱃지 지표·진행도에는 일부러 필터를 걸지 않았습니다(완료 기록 보존)
동시성: 같은 회차를 노리는 동시 승인은 회차 비관 잠금으로 직렬화(지연 유니크 제약의 커밋 시점 500 방지), 이메일 승인은 users 행 선잠금으로 계정 삭제의 FK CASCADE와 잠금 순서를 통일(AB-BA 데드락 차단), 같은 요청 동시 재승인은 전이 UPDATE를 선검사 앞에 둬 1428로 결정적 수렴
users.email은 단일 컬럼 UPDATE: 이 프로젝트는 @DynamicUpdate를 안 써 관리 엔티티 flush가 전 컬럼 UPDATE를 냅니다. 동시 비밀번호 변경을 되덮지 않도록
@ModifyingJPQL로 email만 갱신합니다노출 영역 산술 공용화: 승인(합집합 확장)·중지(남은 가시 위치 재계산)·재시드(시드 ∪ 가시 참여 격자)가
EventExposureArea한 곳의 산술을 입력만 달리해 씁니다. 재시드 합집합을 참여 위치로 한정해 시드 축소 시 옛 격자로 부풀지 않습니다미채택 판정 2건: 미션 업로드의 잠금 없는 숨김 검사(첫 완료는 스탬프 보존 확인이 같은 트랜잭션에서 롤백시켜 실해가 없음), 멱등 재시도의 숨김 게이트(새 저장 없는 과거 사실 재응답이라 게이트를 걸면 멱등 계약이 깨짐) — 근거는 스펙 작업 로그 참조
👀 리뷰 포인트
event-locations/org-submission/*공개 읽기 정책이 dev·prod 미적용입니다(missions/org-submission/은 기존missions/*정책이 커버). 런북은.claude/docs/deploy.md4번https://claude.ai/code/session_01W1NYGqr7zNx6u2iNFvLodV
Footnotes
노출 영역: 지도 뷰포트와의 겹침 판정에 쓰는 격자 경계 사각형. 행사 위치 사각형들을 전부 감싸는 범위로, 상단 행사 칩이 어느 지역 화면에서 보일지를 정합니다. ↩
커밋 후 무효화: 트랜잭션이 실제로 커밋된 뒤에만 캐시를 비우는 방식. 커밋 전에 비우면 아직 저장 안 된 상태를 다른 요청이 읽어 다시 캐시에 담아버립니다. ↩