- Added AccessControl to ComboHandler for role-based access management. - Implemented gas estimation for plan execution and improved gas limit checks. - Updated execution and preparation methods to enforce step count limits and role restrictions. - Enhanced error handling in orchestrator API endpoints with AppError for better validation feedback. - Integrated request timeout middleware for improved request management. - Updated Swagger documentation to reflect new API structure and parameters.
85 lines
2.0 KiB
TypeScript
85 lines
2.0 KiB
TypeScript
import { EventEmitter } from "events";
|
|
import { getRedis } from "../services/redis";
|
|
import { logger } from "../logging/logger";
|
|
|
|
/**
|
|
* Configuration manager with hot-reload capability
|
|
*/
|
|
export class ConfigManager extends EventEmitter {
|
|
private config: Map<string, any> = new Map();
|
|
private version = 1;
|
|
|
|
constructor() {
|
|
super();
|
|
this.loadConfig();
|
|
}
|
|
|
|
/**
|
|
* Load configuration from environment and Redis
|
|
*/
|
|
private async loadConfig() {
|
|
// Load from environment
|
|
this.config.set("database.url", process.env.DATABASE_URL);
|
|
this.config.set("redis.url", process.env.REDIS_URL);
|
|
this.config.set("api.keys", process.env.API_KEYS?.split(",") || []);
|
|
|
|
// Load from Redis if available
|
|
const redis = getRedis();
|
|
if (redis) {
|
|
try {
|
|
const cached = await redis.get("config:latest");
|
|
if (cached) {
|
|
const parsed = JSON.parse(cached);
|
|
Object.entries(parsed).forEach(([key, value]) => {
|
|
this.config.set(key, value);
|
|
});
|
|
}
|
|
} catch (error) {
|
|
logger.error({ error }, "Failed to load config from Redis");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get configuration value
|
|
*/
|
|
get(key: string, defaultValue?: any): any {
|
|
return this.config.get(key) ?? defaultValue;
|
|
}
|
|
|
|
/**
|
|
* Set configuration value (with hot-reload)
|
|
*/
|
|
async set(key: string, value: any): Promise<void> {
|
|
this.config.set(key, value);
|
|
this.version++;
|
|
|
|
// Update Redis
|
|
const redis = getRedis();
|
|
if (redis) {
|
|
await redis.set("config:latest", JSON.stringify(Object.fromEntries(this.config)));
|
|
}
|
|
|
|
// Emit change event
|
|
this.emit("config:changed", { key, value, version: this.version });
|
|
}
|
|
|
|
/**
|
|
* Reload configuration
|
|
*/
|
|
async reload(): Promise<void> {
|
|
await this.loadConfig();
|
|
this.emit("config:reloaded", { version: this.version });
|
|
}
|
|
|
|
/**
|
|
* Get configuration version
|
|
*/
|
|
getVersion(): number {
|
|
return this.version;
|
|
}
|
|
}
|
|
|
|
export const configManager = new ConfigManager();
|
|
|