import { apiClient } from "./client"; const BASE = "/fleet"; export interface FleetDevice { id?: number; device_id: string; company_code?: string; device_name?: string; device_type?: string; ip_address?: string; mac_address?: string; hardware_fingerprint?: string; last_seen_at?: string; is_online?: boolean; equipment_id?: number | null; equipment_name?: string; equipment_code?: string; agent_version?: string; os_info?: Record; hardware_info?: Record; device_group?: string; tags?: any[]; } export interface FleetCommand { id?: number; device_id: string; command_type: string; payload?: Record; status?: string; result?: Record; error_message?: string; issued_by?: string; issued_at?: string; sent_at?: string; responded_at?: string; } export interface FleetAlert { id: number; rule_id: number; rule_name?: string; device_id: string; severity: string; title: string; message: string; metric: string; value: number; threshold: number; status: "open" | "acknowledged" | "resolved"; created_at: string; } export const fleetApi = { // 디바이스 getDevices: (filter?: { is_online?: boolean; search?: string }) => apiClient.get(`${BASE}/devices`, { params: filter }).then((r) => r.data), getDevice: (deviceId: string) => apiClient.get(`${BASE}/devices/${deviceId}`).then((r) => r.data), registerDevice: (data: Partial) => apiClient.post(`${BASE}/devices/register`, data).then((r) => r.data), updateDevice: (deviceId: string, data: Partial) => apiClient.patch(`${BASE}/devices/${deviceId}`, data).then((r) => r.data), deleteDevice: (deviceId: string) => apiClient.delete(`${BASE}/devices/${deviceId}`).then((r) => r.data), getMetrics: (deviceId: string, limit = 100) => apiClient.get(`${BASE}/devices/${deviceId}/metrics`, { params: { limit } }).then((r) => r.data), // 커맨드 getCommands: (filter?: { device_id?: string; status?: string; limit?: number }) => apiClient.get(`${BASE}/commands`, { params: filter }).then((r) => r.data), getCommandTypes: () => apiClient.get(`${BASE}/commands/types`).then((r) => r.data), issueCommand: (data: { device_id: string; command_type: string; payload?: any; timeout_sec?: number }) => apiClient.post(`${BASE}/commands`, data).then((r) => r.data), // 알림 getAlerts: (status: string = "open") => apiClient.get(`${BASE}/alerts`, { params: { status } }).then((r) => r.data), ackAlert: (id: number) => apiClient.post(`${BASE}/alerts/${id}/ack`).then((r) => r.data), resolveAlert: (id: number) => apiClient.post(`${BASE}/alerts/${id}/resolve`).then((r) => r.data), getAlertRules: () => apiClient.get(`${BASE}/alert-rules`).then((r) => r.data), // 배포 getDeployments: () => apiClient.get(`${BASE}/deployments`).then((r) => r.data), getReleases: () => apiClient.get(`${BASE}/releases`).then((r) => r.data), // 통계 getStats: () => apiClient.get(`${BASE}/stats`).then((r) => r.data), // 실시간 데이터 getLatestValues: (deviceId: string) => apiClient.get(`${BASE}/devices/${deviceId}/latest-values`).then((r) => r.data), getLatestValuesByEquipment: (equipmentId: number) => apiClient.get(`${BASE}/equipment/${equipmentId}/latest-values`).then((r) => r.data), getTagTimeseries: (deviceId: string, tagName: string, limit = 500) => apiClient .get(`${BASE}/devices/${deviceId}/tags/${encodeURIComponent(tagName)}/timeseries`, { params: { limit }, }) .then((r) => r.data), getDataStats: (deviceId?: string) => apiClient.get(`${BASE}/data/stats`, { params: { device_id: deviceId } }).then((r) => r.data), // ===== Python Hook 스크립트 ===== getHookTypes: () => apiClient.get(`${BASE}/scripts/hook-types`).then((r) => r.data), listScripts: (filter?: any) => apiClient.get(`${BASE}/scripts`, { params: filter }).then((r) => r.data), getScript: (id: number) => apiClient.get(`${BASE}/scripts/${id}`).then((r) => r.data), createScript: (data: any) => apiClient.post(`${BASE}/scripts`, data).then((r) => r.data), updateScript: (id: number, data: any) => apiClient.put(`${BASE}/scripts/${id}`, data).then((r) => r.data), deleteScript: (id: number) => apiClient.delete(`${BASE}/scripts/${id}`).then((r) => r.data), dryRunScript: (code: string, hook_type: string, test_input: any, timeout_ms?: number) => apiClient.post(`${BASE}/scripts/dry-run`, { code, hook_type, test_input, timeout_ms }).then((r) => r.data), getScriptVersions: (id: number) => apiClient.get(`${BASE}/scripts/${id}/versions`).then((r) => r.data), getScriptVersion: (id: number, version: number) => apiClient.get(`${BASE}/scripts/${id}/versions/${version}`).then((r) => r.data), rollbackScript: (id: number, version: number) => apiClient.post(`${BASE}/scripts/${id}/rollback/${version}`).then((r) => r.data), // ===== 릴리즈 ===== getReleases: (filter?: any) => apiClient.get(`${BASE}/releases`, { params: filter }).then(r => r.data), getRelease: (id: number) => apiClient.get(`${BASE}/releases/${id}`).then(r => r.data), createRelease: (data: any) => apiClient.post(`${BASE}/releases`, data).then(r => r.data), updateRelease: (id: number, data: any) => apiClient.put(`${BASE}/releases/${id}`, data).then(r => r.data), deleteRelease: (id: number) => apiClient.delete(`${BASE}/releases/${id}`).then(r => r.data), transitionRelease: (id: number, status: string) => apiClient.post(`${BASE}/releases/${id}/transition`, { status }).then(r => r.data), // ===== 배포 ===== createDeployment: (data: any) => apiClient.post(`${BASE}/deployments`, data).then(r => r.data), getDeploymentDetail: (id: number) => apiClient.get(`${BASE}/deployments/${id}`).then(r => r.data), getDeploymentStatus: (id: number) => apiClient.get(`${BASE}/deployments/${id}/status`).then(r => r.data), startDeployment: (id: number) => apiClient.post(`${BASE}/deployments/${id}/start`).then(r => r.data), cancelDeployment: (id: number) => apiClient.post(`${BASE}/deployments/${id}/cancel`).then(r => r.data), rollbackDeployment: (id: number) => apiClient.post(`${BASE}/deployments/${id}/rollback`).then(r => r.data), // ===== Harbor ===== getHarborProjects: () => apiClient.get(`${BASE}/harbor/projects`).then(r => r.data), getHarborRepos: (project: string) => apiClient.get(`${BASE}/harbor/projects/${project}/repos`).then(r => r.data), getHarborTags: (project: string, repo: string) => apiClient.get(`${BASE}/harbor/projects/${project}/repos/${repo}/tags`).then(r => r.data), pingHarbor: () => apiClient.get(`${BASE}/harbor/ping`).then(r => r.data), // ===== 태그 템플릿 ===== getTagTemplates: (filter?: any) => apiClient.get(`${BASE}/tag-templates`, { params: filter }).then(r => r.data), getTagTemplate: (id: number) => apiClient.get(`${BASE}/tag-templates/${id}`).then(r => r.data), createTagTemplate: (data: any) => apiClient.post(`${BASE}/tag-templates`, data).then(r => r.data), updateTagTemplate: (id: number, data: any) => apiClient.put(`${BASE}/tag-templates/${id}`, data).then(r => r.data), deleteTagTemplate: (id: number) => apiClient.delete(`${BASE}/tag-templates/${id}`).then(r => r.data), applyTagTemplate: (templateId: number, connectionId: number, overwrite = false) => apiClient.post(`${BASE}/tag-templates/${templateId}/apply/${connectionId}`, { overwrite }).then(r => r.data), // ===== 알림 규칙 ===== createAlertRule: (data: any) => apiClient.post(`${BASE}/alert-rules`, data).then(r => r.data), updateAlertRule: (id: number, data: any) => apiClient.put(`${BASE}/alert-rules/${id}`, data).then(r => r.data), deleteAlertRule: (id: number) => apiClient.delete(`${BASE}/alert-rules/${id}`).then(r => r.data), toggleAlertRule: (id: number) => apiClient.post(`${BASE}/alert-rules/${id}/toggle`).then(r => r.data), // ===== V1 매핑 ===== getV1Mappings: (filter?: any) => apiClient.get(`${BASE}/v1-mappings`, { params: filter }).then(r => r.data), createV1Mapping: (data: any) => apiClient.post(`${BASE}/v1-mappings`, data).then(r => r.data), updateV1Mapping: (id: number, data: any) => apiClient.put(`${BASE}/v1-mappings/${id}`, data).then(r => r.data), deleteV1Mapping: (id: number) => apiClient.delete(`${BASE}/v1-mappings/${id}`).then(r => r.data), // ===== PLC 상태 ===== getPlcStatus: (filter?: any) => apiClient.get(`${BASE}/plc-status`, { params: filter }).then(r => r.data), getPlcSummary: () => apiClient.get(`${BASE}/plc-status/summary`).then(r => r.data), // ===== Audit ===== getAuditLogs: (filter?: any) => apiClient.get(`${BASE}/audit-logs`, { params: filter }).then(r => r.data), getAuditStats: () => apiClient.get(`${BASE}/audit-logs/stats`).then(r => r.data), // ===== Provisioning ===== getPreRegistered: () => apiClient.get(`${BASE}/provision/pre-registered`).then(r => r.data), preRegister: (data: any) => apiClient.post(`${BASE}/provision/pre-register`, data).then(r => r.data), };