Files
factoryOps-v2/dashboard/lib/api.ts
Johngreen ab2a3e35b2 feat: Phase 0-2 complete — auth, machines, equipment parts with full CRUD
Multi-tenant factory inspection system (SpiFox, Enkid, Alpet):
- FastAPI backend with JWT auth, PostgreSQL (asyncpg)
- Next.js 16 frontend with App Router, SWR data fetching
- Machines CRUD with equipment parts management
- Part lifecycle tracking (hours/count/date) with counters
- Partial unique index for soft-delete support
- 24 pytest tests passing, E2E verified

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
2026-02-10 12:05:22 +09:00

74 lines
2.0 KiB
TypeScript

import { getStoredToken } from './auth-context';
import { getTenantFromPath } from './tenant-context';
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000';
function getHeaders(): HeadersInit {
const token = getStoredToken();
return {
'Content-Type': 'application/json',
...(token ? { 'Authorization': `Bearer ${token}` } : {}),
};
}
export async function fetcher<T>(url: string): Promise<T> {
const res = await fetch(`${API_BASE_URL}${url}`, {
headers: getHeaders(),
});
if (!res.ok) {
throw new Error('API request failed');
}
return res.json();
}
export function getTenantUrl(path: string, tenantId?: string): string {
const tenant = tenantId || getTenantFromPath();
if (!tenant) {
throw new Error('Tenant ID not found');
}
return `/api/${tenant}${path}`;
}
export const api = {
get: <T>(url: string) => fetcher<T>(url),
post: async <T>(url: string, data: unknown): Promise<T> => {
const res = await fetch(`${API_BASE_URL}${url}`, {
method: 'POST',
headers: getHeaders(),
body: JSON.stringify(data),
});
if (!res.ok) throw new Error('API request failed');
return res.json();
},
put: async <T>(url: string, data: unknown): Promise<T> => {
const res = await fetch(`${API_BASE_URL}${url}`, {
method: 'PUT',
headers: getHeaders(),
body: JSON.stringify(data),
});
if (!res.ok) throw new Error('API request failed');
return res.json();
},
patch: async <T>(url: string, data: unknown): Promise<T> => {
const res = await fetch(`${API_BASE_URL}${url}`, {
method: 'PATCH',
headers: getHeaders(),
body: JSON.stringify(data),
});
if (!res.ok) throw new Error('API request failed');
return res.json();
},
delete: async <T>(url: string): Promise<T> => {
const res = await fetch(`${API_BASE_URL}${url}`, {
method: 'DELETE',
headers: getHeaders(),
});
if (!res.ok) throw new Error('API request failed');
return res.json();
},
};