removed deprecated code
This commit is contained in:
parent
34c6c36695
commit
ca5f09c459
10 changed files with 18 additions and 377 deletions
|
|
@ -1,103 +0,0 @@
|
||||||
#!/usr/bin/env bun
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test script for CEO handler operations
|
|
||||||
*/
|
|
||||||
import { initializeServiceConfig } from '@stock-bot/config';
|
|
||||||
import { createServiceContainer, initializeServices } from '@stock-bot/di';
|
|
||||||
import { getLogger } from '@stock-bot/logger';
|
|
||||||
|
|
||||||
const logger = getLogger('test-ceo-operations');
|
|
||||||
|
|
||||||
async function testCeoOperations() {
|
|
||||||
logger.info('Testing CEO handler operations...');
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Initialize config
|
|
||||||
const config = initializeServiceConfig();
|
|
||||||
|
|
||||||
// Create Awilix container
|
|
||||||
const awilixConfig = {
|
|
||||||
redis: {
|
|
||||||
host: config.database.dragonfly.host,
|
|
||||||
port: config.database.dragonfly.port,
|
|
||||||
db: config.database.dragonfly.db,
|
|
||||||
},
|
|
||||||
mongodb: {
|
|
||||||
uri: config.database.mongodb.uri,
|
|
||||||
database: config.database.mongodb.database,
|
|
||||||
},
|
|
||||||
postgres: {
|
|
||||||
host: config.database.postgres.host,
|
|
||||||
port: config.database.postgres.port,
|
|
||||||
database: config.database.postgres.database,
|
|
||||||
user: config.database.postgres.user,
|
|
||||||
password: config.database.postgres.password,
|
|
||||||
},
|
|
||||||
questdb: {
|
|
||||||
enabled: false,
|
|
||||||
host: config.database.questdb.host,
|
|
||||||
httpPort: config.database.questdb.httpPort,
|
|
||||||
pgPort: config.database.questdb.pgPort,
|
|
||||||
influxPort: config.database.questdb.ilpPort,
|
|
||||||
database: config.database.questdb.database,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const container = createServiceContainer(awilixConfig);
|
|
||||||
await initializeServices(container);
|
|
||||||
|
|
||||||
const serviceContainer = container.resolve('serviceContainer');
|
|
||||||
|
|
||||||
// Import and create CEO handler
|
|
||||||
const { CeoHandler } = await import('./src/handlers/ceo/ceo.handler');
|
|
||||||
const ceoHandler = new CeoHandler(serviceContainer);
|
|
||||||
|
|
||||||
// Test 1: Check if there are any CEO symbols in the database
|
|
||||||
logger.info('Checking for existing CEO symbols...');
|
|
||||||
const collection = serviceContainer.mongodb.collection('ceoSymbols');
|
|
||||||
const count = await collection.countDocuments();
|
|
||||||
logger.info(`Found ${count} CEO symbols in database`);
|
|
||||||
|
|
||||||
if (count > 0) {
|
|
||||||
// Test 2: Run process-unique-symbols operation
|
|
||||||
logger.info('Testing process-unique-symbols operation...');
|
|
||||||
const result = await ceoHandler.updateUniqueSymbols(undefined, {});
|
|
||||||
logger.info('Process unique symbols result:', result);
|
|
||||||
|
|
||||||
// Test 3: Test individual symbol processing
|
|
||||||
logger.info('Testing process-individual-symbol operation...');
|
|
||||||
const sampleSymbol = await collection.findOne({});
|
|
||||||
if (sampleSymbol) {
|
|
||||||
const individualResult = await ceoHandler.processIndividualSymbol(
|
|
||||||
{
|
|
||||||
ceoId: sampleSymbol.ceoId,
|
|
||||||
symbol: sampleSymbol.symbol,
|
|
||||||
exchange: sampleSymbol.exchange,
|
|
||||||
name: sampleSymbol.name,
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
logger.info('Process individual symbol result:', individualResult);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger.warn('No CEO symbols found. Run the service to populate data first.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
await serviceContainer.mongodb.disconnect();
|
|
||||||
await serviceContainer.postgres.disconnect();
|
|
||||||
if (serviceContainer.cache) {
|
|
||||||
await serviceContainer.cache.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info('Test completed successfully!');
|
|
||||||
process.exit(0);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error('Test failed:', error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the test
|
|
||||||
testCeoOperations();
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
validateConfig,
|
validateConfig,
|
||||||
} from './utils/validation';
|
} from './utils/validation';
|
||||||
import { ConfigManager } from './config-manager';
|
import { ConfigManager } from './config-manager';
|
||||||
import { appConfigSchema } from './schemas';
|
import { baseAppSchema } from './schemas';
|
||||||
import type { Environment } from './types';
|
import type { Environment } from './types';
|
||||||
|
|
||||||
interface CliOptions {
|
interface CliOptions {
|
||||||
|
|
@ -103,10 +103,10 @@ async function main() {
|
||||||
environment,
|
environment,
|
||||||
});
|
});
|
||||||
|
|
||||||
const config = await manager.initialize(appConfigSchema);
|
const config = await manager.initialize(baseAppSchema);
|
||||||
|
|
||||||
if (values.validate) {
|
if (values.validate) {
|
||||||
const result = validateConfig(config, appConfigSchema);
|
const result = validateConfig(config, baseAppSchema);
|
||||||
|
|
||||||
if (values.json) {
|
if (values.json) {
|
||||||
console.log(JSON.stringify(result, null, 2));
|
console.log(JSON.stringify(result, null, 2));
|
||||||
|
|
@ -133,7 +133,7 @@ async function main() {
|
||||||
|
|
||||||
// Schema validation
|
// Schema validation
|
||||||
console.log('1. Schema Validation:');
|
console.log('1. Schema Validation:');
|
||||||
const schemaResult = validateConfig(config, appConfigSchema);
|
const schemaResult = validateConfig(config, baseAppSchema);
|
||||||
console.log(formatValidationResult(schemaResult));
|
console.log(formatValidationResult(schemaResult));
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@
|
||||||
import { EnvLoader } from './loaders/env.loader';
|
import { EnvLoader } from './loaders/env.loader';
|
||||||
import { FileLoader } from './loaders/file.loader';
|
import { FileLoader } from './loaders/file.loader';
|
||||||
import { ConfigManager } from './config-manager';
|
import { ConfigManager } from './config-manager';
|
||||||
import type { AppConfig } from './schemas';
|
import type { BaseAppConfig } from './schemas';
|
||||||
import { appConfigSchema } from './schemas';
|
import { baseAppSchema } from './schemas';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
// Legacy singleton instance for backward compatibility
|
// Legacy singleton instance for backward compatibility
|
||||||
let configInstance: ConfigManager<AppConfig> | null = null;
|
let configInstance: ConfigManager<BaseAppConfig> | null = null;
|
||||||
|
|
||||||
// Synchronously load critical env vars for early initialization
|
// Synchronously load critical env vars for early initialization
|
||||||
function loadCriticalEnvVarsSync(): void {
|
function loadCriticalEnvVarsSync(): void {
|
||||||
|
|
@ -56,25 +56,6 @@ function loadCriticalEnvVarsSync(): void {
|
||||||
// Load critical env vars immediately
|
// Load critical env vars immediately
|
||||||
loadCriticalEnvVarsSync();
|
loadCriticalEnvVarsSync();
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize the global configuration synchronously.
|
|
||||||
* @deprecated Use initializeAppConfig with your own schema instead
|
|
||||||
*
|
|
||||||
* This loads configuration from all sources in the correct hierarchy:
|
|
||||||
* 1. Schema defaults (lowest priority)
|
|
||||||
* 2. default.json
|
|
||||||
* 3. [environment].json (e.g., development.json)
|
|
||||||
* 4. .env file values
|
|
||||||
* 5. process.env values (highest priority)
|
|
||||||
*/
|
|
||||||
export function initializeConfig(configPath?: string): AppConfig {
|
|
||||||
if (!configInstance) {
|
|
||||||
configInstance = new ConfigManager<AppConfig>({
|
|
||||||
configPath,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return configInstance.initialize(appConfigSchema);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize configuration for a service in a monorepo.
|
* Initialize configuration for a service in a monorepo.
|
||||||
|
|
@ -83,10 +64,10 @@ export function initializeConfig(configPath?: string): AppConfig {
|
||||||
* 2. Service-specific config directory (./config)
|
* 2. Service-specific config directory (./config)
|
||||||
* 3. Environment variables
|
* 3. Environment variables
|
||||||
*/
|
*/
|
||||||
export function initializeServiceConfig(): AppConfig {
|
export function initializeServiceConfig(): BaseAppConfig {
|
||||||
if (!configInstance) {
|
if (!configInstance) {
|
||||||
const environment = process.env.NODE_ENV || 'development';
|
const environment = process.env.NODE_ENV || 'development';
|
||||||
configInstance = new ConfigManager<AppConfig>({
|
configInstance = new ConfigManager<BaseAppConfig>({
|
||||||
loaders: [
|
loaders: [
|
||||||
new FileLoader('../../config', environment), // Root config
|
new FileLoader('../../config', environment), // Root config
|
||||||
new FileLoader('./config', environment), // Service config
|
new FileLoader('./config', environment), // Service config
|
||||||
|
|
@ -94,13 +75,13 @@ export function initializeServiceConfig(): AppConfig {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return configInstance.initialize(appConfigSchema);
|
return configInstance.initialize(baseAppSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current configuration
|
* Get the current configuration
|
||||||
*/
|
*/
|
||||||
export function getConfig(): AppConfig {
|
export function getConfig(): BaseAppConfig {
|
||||||
if (!configInstance) {
|
if (!configInstance) {
|
||||||
throw new Error('Configuration not initialized. Call initializeConfig() first.');
|
throw new Error('Configuration not initialized. Call initializeConfig() first.');
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +91,7 @@ export function getConfig(): AppConfig {
|
||||||
/**
|
/**
|
||||||
* Get configuration manager instance
|
* Get configuration manager instance
|
||||||
*/
|
*/
|
||||||
export function getConfigManager(): ConfigManager<AppConfig> {
|
export function getConfigManager(): ConfigManager<BaseAppConfig> {
|
||||||
if (!configInstance) {
|
if (!configInstance) {
|
||||||
throw new Error('Configuration not initialized. Call initializeConfig() first.');
|
throw new Error('Configuration not initialized. Call initializeConfig() first.');
|
||||||
}
|
}
|
||||||
|
|
@ -140,21 +121,7 @@ export function getLogConfig() {
|
||||||
return getConfig().log;
|
return getConfig().log;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated alias for backward compatibility
|
|
||||||
export function getLoggingConfig() {
|
|
||||||
return getConfig().log;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated - provider configs should be app-specific
|
|
||||||
// @deprecated Move provider configs to your app-specific config
|
|
||||||
export function getProviderConfig(_provider: string) {
|
|
||||||
const config = getConfig() as any;
|
|
||||||
const providers = config.providers;
|
|
||||||
if (!providers || !(_provider in providers)) {
|
|
||||||
throw new Error(`Provider configuration not found: ${_provider}`);
|
|
||||||
}
|
|
||||||
return (providers as Record<string, unknown>)[_provider];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getQueueConfig() {
|
export function getQueueConfig() {
|
||||||
return getConfig().queue;
|
return getConfig().queue;
|
||||||
|
|
|
||||||
|
|
@ -16,14 +16,3 @@ export type { BaseAppConfig } from './base-app.schema';
|
||||||
export { unifiedAppSchema, toUnifiedConfig, getStandardServiceName } from './unified-app.schema';
|
export { unifiedAppSchema, toUnifiedConfig, getStandardServiceName } from './unified-app.schema';
|
||||||
export type { UnifiedAppConfig } from './unified-app.schema';
|
export type { UnifiedAppConfig } from './unified-app.schema';
|
||||||
|
|
||||||
// Keep AppConfig for backward compatibility (deprecated)
|
|
||||||
// @deprecated Use baseAppSchema and extend it for your specific app
|
|
||||||
import { z } from 'zod';
|
|
||||||
import { baseAppSchema } from './base-app.schema';
|
|
||||||
import { providerConfigSchema } from './provider.schema';
|
|
||||||
|
|
||||||
export const appConfigSchema = baseAppSchema.extend({
|
|
||||||
providers: providerConfigSchema.optional(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export type AppConfig = z.infer<typeof appConfigSchema>;
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
import type { Browser } from '@stock-bot/browser';
|
import type { Browser } from '@stock-bot/browser';
|
||||||
import type { CacheProvider } from '@stock-bot/cache';
|
import type { CacheProvider } from '@stock-bot/cache';
|
||||||
import type { AppConfig as StockBotAppConfig } from '@stock-bot/config';
|
import type { BaseAppConfig as StockBotAppConfig } from '@stock-bot/config';
|
||||||
import type { IServiceContainer } from '@stock-bot/types';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
import type { Logger } from '@stock-bot/logger';
|
import type { Logger } from '@stock-bot/logger';
|
||||||
import type { MongoDBClient } from '@stock-bot/mongodb';
|
import type { MongoDBClient } from '@stock-bot/mongodb';
|
||||||
|
|
@ -42,24 +42,6 @@ export interface ServiceDefinitions {
|
||||||
serviceContainer: IServiceContainer;
|
serviceContainer: IServiceContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and configure the DI container with type safety
|
|
||||||
*/
|
|
||||||
export function createServiceContainer(rawConfig: unknown): AwilixContainer<ServiceDefinitions> {
|
|
||||||
// Deprecated - use the new modular structure
|
|
||||||
const { createServiceContainer: newCreateServiceContainer } = require('./container/factory');
|
|
||||||
return newCreateServiceContainer(rawConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize async services after container creation
|
|
||||||
*/
|
|
||||||
export async function initializeServices(container: AwilixContainer): Promise<void> {
|
|
||||||
// Deprecated - use the new modular structure
|
|
||||||
const { initializeServices: newInitializeServices } = await import('./container/factory');
|
|
||||||
return newInitializeServices(container as any);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Export typed container
|
// Export typed container
|
||||||
|
|
@ -79,16 +61,4 @@ export interface ServiceContainerOptions {
|
||||||
enableProxy?: boolean;
|
enableProxy?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create service container directly from AppConfig
|
|
||||||
* This eliminates the need for manual config mapping in each service
|
|
||||||
*/
|
|
||||||
export function createServiceContainerFromConfig(
|
|
||||||
appConfig: StockBotAppConfig,
|
|
||||||
options: ServiceContainerOptions = {}
|
|
||||||
): AwilixContainer<ServiceDefinitions> {
|
|
||||||
// Deprecated - use the new modular structure
|
|
||||||
const { createServiceContainerFromConfig: newCreateServiceContainerFromConfig } = require('./container/factory');
|
|
||||||
return newCreateServiceContainerFromConfig(appConfig, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { createContainer, InjectionMode, asFunction, type AwilixContainer } from 'awilix';
|
import { createContainer, InjectionMode, asFunction, type AwilixContainer } from 'awilix';
|
||||||
import type { AppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
import type { BaseAppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
||||||
import { appConfigSchema, type AppConfig } from '../config/schemas';
|
import { appConfigSchema, type AppConfig } from '../config/schemas';
|
||||||
import { toUnifiedConfig } from '@stock-bot/config';
|
import { toUnifiedConfig } from '@stock-bot/config';
|
||||||
import {
|
import {
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,8 @@
|
||||||
import type { AwilixContainer } from 'awilix';
|
import type { AwilixContainer } from 'awilix';
|
||||||
import type { AppConfig as StockBotAppConfig } from '@stock-bot/config';
|
import type { BaseAppConfig as StockBotAppConfig } from '@stock-bot/config';
|
||||||
import { ServiceContainerBuilder } from './builder';
|
import { ServiceContainerBuilder } from './builder';
|
||||||
import type { ServiceDefinitions, ServiceContainerOptions } from './types';
|
import type { ServiceDefinitions, ServiceContainerOptions } from './types';
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a service container from raw configuration
|
|
||||||
* @deprecated Use ServiceContainerBuilder instead
|
|
||||||
*/
|
|
||||||
export function createServiceContainer(rawConfig: unknown): AwilixContainer<ServiceDefinitions> {
|
|
||||||
// For backward compatibility, we need to create the container synchronously
|
|
||||||
// This means we'll use the original implementation pattern
|
|
||||||
const { createContainer, InjectionMode, asValue: _asValue, asFunction } = require('awilix');
|
|
||||||
const { appConfigSchema } = require('../config/schemas');
|
|
||||||
const config = appConfigSchema.parse(rawConfig);
|
|
||||||
|
|
||||||
const container = createContainer({
|
|
||||||
injectionMode: InjectionMode.PROXY,
|
|
||||||
strict: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register all services synchronously
|
|
||||||
const {
|
|
||||||
registerCoreServices,
|
|
||||||
registerCacheServices,
|
|
||||||
registerDatabaseServices,
|
|
||||||
registerApplicationServices
|
|
||||||
} = require('../registrations');
|
|
||||||
|
|
||||||
registerCoreServices(container, config);
|
|
||||||
registerCacheServices(container, config);
|
|
||||||
registerDatabaseServices(container, config);
|
|
||||||
registerApplicationServices(container, config);
|
|
||||||
|
|
||||||
// Register service container aggregate
|
|
||||||
container.register({
|
|
||||||
serviceContainer: asFunction((cradle: ServiceDefinitions) => ({
|
|
||||||
logger: cradle.logger,
|
|
||||||
cache: cradle.cache,
|
|
||||||
proxy: cradle.proxyManager, // Map proxyManager to proxy
|
|
||||||
browser: cradle.browser,
|
|
||||||
queue: cradle.queueManager, // Map queueManager to queue
|
|
||||||
mongodb: cradle.mongoClient, // Map mongoClient to mongodb
|
|
||||||
postgres: cradle.postgresClient, // Map postgresClient to postgres
|
|
||||||
questdb: cradle.questdbClient, // Map questdbClient to questdb
|
|
||||||
})).singleton(),
|
|
||||||
});
|
|
||||||
|
|
||||||
return container;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a service container from StockBotAppConfig
|
|
||||||
* @deprecated Use ServiceContainerBuilder instead
|
|
||||||
*/
|
|
||||||
export function createServiceContainerFromConfig(
|
|
||||||
appConfig: StockBotAppConfig,
|
|
||||||
options: ServiceContainerOptions = {}
|
|
||||||
): AwilixContainer<ServiceDefinitions> {
|
|
||||||
const builder = new ServiceContainerBuilder();
|
|
||||||
return builder
|
|
||||||
.withConfig(appConfig)
|
|
||||||
.withOptions({
|
|
||||||
...options,
|
|
||||||
skipInitialization: true, // Legacy behavior
|
|
||||||
})
|
|
||||||
.build()
|
|
||||||
.then(container => container)
|
|
||||||
.catch(error => {
|
|
||||||
throw error;
|
|
||||||
}) as any; // Sync interface for backward compatibility
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modern async factory for creating service containers
|
* Modern async factory for creating service containers
|
||||||
|
|
@ -86,14 +18,3 @@ export async function createServiceContainerAsync(
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize services in an existing container
|
|
||||||
* @deprecated Handled automatically by ServiceContainerBuilder
|
|
||||||
*/
|
|
||||||
export async function initializeServices(
|
|
||||||
container: AwilixContainer<ServiceDefinitions>
|
|
||||||
): Promise<void> {
|
|
||||||
const { ServiceLifecycleManager } = await import('../utils/lifecycle');
|
|
||||||
const lifecycleManager = new ServiceLifecycleManager();
|
|
||||||
await lifecycleManager.initializeServices(container);
|
|
||||||
}
|
|
||||||
|
|
@ -6,11 +6,8 @@ export * from './types';
|
||||||
// Re-export IServiceContainer from types for convenience
|
// Re-export IServiceContainer from types for convenience
|
||||||
export type { IServiceContainer } from '@stock-bot/types';
|
export type { IServiceContainer } from '@stock-bot/types';
|
||||||
|
|
||||||
// Legacy exports for backward compatibility
|
// Type exports from awilix-container
|
||||||
export {
|
export {
|
||||||
createServiceContainer,
|
|
||||||
createServiceContainerFromConfig,
|
|
||||||
initializeServices,
|
|
||||||
type AppConfig,
|
type AppConfig,
|
||||||
type ServiceCradle,
|
type ServiceCradle,
|
||||||
type ServiceContainer,
|
type ServiceContainer,
|
||||||
|
|
@ -21,9 +18,7 @@ export {
|
||||||
export * from './container/types';
|
export * from './container/types';
|
||||||
export { ServiceContainerBuilder } from './container/builder';
|
export { ServiceContainerBuilder } from './container/builder';
|
||||||
export {
|
export {
|
||||||
createServiceContainerAsync,
|
createServiceContainerAsync
|
||||||
createServiceContainer as createServiceContainerNew,
|
|
||||||
createServiceContainerFromConfig as createServiceContainerFromConfigNew
|
|
||||||
} from './container/factory';
|
} from './container/factory';
|
||||||
|
|
||||||
// Configuration exports
|
// Configuration exports
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { Hono } from 'hono';
|
||||||
import { cors } from 'hono/cors';
|
import { cors } from 'hono/cors';
|
||||||
import { getLogger, setLoggerConfig, shutdownLoggers, type Logger } from '@stock-bot/logger';
|
import { getLogger, setLoggerConfig, shutdownLoggers, type Logger } from '@stock-bot/logger';
|
||||||
import { Shutdown } from '@stock-bot/shutdown';
|
import { Shutdown } from '@stock-bot/shutdown';
|
||||||
import type { AppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
import type { BaseAppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
||||||
import { toUnifiedConfig } from '@stock-bot/config';
|
import { toUnifiedConfig } from '@stock-bot/config';
|
||||||
import type { IServiceContainer } from '@stock-bot/types';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
import type { ServiceContainer } from './awilix-container';
|
import type { ServiceContainer } from './awilix-container';
|
||||||
|
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
||||||
/**
|
|
||||||
* Service Registry Configuration
|
|
||||||
* Maps services to their Redis databases and configurations
|
|
||||||
*
|
|
||||||
* @deprecated This static service registry has been replaced by runtime discovery
|
|
||||||
* using the handler registry. Service ownership is now tracked when handlers are
|
|
||||||
* registered, eliminating the need for static configuration.
|
|
||||||
*
|
|
||||||
* Migration:
|
|
||||||
* - Service names are auto-discovered from handler registration
|
|
||||||
* - Cache prefixes are generated using generateCachePrefix()
|
|
||||||
* - Queue names use getFullQueueName() from service-utils
|
|
||||||
* - Handler ownership is tracked by handlerRegistry.getHandlerService()
|
|
||||||
*/
|
|
||||||
|
|
||||||
export interface ServiceConfig {
|
|
||||||
/** Prefix for cache keys (e.g., 'cache:data-ingestion') */
|
|
||||||
cachePrefix: string;
|
|
||||||
/** List of handlers this service owns (auto-discovered if not provided) */
|
|
||||||
handlers?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Central registry of all services and their configurations
|
|
||||||
*
|
|
||||||
* Database assignments:
|
|
||||||
* - db:0 = All queues (unified queue database)
|
|
||||||
* - db:1 = Global shared cache + service-specific caches
|
|
||||||
*/
|
|
||||||
export const SERVICE_REGISTRY: Record<string, ServiceConfig> = {
|
|
||||||
'data-ingestion': {
|
|
||||||
cachePrefix: 'cache:data-ingestion',
|
|
||||||
handlers: ['ceo', 'qm', 'webshare', 'ib', 'proxy'],
|
|
||||||
},
|
|
||||||
'data-pipeline': {
|
|
||||||
cachePrefix: 'cache:data-pipeline',
|
|
||||||
handlers: ['exchanges', 'symbols'],
|
|
||||||
},
|
|
||||||
'web-api': {
|
|
||||||
cachePrefix: 'cache:web-api',
|
|
||||||
},
|
|
||||||
// Add aliases for services with different naming conventions
|
|
||||||
'webApi': {
|
|
||||||
cachePrefix: 'cache:web-api',
|
|
||||||
},
|
|
||||||
'dataIngestion': {
|
|
||||||
cachePrefix: 'cache:data-ingestion',
|
|
||||||
handlers: ['ceo', 'qm', 'webshare', 'ib', 'proxy'],
|
|
||||||
},
|
|
||||||
'dataPipeline': {
|
|
||||||
cachePrefix: 'cache:data-pipeline',
|
|
||||||
handlers: ['exchanges', 'symbols'],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get service configuration
|
|
||||||
*/
|
|
||||||
export function getServiceConfig(serviceName: string): ServiceConfig | undefined {
|
|
||||||
return SERVICE_REGISTRY[serviceName];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find which service owns a handler
|
|
||||||
*/
|
|
||||||
export function findServiceForHandler(handlerName: string): string | undefined {
|
|
||||||
for (const [serviceName, config] of Object.entries(SERVICE_REGISTRY)) {
|
|
||||||
if (config.handlers?.includes(handlerName)) {
|
|
||||||
return serviceName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get full queue name with service namespace
|
|
||||||
*/
|
|
||||||
export function getFullQueueName(serviceName: string, handlerName: string): string {
|
|
||||||
// Use {service_handler} format for Dragonfly optimization and BullMQ compatibility
|
|
||||||
return `{${serviceName}_${handlerName}}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a full queue name into service and handler
|
|
||||||
*/
|
|
||||||
export function parseQueueName(fullQueueName: string): { service: string; handler: string } | null {
|
|
||||||
// Match pattern {service_handler}
|
|
||||||
const match = fullQueueName.match(/^\{([^_]+)_([^}]+)\}$/);
|
|
||||||
|
|
||||||
if (!match || !match[1] || !match[2]) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
service: match[1],
|
|
||||||
handler: match[2],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue