// API client — typed fetch wrappers for the HWLab Go backend export interface InventoryItem { id: number name: string asset_tag: string | null hw_id: string | null catalog_status: string | null product_url: string | null firmware_version: string | null test_date: string | null test_data: string | null ai_notes: string | null photo_urls: string[] } const BASE = '/api' async function fetchJSON(url: string): Promise { const res = await fetch(url) if (!res.ok) { const body = await res.json().catch(() => ({ error: res.statusText })) throw new Error((body as { error?: string }).error ?? `HTTP ${res.status}`) } return res.json() as Promise } export const fetchInventory = (): Promise => fetchJSON(`${BASE}/inventory`) export const fetchInventoryItem = (id: number): Promise => fetchJSON(`${BASE}/inventory/${id}`) // Intake submission — matches IntakeResult in store/intake.ts export interface IntakeResponse { hw_id: string model: string manufacturer: string category: string specs: Record suggested_tags: string[] ai_notes: string confidence: number catalog_status: string netbox_id: number queued: boolean } export async function submitIntake(photos: File[], quickAdd = false): Promise { const formData = new FormData() photos.forEach((file) => formData.append('photos', file)) formData.append('quick_add', String(quickAdd)) const res = await fetch(`${BASE}/intake`, { method: 'POST', body: formData, }) if (!res.ok) { const body = await res.json().catch(() => ({ error: res.statusText })) throw new Error((body as { error?: string }).error ?? `HTTP ${res.status}`) } return res.json() as Promise }