Spaces:
Runtime error
Runtime error
| const API_BASE = import.meta.env.VITE_API_URL || ""; | |
| export async function request(path, options = {}) { | |
| const url = `${API_BASE}${path}`; | |
| const response = await fetch(url, { | |
| headers: { | |
| "Content-Type": "application/json", | |
| ...options.headers, | |
| }, | |
| ...options, | |
| }); | |
| if (!response.ok) { | |
| const errText = await response.text(); | |
| let parsedErr; | |
| try { | |
| parsedErr = JSON.parse(errText); | |
| } catch { | |
| parsedErr = errText; | |
| } | |
| throw new Error(parsedErr?.detail || parsedErr || "Request failed"); | |
| } | |
| return response.json(); | |
| } | |
| export const api = { | |
| // Products | |
| getProducts: () => request("/api/products/"), | |
| getProductPriceHistory: (id) => request(`/api/products/${id}/price-history`), | |
| updateProduct: (id, data) => request(`/api/products/${id}`, { method: "PUT", body: JSON.stringify(data) }), | |
| getCategories: () => request("/api/products/categories"), | |
| // Inventory | |
| getInventories: () => request("/api/inventory/"), | |
| adjustInventoryStock: (id, change, reason) => | |
| request(`/api/inventory/${id}/adjust?qty_change=${change}&reason=${encodeURIComponent(reason)}`, { method: "POST" }), | |
| getInventoryHistory: (id) => request(`/api/inventory/${id}/history`), | |
| getReplenishmentRecommendations: () => request("/api/inventory/recommendations/replenishment"), | |
| getTransferRecommendations: () => request("/api/inventory/recommendations/transfers"), | |
| getWarehouses: () => request("/api/inventory/warehouses"), | |
| getWarehousesStatus: () => request("/api/inventory/warehouses/status"), | |
| // Orders | |
| getOrders: () => request("/api/orders/"), | |
| createOrder: (data) => request("/api/orders/", { method: "POST", body: JSON.stringify(data) }), | |
| // Simulator Controls | |
| getSimulatorStatus: () => request("/api/orders/simulator/status"), | |
| controlSimulator: (is_running, speed = 1.0, demand_type = "normal", demand_multiplier = 1.0, seasonality_level = "medium", supply_level = "medium", flash_sale_active = false, competitor_discount_active = false, scenario = "Normal Demand") => | |
| request("/api/orders/simulator/control", { | |
| method: "POST", | |
| body: JSON.stringify({ is_running, speed, demand_type, demand_multiplier, seasonality_level, supply_level, flash_sale_active, competitor_discount_active, scenario }) | |
| }), | |
| generateBulkOrders: (count = 10000) => | |
| request(`/api/orders/simulator/generate?count=${count}`, { method: "POST" }), | |
| // Pricing Decisions | |
| getPricingDecisions: () => request("/api/products/pricing-decisions/recommendations"), | |
| // Analytics | |
| getKPIs: () => request("/api/analytics/kpis"), | |
| getRevenueChart: (days = 30) => request(`/api/analytics/revenue-chart?days=${days}`), | |
| getForecastChart: (productId) => request(`/api/analytics/forecast-chart?product_id=${productId}`), | |
| // System Controls | |
| triggerPricingEngine: () => request("/api/system/trigger/pricing", { method: "POST" }), | |
| triggerForecastEngine: () => request("/api/system/trigger/forecast", { method: "POST" }), | |
| triggerAnomalyDetection: () => request("/api/system/trigger/anomaly", { method: "POST" }), | |
| triggerScenarioEvent: (eventType) => | |
| request("/api/system/trigger/event", { method: "POST", body: JSON.stringify({ event_type: eventType }) }), | |
| getAnomalies: (resolved = false) => request(`/api/system/anomalies?resolved=${resolved}`), | |
| resolveAnomaly: (id) => request(`/api/system/anomalies/${id}/resolve`, { method: "POST" }), | |
| getAuditLogs: () => request("/api/system/audit-logs"), | |
| // SSE Stream | |
| subscribeToAlerts: (onEventMap) => { | |
| const eventSource = new EventSource(`${API_BASE}/api/system/alerts/stream`); | |
| // Connect default listeners | |
| Object.entries(onEventMap).forEach(([eventName, callback]) => { | |
| eventSource.addEventListener(eventName, (e) => { | |
| try { | |
| const data = JSON.parse(e.data); | |
| callback(data); | |
| } catch (err) { | |
| console.error(`Error parsing SSE data for [${eventName}]:`, err); | |
| } | |
| }); | |
| }); | |
| eventSource.onerror = (err) => { | |
| console.warn("SSE connection error, attempting auto-reconnect:", err); | |
| }; | |
| return () => { | |
| eventSource.close(); | |
| }; | |
| } | |
| }; | |