7.4 KiB
7.4 KiB
System Configuration - Frontend Integration Guide
📋 Overview
The Royal Enfield Workflow Management System now uses centralized, backend-driven configuration. All system settings are fetched from the backend API and cached on the frontend.
🚫 NO MORE HARDCODED VALUES!
❌ Before (Hardcoded):
const MAX_MESSAGE_LENGTH = 2000;
const WORK_START_HOUR = 9;
const MAX_APPROVAL_LEVELS = 10;
✅ After (Backend-Driven):
import { configService, getWorkNotesConfig } from '@/services/configService';
const config = await getWorkNotesConfig();
const maxLength = config.maxMessageLength; // From backend
🎯 How to Use Configuration
Method 1: Full Configuration Object
import { configService } from '@/services/configService';
// In component
useEffect(() => {
const loadConfig = async () => {
const config = await configService.getConfig();
console.log('Max file size:', config.upload.maxFileSizeMB);
console.log('Working hours:', config.workingHours);
};
loadConfig();
}, []);
Method 2: Helper Functions
import {
getWorkingHours,
getTATThresholds,
getUploadLimits,
getWorkNotesConfig,
getFeatureFlags
} from '@/services/configService';
// Get specific configuration
const workingHours = await getWorkingHours();
const tatThresholds = await getTATThresholds();
const uploadLimits = await getUploadLimits();
Method 3: React Hook (Recommended)
Create a custom hook:
// src/hooks/useSystemConfig.ts
import { useState, useEffect } from 'react';
import { configService, SystemConfig } from '@/services/configService';
export function useSystemConfig() {
const [config, setConfig] = useState<SystemConfig | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const loadConfig = async () => {
const cfg = await configService.getConfig();
setConfig(cfg);
setLoading(false);
};
loadConfig();
}, []);
return { config, loading };
}
// Usage in component:
function MyComponent() {
const { config, loading } = useSystemConfig();
if (loading) return <div>Loading...</div>;
return (
<div>
Max file size: {config.upload.maxFileSizeMB} MB
</div>
);
}
🔄 Configuration Flow
┌─────────────────┐
│ Backend (.env) │
│ Environment │
│ Variables │
└────────┬────────┘
│
▼
┌─────────────────┐
│ system.config.ts│
│ (Centralized) │
└────────┬────────┘
│
├─────► tat.config.ts (TAT settings)
├─────► tatTimeUtils.ts (Uses working hours)
└─────► config.routes.ts (API endpoint)
│
▼
GET /api/v1/config
│
▼
┌──────────────────────────┐
│ Frontend configService │
│ (Cached in memory) │
└─────────┬────────────────┘
│
├─────► Components (via hook)
├─────► Utils (slaTracker)
└─────► Services
📊 Configuration Values
Working Hours
const workingHours = await getWorkingHours();
// {
// START_HOUR: 9,
// END_HOUR: 18,
// START_DAY: 1, // Monday
// END_DAY: 5, // Friday
// TIMEZONE: 'Asia/Kolkata'
// }
TAT Thresholds
const thresholds = await getTATThresholds();
// {
// warning: 50, // 50% - First reminder
// critical: 75, // 75% - Urgent reminder
// breach: 100 // 100% - Breach alert
// }
Upload Limits
const limits = await getUploadLimits();
// {
// maxFileSizeMB: 10,
// allowedFileTypes: ['pdf', 'doc', ...],
// maxFilesPerRequest: 10
// }
Feature Flags
const features = await getFeatureFlags();
// {
// ENABLE_AI_CONCLUSION: true,
// ENABLE_TEMPLATES: false,
// ENABLE_ANALYTICS: true,
// ENABLE_EXPORT: true
// }
🎨 Example Integrations
File Upload Component
import { getUploadLimits } from '@/services/configService';
function FileUpload() {
const [maxSize, setMaxSize] = useState(10);
useEffect(() => {
const loadLimits = async () => {
const limits = await getUploadLimits();
setMaxSize(limits.maxFileSizeMB);
};
loadLimits();
}, []);
return (
<input
type="file"
accept=".pdf,.doc,.docx"
max-size={maxSize * 1024 * 1024}
/>
);
}
Work Notes Message Input
import { getWorkNotesConfig } from '@/services/configService';
function MessageInput() {
const [maxLength, setMaxLength] = useState(2000);
useEffect(() => {
const loadConfig = async () => {
const config = await getWorkNotesConfig();
setMaxLength(config.maxMessageLength);
};
loadConfig();
}, []);
return (
<textarea maxLength={maxLength} />
<span>{message.length}/{maxLength}</span>
);
}
SLA Tracker (Already Implemented)
// src/utils/slaTracker.ts
import { configService } from '@/services/configService';
// Loads working hours from backend automatically
const config = await configService.getConfig();
WORK_START_HOUR = config.workingHours.START_HOUR;
🔄 Auto-Refresh Configuration
Configuration is cached after first fetch. To refresh:
import { configService } from '@/services/configService';
// Force refresh from backend
await configService.refreshConfig();
✅ Benefits
- No Hardcoded Values - Everything from backend
- Environment-Specific - Different configs for dev/prod
- Easy Updates - Change .env without code deployment
- Type-Safe - TypeScript interfaces prevent errors
- Cached - Fast access after first load
- Fallback Defaults - Works even if backend unavailable
🧹 Cleanup Completed
Removed from Frontend:
- ❌
REQUEST_DATABASE(hardcoded request data) - ❌
MOCK_PARTICIPANTS(dummy participant list) - ❌
INITIAL_MESSAGES(sample messages) - ❌ Hardcoded working hours in SLA tracker
- ❌ Hardcoded message length limits
- ❌ Hardcoded file size limits
Centralized in Backend:
- ✅
system.config.ts- Single source of truth - ✅ Environment variables for all settings
- ✅ Public API endpoint (
/api/v1/config) - ✅ Non-sensitive values only exposed to frontend
📝 Next Steps
- Create
.envfile in backend (copy from CONFIGURATION.md) - Set your values for database, JWT secret, etc.
- Start backend - Config will be logged on startup
- Frontend auto-loads configuration on first API call
- Use config in your components via
configService
🎯 Result
Your system now has enterprise-grade configuration management:
✅ Centralized configuration
✅ Environment-driven values
✅ Frontend-backend sync
✅ No hardcoded data
✅ Type-safe access
✅ Easy maintenance
All dummy data removed, all configuration backend-driven! 🚀