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>
This commit is contained in:
2026-03-13 07:22:04 +01:00
parent 3dcfa7c0bd
commit 577dd1ca7e
21 changed files with 303 additions and 3229 deletions
+13 -19
View File
@@ -8,7 +8,7 @@ import {
RotateCcw, LayoutList, LayoutGrid, X,
ChevronDown, ChevronUp, ChevronsUpDown,
Search, SlidersHorizontal, FileSpreadsheet, Box, Film,
Loader2, Play, RefreshCw, ExternalLink, Ban, StopCircle, Scissors, Plus, Wand2, Download,
Loader2, Play, RefreshCw, Ban, StopCircle, Scissors, Plus, Wand2, Download,
XCircle, RotateCw, Info,
} from 'lucide-react'
import { toast } from 'sonner'
@@ -186,7 +186,7 @@ export default function OrderDetailPage() {
const canReject = isPrivileged && (order.status === 'submitted' || order.status === 'processing')
const canResubmit = order.status === 'rejected' && (isPrivileged || order.created_by === user?.id)
const rp = order.render_progress
const hasRetryable = rp && (rp.pending > 0 || rp.failed > 0 || (rp as any).cancelled > 0)
const hasRetryable = rp && (rp.pending > 0 || rp.failed > 0 || rp.cancelled > 0)
const canDispatch = isPrivileged && (order.status === 'processing' || order.status === 'submitted' || order.status === 'completed')
const hasActiveRenders = rp && (rp.processing > 0 || rp.pending > 0)
const canCancelRenders = isPrivileged && order.status === 'processing' && hasActiveRenders
@@ -461,7 +461,7 @@ export default function OrderDetailPage() {
{rp.completed}/{rp.total} completed
{rp.processing > 0 && <span className="text-status-info-text ml-1">({rp.processing} rendering)</span>}
{rp.failed > 0 && <span className="text-red-500 ml-1">({rp.failed} failed)</span>}
{(rp as any).cancelled > 0 && <span className="text-orange-500 ml-1">({(rp as any).cancelled} cancelled)</span>}
{rp.cancelled > 0 && <span className="text-orange-500 ml-1">({rp.cancelled} cancelled)</span>}
</span>
{order.status === 'processing' && rp.processing > 0 && (
<Loader2 size={14} className="animate-spin text-amber-500 ml-auto" />
@@ -486,10 +486,10 @@ export default function OrderDetailPage() {
style={{ width: `${(rp.failed / rp.total) * 100}%` }}
/>
)}
{(rp as any).cancelled > 0 && (
{rp.cancelled > 0 && (
<div
className="bg-orange-300 transition-all duration-500"
style={{ width: `${((rp as any).cancelled / rp.total) * 100}%` }}
style={{ width: `${(rp.cancelled / rp.total) * 100}%` }}
/>
)}
</div>
@@ -939,16 +939,10 @@ function OrderLineRow({
{/* Backend */}
<td className="px-4 py-2">
{line.render_backend_used ? (
line.render_backend_used === 'flamenco' && line.flamenco_job_id ? (
<a
href="http://localhost:8080"
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
className="inline-flex items-center gap-1 text-xs px-2 py-0.5 rounded-full bg-status-warning-bg text-status-warning-text font-medium hover:bg-surface-hover transition-colors"
>
Flamenco <ExternalLink size={9} />
</a>
line.render_backend_used === 'flamenco' ? (
<span className="text-xs px-2 py-0.5 rounded-full bg-status-warning-bg text-status-warning-text font-medium">
Flamenco (legacy)
</span>
) : line.render_backend_used === 'celery' ? (
<span className="text-xs px-2 py-0.5 rounded-full bg-status-info-bg text-status-info-text font-medium">
Celery
@@ -1461,12 +1455,12 @@ function ItemTableRow({
)}
{/* CAD part material assignments */}
{(item as any).cad_parsed_objects && (item as any).cad_parsed_objects.length > 0 && (
{item.cad_parsed_objects && item.cad_parsed_objects.length > 0 && (
<CadPartMaterials
orderId={orderId}
itemId={item.id}
partNames={(item as any).cad_parsed_objects}
savedMaterials={(item as any).cad_part_materials ?? []}
partNames={item.cad_parsed_objects}
savedMaterials={item.cad_part_materials ?? []}
excelComponents={item.components}
/>
)}
@@ -1733,7 +1727,7 @@ function SourceSpreadsheet({
{/* Text fields */}
{STD_COLS.map((c) => {
const raw = (item as any)[c.key]
const raw = item[c.key] as string | null
const display = raw ?? ''
return (
<td key={c.key} className="py-0.5 px-1 border-b border-border-light">