import { getToken } from '@/utils/auth' export interface DeliveryTarget { id: number name: string target_type: string awx_inventory_id: number awx_template_id: number enabled: boolean metadata?: string } export interface CreateMySQLDeliveryPayload { business_line_id: number target_id: number namespace: string instance_name: string mysql_version: string cpu_milli: number memory_mi: number storage_gi: number } export interface DeliveryTask { id: string business_line_id: number requested_by: number target_type: string target_id: number namespace: string instance_name: string target_host?: string target_host_ip?: string mysql_port?: number status: string error_message?: string created_at: string updated_at: string started_at?: string finished_at?: string } export interface TaskEvent { id: number task_id: string from_state: string to_state: string message: string created_at: string } export const deliveryApi = { async listTargets(): Promise { const data = await authRequest('/auth/api/v1/delivery/targets?component=mysql') return Array.isArray(data.items) ? data.items : [] }, async createMySQL(payload: CreateMySQLDeliveryPayload): Promise { const data = await authRequest('/auth/api/v1/delivery/mysql', { method: 'POST', headers: { 'Idempotency-Key': createIdempotencyKey(payload), }, body: JSON.stringify(payload), }) return data.task }, async getTask(taskId: string): Promise<{ task: DeliveryTask; events: TaskEvent[] }> { const data = await authRequest(`/auth/api/v1/delivery/tasks/${encodeURIComponent(taskId)}`) return { task: data.task, events: Array.isArray(data.events) ? data.events : [], } }, async cancel(taskId: string): Promise { await authRequest(`/auth/api/v1/delivery/tasks/${encodeURIComponent(taskId)}/cancel`, { method: 'POST', }) }, } function createIdempotencyKey(payload: CreateMySQLDeliveryPayload) { return [ 'mysql', payload.business_line_id, payload.target_id, payload.namespace, payload.instance_name, Date.now(), ].join(':') } async function authRequest(path: string, init: RequestInit = {}) { const token = getToken() const response = await fetch(path, { ...init, headers: { Accept: 'application/json', 'Content-Type': 'application/json', ...(token ? { Authorization: `Bearer ${token}` } : {}), ...init.headers, }, }) const text = await response.text() const data = parseResponseBody(text) if (!response.ok) { const message = data?.error || data?.message || text || `HTTP ${response.status}` throw new Error(message) } return data || {} } function parseResponseBody(text: string) { if (!text.trim()) { return {} } try { return JSON.parse(text) } catch { return { error: text } } }