REFACTOR ALL APIs fix 1

This commit is contained in:
Urtzi Alfaro
2025-10-07 07:15:07 +02:00
parent 38fb98bc27
commit 7c72f83c51
47 changed files with 1821 additions and 270 deletions

View File

@@ -26,6 +26,10 @@ import {
GetForecastsParams,
ForecastingHealthResponse,
MultiDayForecastResponse,
ScenarioSimulationRequest,
ScenarioSimulationResponse,
ScenarioComparisonRequest,
ScenarioComparisonResponse,
} from '../types/forecasting';
export class ForecastingService {
@@ -258,6 +262,43 @@ export class ForecastingService {
);
}
// ===================================================================
// SCENARIO SIMULATION - PROFESSIONAL/ENTERPRISE ONLY
// Backend: services/forecasting/app/api/scenario_operations.py
// ===================================================================
/**
* Run a "what-if" scenario simulation on forecasts
* POST /tenants/{tenant_id}/forecasting/analytics/scenario-simulation
*
* **PROFESSIONAL/ENTERPRISE ONLY**
*/
async simulateScenario(
tenantId: string,
request: ScenarioSimulationRequest
): Promise<ScenarioSimulationResponse> {
return apiClient.post<ScenarioSimulationResponse, ScenarioSimulationRequest>(
`${this.baseUrl}/${tenantId}/forecasting/analytics/scenario-simulation`,
request
);
}
/**
* Compare multiple scenario simulations
* POST /tenants/{tenant_id}/forecasting/analytics/scenario-comparison
*
* **PROFESSIONAL/ENTERPRISE ONLY**
*/
async compareScenarios(
tenantId: string,
request: ScenarioComparisonRequest
): Promise<ScenarioComparisonResponse> {
return apiClient.post<ScenarioComparisonResponse, ScenarioComparisonRequest>(
`${this.baseUrl}/${tenantId}/forecasting/analytics/scenario-comparison`,
request
);
}
// ===================================================================
// Health Check
// ===================================================================

View File

@@ -215,35 +215,35 @@ export class OrdersService {
/**
* Get current procurement plan for today
* GET /tenants/{tenant_id}/orders/procurement/plans/current
* GET /tenants/{tenant_id}/orders/operations/procurement/plans/current
*/
static async getCurrentProcurementPlan(tenantId: string): Promise<ProcurementPlanResponse | null> {
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/procurement/plans/current`);
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/operations/procurement/plans/current`);
}
/**
* Get procurement plan by specific date
* GET /tenants/{tenant_id}/orders/procurement/plans/date/{plan_date}
* GET /tenants/{tenant_id}/orders/operations/procurement/plans/date/{plan_date}
*/
static async getProcurementPlanByDate(tenantId: string, planDate: string): Promise<ProcurementPlanResponse | null> {
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/procurement/plans/date/${planDate}`);
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/operations/procurement/plans/date/${planDate}`);
}
/**
* Get procurement plan by ID
* GET /tenants/{tenant_id}/orders/procurement/plans/id/{plan_id}
* GET /tenants/{tenant_id}/orders/operations/procurement/plans/id/{plan_id}
*/
static async getProcurementPlanById(tenantId: string, planId: string): Promise<ProcurementPlanResponse | null> {
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/procurement/plans/id/${planId}`);
return apiClient.get<ProcurementPlanResponse | null>(`/tenants/${tenantId}/orders/operations/procurement/plans/id/${planId}`);
}
/**
* List procurement plans with filtering
* GET /tenants/{tenant_id}/orders/procurement/plans/
* GET /tenants/{tenant_id}/orders/operations/procurement/plans/
*/
static async getProcurementPlans(params: GetProcurementPlansParams): Promise<PaginatedProcurementPlans> {
const { tenant_id, status, start_date, end_date, limit = 50, offset = 0 } = params;
const queryParams = new URLSearchParams({
limit: limit.toString(),
offset: offset.toString(),
@@ -254,29 +254,29 @@ export class OrdersService {
if (end_date) queryParams.append('end_date', end_date);
return apiClient.get<PaginatedProcurementPlans>(
`/tenants/${tenant_id}/orders/procurement/plans?${queryParams.toString()}`
`/tenants/${tenant_id}/orders/operations/procurement/plans?${queryParams.toString()}`
);
}
/**
* Generate a new procurement plan
* POST /tenants/{tenant_id}/orders/procurement/plans/generate
* POST /tenants/{tenant_id}/orders/operations/procurement/plans/generate
*/
static async generateProcurementPlan(tenantId: string, request: GeneratePlanRequest): Promise<GeneratePlanResponse> {
return apiClient.post<GeneratePlanResponse>(`/tenants/${tenantId}/orders/procurement/plans/generate`, request);
return apiClient.post<GeneratePlanResponse>(`/tenants/${tenantId}/orders/operations/procurement/plans/generate`, request);
}
/**
* Update procurement plan status
* PUT /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/status
* PUT /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/status
*/
static async updateProcurementPlanStatus(params: UpdatePlanStatusParams): Promise<ProcurementPlanResponse> {
const { tenant_id, plan_id, status } = params;
const queryParams = new URLSearchParams({ status });
return apiClient.put<ProcurementPlanResponse>(
`/tenants/${tenant_id}/orders/procurement/plans/${plan_id}/status?${queryParams.toString()}`,
`/tenants/${tenant_id}/orders/operations/procurement/plans/${plan_id}/status?${queryParams.toString()}`,
{}
);
}
@@ -291,45 +291,45 @@ export class OrdersService {
/**
* Get requirements for a specific plan
* GET /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/requirements
* GET /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/requirements
*/
static async getPlanRequirements(params: GetPlanRequirementsParams): Promise<ProcurementRequirementResponse[]> {
const { tenant_id, plan_id, status, priority } = params;
const queryParams = new URLSearchParams();
if (status) queryParams.append('status', status);
if (priority) queryParams.append('priority', priority);
const url = `/tenants/${tenant_id}/orders/procurement/plans/${plan_id}/requirements${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
const url = `/tenants/${tenant_id}/orders/operations/procurement/plans/${plan_id}/requirements${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return apiClient.get<ProcurementRequirementResponse[]>(url);
}
/**
* Get critical requirements across all plans
* GET /tenants/{tenant_id}/orders/procurement/requirements/critical
* GET /tenants/{tenant_id}/orders/operations/procurement/requirements/critical
*/
static async getCriticalRequirements(tenantId: string): Promise<ProcurementRequirementResponse[]> {
return apiClient.get<ProcurementRequirementResponse[]>(`/tenants/${tenantId}/orders/procurement/requirements/critical`);
return apiClient.get<ProcurementRequirementResponse[]>(`/tenants/${tenantId}/orders/operations/procurement/requirements/critical`);
}
/**
* Trigger daily scheduler manually
* POST /tenants/{tenant_id}/orders/procurement/scheduler/trigger
* POST /tenants/{tenant_id}/orders/operations/procurement/scheduler/trigger
*/
static async triggerDailyScheduler(tenantId: string): Promise<{ success: boolean; message: string; tenant_id: string }> {
return apiClient.post<{ success: boolean; message: string; tenant_id: string }>(
`/tenants/${tenantId}/orders/procurement/scheduler/trigger`,
`/tenants/${tenantId}/orders/operations/procurement/scheduler/trigger`,
{}
);
}
/**
* Get procurement service health
* GET /tenants/{tenant_id}/orders/procurement/health
* GET /tenants/{tenant_id}/orders/base/procurement/health
*/
static async getProcurementHealth(tenantId: string): Promise<{ status: string; service: string; procurement_enabled: boolean; timestamp: string }> {
return apiClient.get<{ status: string; service: string; procurement_enabled: boolean; timestamp: string }>(`/tenants/${tenantId}/orders/procurement/health`);
return apiClient.get<{ status: string; service: string; procurement_enabled: boolean; timestamp: string }>(`/tenants/${tenantId}/orders/base/procurement/health`);
}
// ===================================================================
@@ -339,51 +339,51 @@ export class OrdersService {
/**
* Recalculate an existing procurement plan
* POST /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/recalculate
* POST /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/recalculate
*/
static async recalculateProcurementPlan(tenantId: string, planId: string): Promise<GeneratePlanResponse> {
return apiClient.post<GeneratePlanResponse>(
`/tenants/${tenantId}/orders/procurement/plans/${planId}/recalculate`,
`/tenants/${tenantId}/orders/operations/procurement/plans/${planId}/recalculate`,
{}
);
}
/**
* Approve a procurement plan with notes
* POST /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/approve
* POST /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/approve
*/
static async approveProcurementPlan(tenantId: string, planId: string, request?: ApprovalRequest): Promise<ProcurementPlanResponse> {
return apiClient.post<ProcurementPlanResponse>(
`/tenants/${tenantId}/orders/procurement/plans/${planId}/approve`,
`/tenants/${tenantId}/orders/operations/procurement/plans/${planId}/approve`,
request || {}
);
}
/**
* Reject a procurement plan with notes
* POST /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/reject
* POST /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/reject
*/
static async rejectProcurementPlan(tenantId: string, planId: string, request?: RejectionRequest): Promise<ProcurementPlanResponse> {
return apiClient.post<ProcurementPlanResponse>(
`/tenants/${tenantId}/orders/procurement/plans/${planId}/reject`,
`/tenants/${tenantId}/orders/operations/procurement/plans/${planId}/reject`,
request || {}
);
}
/**
* Create purchase orders automatically from procurement plan
* POST /tenants/{tenant_id}/orders/procurement/plans/{plan_id}/create-purchase-orders
* POST /tenants/{tenant_id}/orders/operations/procurement/plans/{plan_id}/create-purchase-orders
*/
static async createPurchaseOrdersFromPlan(tenantId: string, planId: string, autoApprove: boolean = false): Promise<CreatePOsResult> {
return apiClient.post<CreatePOsResult>(
`/tenants/${tenantId}/orders/procurement/plans/${planId}/create-purchase-orders`,
`/tenants/${tenantId}/orders/operations/procurement/plans/${planId}/create-purchase-orders`,
{ auto_approve: autoApprove }
);
}
/**
* Link a procurement requirement to a purchase order
* POST /tenants/{tenant_id}/orders/procurement/requirements/{requirement_id}/link-purchase-order
* POST /tenants/{tenant_id}/orders/operations/procurement/requirements/{requirement_id}/link-purchase-order
*/
static async linkRequirementToPurchaseOrder(
tenantId: string,
@@ -391,14 +391,14 @@ export class OrdersService {
request: LinkRequirementToPORequest
): Promise<{ success: boolean; message: string; requirement_id: string; purchase_order_id: string }> {
return apiClient.post<{ success: boolean; message: string; requirement_id: string; purchase_order_id: string }>(
`/tenants/${tenantId}/orders/procurement/requirements/${requirementId}/link-purchase-order`,
`/tenants/${tenantId}/orders/operations/procurement/requirements/${requirementId}/link-purchase-order`,
request
);
}
/**
* Update delivery status for a requirement
* PUT /tenants/{tenant_id}/orders/procurement/requirements/{requirement_id}/delivery-status
* PUT /tenants/{tenant_id}/orders/operations/procurement/requirements/{requirement_id}/delivery-status
*/
static async updateRequirementDeliveryStatus(
tenantId: string,
@@ -406,7 +406,7 @@ export class OrdersService {
request: UpdateDeliveryStatusRequest
): Promise<{ success: boolean; message: string; requirement_id: string; delivery_status: string }> {
return apiClient.put<{ success: boolean; message: string; requirement_id: string; delivery_status: string }>(
`/tenants/${tenantId}/orders/procurement/requirements/${requirementId}/delivery-status`,
`/tenants/${tenantId}/orders/operations/procurement/requirements/${requirementId}/delivery-status`,
request
);
}

View File

@@ -188,10 +188,10 @@ export class RecipesService {
/**
* Get recipe statistics for dashboard
* GET /tenants/{tenant_id}/recipes/statistics/dashboard
* GET /tenants/{tenant_id}/recipes/dashboard/statistics
*/
async getRecipeStatistics(tenantId: string): Promise<RecipeStatisticsResponse> {
return apiClient.get<RecipeStatisticsResponse>(`${this.baseUrl}/${tenantId}/recipes/statistics/dashboard`);
return apiClient.get<RecipeStatisticsResponse>(`${this.baseUrl}/${tenantId}/recipes/dashboard/statistics`);
}
/**

View File

@@ -100,7 +100,7 @@ export class SalesService {
}
async getProductCategories(tenantId: string): Promise<string[]> {
return apiClient.get<string[]>(`${this.baseUrl}/${tenantId}/sales/sales/categories`);
return apiClient.get<string[]>(`${this.baseUrl}/${tenantId}/sales/categories`);
}
// ===================================================================

View File

@@ -89,27 +89,27 @@ export class SubscriptionService {
}
async validatePlanUpgrade(tenantId: string, planKey: string): Promise<PlanUpgradeValidation> {
return apiClient.get<PlanUpgradeValidation>(`${this.baseUrl}/${tenantId}/validate-upgrade/${planKey}`);
return apiClient.get<PlanUpgradeValidation>(`${this.baseUrl}/subscriptions/${tenantId}/validate-upgrade/${planKey}`);
}
async upgradePlan(tenantId: string, planKey: string): Promise<PlanUpgradeResult> {
return apiClient.post<PlanUpgradeResult>(`${this.baseUrl}/${tenantId}/upgrade?new_plan=${planKey}`, {});
return apiClient.post<PlanUpgradeResult>(`${this.baseUrl}/subscriptions/${tenantId}/upgrade?new_plan=${planKey}`, {});
}
async canAddLocation(tenantId: string): Promise<{ can_add: boolean; reason?: string; current_count?: number; max_allowed?: number }> {
return apiClient.get(`${this.baseUrl}/${tenantId}/can-add-location`);
return apiClient.get(`${this.baseUrl}/subscriptions/${tenantId}/can-add-location`);
}
async canAddProduct(tenantId: string): Promise<{ can_add: boolean; reason?: string; current_count?: number; max_allowed?: number }> {
return apiClient.get(`${this.baseUrl}/${tenantId}/can-add-product`);
return apiClient.get(`${this.baseUrl}/subscriptions/${tenantId}/can-add-product`);
}
async canAddUser(tenantId: string): Promise<{ can_add: boolean; reason?: string; current_count?: number; max_allowed?: number }> {
return apiClient.get(`${this.baseUrl}/${tenantId}/can-add-user`);
return apiClient.get(`${this.baseUrl}/subscriptions/${tenantId}/can-add-user`);
}
async hasFeature(tenantId: string, featureName: string): Promise<{ has_feature: boolean; feature_value?: any; plan?: string; reason?: string }> {
return apiClient.get(`${this.baseUrl}/${tenantId}/features/${featureName}`);
return apiClient.get(`${this.baseUrl}/subscriptions/${tenantId}/features/${featureName}`);
}
formatPrice(amount: number): string {

View File

@@ -173,7 +173,7 @@ class TrainingService {
*/
getTrainingWebSocketUrl(tenantId: string, jobId: string): string {
const baseWsUrl = apiClient.getAxiosInstance().defaults.baseURL?.replace(/^http/, 'ws');
return `${baseWsUrl}/ws/tenants/${tenantId}/training/jobs/${jobId}/live`;
return `${baseWsUrl}/tenants/${tenantId}/training/jobs/${jobId}/live`;
}
/**