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
+89 -69
View File
@@ -1,90 +1,110 @@
# Plan: P6, P9, P10 Remaining Open Work
# Plan: P12 — Codebase Hygiene Sprint (CLAUDE.md + Type Safety + Stale References)
> **Date:** 2026-03-12 | **Branch:** refactor/v2
> **Date:** 2026-03-13 | **Branch:** refactor/v2
## Status: ALL TASKS COMPLETE ✅
## Context
## Pre-flight Audit Results
All 10 roadmap priorities are complete. A codebase scan reveals three categories of debt:
| Task | State |
|---|---|
| P6: admin.py settings keys, bulk action, Admin.tsx labels, ProductDetail.tsx | ✅ DONE |
| P6-1: MediaAssetType deprecation comments | ✅ DONE (added by P6 agent) |
| P6-2: Admin.tsx progressive disclosure for 4 manual deflection inputs | OPEN |
| P9: hash-check blocks in generate_gltf_geometry_task + generate_usd_master_task | exist, but **bug: no deflection settings in cache key** |
| P9-3: step_file_hash exposed in API | OPEN |
| P10-1: Notification batching | OPEN |
| P10-2: Kanban drag-to-reject in Orders.tsx | OPEN |
1. **CLAUDE.md is dangerously stale**: References 11 services (4 deleted), `worker-thumbnail` (now `render-worker`), `blender-renderer`/`threejs-renderer`/`flamenco` (all removed), wrong roles (`admin` instead of `global_admin`/`tenant_admin`), deleted STL endpoints, and wrong task locations. Since CLAUDE.md is the AI instruction file, every future conversation gets wrong context.
2. **Frontend type safety**: 4 unnecessary `(rp as any).cancelled` casts in OrderDetail.tsx (the type already has `cancelled`), plus 4 `(item as any).cad_parsed_objects`/`cad_part_materials` casts (need 2 fields added to `OrderItem` interface).
3. **Stale service references**: `worker-thumbnail` in the `/scale` endpoint's `ALLOWED_SERVICES`, hardcoded `http://localhost:8080` Flamenco link in OrderDetail.tsx, and obsolete `PLAN.md` + `PLAN_REFACTOR.md` files in the repo root.
**Parallelization:** All 4 tracks are independent and can run in parallel.
## Affected Files
| File | Change |
|------|--------|
| `CLAUDE.md` | Full rewrite — update services, queues, roles, endpoints, structure |
| `frontend/src/pages/OrderDetail.tsx` | Remove `(rp as any)` casts (4 sites), remove `(item as any)` casts (4 sites), remove Flamenco hardcoded link |
| `frontend/src/api/orders.ts` | Add `cad_parsed_objects` and `cad_part_materials` to `OrderItem` interface |
| `backend/app/api/routers/worker.py` | Remove `worker-thumbnail` from `ALLOWED_SERVICES` |
| `PLAN.md` | Delete (superseded by ROADMAP.md) |
| `PLAN_REFACTOR.md` | Delete (superseded by ROADMAP.md) |
## Tasks (in order)
### [x] Task P6-2: Admin.tsx progressive disclosure for tessellation advanced fields
### Track A — CLAUDE.md Rewrite
- **File**: `frontend/src/pages/Admin.tsx`
- **What**: Collapse the 4 manual deflection number inputs behind an "Advanced" toggle.
1. Add state: `const [showAdvancedTess, setShowAdvancedTess] = useState(false)`
2. Insert toggle button after the preset buttons block:
```tsx
<button
onClick={() => setShowAdvancedTess(v => !v)}
className="text-xs text-accent hover:underline flex items-center gap-1 mt-1"
>
{showAdvancedTess ? <ChevronDown size={12} /> : <ChevronRight size={12} />}
{showAdvancedTess ? 'Hide manual values' : 'Advanced: manual deflection values'}
</button>
### [x] Task 1: Update CLAUDE.md to match current architecture — DONE
- **File**: `CLAUDE.md`
- **What**: Full rewrite of the project instructions file:
- **Ziel**: Remove "Flamenco" reference
- **Tech Stack**: Remove Flamenco, Three.js (Playwright), cadquery (STEP→STL). Add: MinIO (S3-compatible storage), OCC (cadquery/OCP for STEP parsing), GMSH (tessellation), usd-core (USD export)
- **Services table**: 8 services (postgres, redis, minio, backend, worker, render-worker, beat, frontend). Remove blender-renderer, threejs-renderer, worker-thumbnail, flamenco-manager, flamenco-worker
- **Logs section**: `docker compose logs -f render-worker` (not worker-thumbnail or blender-renderer). Rebuild: `docker compose up -d --build backend worker render-worker beat`
- **Credentials**: Remove Flamenco Manager line
- **Project structure**: Remove `blender-renderer/`, `threejs-renderer/`, `flamenco/`. Add `render-worker/scripts/`. Update `tasks/` description to mention it's a compatibility shim, active tasks in `domains/pipeline/tasks/`. Add `domains/` directory
- **Celery queues**: `asset_pipeline` queue on `render-worker` (not `worker-thumbnail`). Remove "blender-renderer only 1 request" note — now it's "render-worker concurrency=1 because Blender is single-threaded". Add `thumbnail_rendering` if it's different from `asset_pipeline` — CHECK: docker-compose says `asset_pipeline`
- **Roles**: Add `global_admin`, `tenant_admin`. Update table to 4 roles
- **API endpoints**: Remove `generate-stl/{quality}`, `generate-missing-stls`. Add `generate-usd-master`, `generate-gltf-geometry`, `scene-manifest`
- **Bekannte Eigenheiten**: Remove Flamenco GPU note
- **Pipeline section**: Update to mention OCC/GMSH tessellation, USD export
- **Acceptance gate**: `grep -c "blender-renderer\|threejs-renderer\|flamenco\|worker-thumbnail\|11 Services" CLAUDE.md` returns 0
- **Dependencies**: none
- **Risk**: None. Documentation only.
### Track B — Frontend Type Safety
### [x] Task 2: Fix `as any` casts in OrderDetail.tsx and OrderItem type — DONE
- **Files**: `frontend/src/api/orders.ts`, `frontend/src/pages/OrderDetail.tsx`
- **What**:
1. Add to `OrderItem` interface in `orders.ts`:
```typescript
cad_parsed_objects: string[] | null
cad_part_materials: Array<{ part_name: string; material_name: string; [key: string]: unknown }>
```
3. Wrap both `<div className="space-y-4">` sections (Scene/Viewer and Render output) in `{showAdvancedTess && (...)}`
4. Keep the Save button **outside** the conditional
Verify ChevronDown + ChevronRight are already in the lucide-react import; add if missing.
- **Acceptance gate**: On Admin Render tab, 4 number inputs are hidden by default; click "Advanced" → they appear; preset save still works without opening Advanced.
- **Risk**: Low — local state only.
2. Remove `(rp as any).cancelled` → just `rp.cancelled` (4 sites in OrderDetail.tsx — the type already has `cancelled: number`)
3. Remove `(item as any).cad_parsed_objects` → `item.cad_parsed_objects` (2 sites)
4. Remove `(item as any).cad_part_materials` → `item.cad_part_materials` (1 site)
5. For `(item as any)[c.key]` dynamic access: replace with `(item as Record<string, unknown>)[c.key]` (narrower cast)
- **Acceptance gate**: `grep -c "as any" frontend/src/pages/OrderDetail.tsx` decreases by at least 8. Run `docker compose exec frontend npx tsc --noEmit` — no new errors
- **Dependencies**: none
- **Risk**: Low. Type-only changes, no behavioral change. Must run tsc check.
### [x] Task P9-1: Fix geometry GLB cache key to include deflection settings
### Track C — Stale Backend Reference
- **File**: `backend/app/domains/pipeline/tasks/export_glb.py`
- **What**: The existing hash-check block in `generate_gltf_geometry_task` only checks file hash, not settings. Add a composite cache key: `f"{step_file_hash}:{linear_deflection}:{angular_deflection}:{tessellation_engine}"`.
Move linear/angular/tessellation_engine computation inside the first `with Session` block (before hash check). Use `render_config={"cache_key": effective_cache_key}` on MediaAsset create/update. Compare stored `render_config.get("cache_key")` instead of raw hash.
- **Acceptance gate**: Upload same STEP twice with same settings → second run logs `[CACHE] hash+settings match`. Change deflection → re-tessellates.
- **Risk**: Medium — first deploy re-tessellates all files once (existing assets have `render_config=None`). Acceptable.
### [x] Task 3: Remove `worker-thumbnail` from scale endpoint — DONE
- **File**: `backend/app/api/routers/worker.py`
- **What**:
1. Remove `"worker-thumbnail"` from `ALLOWED_SERVICES` set (line 424)
2. Update the `ScaleRequest` docstring/comment (line 367) to list only `"render-worker" | "worker"`
3. Update the endpoint docstring (line 414) to remove `worker-thumbnail`
- **Acceptance gate**: `grep "worker-thumbnail" backend/app/api/routers/worker.py` returns 0 matches
- **Dependencies**: none
- **Risk**: None. `worker-thumbnail` service doesn't exist in docker-compose.
### [x] Task P9-2: Fix USD master cache key to include deflection settings
### Track D — Delete Obsolete Files + Flamenco Link
- **File**: `backend/app/domains/pipeline/tasks/export_glb.py`
- **What**: Same fix for `generate_usd_master_task`. Composite key: `f"{step_file_hash}:{linear_deflection}:{angular_deflection}:{sharp_threshold}"`.
- **Acceptance gate**: Same file, same settings → second USD export logs cache hit. Change `render_linear_deflection` → fresh export.
- **Risk**: Same as P9-1.
### [x] Task P9-3: Expose step_file_hash in CadFile API responses
- **File**: `backend/app/api/routers/cad.py`
- **What**: Add `"step_hash": cad.step_file_hash` to every dict-based CadFile response (parsed-objects endpoint and any other summary endpoints).
- **Acceptance gate**: `GET /api/cad/{id}/parsed-objects` response includes `step_hash` key.
- **Risk**: Low — nullable additive field.
### [x] Task P10-1: Notification batching in NotificationCenter
- **File**: `frontend/src/components/layout/NotificationCenter.tsx`
- **What**: Group consecutive `render.completed`/`render.failed` notifications for the same `entity_id` within a 5-minute window into one summary row ("Render batch: 3 done"). No backend changes needed. Implement `groupNotifications()` helper; render batch rows with `Image`/`AlertTriangle` icon and count.
- **Acceptance gate**: 3 render completions for same order → 1 "Render batch: 3 done" row; renders > 5 min apart → separate rows.
- **Risk**: Low — client-side only.
### [x] Task P10-2: Per-line reject button in OrderDetail.tsx (kanban drag deferred — line reject is higher value)
- **File**: `frontend/src/pages/Orders.tsx`
- **What**: Native HTML5 DnD. `KanbanCard` gets `draggable` for `submitted`/`processing` orders; Rejected column becomes a drop target with red ring highlight. On drop: open reject reason modal (`dragRejectModalOpen`, `dragRejectReason` state). Confirm → call `rejectOrder()` mutation, toast, invalidate orders.
- **Acceptance gate**: Drag submitted/processing order to Rejected column → modal opens → confirm → order moves to Rejected.
- **Risk**: Medium — native DnD; desktop only (mobile not required).
### [x] Task 4: Delete PLAN.md, PLAN_REFACTOR.md, and remove Flamenco hardcoded link — DONE
- **Files**: `PLAN.md`, `PLAN_REFACTOR.md`, `frontend/src/pages/OrderDetail.tsx`
- **What**:
1. Delete `PLAN.md` (superseded by ROADMAP.md — noted in the Archive section)
2. Delete `PLAN_REFACTOR.md` (superseded by ROADMAP.md)
3. In OrderDetail.tsx (~line 942950): Remove the `localhost:8080` Flamenco link block. Replace with just the job ID text (since `render_backend_used === 'flamenco'` only applies to historical data, show the ID as plain text instead of a broken link)
- **Acceptance gate**: `ls PLAN.md PLAN_REFACTOR.md 2>&1 | grep "No such file"` succeeds. `grep "localhost:8080" frontend/src/pages/OrderDetail.tsx` returns 0 matches
- **Dependencies**: none
- **Risk**: Low. PLAN files are archived references. Flamenco link is non-functional (service removed).
## Migration Check
No new migrations needed (P6 migration `6ebfe2737531` already applied).
No. No database changes.
## Order
## Order Recommendation
P6-2 and P9-1/P9-2 and P10-1/P10-2 can all run in parallel (different files).
P9-3 (cad.py) can run alongside any of the above.
**Fully parallel — all 4 tracks independent:**
- **Agent 1**: Task 1 (CLAUDE.md rewrite) — largest, highest impact
- **Agent 2**: Task 2 (frontend type safety)
- **Agent 3**: Task 3 (worker.py cleanup)
- **Agent 4**: Task 4 (file deletion + Flamenco link)
## Risks / Open Questions
- P9: existing assets have `render_config=None` → first run after deploy re-tessellates. Acceptable.
- P10-2: `rejectOrder` API function exists in `frontend/src/api/orders.ts` — verify import before writing.
1. **CLAUDE.md as AI instructions**: This file is loaded into every AI conversation as project context. Getting it wrong means every future session starts with bad information. The rewrite must be verified against the actual docker-compose.yml and codebase.
2. **OrderItem `cad_part_materials` type**: Backend returns `list[dict]` — need to check what keys the dicts actually contain. The frontend uses `part_name` and `material_name` based on grep of CadPartMaterials component.
3. **`require_admin_or_pm` rename**: 71 occurrences across 13 files could be renamed to `require_pm_or_above` for consistency. Deferred — it's high churn, low impact (the alias works correctly), and can be a separate micro-task later.