import api from './client' // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- export interface CadObjects { cad_file_id: string original_name: string processing_status: 'pending' | 'processing' | 'completed' | 'failed' parsed_objects: Record | null } export interface RegenerateThumbnailResponse { cad_file_id: string original_name: string status: 'queued' task_id: string | null } // --------------------------------------------------------------------------- // API functions // --------------------------------------------------------------------------- /** * Returns the URL to the thumbnail PNG for a CAD file. * Use directly in – the browser will * handle the authenticated request via the axios interceptor when called * programmatically, or you can construct the URL for use in img tags when * the auth token is set as a header. * * For use in tags without auth headers, prefer fetching as a blob and * creating an object URL (see fetchThumbnailBlob below). */ export function getCadThumbnailUrl(cadFileId: string): string { return `/api/cad/${cadFileId}/thumbnail` } /** * Fetch the thumbnail PNG as a Blob and return an object URL suitable for * use in without needing explicit auth headers. * Remember to call URL.revokeObjectURL() when the component unmounts. */ export async function fetchThumbnailBlob(cadFileId: string): Promise { const res = await api.get(`/cad/${cadFileId}/thumbnail`, { responseType: 'blob', }) return URL.createObjectURL(res.data) } /** * Fetch the glTF model file as a Blob and return an object URL. * Remember to call URL.revokeObjectURL() when the consumer is done. */ export async function fetchModelBlob(cadFileId: string): Promise { const res = await api.get(`/cad/${cadFileId}/model`, { responseType: 'blob', }) return URL.createObjectURL(res.data) } /** * Return the parsed_objects JSON for a CAD file. */ export async function getCadObjects(cadFileId: string): Promise { const res = await api.get(`/cad/${cadFileId}/objects`) return res.data } /** * Ask the backend to re-queue STEP processing for a CAD file (admin only). * Returns the Celery task_id (or null if the worker is not available). */ export async function regenerateThumbnail( cadFileId: string, ): Promise { const res = await api.post( `/cad/${cadFileId}/regenerate-thumbnail`, ) return res.data } export interface GenerateGltfResponse { status: 'queued' task_id: string cad_file_id: string } /** Queue geometry GLB export directly from STEP via OCC (no Blender, no STL). */ export async function generateGltfGeometry(cadFileId: string): Promise { const res = await api.post(`/cad/${cadFileId}/generate-gltf-geometry`) return res.data } export interface ParsedObjectsResponse { cad_file_id: string original_name: string processing_status: string parsed_objects: { dimensions_mm?: { x: number; y: number; z: number } bbox_center_mm?: { x: number; y: number; z: number } [key: string]: unknown } | null } /** Return the parsed_objects metadata (dimensions, bbox) for a CAD file. */ export async function getParsedObjects(cadFileId: string): Promise { const res = await api.get(`/cad/${cadFileId}/parsed-objects`) return res.data } /** Force-reset a CAD file stuck in 'processing' to 'failed'. */ export async function resetStuckProcessing(cadFileId: string): Promise<{ status: string; message: string }> { const res = await api.post<{ status: string; message: string }>(`/cad/${cadFileId}/reset-stuck`) return res.data } // --------------------------------------------------------------------------- // Part-material assignment // --------------------------------------------------------------------------- export interface PartMaterialEntry { type: 'library' | 'hex' value: string } export type PartMaterialMap = Record interface PartMaterialsResponse { cad_file_id: string part_materials: PartMaterialMap | null } /** Return the saved part-material assignments for a CAD file (empty object if none). */ export async function getPartMaterials(cadFileId: string): Promise { const res = await api.get(`/cad/${cadFileId}/part-materials`) return res.data.part_materials ?? {} } /** Replace the part-material assignment map for a CAD file. Returns the updated map. */ export async function savePartMaterials( cadFileId: string, map: PartMaterialMap, ): Promise { const res = await api.put(`/cad/${cadFileId}/part-materials`, map) return res.data.part_materials ?? {} } // --------------------------------------------------------------------------- // Manual material overrides (partKey-keyed, Priority 4) // --------------------------------------------------------------------------- export interface ManualMaterialOverridesResponse { cad_file_id: string manual_material_overrides: Record | null } /** Return the manual material overrides for a CAD file ({partKey: materialName}, empty if none). */ export async function getManualOverrides(cadFileId: string): Promise> { const res = await api.get( `/cad/${cadFileId}/manual-material-overrides`, ) return res.data.manual_material_overrides ?? {} } /** Save manual material overrides keyed by partKey. Returns the saved map. */ export async function saveManualOverrides( cadFileId: string, overrides: Record, ): Promise> { const res = await api.put( `/cad/${cadFileId}/manual-material-overrides`, { overrides }, ) return res.data.manual_material_overrides ?? {} }