Antes de la última revisión de etapa 4. Sprint 1. Previo al ajuste de look n feel de app, reportes, nombre y colores.
This commit is contained in:
@@ -1,28 +1,76 @@
|
||||
import { create } from 'zustand'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import type { SimulationResult } from '@/domain/types'
|
||||
import { simulationRepo } from '@/persistence/repositories'
|
||||
|
||||
// Excepción arquitectónica documentada: simulation-store importa process-store en una dirección
|
||||
// para suscribirse a cambios de datos y invalidar resultados. No existe dependencia inversa.
|
||||
import { useProcessStore } from '@/store/process-store'
|
||||
|
||||
interface SimulationState {
|
||||
result: SimulationResult | null
|
||||
resultActual: SimulationResult | null // resultado del escenario actual
|
||||
resultAutomated: SimulationResult | null // resultado del escenario automatizado
|
||||
lastSimulatedAt: Date | null // timestamp de la última simulación exitosa
|
||||
isRunning: boolean
|
||||
error: string | null
|
||||
selectedActivityId: string | null
|
||||
|
||||
setResult: (result: SimulationResult) => void
|
||||
// Persiste ambos resultados en IndexedDB y actualiza el estado en memoria.
|
||||
// REGLA: los dos resultados siempre se guardan y actualizan en conjunto.
|
||||
persistResults: (processId: string, actual: SimulationResult, automated: SimulationResult) => Promise<void>
|
||||
setRunning: (running: boolean) => void
|
||||
setError: (error: string | null) => void
|
||||
selectActivity: (bpmnElementId: string | null) => void
|
||||
// Invalida AMBOS resultados a null. Se llama cuando cambian datos del proceso.
|
||||
invalidateResults: () => void
|
||||
reset: () => void
|
||||
}
|
||||
|
||||
export const useSimulationStore = create<SimulationState>((set) => ({
|
||||
result: null,
|
||||
resultActual: null,
|
||||
resultAutomated: null,
|
||||
lastSimulatedAt: null,
|
||||
isRunning: false,
|
||||
error: null,
|
||||
selectedActivityId: null,
|
||||
|
||||
setResult: (result) => set({ result, error: null }),
|
||||
persistResults: async (processId, actual, automated) => {
|
||||
await simulationRepo.save({
|
||||
id: uuidv4(),
|
||||
processId,
|
||||
executedAt: Date.now(),
|
||||
result: actual,
|
||||
resultAutomated: automated,
|
||||
})
|
||||
set({ resultActual: actual, resultAutomated: automated, lastSimulatedAt: new Date(), error: null })
|
||||
},
|
||||
|
||||
setRunning: (isRunning) => set({ isRunning }),
|
||||
setError: (error) => set({ error }),
|
||||
selectActivity: (selectedActivityId) => set({ selectedActivityId }),
|
||||
reset: () => set({ result: null, isRunning: false, error: null, selectedActivityId: null }),
|
||||
|
||||
invalidateResults: () =>
|
||||
set({ resultActual: null, resultAutomated: null, lastSimulatedAt: null }),
|
||||
|
||||
reset: () =>
|
||||
set({
|
||||
resultActual: null,
|
||||
resultAutomated: null,
|
||||
lastSimulatedAt: null,
|
||||
isRunning: false,
|
||||
error: null,
|
||||
selectedActivityId: null,
|
||||
}),
|
||||
}))
|
||||
|
||||
// Suscripción reactiva: cualquier cambio en activities o currentProcess del process-store
|
||||
// invalida los resultados para garantizar que nunca haya resultados "viejos" visibles.
|
||||
// La comparación por referencia de Zustand asegura que solo fires en cambios reales.
|
||||
useProcessStore.subscribe((state, prevState) => {
|
||||
if (
|
||||
state.activities !== prevState.activities ||
|
||||
state.currentProcess !== prevState.currentProcess
|
||||
) {
|
||||
useSimulationStore.getState().invalidateResults()
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user