/** * Training service API implementation * Handles all training-related backend communications */ import { apiClient } from '../client/apiClient'; import type { TrainingJobRequest, TrainingJobResponse, TrainingJobStatus, SingleProductTrainingRequest, ActiveModelResponse, ModelMetricsResponse, TrainedModelResponse, TenantStatistics, ModelPerformanceResponse, ModelsQueryParams, PaginatedResponse, } from '../types/training'; class TrainingService { private readonly baseUrl = '/tenants'; // Training Jobs async createTrainingJob( tenantId: string, request: TrainingJobRequest ): Promise { return apiClient.post( `${this.baseUrl}/${tenantId}/training/jobs`, request ); } async trainSingleProduct( tenantId: string, inventoryProductId: string, request: SingleProductTrainingRequest ): Promise { return apiClient.post( `${this.baseUrl}/${tenantId}/training/products/${inventoryProductId}`, request ); } async getTrainingJobStatus( tenantId: string, jobId: string ): Promise { return apiClient.get( `${this.baseUrl}/${tenantId}/training/jobs/${jobId}/status` ); } // Models Management async getActiveModel( tenantId: string, inventoryProductId: string ): Promise { return apiClient.get( `${this.baseUrl}/${tenantId}/models/${inventoryProductId}/active` ); } async getModelMetrics( tenantId: string, modelId: string ): Promise { return apiClient.get( `${this.baseUrl}/${tenantId}/models/${modelId}/metrics` ); } async getModels( tenantId: string, queryParams?: ModelsQueryParams ): Promise> { const params = new URLSearchParams(); if (queryParams?.status) params.append('status', queryParams.status); if (queryParams?.model_type) params.append('model_type', queryParams.model_type); if (queryParams?.limit) params.append('limit', queryParams.limit.toString()); if (queryParams?.offset) params.append('offset', queryParams.offset.toString()); const queryString = params.toString() ? `?${params.toString()}` : ''; return apiClient.get>( `${this.baseUrl}/${tenantId}/models${queryString}` ); } async getModelPerformance( tenantId: string, modelId: string ): Promise { return apiClient.get( `${this.baseUrl}/${tenantId}/models/${modelId}/performance` ); } // Statistics and Analytics async getTenantStatistics(tenantId: string): Promise { return apiClient.get( `${this.baseUrl}/${tenantId}/statistics` ); } // Admin endpoints (requires admin role) async deleteAllTenantModels(tenantId: string): Promise<{ message: string }> { return apiClient.delete<{ message: string }>(`/models/tenant/${tenantId}`); } // WebSocket connection helper (for real-time training updates) getTrainingWebSocketUrl(tenantId: string, jobId: string): string { const baseWsUrl = apiClient.getAxiosInstance().defaults.baseURL?.replace(/^http/, 'ws'); return `${baseWsUrl}/ws/tenants/${tenantId}/training/jobs/${jobId}/live`; } // Helper method to construct WebSocket connection createWebSocketConnection( tenantId: string, jobId: string, token?: string ): WebSocket { const wsUrl = this.getTrainingWebSocketUrl(tenantId, jobId); const urlWithToken = token ? `${wsUrl}?token=${token}` : wsUrl; return new WebSocket(urlWithToken); } } // Create and export singleton instance export const trainingService = new TrainingService(); export default trainingService;