homelabby/web/src/lib/api.ts

62 lines
1.8 KiB
TypeScript

// 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<T>(url: string): Promise<T> {
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<T>
}
export const fetchInventory = (): Promise<InventoryItem[]> =>
fetchJSON<InventoryItem[]>(`${BASE}/inventory`)
export const fetchInventoryItem = (id: number): Promise<InventoryItem> =>
fetchJSON<InventoryItem>(`${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<string, string>
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<IntakeResponse> {
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<IntakeResponse>
}