feat: MVP Fase 0 — Process Cost Platform v0.1.0

Plataforma completa de análisis de costos operativos basada en BPMN 2.0.

Funcionalidades incluidas:
- Import de archivos BPMN 2.0 por drag & drop + 3 procesos de ejemplo
- Visualización read-only del diagrama (bpmn-js)
- Configuración de actividades (costo, tiempo, recursos asignados)
- CRUD de recursos (rol, persona, sistema, equipo, insumo)
- Configuración global (moneda, overhead %, nombre, cliente)
- Motor de simulación determinístico agregado con propagación de gateways XOR/AND
- Reporte visual con mapa de calor en dos modos (relativo/absoluto)
- Gráficos: KPIs, top actividades, composición, costo por recurso
- Export PDF (jsPDF + html2canvas) y CSV (papaparse)
- Persistencia en IndexedDB (Dexie)
- 268 tests unitarios/integración + 6 E2E con Playwright
- Deploy: https://process-cost-platform.pages.dev

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 01:58:40 -03:00
commit bed161c92a
97 changed files with 19638 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
import { useEffect, useState } from 'react'
import { processRepo, activityRepo, resourceRepo, simulationRepo } from '@/persistence/repositories'
import type { Process, Activity, Resource, Simulation } from '@/domain/types'
interface ReportData {
process: Process | null
simulation: Simulation | null
activities: Activity[]
resources: Resource[]
isLoading: boolean
error: string | null
}
export function useReportData(processId: string): ReportData {
const [process, setProcess] = useState<Process | null>(null)
const [simulation, setSimulation] = useState<Simulation | null>(null)
const [activities, setActivities] = useState<Activity[]>([])
const [resources, setResources] = useState<Resource[]>([])
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
let cancelled = false
async function load() {
setIsLoading(true)
setError(null)
try {
const [proc, sim, acts, res] = await Promise.all([
processRepo.getById(processId),
simulationRepo.getLatestByProcess(processId),
activityRepo.getByProcess(processId),
resourceRepo.getByProcess(processId),
])
if (cancelled) return
if (!proc) throw new Error('Proceso no encontrado en la base de datos local')
if (!sim) throw new Error('Sin simulación disponible. Volvé al workspace y ejecutá "Simular" primero.')
setProcess(proc)
setSimulation(sim)
setActivities(acts)
setResources(res)
} catch (err) {
if (!cancelled) setError(err instanceof Error ? err.message : 'Error al cargar el reporte')
} finally {
if (!cancelled) setIsLoading(false)
}
}
load()
return () => { cancelled = true }
}, [processId])
return { process, simulation, activities, resources, isLoading, error }
}