Codex Lab 환경(iran-airstrike-replay-codex)에서 검증 완료된
어구 모선 자동 추론 + 검토 워크플로우 전체를 이식.
## Python (prediction/)
- gear_parent_inference(1,428줄): 다층 점수 모델 (correlation + name + track + prior bonus)
- gear_parent_episode(631줄): Episode 연속성 (Jaccard + 공간거리)
- gear_name_rules: 모선 이름 정규화 + 4자 미만 필터
- scheduler: 추론 호출 단계 추가 (4.8)
- fleet_tracker/kcgdb: SQL qualified_table() 동적화
- gear_correlation: timestamp 필드 추가
## DB (database/migration/ 012~015)
- 후보 스냅샷, resolution, episode, 라벨 세션, 제외 관리 테이블 9개 + VIEW 2개
## Backend (Java)
- 12개 DTO/Controller (ParentInferenceWorkflowController 등)
- GroupPolygonService: parent_resolution LEFT JOIN + 15개 API 메서드
## Frontend
- ParentReviewPanel: 모선 검토 대시보드
- vesselAnalysis: 10개 신규 API 함수 + 6개 타입
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
snpdb time_bucket은 tz-naive KST인데 UTC tzinfo를 강제 부여하여
incremental fetch WHERE time_bucket > %s 비교 시 미래 시간으로 해석,
항상 0 rows 반환 → 1h 어구 그룹이 점진적으로 소멸하는 버그.
tz-naive 그대로 유지하도록 수정 (load_initial, merge_incremental 3곳).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
서브클러스터 분리 후 개별 서브그룹의 1h 멤버가 2개 미만이더라도,
parent_name 전체(모든 서브클러스터 합산)에서 1h 활성 멤버 >= 2이면
resolution='1h'로 저장하여 라이브 현황에 표시.
결과: 라이브 1h 그룹 5개 → 927개 정상 복구
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 1h 실제 활성 멤버 < 2일 때 resolution='1h-fb' (fallback)로 저장
- LATEST_GROUPS_SQL은 resolution='1h'만 필터 → fallback 자동 제외
- FLEET 타입에 resolution='1h' 추가 (이전 누락)
- DB resolution 컬럼: VARCHAR(4) → VARCHAR(8) 확장
- 프론트 리플레이: '1h' + '1h-fb' 모두 1h 프레임으로 처리
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 1h 실제 활성 멤버 < 2일 때 resolution='1h-fb' (fallback)로 저장
- LATEST_GROUPS_SQL은 resolution='1h'만 필터 → fallback 자동 제외
- 리플레이 history API는 1h-fb 포함 (리플레이/일치율 추적 유지)
- 프론트 리플레이: '1h' + '1h-fb' 모두 1h 프레임으로 처리
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FLEET 스냅샷에 resolution 필드를 설정하지 않아 DB default '6h'로 저장됨.
LATEST_GROUPS_SQL이 resolution='1h' 필터를 사용하므로 FLEET 전부 누락.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ENC 전자해도: gcnautical 벡터 타일 연동 (gc-wing-dev 이식)
- 상단 위성/ENC 토글 버튼 + ⚙ 드롭다운 설정 패널
- 12개 심볼 토글 + 8개 색상 수정 + 초기화
- mapMode/encSettings localStorage 영속화
- style.load 대기 패턴으로 스타일 전환 시 설정 자동 적용
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 항공기 아이콘에 정수레벨 줌 기반 스케일 적용 (getZoomScale export)
- 심볼 크기 조정: SymbolScaleContext + SymbolScalePanel (0.5~2.0x)
- LayerPanel에 '심볼 크기' 섹션 추가 (선박/항공기 개별 조정)
- localStorage 영속화 (mapSymbolScale)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Python: 1h/6h 듀얼 스냅샷 생성 (polygon_builder), 1h 멤버 기반 일치율 후보 (gear_correlation)
- DB: resolution 컬럼 추가 (011_polygon_resolution.sql)
- Backend: resolution 필드 지원 (DTO/Service/Controller)
- Frontend: 6h identity 레이어 독립 구현 (폴리곤/아이콘/라벨/항적/센터)
- 리플레이 컨트롤러: 프로그레스바 통합, 1h/6h 스냅샷 표시, A-B 구간 반복
- 리치 툴팁: 클릭 고정 + 멤버 호버 강조 + 선박/어구/모델 소속 표시
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 서브클러스터별 독립 폴리곤/센터/center trail 렌더링
- 반경 밖 이탈 선박 강제 감쇠 (OUT_OF_RANGE)
- Backend correlation API에 sub_cluster_id 추가
- 모델 패널 5개 항상 표시, 드롭다운 기본값 70%
- DISPLAY_STALE_SEC (time_bucket 기반) 폴리곤 노출 필터
- AIS 수집 bbox 122~132E/31~39N 확장
- historyActive 시 deck.gl 이중 렌더링 수정
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
prediction/ 변경 시 ssh redis-211으로 수동 scp + restart
CI/CD는 Frontend + Backend만 자동 배포
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
사전계산 (gearReplayPreprocess):
- buildModelCenterTrails(): 각 프레임에서 멤버+연관선박 위치 → 폴리곤 → 중심점
- 모델별 path[]/timestamps[] (PathLayer + 보간용)
스토어 (gearReplayStore):
- modelCenterTrails 필드 추가 (loadHistory/updateCorrelation에서 빌드)
렌더링 (useGearReplayLayers):
- PathLayer: 모델별 폴리곤 중심 경로 (연한 모델 색상, alpha 100)
- ScatterplotLayer: 현재 시간 중심점 (고채도 모델 색상, 흰 테두리)
- 모델 ON 시에만 표시 (enabledModels 체크)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
패널 위치:
- left: 10 → left: calc(50% - 210px) (재생 컨트롤러 중앙 정렬 근처)
일치율 드롭다운 전역 적용:
- 기존: 현재 ON인 모델의 대상만 필터
- 수정: 모든 모델의 모든 대상에 전역 적용 (모델 on/off 무관)
- 동일 MMSI가 여러 모델에 있을 때 최고 score 기준 판단
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- kcgdb.get_conn()을 with문 없이 사용 → cursor 에러
- with kcgdb.get_conn() as conn: 으로 수정
- 디버그 로그 추가 (rows 수, track 매칭 수, vessel_store 크기)
- 결과: 47 vessels, 47 with track data (25567#1 그룹)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 트랙 시간 범위 밖: 가장 가까운 끝점으로 clamp (기존: skip)
→ 트랙 시작 전 = 첫 점, 트랙 종료 후 = 마지막 점
- 디버그 로그: corrPositions 상세 (track/live 소스별, 모델별 위치확인 수)
- 기존 중복 로그 정리
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prediction API:
- /correlation/{group}/tracks: is_default=TRUE 제거 → 모든 활성 모델 조회
- 응답에 models: {modelName: score} 딕셔너리 추가 (모델별 점수)
- MMSI 기준 중복 제거, 최고 점수 유지
Frontend:
- CorrelationVesselTrack 타입: models 필드 추가, type 필드 추가
- 오퍼레이셔널 폴리곤: enabledVessels 기반 on/off 제어
(score 임계값 → 개별 체크박스 토글로 전환)
- identity OFF 시 폴리곤 base points에서 멤버 위치 제외
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- useGearReplayLayers에 shipsRef 파라미터 추가
- corrPositions 계산: 트랙 보간 우선 → live 선박 위치 fallback
- KoreaMap: allShips → shipsRef에 매 렌더 동기화 (ref로 re-render 방지)
- globalThis.Map으로 react-map-gl Map 타입 충돌 해결
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>