export interface Staff { id: string; name: string; active: boolean; } export type BusinessStatus = 'ACTIVE' | 'SOLD' | 'INACTIVE'; export interface BusinessListItem { id: string; name: string; status: BusinessStatus; } export interface BusinessList { businesses: BusinessListItem[]; counts: Record; } export interface Business { id: string; name: string; nas_path: string; status: BusinessStatus; } export interface BusinessFile { name: string; size: number; mtime: string; } export interface ScanResult { scanned: number; inserted: number; updated: number; missing: number; } export class ApiError extends Error { constructor(readonly status: number, message: string) { super(message); } } async function request(path: string, init?: RequestInit): Promise { const res = await fetch(path, { credentials: 'same-origin', ...init }); if (!res.ok) { const body = (await res.json().catch(() => null)) as { error?: string } | null; throw new ApiError(res.status, body?.error ?? `Request failed (${res.status})`); } return (await res.json()) as T; } function post(path: string, body?: unknown): Promise { return request(path, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body ?? {}), }); } export const api = { me: () => request('/api/me'), staff: () => request('/api/staff'), login: (staffId: string) => post<{ ok: boolean; staff: Staff }>('/api/login', { staff_id: staffId }), logout: () => post<{ ok: boolean }>('/api/logout'), businesses: (status: BusinessStatus, search: string) => request( `/api/businesses?status=${encodeURIComponent(status)}&search=${encodeURIComponent(search)}`, ), business: (id: string) => request(`/api/businesses/${id}`), businessFiles: (id: string) => request(`/api/businesses/${id}/files`), scan: () => post('/api/businesses/scan'), };