197 lines
5.9 KiB
TypeScript
197 lines
5.9 KiB
TypeScript
// ================================================================
|
|
// frontend/src/api/services/training.ts
|
|
// ================================================================
|
|
/**
|
|
* Training Service - Complete backend alignment
|
|
*
|
|
* Backend API structure (3-tier architecture):
|
|
* - ATOMIC: training_jobs.py, models.py
|
|
* - OPERATIONS: training_operations.py
|
|
*
|
|
* Last Updated: 2025-10-05
|
|
* Status: ✅ Complete - Zero drift with backend
|
|
*/
|
|
|
|
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';
|
|
|
|
// ===================================================================
|
|
// OPERATIONS: Training Job Creation
|
|
// Backend: services/training/app/api/training_operations.py
|
|
// ===================================================================
|
|
|
|
/**
|
|
* Create a new training job
|
|
* POST /tenants/{tenant_id}/training/jobs
|
|
*/
|
|
async createTrainingJob(
|
|
tenantId: string,
|
|
request: TrainingJobRequest
|
|
): Promise<TrainingJobResponse> {
|
|
return apiClient.post<TrainingJobResponse>(
|
|
`${this.baseUrl}/${tenantId}/training/jobs`,
|
|
request
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Train a single product
|
|
* POST /tenants/{tenant_id}/training/products/{inventory_product_id}
|
|
*/
|
|
async trainSingleProduct(
|
|
tenantId: string,
|
|
inventoryProductId: string,
|
|
request: SingleProductTrainingRequest
|
|
): Promise<TrainingJobResponse> {
|
|
return apiClient.post<TrainingJobResponse>(
|
|
`${this.baseUrl}/${tenantId}/training/products/${inventoryProductId}`,
|
|
request
|
|
);
|
|
}
|
|
|
|
// ===================================================================
|
|
// ATOMIC: Training Job Status
|
|
// Backend: services/training/app/api/training_jobs.py
|
|
// ===================================================================
|
|
|
|
/**
|
|
* Get training job status
|
|
* GET /tenants/{tenant_id}/training/jobs/{job_id}/status
|
|
*/
|
|
async getTrainingJobStatus(
|
|
tenantId: string,
|
|
jobId: string
|
|
): Promise<TrainingJobStatus> {
|
|
return apiClient.get<TrainingJobStatus>(
|
|
`${this.baseUrl}/${tenantId}/training/jobs/${jobId}/status`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get training statistics
|
|
* GET /tenants/{tenant_id}/training/statistics
|
|
*/
|
|
async getTenantStatistics(tenantId: string): Promise<TenantStatistics> {
|
|
return apiClient.get<TenantStatistics>(
|
|
`${this.baseUrl}/${tenantId}/training/statistics`
|
|
);
|
|
}
|
|
|
|
// ===================================================================
|
|
// ATOMIC: Model Management
|
|
// Backend: services/training/app/api/models.py
|
|
// ===================================================================
|
|
|
|
/**
|
|
* Get active model for a product
|
|
* GET /tenants/{tenant_id}/training/models/{inventory_product_id}/active
|
|
*/
|
|
async getActiveModel(
|
|
tenantId: string,
|
|
inventoryProductId: string
|
|
): Promise<ActiveModelResponse> {
|
|
return apiClient.get<ActiveModelResponse>(
|
|
`${this.baseUrl}/${tenantId}/training/models/${inventoryProductId}/active`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get model metrics
|
|
* GET /tenants/{tenant_id}/training/models/{model_id}/metrics
|
|
*/
|
|
async getModelMetrics(
|
|
tenantId: string,
|
|
modelId: string
|
|
): Promise<ModelMetricsResponse> {
|
|
return apiClient.get<ModelMetricsResponse>(
|
|
`${this.baseUrl}/${tenantId}/training/models/${modelId}/metrics`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* List models with optional filters
|
|
* GET /tenants/{tenant_id}/training/models
|
|
*/
|
|
async getModels(
|
|
tenantId: string,
|
|
queryParams?: ModelsQueryParams
|
|
): Promise<PaginatedResponse<TrainedModelResponse>> {
|
|
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<PaginatedResponse<TrainedModelResponse>>(
|
|
`${this.baseUrl}/${tenantId}/training/models${queryString}`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get model performance metrics
|
|
* Note: This endpoint might be deprecated - check backend for actual implementation
|
|
*/
|
|
async getModelPerformance(
|
|
tenantId: string,
|
|
modelId: string
|
|
): Promise<ModelPerformanceResponse> {
|
|
return apiClient.get<ModelPerformanceResponse>(
|
|
`${this.baseUrl}/${tenantId}/training/models/${modelId}/performance`
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete all tenant models (Admin only)
|
|
* DELETE /models/tenant/{tenant_id}
|
|
*/
|
|
async deleteAllTenantModels(tenantId: string): Promise<{ message: string }> {
|
|
return apiClient.delete<{ message: string }>(`/models/tenant/${tenantId}`);
|
|
}
|
|
|
|
// ===================================================================
|
|
// WebSocket Support
|
|
// ===================================================================
|
|
|
|
/**
|
|
* Get WebSocket URL 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;
|