bibimbap/.atp/work-session/20260624-100749/implementation/W2-2-impl.md

8.7 KiB

phase agent agent_version generated_at workstream concerns concerns_checked workers_spawned planned_workers actual_workers self_verification
implementation implementation-advisor 1 2026-06-24T11:05:00+09:00 W2-2-심사위원 역할 권한(jam_judges + JamRoleGate)
true 7 7 7
checklist_passed unused_diagnostics test_compile
true 0 BUILD SUCCESS

구현 보고: W2-2 심사위원 역할 권한 (jam_judges + JamRoleGate)

권위 설계도: .atp/work-session/20260623-104307/implementation/W2-2-judge-role-design.md (오픈질문 0, 정본 그대로 구현, 임의 변경 0).

변경 목록

파일 worker 결과 요약
docs/jam-judge-ddl.sql (신규) migration-writer w-001 권위 DDL. jam_judges(id/jam_id/user_id/assigned_by/created_at) + FK 3종(jams/users/users) + ux_jam_judges_jam_user UNIQUE + idx_jam_judges_jam. 멱등(SEQUENCE/TABLE IF NOT EXISTS, DO pg_constraint guard, CREATE UNIQUE INDEX IF NOT EXISTS) — jam-ddl 선례 동형
db/schema.sql (수정) migration-writer w-001 파일 끝(558~596행) jam_judges 블록 동기 사본 추가. 헤더 주석 game_reviews/jam 블록 선례 동형. docs 본문과 바이트 일치(diff 0). jams 블록(374~) 뒤 → FK 순서 정합
data/JamJudgeData.java (신규) code-writer w-002 POJO 6필드(id/jamId/userId/assignedBy/createdAt/displayName) + getter/setter. JamEntryData 동형(Lombok 미사용)
mapper/JamJudgesMapper.java (신규) code-writer w-003 @Mapper insert/delete/exists/listByJam. #{} only, §33 alias 가드(POJO 비인용 alias, 큰따옴표 0). exists=EXISTS boolean(UserPermissionsMapper 선례)
mapper/JamEntriesMapper.java (수정) code-writer w-004 isOwnEntry(jamId,gameId,userId) 1건 추가. 기존 3메서드 보존. USER+TEAM 양경로 OR-EXISTS. #{} only
security/JamRoleGate.java (신규) code-writer w-005 @Component 잼 스코프 게이트(별도 축). isJudge(session,jamId)/isOwnEntry(jamId,gameId,judgeUserId). 두 매퍼 생성자 주입. 요청당 직접 조회(epoch/캐시 0). sessionUserId PermissionGate 동형
controller/JamJudgeAdminController.java (신규) code-writer w-006 @Controller. assign(POST)/remove(POST)/list(GET) 3핸들러. requireJamManage 전수 진입 게이트 + 상태변경 CSRF 2건. DuplicateKeyException catch→409. JamAdminController 헬퍼 동형
webapp/.../admin-jam-list.jsp (수정) code-writer w-007 심사위원 관리 섹션 + data-action 위임 핸들러(judges/judge-assign/judge-remove). fetch GET 목록 + post 지정/해제. 클라 렌더 textContent only(innerHTML 0). 기존 폼/스크립트 보존
test/.../BibimbapApplicationTests.java (수정) advisor 직접 @MockBean 2건 추가(JamJudgesMapper, JamRoleGate). contextLoads 빈 의존 해소 (설계 §VP-8/AC-T6, concern 2)

Bash 단계 (advisor 직접)

  • ./mvnw -o test-compile (JAVA_HOME=/opt/homebrew/opt/openjdk@21/...) → BUILD SUCCESS, MAVEN_EXIT=0. main+test 전 소스 컴파일 통과(신규 @MockBean 포함).
  • ./mvnw -o clean compile -Dmaven.compiler.compilerArgument=-Xlint:allBUILD SUCCESS, 전체 WARNING 0, W2-2 파일 unused 0. unused 진단 별도 게이트 통과.
  • AC-T1~T7 + §33 정적 grep 게이트 전수 실행 → 전부 기대값 일치(아래 §검증 echo).
  • 테스트 실행·DB 적용·git commit 안 함(verification/수동/orchestrator 영역).

설계와의 차이

없음. planned_workers(7) == actual_workers(7). 설계 파일영향맵·시그니처·DDL·API 계약·시퀀스를 정본 그대로 구현.

세부 결정(설계 범위 내, 임의 변경 아님):

  • 목록 조회 UI = 클라이언트 fetch GET: 설계 §외부계약이 목록 조회를 JSON API(GET /admin/jams/{jamId}/judges)로 명시했고, W2-1 console() 핸들러(model 에 jams/csrfToken 만 주입)를 수정하면 안 되므로, JSP 는 비동기 fetch 로 목록을 로드(SSR 추가 데이터 0). console() 무수정 = W2-1 검증 동작(6핸들러 게이트) 보존.
  • JamRoleGate @MockBean 채택: 설계 concern 2 가 "@Component 면 @MockBean 또는 실제빈+의존매퍼 MockBean" 명시. @MockBean 채택(W1 PermissionGate 동형). 의존 매퍼(JamJudgesMapper/JamEntriesMapper)도 @MockBean 이라 양립.

W2-1 기존 파일 수정 여부 + 근거

  1. JamEntriesMapper.java (수정) — 설계 §파일영향맵 명시(K-MAPPER, crossRefs). isOwnEntry 메서드 1건 추가만, 기존 insert/listByJam/exists 3메서드 한 글자도 변경 0(자기출품 충돌 판정 = W2-2 소관). W2-1 호출지점 깨짐 0(신규 메서드).
  2. admin-jam-list.jsp (수정) — 설계 §파일영향맵 명시(K-ADMIN, crossRefs). 심사위원 섹션·버튼·스크립트 핸들러 추가만. 기존 생성 폼/목록 테이블/transitionStatus·toggleVisibility·removeJam 스크립트 보존(grep 7매치 확인).
  3. BibimbapApplicationTests.java (수정) — 설계 §파일영향맵 (검증) 명시. @MockBean 2건 추가만(contextLoads 보존 의무).
  4. db/schema.sql (수정) — 설계 §데이터모델 명시. jam_judges 블록 추가만(전역 RBAC/jams/jam_entries 블록 무변경).

JamController/JamAdminController/InterceptorConfig/W2-1 5매퍼는 무수정 — 설계 J3-A(InterceptorConfig 의 /admin/jams/** exclude 가 /admin/jams/{id}/judges 트리 커버 → 추가 수정 불요)에 따라 건드리지 않음. W2-1 검증 동작(requireJamManage·CSRF·#{}) 회귀 0.

concerns 처리 결과

설계 frontmatter concerns 5건은 본 구현이 모두 해소(설계가 결정으로 고정한 항목):

  • concern 1 (시그니처 inflate): isJudge(session,jamId)/isOwnEntry(jamId,gameId,judgeUserId)/매퍼 시그니처 전부 최소 인자, dead parameter 0. -Xlint:all unused 0 + 수동 교차검증(JamRoleGate 두 매퍼 7회 사용, Controller 4 주입필드 전부 사용).
  • concern 2 (신규 빈 @MockBean / full test): JamJudgesMapper + JamRoleGate @MockBean 등록. test-compile BUILD SUCCESS. full ./mvnw -o test 실행은 verification-advisor 몫(본 advisor 실행 금지) — VP-8 로 이관.
  • concern 3 (§33 alias): JamJudgesMapper resultType=POJO(JamJudgeData) → snake→camel 직접 alias, 큰따옴표 alias 0건(grep 확인). isOwnEntry/exists boolean(EXISTS) 매핑.
  • concern 4 (자기출품 충돌 = 계약, enforce=W2-4): 본 W2-2 는 JamRoleGate.isOwnEntry + JamEntriesMapper.isOwnEntry 헬퍼·계약만 제공. 지정 시점 충돌 미차단(J7). W2-4 점수입력 소비점은 verification 시 crossRefs 재확인.
  • concern 5 (배포 순서 의존): InterceptorConfig 무수정(J3-A). W2-1 의 /admin/jams/** exclude 선배포 의존 — 롤아웃 순서 문서화(설계 §롤아웃). 코드 결함 아님.

Verification 을 위한 힌트

  • acceptance criteria 는 design.md 의 "검증 포인트" + "집합 전수 체크 AC" 참조(아래 verbatim echo).
  • 이번 변경으로 영향받는/신규 테스트 파일(설계 §파일영향맵 (검증) — 본 advisor 미작성, verification 작성 대상):
    • src/test/.../JamJudgeAdminControllerTest.java (신규 — VP-1/4/5/6)
    • src/test/.../JamRoleGateTest.java (신규 — VP-2/3)
    • src/test/.../BibimbapApplicationTests.java (수정 완료 — VP-8/AC-T6 contextLoads)
  • full ./mvnw -o test 의무(설계 §30/concern 2). JAVA_HOME=/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home 사용(시스템 java 없음).
  • DB-방언 L2 실측 권장: isOwnEntry OR-EXISTS, JamJudgesMapper EXISTS boolean, listByJam JOIN users alias (dev DB contract).

자가확인 정적 게이트 결과 (verification echo 근거)

  • AC-T1: docs ADD CONSTRAINT=3, CREATE UNIQUE INDEX=1 / schema.sql jam_judges ADD CONSTRAINT=3, UNIQUE INDEX=1 → PASS
  • AC-T2: @Post/@GetMapping 핸들러=3, requireJamManage=4(정의1+호출3) → 전수 게이트 PASS
  • AC-T3: CsrfTokens.isValid=2(상태변경 2핸들러) → PASS
  • AC-T4: entrant_type 'USER'=1, 'TEAM'=1 → 양경로 PASS
  • AC-T5: JamJudgesMapper+JamEntriesMapper ${=0 → PASS
  • AC-T6: JamJudgesMapper @MockBean=1, JamRoleGate @MockBean=1 → PASS
  • AC-T7: docs 전역테이블(users/user_permissions/permissions) ALTER/CREATE=0 → 전역 RBAC 무변경 PASS
  • §33: JamJudgesMapper 큰따옴표 alias=0 → PASS

미해결 / 리스크

  • DB 미적용(NOT APPLIED). db/apply-local-ddl.sh 로 jam-judge-ddl 적용은 수동 영역(jam-ddl < jam-judge-ddl 알파벳 순 → FK 선행 jams 자동 보장).
  • 테스트 코드(JamJudgeAdminControllerTest/JamRoleGateTest) 미작성 — verification-advisor 작성·실행 대상.
  • W2-4 점수입력의 isJudge/isOwnEntry 소비점은 W2-4 워크스트림에서 검증(crossRefs).