Files
HartOMat/frontend/src/api/cad.ts
T
Hartmut 577dd1ca7e refactor(P11+P12): codebase hygiene — CLAUDE.md rewrite, type safety, dead code removal
- Rewrite CLAUDE.md to match current 8-service architecture (was 11, 5 deleted)
- Remove all as-any casts in OrderDetail.tsx (9 casts → 0)
- Add cad_parsed_objects/cad_part_materials to OrderItem interface
- Rename require_admin → require_global_admin across 6 router files (22 calls)
- Remove EXPORT_GLB_PRODUCTION enum + generate_gltf_production_task (dead code)
- Remove worker-thumbnail from ALLOWED_SERVICES, replace Flamenco link
- Delete obsolete PLAN.md (1455 lines) and PLAN_REFACTOR.md (1174 lines)
- Fix digit-only USD prim names with p_ prefix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 07:22:04 +01:00

177 lines
6.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import api from './client'
// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------
export interface CadObjects {
cad_file_id: string
original_name: string
processing_status: 'pending' | 'processing' | 'completed' | 'failed'
parsed_objects: Record<string, unknown> | 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 <img src={getCadThumbnailUrl(id)} /> 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 <img> 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 <img src=...> without needing explicit auth headers.
* Remember to call URL.revokeObjectURL() when the component unmounts.
*/
export async function fetchThumbnailBlob(cadFileId: string): Promise<string> {
const res = await api.get<Blob>(`/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<string> {
const res = await api.get<Blob>(`/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<CadObjects> {
const res = await api.get<CadObjects>(`/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<RegenerateThumbnailResponse> {
const res = await api.post<RegenerateThumbnailResponse>(
`/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<GenerateGltfResponse> {
const res = await api.post<GenerateGltfResponse>(`/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<ParsedObjectsResponse> {
const res = await api.get<ParsedObjectsResponse>(`/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<string, PartMaterialEntry>
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<PartMaterialMap> {
const res = await api.get<PartMaterialsResponse>(`/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<PartMaterialMap> {
const res = await api.put<PartMaterialsResponse>(`/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<string, string> | null
}
/** Return the manual material overrides for a CAD file ({partKey: materialName}, empty if none). */
export async function getManualOverrides(cadFileId: string): Promise<Record<string, string>> {
const res = await api.get<ManualMaterialOverridesResponse>(
`/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<string, string>,
): Promise<Record<string, string>> {
const res = await api.put<ManualMaterialOverridesResponse>(
`/cad/${cadFileId}/manual-material-overrides`,
{ overrides },
)
return res.data.manual_material_overrides ?? {}
}