REFACTOR ALL APIs fix 1
This commit is contained in:
@@ -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
|
||||
// ===================================================================
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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`);
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,7 +90,7 @@ export interface ForecastResponse {
|
||||
// Metadata
|
||||
created_at: string; // ISO datetime string
|
||||
processing_time_ms?: number | null;
|
||||
features_used?: Record<string, any> | null;
|
||||
features?: Record<string, any> | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,3 +260,165 @@ export interface PredictionsPerformanceParams {
|
||||
export interface MessageResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// SCENARIO SIMULATION TYPES - PROFESSIONAL/ENTERPRISE ONLY
|
||||
// ================================================================
|
||||
|
||||
/**
|
||||
* Types of scenarios available for simulation
|
||||
* Backend: ScenarioType enum in schemas/forecasts.py (lines 114-123)
|
||||
*/
|
||||
export enum ScenarioType {
|
||||
WEATHER = 'weather',
|
||||
COMPETITION = 'competition',
|
||||
EVENT = 'event',
|
||||
PRICING = 'pricing',
|
||||
PROMOTION = 'promotion',
|
||||
HOLIDAY = 'holiday',
|
||||
SUPPLY_DISRUPTION = 'supply_disruption',
|
||||
CUSTOM = 'custom'
|
||||
}
|
||||
|
||||
/**
|
||||
* Weather scenario parameters
|
||||
* Backend: WeatherScenario in schemas/forecasts.py (lines 126-130)
|
||||
*/
|
||||
export interface WeatherScenario {
|
||||
temperature_change?: number | null; // Temperature change in °C (-30 to +30)
|
||||
precipitation_change?: number | null; // Precipitation change in mm (0-100)
|
||||
weather_type?: string | null; // Weather type (heatwave, cold_snap, rainy, etc.)
|
||||
}
|
||||
|
||||
/**
|
||||
* Competition scenario parameters
|
||||
* Backend: CompetitionScenario in schemas/forecasts.py (lines 133-137)
|
||||
*/
|
||||
export interface CompetitionScenario {
|
||||
new_competitors: number; // Number of new competitors (1-10)
|
||||
distance_km: number; // Distance from location in km (0.1-10)
|
||||
estimated_market_share_loss: number; // Estimated market share loss (0-0.5)
|
||||
}
|
||||
|
||||
/**
|
||||
* Event scenario parameters
|
||||
* Backend: EventScenario in schemas/forecasts.py (lines 140-145)
|
||||
*/
|
||||
export interface EventScenario {
|
||||
event_type: string; // Type of event (festival, sports, concert, etc.)
|
||||
expected_attendance: number; // Expected attendance
|
||||
distance_km: number; // Distance from location in km (0-50)
|
||||
duration_days: number; // Duration in days (1-30)
|
||||
}
|
||||
|
||||
/**
|
||||
* Pricing scenario parameters
|
||||
* Backend: PricingScenario in schemas/forecasts.py (lines 148-151)
|
||||
*/
|
||||
export interface PricingScenario {
|
||||
price_change_percent: number; // Price change percentage (-50 to +100)
|
||||
affected_products?: string[] | null; // List of affected product IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* Promotion scenario parameters
|
||||
* Backend: PromotionScenario in schemas/forecasts.py (lines 154-158)
|
||||
*/
|
||||
export interface PromotionScenario {
|
||||
discount_percent: number; // Discount percentage (0-75)
|
||||
promotion_type: string; // Type of promotion (bogo, discount, bundle, etc.)
|
||||
expected_traffic_increase: number; // Expected traffic increase (0-2.0 = 0-200%)
|
||||
}
|
||||
|
||||
/**
|
||||
* Request schema for scenario simulation
|
||||
* Backend: ScenarioSimulationRequest in schemas/forecasts.py (lines 161-189)
|
||||
*/
|
||||
export interface ScenarioSimulationRequest {
|
||||
scenario_name: string; // Name for this scenario (3-200 chars)
|
||||
scenario_type: ScenarioType;
|
||||
inventory_product_ids: string[]; // Products to simulate (min 1)
|
||||
start_date: string; // ISO date string
|
||||
duration_days?: number; // Default: 7, range: 1-30
|
||||
|
||||
// Scenario-specific parameters (provide based on scenario_type)
|
||||
weather_params?: WeatherScenario | null;
|
||||
competition_params?: CompetitionScenario | null;
|
||||
event_params?: EventScenario | null;
|
||||
pricing_params?: PricingScenario | null;
|
||||
promotion_params?: PromotionScenario | null;
|
||||
|
||||
// Custom scenario parameters
|
||||
custom_multipliers?: Record<string, number> | null;
|
||||
|
||||
// Comparison settings
|
||||
include_baseline?: boolean; // Default: true
|
||||
}
|
||||
|
||||
/**
|
||||
* Impact of scenario on a specific product
|
||||
* Backend: ScenarioImpact in schemas/forecasts.py (lines 192-199)
|
||||
*/
|
||||
export interface ScenarioImpact {
|
||||
inventory_product_id: string;
|
||||
baseline_demand: number;
|
||||
simulated_demand: number;
|
||||
demand_change_percent: number;
|
||||
confidence_range: [number, number];
|
||||
impact_factors: Record<string, any>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Response schema for scenario simulation
|
||||
* Backend: ScenarioSimulationResponse in schemas/forecasts.py (lines 202-256)
|
||||
*/
|
||||
export interface ScenarioSimulationResponse {
|
||||
id: string;
|
||||
tenant_id: string;
|
||||
scenario_name: string;
|
||||
scenario_type: ScenarioType;
|
||||
|
||||
// Simulation parameters
|
||||
start_date: string; // ISO date string
|
||||
end_date: string; // ISO date string
|
||||
duration_days: number;
|
||||
|
||||
// Results
|
||||
baseline_forecasts?: ForecastResponse[] | null;
|
||||
scenario_forecasts: ForecastResponse[];
|
||||
|
||||
// Impact summary
|
||||
total_baseline_demand: number;
|
||||
total_scenario_demand: number;
|
||||
overall_impact_percent: number;
|
||||
product_impacts: ScenarioImpact[];
|
||||
|
||||
// Insights and recommendations
|
||||
insights: string[];
|
||||
recommendations: string[];
|
||||
risk_level: string; // low, medium, high
|
||||
|
||||
// Metadata
|
||||
created_at: string; // ISO datetime string
|
||||
processing_time_ms: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to compare multiple scenarios
|
||||
* Backend: ScenarioComparisonRequest in schemas/forecasts.py (lines 259-261)
|
||||
*/
|
||||
export interface ScenarioComparisonRequest {
|
||||
scenario_ids: string[]; // 2-5 scenario IDs to compare
|
||||
}
|
||||
|
||||
/**
|
||||
* Response comparing multiple scenarios
|
||||
* Backend: ScenarioComparisonResponse in schemas/forecasts.py (lines 264-270)
|
||||
*/
|
||||
export interface ScenarioComparisonResponse {
|
||||
scenarios: ScenarioSimulationResponse[];
|
||||
comparison_matrix: Record<string, Record<string, any>>;
|
||||
best_case_scenario_id: string;
|
||||
worst_case_scenario_id: string;
|
||||
recommended_action: string;
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ export interface ModelMetricsResponse {
|
||||
rmse: number; // Root Mean Square Error
|
||||
r2_score: number;
|
||||
training_samples: number;
|
||||
features_used: string[];
|
||||
features?: string[]; // Features used by the model
|
||||
model_type: string;
|
||||
created_at?: string | null; // ISO datetime string
|
||||
last_used_at?: string | null; // ISO datetime string
|
||||
|
||||
Reference in New Issue
Block a user