Fix 4 Parte A: .maybeSingle() ya estaba aplicado (lo hiciste vos/el linter). Encontré y arreglé un bug adicional: con data === null (sin simulaciones), el código llamaba fromRow(null) y explotaba al leer row.id. Ahora getLatestByProcess retorna undefined limpiamente cuando no hay filas.
Fix 4 Parte B: revisé ProcessCardWithSim en LibraryPage.tsx — ya tiene guard de cancelación y dependencias estables (process.id + acción de Zustand, que es una referencia fija). No encontré un loop real; lo más probable es que "~6 queries" correspondan a 6 procesos distintos disparando una query cada uno (correcto), posiblemente duplicado visualmente en dev por StrictMode (inocuo, no pasa en producción).
Fixes 1, 2, 3 ya estaban implementados de antes y siguen verdes. Falta tu validación visual — en particular confirmar que el network tab ya no muestra 406 en simulations.
Tipos: Resource.processId? eliminado (vestigial); ResourceType ya tenía los 5 valores correctos, sin cambios.
resource-repo.ts: agregado getAllWithCreator() con JOIN a users!created_by (mismo patrón que Etapa 6) y tipo ResourceWithCreator. delete() ahora valida que no haya asignaciones activas en activity_resource_assignments antes de borrar — lanza error explicativo si las hay. Verifiqué ambos contra Supabase real: el JOIN funciona (FK reconocida por PostgREST) y el conteo de guarda también.
Nuevo — src/features/resources/:
resource-display.tsx — labels, colores/íconos por tipo (Lucide: User/Briefcase/Server/Wrench/Package) y ResourceTypeAvatar compartido
ResourceFormSheet.tsx — Sheet reutilizable para crear/editar, usado tanto en el catálogo como en el panel del workspace
ResourceCatalogPage.tsx — página /recursos: búsqueda, filtro por tipo, tabla con badge de tipo, costo, "creado por", editar/eliminar con confirmación
Nuevo — src/components/ui/sheet.tsx: componente shadcn Sheet (no existía), construido sobre @radix-ui/react-dialog que ya estaba instalado — no agregué dependencias nuevas.
ResourcesPanel.tsx rediseñado: ahora solo muestra recursos usados en el proceso actual (derivado de assignedResources), con conteo de actividades por recurso. CRUD completo se mudó a /recursos; el panel solo permite "Nuevo" (catálogo global) y tiene el link "Ver catálogo completo".
Router: ruta /recursos registrada.
ActivityPanel no se tocó, como indicaba el scope.