kcg-ai-monitoring/frontend/src/stores/patrolStore.ts
htlee c17d190e1d feat: S5 프론트 나머지 화면 실데이터 전환 — 탐지/함정/단속계획
탐지 화면 3개:
- GearDetection: gearStore 더미 → fetchGroups() API (GEAR_IN/OUT_ZONE)
- DarkVesselDetection: vesselStore 더미 → fetchVesselAnalysis() + filterDarkVessels()
  - 패턴 자동 분류 (완전차단/장기소실/MMSI변조/간헐송출)
- ChinaFishing: inline 더미 → fetchVesselAnalysis() + mmsi 412* 필터
  - 센서 카운터 동적 계산, 위험도 분포 도넛 차트

함정/단속계획:
- patrol.ts: 스텁 → GET /api/patrol-ships 실제 호출
- patrolStore: API 기반 (routes/scenarios는 mock 유지)
- EnforcementPlan: GET /api/enforcement/plans 연결

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 12:46:08 +09:00

69 lines
1.9 KiB
TypeScript

import { create } from 'zustand';
import type {
PatrolShip,
PatrolRoute,
PatrolScenario,
CoverageZone,
} from '@data/mock/patrols';
import { getPatrolShips, toLegacyPatrolShip } from '@/services/patrol';
interface PatrolStore {
ships: PatrolShip[];
routes: Record<string, PatrolRoute>;
scenarios: PatrolScenario[];
coverage: CoverageZone[];
fleetRoutes: Record<string, [number, number][]>;
selectedShipId: string | null;
loaded: boolean;
loading: boolean;
error: string | null;
load: () => Promise<void>;
selectShip: (id: string | null) => void;
}
export const usePatrolStore = create<PatrolStore>((set, get) => ({
ships: [],
routes: {},
scenarios: [],
coverage: [],
fleetRoutes: {},
selectedShipId: null,
loaded: false,
loading: false,
error: null,
load: async () => {
if (get().loaded && !get().error) return;
set({ loading: true, error: null });
try {
// 함정 목록은 API에서, 나머지(routes/scenarios/coverage)는 mock 유지
const [apiShips, mockModule] = await Promise.all([
getPatrolShips(),
get().routes && Object.keys(get().routes).length > 0
? Promise.resolve(null)
: import('@data/mock/patrols').then((m) => ({
routes: m.MOCK_PATROL_ROUTES,
scenarios: m.MOCK_PATROL_SCENARIOS,
coverage: m.MOCK_COVERAGE_ZONES,
fleetRoutes: m.MOCK_FLEET_ROUTES,
})),
]);
set({
ships: apiShips.map(toLegacyPatrolShip),
routes: mockModule?.routes ?? get().routes,
scenarios: mockModule?.scenarios ?? get().scenarios,
coverage: mockModule?.coverage ?? get().coverage,
fleetRoutes: mockModule?.fleetRoutes ?? get().fleetRoutes,
loaded: true,
loading: false,
});
} catch (err) {
set({ error: err instanceof Error ? err.message : String(err), loading: false });
}
},
selectShip: (id) => set({ selectedShipId: id }),
}));