Add frontend order API

This commit is contained in:
Urtzi Alfaro
2025-09-09 08:30:06 +02:00
parent 5269a083b6
commit bc3d0ff90c
4 changed files with 844 additions and 0 deletions

View File

@@ -0,0 +1,332 @@
/**
* Orders React Query hooks
*/
import { useMutation, useQuery, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
import { OrdersService } from '../services/orders';
import {
OrderResponse,
OrderCreate,
OrderUpdate,
CustomerResponse,
CustomerCreate,
CustomerUpdate,
OrdersDashboardSummary,
DemandRequirements,
BusinessModelDetection,
ServiceStatus,
GetOrdersParams,
GetCustomersParams,
UpdateOrderStatusParams,
GetDemandRequirementsParams,
} from '../types/orders';
import { ApiError } from '../client/apiClient';
// Query Keys
export const ordersKeys = {
all: ['orders'] as const,
// Orders
orders: () => [...ordersKeys.all, 'orders'] as const,
ordersList: (params: GetOrdersParams) => [...ordersKeys.orders(), 'list', params] as const,
order: (tenantId: string, orderId: string) => [...ordersKeys.orders(), 'detail', tenantId, orderId] as const,
// Customers
customers: () => [...ordersKeys.all, 'customers'] as const,
customersList: (params: GetCustomersParams) => [...ordersKeys.customers(), 'list', params] as const,
customer: (tenantId: string, customerId: string) => [...ordersKeys.customers(), 'detail', tenantId, customerId] as const,
// Dashboard & Analytics
dashboard: (tenantId: string) => [...ordersKeys.all, 'dashboard', tenantId] as const,
demandRequirements: (params: GetDemandRequirementsParams) => [...ordersKeys.all, 'demand', params] as const,
businessModel: (tenantId: string) => [...ordersKeys.all, 'business-model', tenantId] as const,
// Status
status: (tenantId: string) => [...ordersKeys.all, 'status', tenantId] as const,
} as const;
// ===== Order Queries =====
export const useOrders = (
params: GetOrdersParams,
options?: Omit<UseQueryOptions<OrderResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<OrderResponse[], ApiError>({
queryKey: ordersKeys.ordersList(params),
queryFn: () => OrdersService.getOrders(params),
staleTime: 2 * 60 * 1000, // 2 minutes
...options,
});
};
export const useOrder = (
tenantId: string,
orderId: string,
options?: Omit<UseQueryOptions<OrderResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<OrderResponse, ApiError>({
queryKey: ordersKeys.order(tenantId, orderId),
queryFn: () => OrdersService.getOrder(tenantId, orderId),
staleTime: 1 * 60 * 1000, // 1 minute
enabled: !!tenantId && !!orderId,
...options,
});
};
// ===== Customer Queries =====
export const useCustomers = (
params: GetCustomersParams,
options?: Omit<UseQueryOptions<CustomerResponse[], ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<CustomerResponse[], ApiError>({
queryKey: ordersKeys.customersList(params),
queryFn: () => OrdersService.getCustomers(params),
staleTime: 5 * 60 * 1000, // 5 minutes
...options,
});
};
export const useCustomer = (
tenantId: string,
customerId: string,
options?: Omit<UseQueryOptions<CustomerResponse, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<CustomerResponse, ApiError>({
queryKey: ordersKeys.customer(tenantId, customerId),
queryFn: () => OrdersService.getCustomer(tenantId, customerId),
staleTime: 5 * 60 * 1000, // 5 minutes
enabled: !!tenantId && !!customerId,
...options,
});
};
// ===== Dashboard & Analytics Queries =====
export const useOrdersDashboard = (
tenantId: string,
options?: Omit<UseQueryOptions<OrdersDashboardSummary, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<OrdersDashboardSummary, ApiError>({
queryKey: ordersKeys.dashboard(tenantId),
queryFn: () => OrdersService.getDashboardSummary(tenantId),
staleTime: 1 * 60 * 1000, // 1 minute
enabled: !!tenantId,
...options,
});
};
export const useDemandRequirements = (
params: GetDemandRequirementsParams,
options?: Omit<UseQueryOptions<DemandRequirements, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<DemandRequirements, ApiError>({
queryKey: ordersKeys.demandRequirements(params),
queryFn: () => OrdersService.getDemandRequirements(params),
staleTime: 30 * 60 * 1000, // 30 minutes
enabled: !!params.tenant_id && !!params.target_date,
...options,
});
};
export const useBusinessModelDetection = (
tenantId: string,
options?: Omit<UseQueryOptions<BusinessModelDetection, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<BusinessModelDetection, ApiError>({
queryKey: ordersKeys.businessModel(tenantId),
queryFn: () => OrdersService.detectBusinessModel(tenantId),
staleTime: 60 * 60 * 1000, // 1 hour
enabled: !!tenantId,
...options,
});
};
export const useOrdersServiceStatus = (
tenantId: string,
options?: Omit<UseQueryOptions<ServiceStatus, ApiError>, 'queryKey' | 'queryFn'>
) => {
return useQuery<ServiceStatus, ApiError>({
queryKey: ordersKeys.status(tenantId),
queryFn: () => OrdersService.getServiceStatus(tenantId),
staleTime: 30 * 1000, // 30 seconds
enabled: !!tenantId,
...options,
});
};
// ===== Order Mutations =====
export const useCreateOrder = (
options?: UseMutationOptions<OrderResponse, ApiError, OrderCreate>
) => {
const queryClient = useQueryClient();
return useMutation<OrderResponse, ApiError, OrderCreate>({
mutationFn: (orderData: OrderCreate) => OrdersService.createOrder(orderData),
onSuccess: (data, variables) => {
// Invalidate orders list for this tenant
queryClient.invalidateQueries({
queryKey: ordersKeys.orders(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(variables.tenant_id);
},
});
// Invalidate dashboard
queryClient.invalidateQueries({
queryKey: ordersKeys.dashboard(variables.tenant_id),
});
// Add the new order to cache
queryClient.setQueryData(
ordersKeys.order(variables.tenant_id, data.id),
data
);
},
...options,
});
};
export const useUpdateOrderStatus = (
options?: UseMutationOptions<OrderResponse, ApiError, UpdateOrderStatusParams>
) => {
const queryClient = useQueryClient();
return useMutation<OrderResponse, ApiError, UpdateOrderStatusParams>({
mutationFn: (params: UpdateOrderStatusParams) => OrdersService.updateOrderStatus(params),
onSuccess: (data, variables) => {
// Update the specific order in cache
queryClient.setQueryData(
ordersKeys.order(variables.tenant_id, variables.order_id),
data
);
// Invalidate orders list for this tenant
queryClient.invalidateQueries({
queryKey: ordersKeys.orders(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(variables.tenant_id);
},
});
// Invalidate dashboard
queryClient.invalidateQueries({
queryKey: ordersKeys.dashboard(variables.tenant_id),
});
},
...options,
});
};
// ===== Customer Mutations =====
export const useCreateCustomer = (
options?: UseMutationOptions<CustomerResponse, ApiError, CustomerCreate>
) => {
const queryClient = useQueryClient();
return useMutation<CustomerResponse, ApiError, CustomerCreate>({
mutationFn: (customerData: CustomerCreate) => OrdersService.createCustomer(customerData),
onSuccess: (data, variables) => {
// Invalidate customers list for this tenant
queryClient.invalidateQueries({
queryKey: ordersKeys.customers(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(variables.tenant_id);
},
});
// Add the new customer to cache
queryClient.setQueryData(
ordersKeys.customer(variables.tenant_id, data.id),
data
);
// Invalidate dashboard (for customer metrics)
queryClient.invalidateQueries({
queryKey: ordersKeys.dashboard(variables.tenant_id),
});
},
...options,
});
};
export const useUpdateCustomer = (
options?: UseMutationOptions<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>
) => {
const queryClient = useQueryClient();
return useMutation<CustomerResponse, ApiError, { tenantId: string; customerId: string; data: CustomerUpdate }>({
mutationFn: ({ tenantId, customerId, data }) => OrdersService.updateCustomer(tenantId, customerId, data),
onSuccess: (data, variables) => {
// Update the specific customer in cache
queryClient.setQueryData(
ordersKeys.customer(variables.tenantId, variables.customerId),
data
);
// Invalidate customers list for this tenant
queryClient.invalidateQueries({
queryKey: ordersKeys.customers(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(variables.tenantId);
},
});
},
...options,
});
};
// ===== Utility Functions =====
export const useInvalidateOrders = () => {
const queryClient = useQueryClient();
return {
invalidateAllOrders: (tenantId?: string) => {
if (tenantId) {
queryClient.invalidateQueries({
queryKey: ordersKeys.all,
predicate: (query) => {
return JSON.stringify(query.queryKey).includes(tenantId);
},
});
} else {
queryClient.invalidateQueries({ queryKey: ordersKeys.all });
}
},
invalidateOrdersList: (tenantId: string) => {
queryClient.invalidateQueries({
queryKey: ordersKeys.orders(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(tenantId);
},
});
},
invalidateCustomersList: (tenantId: string) => {
queryClient.invalidateQueries({
queryKey: ordersKeys.customers(),
predicate: (query) => {
const queryKey = query.queryKey as string[];
return queryKey.includes('list') &&
JSON.stringify(queryKey).includes(tenantId);
},
});
},
invalidateDashboard: (tenantId: string) => {
queryClient.invalidateQueries({
queryKey: ordersKeys.dashboard(tenantId),
});
},
};
};

View File

@@ -24,6 +24,7 @@ export { foodSafetyService } from './services/foodSafety';
export { trainingService } from './services/training'; export { trainingService } from './services/training';
export { alertProcessorService } from './services/alert_processor'; export { alertProcessorService } from './services/alert_processor';
export { suppliersService } from './services/suppliers'; export { suppliersService } from './services/suppliers';
export { OrdersService } from './services/orders';
// Types - Auth // Types - Auth
export type { export type {
@@ -234,6 +235,42 @@ export {
PerformanceMetricType, PerformanceMetricType,
} from './types/suppliers'; } from './types/suppliers';
// Types - Orders
export type {
CustomerType,
DeliveryMethod,
PaymentTerms as OrdersPaymentTerms,
PaymentMethod,
PaymentStatus,
CustomerSegment,
PriorityLevel,
OrderType,
OrderStatus,
OrderSource,
SalesChannel,
BusinessModel,
CustomerBase,
CustomerCreate,
CustomerUpdate,
CustomerResponse,
OrderItemBase,
OrderItemCreate,
OrderItemUpdate,
OrderItemResponse,
OrderBase,
OrderCreate,
OrderUpdate,
OrderResponse,
OrdersDashboardSummary,
DemandRequirements,
BusinessModelDetection,
ServiceStatus,
GetOrdersParams,
GetCustomersParams,
UpdateOrderStatusParams,
GetDemandRequirementsParams,
} from './types/orders';
// Hooks - Auth // Hooks - Auth
export { export {
useAuthProfile, useAuthProfile,
@@ -460,6 +497,24 @@ export {
suppliersKeys, suppliersKeys,
} from './hooks/suppliers'; } from './hooks/suppliers';
// Hooks - Orders
export {
useOrders,
useOrder,
useCustomers,
useCustomer,
useOrdersDashboard,
useDemandRequirements,
useBusinessModelDetection,
useOrdersServiceStatus,
useCreateOrder,
useUpdateOrderStatus,
useCreateCustomer,
useUpdateCustomer,
useInvalidateOrders,
ordersKeys,
} from './hooks/orders';
// Query Key Factories (for advanced usage) // Query Key Factories (for advanced usage)
export { export {
authKeys, authKeys,
@@ -474,5 +529,6 @@ export {
trainingKeys, trainingKeys,
alertProcessorKeys, alertProcessorKeys,
suppliersKeys, suppliersKeys,
ordersKeys,
dataImportKeys, dataImportKeys,
}; };

View File

@@ -0,0 +1,173 @@
/**
* Orders Service - API endpoints for Orders Service
*
* This service mirrors the backend API endpoints defined in:
* services/orders/app/api/orders.py
*/
import { apiClient } from '../client/apiClient';
import {
OrderResponse,
OrderCreate,
OrderUpdate,
CustomerResponse,
CustomerCreate,
CustomerUpdate,
OrdersDashboardSummary,
DemandRequirements,
BusinessModelDetection,
ServiceStatus,
GetOrdersParams,
GetCustomersParams,
UpdateOrderStatusParams,
GetDemandRequirementsParams,
} from '../types/orders';
export class OrdersService {
// ===== Dashboard and Analytics Endpoints =====
/**
* Get comprehensive dashboard summary for orders
* GET /tenants/{tenant_id}/orders/dashboard-summary
*/
static async getDashboardSummary(tenantId: string): Promise<OrdersDashboardSummary> {
return apiClient.get<OrdersDashboardSummary>(`/tenants/${tenantId}/orders/dashboard-summary`);
}
/**
* Get demand requirements for production planning
* GET /tenants/{tenant_id}/orders/demand-requirements
*/
static async getDemandRequirements(params: GetDemandRequirementsParams): Promise<DemandRequirements> {
const { tenant_id, target_date } = params;
return apiClient.get<DemandRequirements>(
`/tenants/${tenant_id}/orders/demand-requirements?target_date=${target_date}`
);
}
// ===== Order Management Endpoints =====
/**
* Create a new customer order
* POST /tenants/{tenant_id}/orders
*/
static async createOrder(orderData: OrderCreate): Promise<OrderResponse> {
const { tenant_id, ...data } = orderData;
return apiClient.post<OrderResponse>(`/tenants/${tenant_id}/orders`, data);
}
/**
* Get order details with items
* GET /tenants/{tenant_id}/orders/{order_id}
*/
static async getOrder(tenantId: string, orderId: string): Promise<OrderResponse> {
return apiClient.get<OrderResponse>(`/tenants/${tenantId}/orders/${orderId}`);
}
/**
* Get orders with filtering and pagination
* GET /tenants/{tenant_id}/orders
*/
static async getOrders(params: GetOrdersParams): Promise<OrderResponse[]> {
const { tenant_id, status_filter, start_date, end_date, skip = 0, limit = 100 } = params;
const queryParams = new URLSearchParams({
skip: skip.toString(),
limit: limit.toString(),
});
if (status_filter) {
queryParams.append('status_filter', status_filter);
}
if (start_date) {
queryParams.append('start_date', start_date);
}
if (end_date) {
queryParams.append('end_date', end_date);
}
return apiClient.get<OrderResponse[]>(`/tenants/${tenant_id}/orders?${queryParams.toString()}`);
}
/**
* Update order status
* PUT /tenants/{tenant_id}/orders/{order_id}/status
*/
static async updateOrderStatus(params: UpdateOrderStatusParams): Promise<OrderResponse> {
const { tenant_id, order_id, new_status, reason } = params;
const queryParams = new URLSearchParams();
if (reason) {
queryParams.append('reason', reason);
}
const url = `/tenants/${tenant_id}/orders/${order_id}/status${queryParams.toString() ? `?${queryParams.toString()}` : ''}`;
return apiClient.put<OrderResponse>(url, { status: new_status });
}
// ===== Customer Management Endpoints =====
/**
* Create a new customer
* POST /tenants/{tenant_id}/customers
*/
static async createCustomer(customerData: CustomerCreate): Promise<CustomerResponse> {
const { tenant_id, ...data } = customerData;
return apiClient.post<CustomerResponse>(`/tenants/${tenant_id}/customers`, data);
}
/**
* Get customers with filtering and pagination
* GET /tenants/{tenant_id}/customers
*/
static async getCustomers(params: GetCustomersParams): Promise<CustomerResponse[]> {
const { tenant_id, active_only = true, skip = 0, limit = 100 } = params;
const queryParams = new URLSearchParams({
active_only: active_only.toString(),
skip: skip.toString(),
limit: limit.toString(),
});
return apiClient.get<CustomerResponse[]>(`/tenants/${tenant_id}/customers?${queryParams.toString()}`);
}
/**
* Get customer details
* GET /tenants/{tenant_id}/customers/{customer_id}
*/
static async getCustomer(tenantId: string, customerId: string): Promise<CustomerResponse> {
return apiClient.get<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`);
}
/**
* Update customer details
* PUT /tenants/{tenant_id}/customers/{customer_id}
*/
static async updateCustomer(tenantId: string, customerId: string, customerData: CustomerUpdate): Promise<CustomerResponse> {
return apiClient.put<CustomerResponse>(`/tenants/${tenantId}/customers/${customerId}`, customerData);
}
// ===== Business Intelligence Endpoints =====
/**
* Detect business model based on order patterns
* GET /tenants/{tenant_id}/orders/business-model
*/
static async detectBusinessModel(tenantId: string): Promise<BusinessModelDetection> {
return apiClient.get<BusinessModelDetection>(`/tenants/${tenantId}/orders/business-model`);
}
// ===== Health and Status Endpoints =====
/**
* Get orders service status
* GET /tenants/{tenant_id}/orders/status
*/
static async getServiceStatus(tenantId: string): Promise<ServiceStatus> {
return apiClient.get<ServiceStatus>(`/tenants/${tenantId}/orders/status`);
}
}
export default OrdersService;

View File

@@ -0,0 +1,283 @@
/**
* TypeScript types for Orders Service
* Based on backend schemas in services/orders/app/schemas/order_schemas.py
*/
export type CustomerType = 'individual' | 'business' | 'central_bakery';
export type DeliveryMethod = 'delivery' | 'pickup';
export type PaymentTerms = 'immediate' | 'net_30' | 'net_60';
export type PaymentMethod = 'cash' | 'card' | 'bank_transfer' | 'account';
export type PaymentStatus = 'pending' | 'partial' | 'paid' | 'failed' | 'refunded';
export type CustomerSegment = 'vip' | 'regular' | 'wholesale';
export type PriorityLevel = 'high' | 'normal' | 'low';
export type OrderType = 'standard' | 'rush' | 'recurring' | 'special';
export type OrderStatus = 'pending' | 'confirmed' | 'in_production' | 'ready' | 'out_for_delivery' | 'delivered' | 'cancelled' | 'failed';
export type OrderSource = 'manual' | 'online' | 'phone' | 'app' | 'api';
export type SalesChannel = 'direct' | 'wholesale' | 'retail';
export type BusinessModel = 'individual_bakery' | 'central_bakery';
// ===== Customer Types =====
export interface CustomerBase {
name: string;
business_name?: string;
customer_type: CustomerType;
email?: string;
phone?: string;
address_line1?: string;
address_line2?: string;
city?: string;
state?: string;
postal_code?: string;
country: string;
is_active: boolean;
preferred_delivery_method: DeliveryMethod;
payment_terms: PaymentTerms;
credit_limit?: number;
discount_percentage: number;
customer_segment: CustomerSegment;
priority_level: PriorityLevel;
special_instructions?: string;
delivery_preferences?: Record<string, any>;
product_preferences?: Record<string, any>;
}
export interface CustomerCreate extends CustomerBase {
customer_code: string;
tenant_id: string;
}
export interface CustomerUpdate extends Partial<Omit<CustomerBase, 'country' | 'is_active' | 'preferred_delivery_method' | 'payment_terms' | 'discount_percentage' | 'customer_segment' | 'priority_level'>> {
country?: string;
is_active?: boolean;
preferred_delivery_method?: DeliveryMethod;
payment_terms?: PaymentTerms;
discount_percentage?: number;
customer_segment?: CustomerSegment;
priority_level?: PriorityLevel;
}
export interface CustomerResponse extends CustomerBase {
id: string;
tenant_id: string;
customer_code: string;
total_orders: number;
total_spent: number;
average_order_value: number;
last_order_date?: string;
created_at: string;
updated_at: string;
}
// ===== Order Item Types =====
export interface OrderItemBase {
product_id: string;
product_name: string;
product_sku?: string;
product_category?: string;
quantity: number;
unit_of_measure: string;
weight?: number;
unit_price: number;
line_discount: number;
product_specifications?: Record<string, any>;
customization_details?: string;
special_instructions?: string;
recipe_id?: string;
}
export interface OrderItemCreate extends OrderItemBase {}
export interface OrderItemUpdate {
quantity?: number;
unit_price?: number;
line_discount?: number;
product_specifications?: Record<string, any>;
customization_details?: string;
special_instructions?: string;
}
export interface OrderItemResponse extends OrderItemBase {
id: string;
order_id: string;
line_total: number;
status: string;
created_at: string;
updated_at: string;
}
// ===== Order Types =====
export interface OrderBase {
customer_id: string;
order_type: OrderType;
priority: PriorityLevel;
requested_delivery_date: string;
delivery_method: DeliveryMethod;
delivery_address?: Record<string, any>;
delivery_instructions?: string;
delivery_window_start?: string;
delivery_window_end?: string;
discount_percentage: number;
delivery_fee: number;
payment_method?: PaymentMethod;
payment_terms: PaymentTerms;
special_instructions?: string;
custom_requirements?: Record<string, any>;
allergen_warnings?: Record<string, any>;
order_source: OrderSource;
sales_channel: SalesChannel;
order_origin?: string;
communication_preferences?: Record<string, any>;
}
export interface OrderCreate extends OrderBase {
tenant_id: string;
items: OrderItemCreate[];
}
export interface OrderUpdate {
status?: OrderStatus;
priority?: PriorityLevel;
requested_delivery_date?: string;
confirmed_delivery_date?: string;
delivery_method?: DeliveryMethod;
delivery_address?: Record<string, any>;
delivery_instructions?: string;
delivery_window_start?: string;
delivery_window_end?: string;
payment_method?: PaymentMethod;
payment_status?: PaymentStatus;
special_instructions?: string;
custom_requirements?: Record<string, any>;
allergen_warnings?: Record<string, any>;
}
export interface OrderResponse extends OrderBase {
id: string;
tenant_id: string;
order_number: string;
status: OrderStatus;
order_date: string;
confirmed_delivery_date?: string;
actual_delivery_date?: string;
subtotal: number;
discount_amount: number;
tax_amount: number;
total_amount: number;
payment_status: PaymentStatus;
business_model?: string;
estimated_business_model?: string;
production_batch_id?: string;
quality_score?: number;
customer_rating?: number;
created_at: string;
updated_at: string;
items: OrderItemResponse[];
}
// ===== Dashboard and Analytics Types =====
export interface OrdersDashboardSummary {
// Current period metrics
total_orders_today: number;
total_orders_this_week: number;
total_orders_this_month: number;
// Revenue metrics
revenue_today: number;
revenue_this_week: number;
revenue_this_month: number;
// Order status breakdown
pending_orders: number;
confirmed_orders: number;
in_production_orders: number;
ready_orders: number;
delivered_orders: number;
// Customer metrics
total_customers: number;
new_customers_this_month: number;
repeat_customers_rate: number;
// Performance metrics
average_order_value: number;
order_fulfillment_rate: number;
on_time_delivery_rate: number;
// Business model detection
business_model?: string;
business_model_confidence?: number;
// Recent activity
recent_orders: OrderResponse[];
high_priority_orders: OrderResponse[];
}
export interface DemandRequirements {
date: string;
tenant_id: string;
// Product demand breakdown
product_demands: Record<string, any>[];
// Aggregate metrics
total_orders: number;
total_quantity: number;
total_value: number;
// Business context
business_model?: string;
rush_orders_count: number;
special_requirements: string[];
// Timing requirements
earliest_delivery: string;
latest_delivery: string;
average_lead_time_hours: number;
}
export interface BusinessModelDetection {
business_model: string;
confidence: string;
detected_at: string;
}
export interface ServiceStatus {
service: string;
status: string;
timestamp: string;
tenant_id: string;
}
// ===== Query Parameters Types =====
export interface GetOrdersParams {
tenant_id: string;
status_filter?: string;
start_date?: string;
end_date?: string;
skip?: number;
limit?: number;
}
export interface GetCustomersParams {
tenant_id: string;
active_only?: boolean;
skip?: number;
limit?: number;
}
export interface UpdateOrderStatusParams {
tenant_id: string;
order_id: string;
new_status: OrderStatus;
reason?: string;
}
export interface GetDemandRequirementsParams {
tenant_id: string;
target_date: string;
}