Files
zeavis-edu/apps/web/src/lib/api-client.ts
T
Asep Haryana Saputra 15c6be9e84 feat: implement backend image classification with TensorFlow.js model
- Extend shared types for image classification, including PredictionProbability, UploaderMetadata, and ImageClassificationRecord.
- Create image_classifications table in the database with necessary fields and foreign key constraints.
- Implement disease mappers to convert database rows to shared disease records.
- Develop uploader client to handle image uploads to external service.
- Create image model service to load and classify images using TensorFlow.js.
- Add API routes for image classification, including GET for history and POST for new classifications.
- Implement frontend components for image classification form and display results.
- Update dashboard to integrate image classification functionality and display results.
- Document implementation plan for backend image classification.
2026-05-22 15:13:22 +00:00

74 lines
1.9 KiB
TypeScript

import type {
DiseaseSlug,
DiseaseCatalogItem,
ManualClassificationRequest,
ManualClassificationRecord,
ImageClassificationRecord,
DashboardSummary,
} from '@zeavis/shared';
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL ?? '';
async function fetchApi<T>(endpoint: string, options?: RequestInit): Promise<T> {
const url = `${apiBaseUrl}${endpoint}`;
const response = await fetch(url, options);
if (!response.ok) {
let errorMessage = `HTTP ${response.status}`;
try {
const errorData = await response.json();
if (errorData.error) {
errorMessage = errorData.error;
}
} catch {
}
throw new Error(errorMessage);
}
return response.json();
}
export const apiClient = {
async getDiseases(): Promise<DiseaseCatalogItem[]> {
return fetchApi('/api/v1/diseases');
},
async getDisease(slug: DiseaseSlug): Promise<DiseaseCatalogItem> {
return fetchApi(`/api/v1/diseases/${slug}`);
},
async getManualClassifications(): Promise<ManualClassificationRecord[]> {
return fetchApi('/api/v1/classifications/manual');
},
async createManualClassification(
payload: ManualClassificationRequest,
): Promise<ManualClassificationRecord> {
return fetchApi('/api/v1/classifications/manual', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
},
async getImageClassifications(): Promise<ImageClassificationRecord[]> {
return fetchApi('/api/v1/classifications/image');
},
async createImageClassification(file: File): Promise<ImageClassificationRecord> {
const formData = new FormData();
formData.append('file', file);
return fetchApi('/api/v1/classifications/image', {
method: 'POST',
body: formData,
});
},
async getDashboardSummary(): Promise<DashboardSummary> {
return fetchApi('/api/v1/dashboard/summary');
},
};