MattermostException만 catch하던 ensure()를 RuntimeException으로 넓혀,
채널 생성 직후 mapper 저장이 DataAccessException 계열로 실패해도
반대쪽 채널 시도를 막지 않고 FAILED로 강등되도록 수정. applyChannelId는
exhaustive switch 식으로 바꿔 컬럼 오기입 방지 주장을 실제로 컴파일
타임에 보장하고, 첫 채널 실패/양쪽 실패/DB 저장 실패 회귀 테스트를
추가했다.
Co-Authored-By: Claude Opus 4.8 (1M context)
같은 시트에 동일 기관이 두 번 들어오면 DB는 upsert로 한 행에 합치지만
집계는 둘 다 created로 세어 report가 실제 결과와 어긋났다. 처리 완료된
키를 그 자리에서 seen 집합에 반영해 두 번째 등장부터는 updated로 잡히게
했다.
또한 seed()가 엑셀 파싱까지 @Transactional 안에서 수행해 파싱 중에도
DB 커넥션을 점유하고 있었다. 파싱은 트랜잭션 밖으로 빼고, DB 조회+upsert
구간만 TransactionTemplate으로 감싸 커넥션 점유 구간을 최소화했다.
(같은 빈 self-invocation으로 @Transactional을 추가하면 프록시를 우회해
트랜잭션이 걸리지 않으므로 이 방식을 택함.)
중복 기관 업로드 시나리오에 대한 테스트를 추가했다.
- 연번1 등 NUMERIC 셀을 (long) 캐스팅해 절삭하던 것을 Math.round로 교체.
부동소수점 오차(예: 6.999999999999998)가 실제 값보다 한 자리 작은
기관번호("006")로 읽혀 채널명이 잘못 생성되는 문제를 막는다.
- FORMULA 셀은 default 분기로 빠져 항상 빈 문자열로 읽히던 것을 고쳐,
캐시된 수식 결과 타입(getCachedFormulaResultType)에 따라 STRING/NUMERIC
처리 로직을 재사용하도록 cellValue(Cell, CellType) 재귀 구조로 정리.
- 두 결함을 각각 재현하는 테스트 추가(부동소수점 절삭, 수식 셀 캐시값 읽기).
Co-Authored-By: Claude Opus 4.8 (1M context)
updateChannelId(id, kind, channelId)는 kind가 "mj"가 아니면 무조건
로 빠져 channel_id_law에 잘못 기록됐다. 오타·null·새 kind가
들어와도 예외 없이 조용히 엉뚱한 컬럼을 덮어써 검증이 불가능했다.
분기를 없애고 updateChannelIdMj/updateChannelIdLaw로 나눠
컬럼을 컴파일 타임에 고정한다. 폴백 경로 자체가 사라져 다음 단계인
Mattermost 채널 프로비저닝에서 한쪽씩 기록해도 안전하다.
@Testcontainers/@Container를 쓰면 클래스마다 컨테이너가 stop되는데 Spring
컨텍스트 캐시는 죽은 포트를 가리키는 DataSource를 재사용해, 전체 스위트
실행 시 두 번째로 실행되는 DB 테스트 클래스가 순서에 따라 Connection
refused로 깨졌다. 컨테이너를 static 블록에서 한 번만 start하고 절대
stop하지 않도록 바꿔 모든 AbstractDbTest 하위 클래스가 동일한 컨텍스트/
컨테이너를 공유하게 했다. SchemaMigrationTest는 자체 스캐폴딩을 지우고
AbstractDbTest를 상속하도록 정리했다.
생성자가 2개(공개 1-인자, 패키지 전용 2-인자)로 늘어나며 Spring의
단일 생성자 자동 선택 규칙이 더 이상 적용되지 않아, 기본 생성자를
찾지 못해 컨텍스트 리프레시 단계에서 BeanCreationException으로
애플리케이션 기동이 실패하고 있었다. 공개 1-인자 생성자에
@Autowired를 명시해 Spring이 이를 명확히 선택하도록 고쳤다.
Spring 컨텍스트를 실제로 로딩해 MattermostClient 빈을 검증하는
테스트가 없어 이 회귀를 잡지 못했으므로, AbstractDbTest(신규
공통 베이스)와 이를 상속하는 MattermostRestClientSpringWiringTest를
추가해 재발을 방지한다.
WireMock(Jetty)의 h2c 업그레이드 협상 문제를 회피하려던 HTTP/1.1 고정이
운영 코드(RestClient)에 들어가 있어 실제로는 HTTPS/ALPN으로 협상하는
운영 전송 계층까지 불필요하게 좁히고 있었다. 전송 설정을 주입 가능한
생성자로 분리해 운영 생성자는 프레임워크 기본값을 쓰고, 테스트만
HTTP/1.1을 고정하도록 수정했다.
연번+기관명 유니크 테스트가 단일 삽입 후 건수만 확인해 uq_organization_no_name
제약이 삭제돼도 통과하는 문제를 수정. 동일 조합 중복 삽입 시 예외 발생과,
동일 연번(008 경찰청/경찰청_치안정책연구소)의 다른 기관명은 정상 저장되는
두 경우를 모두 검증하도록 변경. application.yml의 hikari.schema 설정에는
Flyway 스키마 지정과 별개로 필요한 이유를 주석으로 명시.