diff --git a/.serena/cache/typescript/document_symbols_cache_v20-05-25.pkl b/.serena/cache/typescript/document_symbols_cache_v20-05-25.pkl index 59ee04e..8375536 100644 Binary files a/.serena/cache/typescript/document_symbols_cache_v20-05-25.pkl and b/.serena/cache/typescript/document_symbols_cache_v20-05-25.pkl differ diff --git a/libs/core/di/package.json b/libs/core/di/package.json index 6311d2a..0b65964 100644 --- a/libs/core/di/package.json +++ b/libs/core/di/package.json @@ -10,7 +10,7 @@ "dependencies": { "@stock-bot/config": "workspace:*", "@stock-bot/logger": "workspace:*", - "@stock-bot/handlers": "workspace:*" + "@stock-bot/types": "workspace:*" }, "devDependencies": { "@types/pg": "^8.10.7" diff --git a/libs/core/di/src/index.ts b/libs/core/di/src/index.ts index 6b330d2..67fdd0e 100644 --- a/libs/core/di/src/index.ts +++ b/libs/core/di/src/index.ts @@ -3,6 +3,9 @@ export * from './operation-context'; export * from './pool-size-calculator'; export * from './types'; +// Re-export IServiceContainer from types for convenience +export type { IServiceContainer } from '@stock-bot/types'; + // Legacy exports for backward compatibility export { createServiceContainer, diff --git a/libs/core/handlers/src/base/BaseHandler.ts b/libs/core/handlers/src/base/BaseHandler.ts index 95af980..75eedd6 100644 --- a/libs/core/handlers/src/base/BaseHandler.ts +++ b/libs/core/handlers/src/base/BaseHandler.ts @@ -1,12 +1,15 @@ import type { Collection } from 'mongodb'; import { getLogger } from '@stock-bot/logger'; -import type { HandlerConfigWithSchedule } from '@stock-bot/types'; +import type { + HandlerConfigWithSchedule, + IServiceContainer, + ExecutionContext, + IHandler +} from '@stock-bot/types'; import { fetch } from '@stock-bot/utils'; import { createNamespacedCache } from '@stock-bot/cache'; -import type { IServiceContainer } from '@stock-bot/types'; import { handlerRegistry } from '../registry/handler-registry'; import { createJobHandler } from '../utils/create-job-handler'; -import type { ExecutionContext, IHandler } from '../types/types'; /** * Job scheduling options diff --git a/libs/core/handlers/src/index.ts b/libs/core/handlers/src/index.ts index f8bac94..f531f38 100644 --- a/libs/core/handlers/src/index.ts +++ b/libs/core/handlers/src/index.ts @@ -8,7 +8,7 @@ export { handlerRegistry } from './registry/handler-registry'; // Utilities export { createJobHandler } from './utils/create-job-handler'; -// Types +// Re-export types from types package for convenience export type { ExecutionContext, IHandler, @@ -19,10 +19,8 @@ export type { TypedJobHandler, HandlerMetadata, OperationMetadata, -} from './types/types'; - -// Re-export IServiceContainer from types package -export type { IServiceContainer } from '@stock-bot/types'; + IServiceContainer, +} from '@stock-bot/types'; // Decorators export { diff --git a/libs/core/handlers/src/registry/HandlerRegistry.ts b/libs/core/handlers/src/registry/HandlerRegistry.ts deleted file mode 100644 index e5b5c89..0000000 --- a/libs/core/handlers/src/registry/HandlerRegistry.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { getLogger } from '@stock-bot/logger'; -import type { - HandlerConfig, - HandlerConfigWithSchedule, - JobHandler, - ScheduledJob, -} from '../types/types'; - -const logger = getLogger('handler-registry'); - -class HandlerRegistry { - private handlers = new Map(); - private handlerSchedules = new Map(); - - /** - * Register a handler with its operations (simple config) - */ - register(handlerName: string, config: HandlerConfig): void { - logger.info(`Registering handler: ${handlerName}`, { - operations: Object.keys(config), - }); - - this.handlers.set(handlerName, config); - } - - /** - * Register a handler with operations and scheduled jobs (full config) - */ - registerWithSchedule(config: HandlerConfigWithSchedule): void { - logger.info(`Registering handler with schedule: ${config.name}`, { - operations: Object.keys(config.operations), - scheduledJobs: config.scheduledJobs?.length || 0, - }); - - this.handlers.set(config.name, config.operations); - - if (config.scheduledJobs && config.scheduledJobs.length > 0) { - this.handlerSchedules.set(config.name, config.scheduledJobs); - } - } - - /** - * Get a handler for a specific handler and operation - */ - getHandler(handler: string, operation: string): JobHandler | null { - const handlerConfig = this.handlers.get(handler); - if (!handlerConfig) { - logger.warn(`Handler not found: ${handler}`); - return null; - } - - const jobHandler = handlerConfig[operation]; - if (!jobHandler) { - logger.warn(`Operation not found: ${handler}:${operation}`, { - availableOperations: Object.keys(handlerConfig), - }); - return null; - } - - return jobHandler; - } - - /** - * Get all scheduled jobs from all handlers - */ - getAllScheduledJobs(): Array<{ handler: string; job: ScheduledJob }> { - const allJobs: Array<{ handler: string; job: ScheduledJob }> = []; - - for (const [handlerName, jobs] of this.handlerSchedules) { - for (const job of jobs) { - allJobs.push({ - handler: handlerName, - job, - }); - } - } - - return allJobs; - } - - /** - * Get scheduled jobs for a specific handler - */ - getScheduledJobs(handler: string): ScheduledJob[] { - return this.handlerSchedules.get(handler) || []; - } - - /** - * Check if a handler has scheduled jobs - */ - hasScheduledJobs(handler: string): boolean { - return this.handlerSchedules.has(handler); - } - - /** - * Get all registered handlers with their configurations - */ - getHandlerConfigs(): Array<{ name: string; operations: string[]; scheduledJobs: number }> { - return Array.from(this.handlers.keys()).map(name => ({ - name, - operations: Object.keys(this.handlers.get(name) || {}), - scheduledJobs: this.handlerSchedules.get(name)?.length || 0, - })); - } - - /** - * Get all handlers with their full configurations for queue manager registration - */ - getAllHandlers(): Map { - const result = new Map(); - - for (const [name, operations] of this.handlers) { - const scheduledJobs = this.handlerSchedules.get(name); - result.set(name, { - operations, - scheduledJobs, - }); - } - - return result; - } - - /** - * Get all registered handlers - */ - getHandlers(): string[] { - return Array.from(this.handlers.keys()); - } - - /** - * Get operations for a specific handler - */ - getOperations(handler: string): string[] { - const handlerConfig = this.handlers.get(handler); - return handlerConfig ? Object.keys(handlerConfig) : []; - } - - /** - * Check if a handler exists - */ - hasHandler(handler: string): boolean { - return this.handlers.has(handler); - } - - /** - * Check if a handler has a specific operation - */ - hasOperation(handler: string, operation: string): boolean { - const handlerConfig = this.handlers.get(handler); - return handlerConfig ? operation in handlerConfig : false; - } - - /** - * Remove a handler - */ - unregister(handler: string): boolean { - this.handlerSchedules.delete(handler); - return this.handlers.delete(handler); - } - - /** - * Clear all handlers - */ - clear(): void { - this.handlers.clear(); - this.handlerSchedules.clear(); - } - - /** - * Get registry statistics - */ - getStats(): { handlers: number; totalOperations: number; totalScheduledJobs: number } { - let totalOperations = 0; - let totalScheduledJobs = 0; - - for (const config of this.handlers.values()) { - totalOperations += Object.keys(config).length; - } - - for (const jobs of this.handlerSchedules.values()) { - totalScheduledJobs += jobs.length; - } - - return { - handlers: this.handlers.size, - totalOperations, - totalScheduledJobs, - }; - } -} - -// Export singleton instance -export const handlerRegistry = new HandlerRegistry(); diff --git a/libs/core/handlers/src/types/types.ts b/libs/core/handlers/src/types/types.ts deleted file mode 100644 index 0cb2562..0000000 --- a/libs/core/handlers/src/types/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -// Re-export all handler types from the shared types package -export type { - ExecutionContext, - HandlerConfig, - HandlerConfigWithSchedule, - HandlerMetadata, - IHandler, - JobHandler, - OperationMetadata, - ScheduledJob, - TypedJobHandler, -} from '@stock-bot/types'; diff --git a/libs/core/types/src/decorators.ts b/libs/core/types/src/decorators.ts new file mode 100644 index 0000000..1b004f3 --- /dev/null +++ b/libs/core/types/src/decorators.ts @@ -0,0 +1,41 @@ +/** + * Decorator Type Definitions + * Type definitions for handler decorators + */ + +/** + * Schedule configuration for operations + */ +export interface ScheduleConfig { + cronPattern: string; + priority?: number; + immediately?: boolean; + description?: string; +} + +/** + * Decorator metadata stored on classes + */ +export interface DecoratorMetadata { + handlerName?: string; + operations?: Array<{ + name: string; + methodName: string; + schedules?: ScheduleConfig[]; + }>; + disabled?: boolean; +} + +/** + * Type for decorator factories + */ +export type DecoratorFactory = (target: T, context?: any) => T | void; + +/** + * Type for method decorators + */ +export type MethodDecoratorFactory = ( + target: any, + propertyKey: string, + descriptor?: PropertyDescriptor +) => any; \ No newline at end of file diff --git a/libs/core/types/src/index.ts b/libs/core/types/src/index.ts index c90cfce..8c5c2ae 100644 --- a/libs/core/types/src/index.ts +++ b/libs/core/types/src/index.ts @@ -61,6 +61,22 @@ export type { TypedJobHandler, } from './handlers'; - -// Export service container types +// Export service container interface export type { IServiceContainer } from './service-container'; + +// Export decorator types +export type { + ScheduleConfig, + DecoratorMetadata, + DecoratorFactory, + MethodDecoratorFactory, +} from './decorators'; + +// Export queue types +export type { + JobData, + JobOptions, + QueueStats, + BatchJobData, + QueueWorkerConfig, +} from './queue'; diff --git a/libs/core/types/src/queue.ts b/libs/core/types/src/queue.ts new file mode 100644 index 0000000..bf8bfa0 --- /dev/null +++ b/libs/core/types/src/queue.ts @@ -0,0 +1,64 @@ +/** + * Queue Type Definitions + * Types specific to queue operations + */ + +/** + * Job data structure for queue operations + */ +export interface JobData { + handler: string; + operation: string; + payload: T; + priority?: number; +} + +/** + * Queue job options + */ +export interface JobOptions { + priority?: number; + delay?: number; + attempts?: number; + backoff?: { + type: 'exponential' | 'fixed'; + delay: number; + }; + removeOnComplete?: boolean | number; + removeOnFail?: boolean | number; + timeout?: number; +} + +/** + * Queue statistics + */ +export interface QueueStats { + waiting: number; + active: number; + completed: number; + failed: number; + delayed: number; + paused: boolean; + workers?: number; +} + +/** + * Batch job configuration + */ +export interface BatchJobData { + payloadKey: string; + batchIndex: number; + totalBatches: number; + items: unknown[]; +} + +/** + * Queue worker configuration + */ +export interface QueueWorkerConfig { + concurrency?: number; + maxStalledCount?: number; + stalledInterval?: number; + lockDuration?: number; + lockRenewTime?: number; +} \ No newline at end of file diff --git a/libs/core/types/src/service-container.ts b/libs/core/types/src/service-container.ts index 135ce2f..6a69bee 100644 --- a/libs/core/types/src/service-container.ts +++ b/libs/core/types/src/service-container.ts @@ -1,11 +1,13 @@ /** - * Universal Service Container for Handlers - * Simple, comprehensive container with all services available + * Service Container Interface + * Pure interface definition with no dependencies + * Used by both DI and Handlers packages */ /** - * Universal service container with all common services - * Designed to work across different service contexts (data-ingestion, processing, etc.) + * Universal service container interface + * Provides access to all common services in a type-safe manner + * Designed to work across different service contexts */ export interface IServiceContainer { // Core infrastructure diff --git a/libs/services/queue/src/index.ts b/libs/services/queue/src/index.ts index 70111e2..5504861 100644 --- a/libs/services/queue/src/index.ts +++ b/libs/services/queue/src/index.ts @@ -1,5 +1,5 @@ // Core exports -export { Queue, type QueueWorkerConfig } from './queue'; +export { Queue } from './queue'; export { QueueManager } from './queue-manager'; export { SmartQueueManager } from './smart-queue-manager'; export { ServiceCache, createServiceCache } from './service-cache'; @@ -32,7 +32,6 @@ export type { JobData, JobOptions, QueueOptions, - QueueStats, GlobalStats, // Batch processing types @@ -46,6 +45,8 @@ export type { HandlerConfig, HandlerConfigWithSchedule, HandlerInitializer, + QueueStats, + QueueWorkerConfig, // Configuration types RedisConfig, diff --git a/libs/services/queue/src/queue.ts b/libs/services/queue/src/queue.ts index 479f8bd..3fc4572 100644 --- a/libs/services/queue/src/queue.ts +++ b/libs/services/queue/src/queue.ts @@ -1,6 +1,6 @@ import { Queue as BullQueue, QueueEvents, Worker, type Job } from 'bullmq'; import { handlerRegistry } from '@stock-bot/handlers'; -import type { JobData, JobOptions, QueueStats, RedisConfig } from './types'; +import type { JobData, JobOptions, ExtendedJobOptions, QueueStats, RedisConfig } from './types'; import { getRedisConnection } from './utils'; // Logger interface for type safety @@ -116,9 +116,9 @@ export class Queue { name: string, data: JobData, cronPattern: string, - options: JobOptions = {} + options: ExtendedJobOptions = {} ): Promise { - const scheduledOptions: JobOptions = { + const scheduledOptions: ExtendedJobOptions = { ...options, repeat: { pattern: cronPattern, diff --git a/libs/services/queue/src/types.ts b/libs/services/queue/src/types.ts index 87f3e4e..780b8ff 100644 --- a/libs/services/queue/src/types.ts +++ b/libs/services/queue/src/types.ts @@ -1,17 +1,19 @@ -// Re-export handler types from shared types package +// Import types we need to extend +import type { JobOptions, QueueStats } from '@stock-bot/types'; + +// Re-export handler and queue types from shared types package export type { HandlerConfig, - HandlerConfigWithSchedule, JobHandler, ScheduledJob, TypedJobHandler + HandlerConfigWithSchedule, + JobHandler, + ScheduledJob, + TypedJobHandler, + JobData, + JobOptions, + QueueWorkerConfig, + QueueStats } from '@stock-bot/types'; -// Types for queue operations -export interface JobData { - handler: string; - operation: string; - payload: T; - priority?: number; -} - export interface ProcessOptions { totalDelayHours: number; batchSize?: number; @@ -42,16 +44,8 @@ export interface RedisConfig { db?: number; } -export interface JobOptions { - priority?: number; - delay?: number; - attempts?: number; - removeOnComplete?: number; - removeOnFail?: number; - backoff?: { - type: 'exponential' | 'fixed'; - delay: number; - }; +// Extended job options specific to this queue implementation +export interface ExtendedJobOptions extends JobOptions { repeat?: { pattern?: string; key?: string; @@ -62,7 +56,7 @@ export interface JobOptions { } export interface QueueOptions { - defaultJobOptions?: JobOptions; + defaultJobOptions?: ExtendedJobOptions; workers?: number; concurrency?: number; enableMetrics?: boolean; @@ -80,16 +74,7 @@ export interface QueueManagerConfig { delayWorkerStart?: boolean; // If true, workers won't start automatically } -export interface QueueStats { - waiting: number; - active: number; - completed: number; - failed: number; - delayed: number; - paused: boolean; - workers?: number; -} - +// Queue-specific stats that extend the base types export interface GlobalStats { queues: Record; totalJobs: number; @@ -108,6 +93,7 @@ export interface QueueConfig extends QueueManagerConfig { } +// Extended batch job data for queue implementation export interface BatchJobData { payloadKey: string; batchIndex: number; @@ -156,7 +142,7 @@ export interface ScheduleConfig { pattern: string; jobName: string; data?: unknown; - options?: JobOptions; + options?: ExtendedJobOptions; } // Smart Queue Types