Files
bakery-ia/frontend/src/api/services/trainingService.ts

221 lines
5.4 KiB
TypeScript
Raw Normal View History

2025-07-22 17:01:12 +02:00
// src/api/services/TrainingService.ts
import { apiClient } from '../base/apiClient';
import {
ApiResponse,
TrainingRequest,
TrainingJobStatus,
TrainedModel,
} from '../types/api';
export interface TrainingJobProgress {
id: string;
status: 'queued' | 'running' | 'completed' | 'failed' | 'cancelled';
progress: number;
current_step?: string;
total_steps?: number;
step_details?: string;
estimated_completion?: string;
logs?: string[];
}
export interface ModelMetrics {
mape: number;
rmse: number;
mae: number;
r2_score: number;
training_samples: number;
validation_samples: number;
features_used: string[];
}
export interface TrainingConfiguration {
include_weather: boolean;
include_traffic: boolean;
min_data_points: number;
forecast_horizon_days: number;
cross_validation_folds: number;
hyperparameter_tuning: boolean;
products?: string[];
}
export class TrainingService {
/**
* Start new training job
*/
async startTraining(config: TrainingConfiguration): Promise<TrainingJobStatus> {
const response = await apiClient.post<ApiResponse<TrainingJobStatus>>(
'/training/jobs',
config
);
return response.data!;
}
/**
* Get training job status
*/
async getTrainingStatus(jobId: string): Promise<TrainingJobProgress> {
const response = await apiClient.get<ApiResponse<TrainingJobProgress>>(
2025-07-23 07:26:04 +02:00
`/api/v1/training/jobs/${jobId}`
2025-07-22 17:01:12 +02:00
);
return response.data!;
}
/**
* Get all training jobs
*/
async getTrainingHistory(params?: {
page?: number;
limit?: number;
status?: string;
}): Promise<{
jobs: TrainingJobStatus[];
total: number;
page: number;
pages: number;
}> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get<ApiResponse<any>>('/api/v1/training/jobs', { params });
2025-07-22 17:01:12 +02:00
return response.data!;
}
/**
* Cancel training job
*/
async cancelTraining(jobId: string): Promise<void> {
2025-07-23 07:26:04 +02:00
await apiClient.post(`/api/v1/training/jobs/${jobId}/cancel`);
2025-07-22 17:01:12 +02:00
}
/**
* Get trained models
*/
async getModels(params?: {
productName?: string;
active?: boolean;
page?: number;
limit?: number;
}): Promise<{
models: TrainedModel[];
total: number;
page: number;
pages: number;
}> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get<ApiResponse<any>>('/api/v1/training/models', { params });
2025-07-22 17:01:12 +02:00
return response.data!;
}
/**
* Get specific model details
*/
async getModel(modelId: string): Promise<TrainedModel> {
const response = await apiClient.get<ApiResponse<TrainedModel>>(
2025-07-23 07:26:04 +02:00
`/api/v1/training/models/${modelId}`
2025-07-22 17:01:12 +02:00
);
return response.data!;
}
/**
* Get model metrics
*/
async getModelMetrics(modelId: string): Promise<ModelMetrics> {
const response = await apiClient.get<ApiResponse<ModelMetrics>>(
2025-07-23 07:26:04 +02:00
`/api/v1/training/models/${modelId}/metrics`
2025-07-22 17:01:12 +02:00
);
return response.data!;
}
/**
* Activate/deactivate model
*/
async toggleModelStatus(modelId: string, active: boolean): Promise<TrainedModel> {
const response = await apiClient.patch<ApiResponse<TrainedModel>>(
2025-07-23 07:26:04 +02:00
`/api/v1/training/models/${modelId}`,
2025-07-22 17:01:12 +02:00
{ is_active: active }
);
return response.data!;
}
/**
* Delete model
*/
async deleteModel(modelId: string): Promise<void> {
2025-07-23 07:26:04 +02:00
await apiClient.delete(`/api/v1/training/models/${modelId}`);
2025-07-22 17:01:12 +02:00
}
/**
* Train specific product
*/
async trainProduct(productName: string, config?: Partial<TrainingConfiguration>): Promise<TrainingJobStatus> {
const response = await apiClient.post<ApiResponse<TrainingJobStatus>>(
2025-07-23 07:26:04 +02:00
'/api/v1/training/products/train',
2025-07-22 17:01:12 +02:00
{
product_name: productName,
...config,
}
);
return response.data!;
}
/**
* Get training statistics
*/
async getTrainingStats(): Promise<{
total_models: number;
active_models: number;
avg_accuracy: number;
last_training_date: string | null;
products_trained: number;
training_time_avg_minutes: number;
}> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get<ApiResponse<any>>('/api/v1/training/stats');
2025-07-22 17:01:12 +02:00
return response.data!;
}
/**
* Validate training data
*/
async validateTrainingData(products?: string[]): Promise<{
valid: boolean;
errors: string[];
warnings: string[];
product_data_points: Record<string, number>;
recommendation: string;
}> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.post<ApiResponse<any>>('/api/v1/training/validate', {
2025-07-22 17:01:12 +02:00
products,
});
return response.data!;
}
/**
* Get training recommendations
*/
async getTrainingRecommendations(): Promise<{
should_retrain: boolean;
reasons: string[];
recommended_products: string[];
optimal_config: TrainingConfiguration;
}> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get<ApiResponse<any>>('/api/v1/training/recommendations');
2025-07-22 17:01:12 +02:00
return response.data!;
}
/**
* Get training logs
*/
async getTrainingLogs(jobId: string): Promise<string[]> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get<ApiResponse<string[]>>(`/api/v1/training/jobs/${jobId}/logs`);
2025-07-22 17:01:12 +02:00
return response.data!;
}
/**
* Export model
*/
async exportModel(modelId: string, format: 'pickle' | 'onnx' = 'pickle'): Promise<Blob> {
2025-07-23 07:26:04 +02:00
const response = await apiClient.get(`/api/v1/training/models/${modelId}/export`, {
2025-07-22 17:01:12 +02:00
params: { format },
responseType: 'blob',
});
return response as unknown as Blob;
}
}
export const trainingService = new TrainingService();