2025-08-03 17:48:34 +02:00
|
|
|
// frontend/src/api/client/config.ts
|
|
|
|
|
/**
|
|
|
|
|
* API Client Configuration
|
|
|
|
|
* Centralized configuration for all API clients
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
export interface ApiConfig {
|
|
|
|
|
baseURL: string;
|
|
|
|
|
timeout: number;
|
|
|
|
|
retries: number;
|
|
|
|
|
retryDelay: number;
|
|
|
|
|
enableLogging: boolean;
|
|
|
|
|
enableCaching: boolean;
|
|
|
|
|
cacheTimeout: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceEndpoints {
|
|
|
|
|
auth: string;
|
|
|
|
|
tenant: string;
|
|
|
|
|
data: string;
|
|
|
|
|
training: string;
|
|
|
|
|
forecasting: string;
|
|
|
|
|
notification: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Environment-based configuration
|
|
|
|
|
const getEnvironmentConfig = (): ApiConfig => {
|
2025-08-03 20:42:29 +02:00
|
|
|
// Use import.meta.env instead of process.env for Vite
|
|
|
|
|
const isDevelopment = import.meta.env.DEV;
|
|
|
|
|
const isProduction = import.meta.env.PROD;
|
2025-08-03 17:48:34 +02:00
|
|
|
|
|
|
|
|
return {
|
2025-08-03 20:42:29 +02:00
|
|
|
baseURL: import.meta.env.VITE_API_URL || 'http://localhost:8000/api/v1',
|
|
|
|
|
timeout: parseInt(import.meta.env.VITE_API_TIMEOUT || '30000'),
|
|
|
|
|
retries: parseInt(import.meta.env.VITE_API_RETRIES || '3'),
|
|
|
|
|
retryDelay: parseInt(import.meta.env.VITE_API_RETRY_DELAY || '1000'),
|
|
|
|
|
enableLogging: isDevelopment || import.meta.env.VITE_API_LOGGING === 'true',
|
|
|
|
|
enableCaching: import.meta.env.VITE_API_CACHING !== 'false',
|
|
|
|
|
cacheTimeout: parseInt(import.meta.env.VITE_API_CACHE_TIMEOUT || '300000'), // 5 minutes
|
2025-08-03 17:48:34 +02:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const apiConfig: ApiConfig = getEnvironmentConfig();
|
|
|
|
|
|
|
|
|
|
// Service endpoint configuration
|
|
|
|
|
export const serviceEndpoints: ServiceEndpoints = {
|
|
|
|
|
auth: '/auth',
|
|
|
|
|
tenant: '/tenants',
|
|
|
|
|
data: '/tenants', // Data operations are tenant-scoped
|
|
|
|
|
training: '/tenants', // Training operations are tenant-scoped
|
|
|
|
|
forecasting: '/tenants', // Forecasting operations are tenant-scoped
|
|
|
|
|
notification: '/tenants', // Notification operations are tenant-scoped
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// HTTP status codes
|
|
|
|
|
export const HttpStatus = {
|
|
|
|
|
OK: 200,
|
|
|
|
|
CREATED: 201,
|
|
|
|
|
NO_CONTENT: 204,
|
|
|
|
|
BAD_REQUEST: 400,
|
|
|
|
|
UNAUTHORIZED: 401,
|
|
|
|
|
FORBIDDEN: 403,
|
|
|
|
|
NOT_FOUND: 404,
|
|
|
|
|
CONFLICT: 409,
|
|
|
|
|
UNPROCESSABLE_ENTITY: 422,
|
|
|
|
|
INTERNAL_SERVER_ERROR: 500,
|
|
|
|
|
BAD_GATEWAY: 502,
|
|
|
|
|
SERVICE_UNAVAILABLE: 503,
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
// Request timeout configuration
|
|
|
|
|
export const RequestTimeouts = {
|
|
|
|
|
SHORT: 5000, // 5 seconds - for quick operations
|
|
|
|
|
MEDIUM: 15000, // 15 seconds - for normal operations
|
|
|
|
|
LONG: 60000, // 1 minute - for file uploads
|
|
|
|
|
EXTENDED: 300000, // 5 minutes - for training operations
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
// Cache configuration
|
|
|
|
|
export interface CacheConfig {
|
|
|
|
|
defaultTTL: number;
|
|
|
|
|
maxSize: number;
|
|
|
|
|
strategies: {
|
|
|
|
|
user: number;
|
|
|
|
|
tenant: number;
|
|
|
|
|
data: number;
|
|
|
|
|
forecast: number;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const cacheConfig: CacheConfig = {
|
|
|
|
|
defaultTTL: 300000, // 5 minutes
|
|
|
|
|
maxSize: 100, // Maximum cached items
|
|
|
|
|
strategies: {
|
|
|
|
|
user: 600000, // 10 minutes
|
|
|
|
|
tenant: 1800000, // 30 minutes
|
|
|
|
|
data: 300000, // 5 minutes
|
|
|
|
|
forecast: 600000, // 10 minutes
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Retry configuration
|
|
|
|
|
export interface RetryConfig {
|
|
|
|
|
attempts: number;
|
|
|
|
|
delay: number;
|
|
|
|
|
backoff: number;
|
|
|
|
|
retryCondition: (error: any) => boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const retryConfig: RetryConfig = {
|
|
|
|
|
attempts: 3,
|
|
|
|
|
delay: 1000,
|
|
|
|
|
backoff: 2, // Exponential backoff multiplier
|
|
|
|
|
retryCondition: (error: any) => {
|
|
|
|
|
// Retry on network errors and specific HTTP status codes
|
|
|
|
|
if (!error.response) return true; // Network error
|
|
|
|
|
const status = error.response.status;
|
|
|
|
|
return status >= 500 || status === 408 || status === 429;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// API versioning
|
|
|
|
|
export const ApiVersion = {
|
|
|
|
|
V1: 'v1',
|
|
|
|
|
CURRENT: 'v1',
|
|
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
export interface FeatureFlags {
|
|
|
|
|
enableWebSockets: boolean;
|
|
|
|
|
enableOfflineMode: boolean;
|
|
|
|
|
enableOptimisticUpdates: boolean;
|
|
|
|
|
enableRequestDeduplication: boolean;
|
|
|
|
|
enableMetrics: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const featureFlags: FeatureFlags = {
|
2025-08-03 20:42:29 +02:00
|
|
|
enableWebSockets: import.meta.env.VITE_ENABLE_WEBSOCKETS === 'true',
|
|
|
|
|
enableOfflineMode: import.meta.env.VITE_ENABLE_OFFLINE === 'true',
|
|
|
|
|
enableOptimisticUpdates: import.meta.env.VITE_ENABLE_OPTIMISTIC_UPDATES !== 'false',
|
|
|
|
|
enableRequestDeduplication: import.meta.env.VITE_ENABLE_DEDUPLICATION !== 'false',
|
|
|
|
|
enableMetrics: import.meta.env.VITE_ENABLE_METRICS === 'true',
|
2025-08-03 17:48:34 +02:00
|
|
|
};
|