기관별 권리확인 엑셀(Sheet0, ~1000행)을 업로드해 review_item 테이블에 반영하고,
조사원 항목은 항상 최신화하되 변호사 판정은 웹에서 한번 수정되면(web_edited_at)
재업로드가 덮어쓰지 않는 병합 정책을 적용한다. 목록/단건조회/판정저장/삭제/원본
서식 그대로의 엑셀 다운로드까지 REST로 제공한다.
- V8 마이그레이션으로 organization.stage와 stage_history 테이블 도입
- PUT /api/orgs/{id}/stage: 1..12 범위 검증 후 단계 변경 + 이력 적재
- 채널 2개가 처음 모두 갖춰지면 진행단계 1(신청)을 자동 시작(재실행 안전)
- GET /api/orgs/{id}/timeline: 단계 이력·업무메모·채널 첨부파일을 최신순으로 합쳐 제공
(Mattermost 조회 실패는 채널별로 흡수하고 200 유지)
경찰청 계열처럼 연번1(기관번호) 하나로 하위기관을 대표기관에 흡수하던 모델을
폐기하고, 시트의 모든 행(연번1_연번2)이 각자 독립된 기관·채널 쌍을 갖도록 바꿨다.
경찰청_치안정책연구소에 대한 -policy- 특례는 연번 자체가 하위기관까지 구분하므로
더 이상 필요 없어 제거했다. 기존 채널 ID는 V5 마이그레이션이 org_no만 변환해
그대로 보존한다.
기관에 박혀 있던 담당자 3종(신청기관/문정원/변호사) 컬럼을 contact 테이블로 옮기고,
기관은 담당자 id만 배정으로 참조하게 했다. 신청기관 담당자 배정 여부가 채널 생성
가능(READY) 판정 기준이 되도록 상태 로직도 함께 바꿨다.
- V4 마이그레이션: contact 테이블 생성 + 기존 임베디드 컬럼 백필 후 제거
- kr.itn.itnhub.contact 패키지: 담당자 CRUD API (GET/POST/PUT/DELETE /api/contacts)
- PUT /api/orgs/{id}/assignments가 기존 /contact 엔드포인트를 대체 (구분 불일치 400)
- SeedService: 시트의 담당자명은 신청기관 담당자가 아직 없을 때만 새로 만들어 연결
- ChannelProvisionService 게이트를 hasApplicantAssigned()로 교체
신청기관 담당자 1종만 저장하던 기관 테이블에 문정원 담당자(부서/담당자/연락처/이메일)와
담당 변호사(성명/연락처/이메일/배정일) 정보를 추가해, 채널관리 화면에서 세 담당자를
한 번에 저장하고 다른 화면(기관관리·업무메모)에서도 쓸 수 있게 한다.
- V3 마이그레이션으로 organization에 컬럼 8개 추가 (upsertBySeed는 그대로 둬서
엑셀 재시드가 새 컬럼을 건드리지 않는다)
- ContactRequest/OrgResponse/updateContact에 8개 필드를 선택값으로 반영
- 컨트롤러 테스트 2건(신규 필드 왕복, 신규 필드 없는 기존 페이로드) +
매퍼 테스트 2건(영속화 왕복, 재시드 시 보존) 추가
기관관리 상세의 업무메모 탭이 쓸 CRUD 엔드포인트를 추가한다. 통화 등
담당자와의 연락 내용을 기관별로 남기는 단순 기능이라 Mattermost 연동
없이 순수 DB로만 처리한다.
- V2__work_memo.sql: work_memo 테이블, org_id+created_at 인덱스
- WorkMemoMapper/xml: 최신순 조회, 등록, (orgId, id) 동시 조건 삭제
- WorkMemoService/Controller: GET/POST /api/orgs/{id}/memos,
DELETE /api/orgs/{id}/memos/{memoId}
- GlobalExceptionHandler: contactName/body 검증 메시지 한글 라벨 추가
- WorkMemoControllerTest: 등록/조회/최신순/검증/404/삭제/인증 검증
Co-Authored-By: Claude Opus 4.8 (1M context)