Files
bakery-ia/frontend/src/hooks/api/useForecasting.ts
2025-08-28 10:41:04 +02:00

568 lines
17 KiB
TypeScript

/**
* Forecasting hook for managing demand forecasting and ML models
*/
import { useState, useEffect, useCallback } from 'react';
import { ForecastingService } from '../../services/api/forecasting.service';
import {
ForecastModel,
ForecastModelCreate,
ForecastModelUpdate,
ForecastPrediction,
ForecastPredictionCreate,
ForecastBatch,
ModelTraining,
ModelEvaluation
} from '../../types/forecasting.types';
import { ApiResponse, PaginatedResponse, QueryParams } from '../../types/api.types';
interface ForecastingState {
models: ForecastModel[];
predictions: ForecastPrediction[];
batches: ForecastBatch[];
trainings: ModelTraining[];
evaluations: ModelEvaluation[];
isLoading: boolean;
error: string | null;
pagination: {
total: number;
page: number;
pages: number;
limit: number;
};
}
interface ForecastingActions {
// Models
fetchModels: (params?: QueryParams) => Promise<void>;
createModel: (data: ForecastModelCreate) => Promise<boolean>;
updateModel: (id: string, data: ForecastModelUpdate) => Promise<boolean>;
deleteModel: (id: string) => Promise<boolean>;
getModel: (id: string) => Promise<ForecastModel | null>;
trainModel: (id: string, parameters?: any) => Promise<boolean>;
deployModel: (id: string) => Promise<boolean>;
// Predictions
fetchPredictions: (params?: QueryParams) => Promise<void>;
createPrediction: (data: ForecastPredictionCreate) => Promise<boolean>;
getPrediction: (id: string) => Promise<ForecastPrediction | null>;
generateDemandForecast: (modelId: string, horizon: number, parameters?: any) => Promise<any>;
// Batch Predictions
fetchBatches: (params?: QueryParams) => Promise<void>;
createBatch: (modelId: string, data: any) => Promise<boolean>;
getBatch: (id: string) => Promise<ForecastBatch | null>;
downloadBatchResults: (id: string) => Promise<boolean>;
// Model Training
fetchTrainings: (modelId?: string) => Promise<void>;
getTraining: (id: string) => Promise<ModelTraining | null>;
cancelTraining: (id: string) => Promise<boolean>;
// Model Evaluation
fetchEvaluations: (modelId?: string) => Promise<void>;
createEvaluation: (modelId: string, testData: any) => Promise<boolean>;
getEvaluation: (id: string) => Promise<ModelEvaluation | null>;
// Analytics
getModelPerformance: (modelId: string, period?: string) => Promise<any>;
getAccuracyReport: (modelId: string, startDate?: string, endDate?: string) => Promise<any>;
getFeatureImportance: (modelId: string) => Promise<any>;
// Utilities
clearError: () => void;
refresh: () => Promise<void>;
}
export const useForecasting = (): ForecastingState & ForecastingActions => {
const [state, setState] = useState<ForecastingState>({
models: [],
predictions: [],
batches: [],
trainings: [],
evaluations: [],
isLoading: false,
error: null,
pagination: {
total: 0,
page: 1,
pages: 1,
limit: 20,
},
});
const forecastingService = new ForecastingService();
// Fetch forecast models
const fetchModels = useCallback(async (params?: QueryParams) => {
setState(prev => ({ ...prev, isLoading: true, error: null }));
try {
const response = await forecastingService.getModels(params);
if (response.success && response.data) {
setState(prev => ({
...prev,
models: Array.isArray(response.data) ? response.data : response.data.items || [],
pagination: response.data.pagination || prev.pagination,
isLoading: false,
}));
} else {
setState(prev => ({
...prev,
isLoading: false,
error: response.error || 'Error al cargar modelos de predicción',
}));
}
} catch (error) {
setState(prev => ({
...prev,
isLoading: false,
error: 'Error de conexión al servidor',
}));
}
}, [forecastingService]);
// Create forecast model
const createModel = useCallback(async (data: ForecastModelCreate): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.createModel(data);
if (response.success) {
await fetchModels();
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al crear modelo de predicción',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService, fetchModels]);
// Update forecast model
const updateModel = useCallback(async (id: string, data: ForecastModelUpdate): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.updateModel(id, data);
if (response.success) {
await fetchModels();
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al actualizar modelo de predicción',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService, fetchModels]);
// Delete forecast model
const deleteModel = useCallback(async (id: string): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.deleteModel(id);
if (response.success) {
setState(prev => ({
...prev,
models: prev.models.filter(model => model.id !== id),
}));
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al eliminar modelo de predicción',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService]);
// Get single forecast model
const getModel = useCallback(async (id: string): Promise<ForecastModel | null> => {
try {
const response = await forecastingService.getModel(id);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching model:', error);
return null;
}
}, [forecastingService]);
// Train forecast model
const trainModel = useCallback(async (id: string, parameters?: any): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.trainModel(id, parameters);
if (response.success) {
await fetchModels();
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al entrenar modelo',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService, fetchModels]);
// Deploy forecast model
const deployModel = useCallback(async (id: string): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.deployModel(id);
if (response.success) {
await fetchModels();
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al desplegar modelo',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService, fetchModels]);
// Fetch predictions
const fetchPredictions = useCallback(async (params?: QueryParams) => {
setState(prev => ({ ...prev, isLoading: true, error: null }));
try {
const response = await forecastingService.getPredictions(params);
if (response.success && response.data) {
setState(prev => ({
...prev,
predictions: Array.isArray(response.data) ? response.data : response.data.items || [],
isLoading: false,
}));
} else {
setState(prev => ({
...prev,
isLoading: false,
error: response.error || 'Error al cargar predicciones',
}));
}
} catch (error) {
setState(prev => ({
...prev,
isLoading: false,
error: 'Error de conexión al servidor',
}));
}
}, [forecastingService]);
// Create prediction
const createPrediction = useCallback(async (data: ForecastPredictionCreate): Promise<boolean> => {
setState(prev => ({ ...prev, error: null }));
try {
const response = await forecastingService.createPrediction(data);
if (response.success) {
await fetchPredictions();
return true;
} else {
setState(prev => ({
...prev,
error: response.error || 'Error al crear predicción',
}));
return false;
}
} catch (error) {
setState(prev => ({
...prev,
error: 'Error de conexión al servidor',
}));
return false;
}
}, [forecastingService, fetchPredictions]);
// Get single prediction
const getPrediction = useCallback(async (id: string): Promise<ForecastPrediction | null> => {
try {
const response = await forecastingService.getPrediction(id);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching prediction:', error);
return null;
}
}, [forecastingService]);
// Generate demand forecast
const generateDemandForecast = useCallback(async (modelId: string, horizon: number, parameters?: any) => {
try {
const response = await forecastingService.generateDemandForecast(modelId, horizon, parameters);
return response.success ? response.data : null;
} catch (error) {
console.error('Error generating demand forecast:', error);
return null;
}
}, [forecastingService]);
// Fetch batch predictions
const fetchBatches = useCallback(async (params?: QueryParams) => {
try {
const response = await forecastingService.getBatches(params);
if (response.success && response.data) {
setState(prev => ({
...prev,
batches: Array.isArray(response.data) ? response.data : response.data.items || [],
}));
}
} catch (error) {
console.error('Error fetching batches:', error);
}
}, [forecastingService]);
// Create batch prediction
const createBatch = useCallback(async (modelId: string, data: any): Promise<boolean> => {
try {
const response = await forecastingService.createBatch(modelId, data);
if (response.success) {
await fetchBatches();
return true;
}
return false;
} catch (error) {
console.error('Error creating batch:', error);
return false;
}
}, [forecastingService, fetchBatches]);
// Get single batch
const getBatch = useCallback(async (id: string): Promise<ForecastBatch | null> => {
try {
const response = await forecastingService.getBatch(id);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching batch:', error);
return null;
}
}, [forecastingService]);
// Download batch results
const downloadBatchResults = useCallback(async (id: string): Promise<boolean> => {
try {
const response = await forecastingService.downloadBatchResults(id);
return response.success;
} catch (error) {
console.error('Error downloading batch results:', error);
return false;
}
}, [forecastingService]);
// Fetch model trainings
const fetchTrainings = useCallback(async (modelId?: string) => {
try {
const response = await forecastingService.getTrainings(modelId);
if (response.success && response.data) {
setState(prev => ({
...prev,
trainings: Array.isArray(response.data) ? response.data : response.data.items || [],
}));
}
} catch (error) {
console.error('Error fetching trainings:', error);
}
}, [forecastingService]);
// Get single training
const getTraining = useCallback(async (id: string): Promise<ModelTraining | null> => {
try {
const response = await forecastingService.getTraining(id);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching training:', error);
return null;
}
}, [forecastingService]);
// Cancel model training
const cancelTraining = useCallback(async (id: string): Promise<boolean> => {
try {
const response = await forecastingService.cancelTraining(id);
if (response.success) {
await fetchTrainings();
return true;
}
return false;
} catch (error) {
console.error('Error canceling training:', error);
return false;
}
}, [forecastingService, fetchTrainings]);
// Fetch model evaluations
const fetchEvaluations = useCallback(async (modelId?: string) => {
try {
const response = await forecastingService.getEvaluations(modelId);
if (response.success && response.data) {
setState(prev => ({
...prev,
evaluations: Array.isArray(response.data) ? response.data : response.data.items || [],
}));
}
} catch (error) {
console.error('Error fetching evaluations:', error);
}
}, [forecastingService]);
// Create model evaluation
const createEvaluation = useCallback(async (modelId: string, testData: any): Promise<boolean> => {
try {
const response = await forecastingService.createEvaluation(modelId, testData);
if (response.success) {
await fetchEvaluations(modelId);
return true;
}
return false;
} catch (error) {
console.error('Error creating evaluation:', error);
return false;
}
}, [forecastingService, fetchEvaluations]);
// Get single evaluation
const getEvaluation = useCallback(async (id: string): Promise<ModelEvaluation | null> => {
try {
const response = await forecastingService.getEvaluation(id);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching evaluation:', error);
return null;
}
}, [forecastingService]);
// Get model performance
const getModelPerformance = useCallback(async (modelId: string, period?: string) => {
try {
const response = await forecastingService.getModelPerformance(modelId, period);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching model performance:', error);
return null;
}
}, [forecastingService]);
// Get accuracy report
const getAccuracyReport = useCallback(async (modelId: string, startDate?: string, endDate?: string) => {
try {
const response = await forecastingService.getAccuracyReport(modelId, startDate, endDate);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching accuracy report:', error);
return null;
}
}, [forecastingService]);
// Get feature importance
const getFeatureImportance = useCallback(async (modelId: string) => {
try {
const response = await forecastingService.getFeatureImportance(modelId);
return response.success ? response.data : null;
} catch (error) {
console.error('Error fetching feature importance:', error);
return null;
}
}, [forecastingService]);
// Clear error
const clearError = useCallback(() => {
setState(prev => ({ ...prev, error: null }));
}, []);
// Refresh all data
const refresh = useCallback(async () => {
await Promise.all([
fetchModels(),
fetchPredictions(),
fetchBatches(),
]);
}, [fetchModels, fetchPredictions, fetchBatches]);
// Initialize data on mount
useEffect(() => {
refresh();
}, []);
return {
...state,
fetchModels,
createModel,
updateModel,
deleteModel,
getModel,
trainModel,
deployModel,
fetchPredictions,
createPrediction,
getPrediction,
generateDemandForecast,
fetchBatches,
createBatch,
getBatch,
downloadBatchResults,
fetchTrainings,
getTraining,
cancelTraining,
fetchEvaluations,
createEvaluation,
getEvaluation,
getModelPerformance,
getAccuracyReport,
getFeatureImportance,
clearError,
refresh,
};
};