removed doodoo projects, getting ready for restructuring

This commit is contained in:
Bojan Kucera 2025-06-04 14:48:03 -04:00
parent 674112af05
commit 5c64b1ccf8
82 changed files with 5 additions and 8917 deletions

2582
bun.lock

File diff suppressed because it is too large Load diff

View file

@ -157,7 +157,6 @@ Market Data Gateway
├── ✅ Hono (Web framework)
├── ✅ ioredis (Redis client)
├── ✅ @stock-bot/config (Workspace package)
├── ✅ @stock-bot/types (Workspace package)
└── ✅ ws (WebSocket library)
Trading Dashboard

View file

@ -6,7 +6,7 @@ This guide describes how the project architecture has been improved to better se
We've reorganized the project's shared libraries for improved maintainability:
### 1. Shared Types (`@stock-bot/types`)
### 1. Shared Types
Types are now organized by domain:

View file

@ -1,68 +0,0 @@
# API Client Library
Type-safe HTTP clients for inter-service communication in the stock-bot project.
## Available Clients
### BacktestClient
Client for interacting with the Backtest Engine service:
```typescript
import { createBacktestClient } from '@stock-bot/api-client';
// Create a client instance
const backtestClient = createBacktestClient('http://localhost:4002');
// Run a backtest
const result = await backtestClient.runBacktest({
strategyId: '123',
startDate: new Date('2023-01-01'),
endDate: new Date('2023-12-31'),
symbols: ['AAPL', 'MSFT', 'GOOG'],
initialCapital: 100000,
parameters: {
riskFactor: 0.5,
positionSizeLimit: 0.1
}
});
```
### StrategyClient
Client for interacting with the Strategy Orchestrator service:
```typescript
import { createStrategyClient } from '@stock-bot/api-client';
// Create a client instance
const strategyClient = createStrategyClient('http://localhost:4001');
// Get a strategy by ID
const strategy = await strategyClient.getStrategy('123');
// Update a strategy
await strategyClient.updateStrategy('123', {
parameters: {
lookbackPeriod: 20,
threshold: 0.02
}
});
// Enable a strategy
await strategyClient.enableStrategy('123');
```
## Creating Custom Clients
Extend the `BaseApiClient` to create clients for other services:
```typescript
import { BaseApiClient } from '@stock-bot/api-client';
class RiskGuardianClient extends BaseApiClient {
async getRiskLimits(portfolioId: string) {
return this.client.get(`/api/risk/limits/${portfolioId}`);
}
}
```

View file

@ -1,22 +0,0 @@
{
"name": "@stock-bot/api-client",
"version": "1.0.0",
"description": "API clients for inter-service communication",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"clean": "rm -rf dist",
"test": "jest"
},
"dependencies": {
"@stock-bot/types": "*",
"axios": "^1.6.0"
},
"devDependencies": {
"@types/jest": "^29.5.2",
"jest": "^29.5.0",
"typescript": "^5.4.5"
}
}

View file

@ -1,30 +0,0 @@
import { BaseApiClient } from './BaseApiClient';
import { ApiResponse, BacktestConfig, BacktestResult } from '@stock-bot/types';
/**
* Client for interacting with the Backtest Engine service
*/
export class BacktestClient extends BaseApiClient {
/**
* Run a backtest
*/
async runBacktest(config: BacktestConfig): Promise<ApiResponse<BacktestResult>> {
return this.client.post('/api/backtest/run', config);
}
/**
* Get a backtest by ID
*/
async getBacktest(id: string): Promise<ApiResponse<BacktestResult>> {
return this.client.get(`/api/backtest/${id}`);
}
/**
* List all backtests for a strategy
*/
async listBacktests(strategyId: string): Promise<ApiResponse<BacktestResult[]>> {
return this.client.get(`/api/backtest`, {
params: { strategyId }
});
}
}

View file

@ -1,39 +0,0 @@
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
import { ApiResponse } from '@stock-bot/types';
/**
* Base API client that all service clients extend
*/
export abstract class BaseApiClient {
protected client: AxiosInstance;
constructor(baseURL: string, config?: AxiosRequestConfig) {
this.client = axios.create({
baseURL,
timeout: 10000, // 10 seconds timeout
...config
});
// Add response interceptor for consistent error handling
this.client.interceptors.response.use(
(response) => response.data,
(error) => {
// Format error for consistent error handling
const formattedError = {
status: error.response?.status || 500,
message: error.response?.data?.error || error.message || 'Unknown error',
originalError: error
};
return Promise.reject(formattedError);
}
);
}
/**
* Get the health status of a service
*/
async getHealth(): Promise<ApiResponse<{ status: string }>> {
return this.client.get('/api/health');
}
}

View file

@ -1,56 +0,0 @@
import { BaseApiClient } from './BaseApiClient';
import { ApiResponse, Strategy } from '@stock-bot/types';
/**
* Client for interacting with the Strategy Orchestrator service
*/
export class StrategyClient extends BaseApiClient {
/**
* Get a strategy by ID
*/
async getStrategy(id: string): Promise<ApiResponse<Strategy>> {
return this.client.get(`/api/strategy/${id}`);
}
/**
* List all strategies
*/
async listStrategies(): Promise<ApiResponse<Strategy[]>> {
return this.client.get('/api/strategy');
}
/**
* Create a new strategy
*/
async createStrategy(strategy: Omit<Strategy, 'id'>): Promise<ApiResponse<Strategy>> {
return this.client.post('/api/strategy', strategy);
}
/**
* Update a strategy
*/
async updateStrategy(id: string, strategy: Partial<Strategy>): Promise<ApiResponse<Strategy>> {
return this.client.put(`/api/strategy/${id}`, strategy);
}
/**
* Delete a strategy
*/
async deleteStrategy(id: string): Promise<ApiResponse<void>> {
return this.client.delete(`/api/strategy/${id}`);
}
/**
* Enable a strategy
*/
async enableStrategy(id: string): Promise<ApiResponse<Strategy>> {
return this.client.post(`/api/strategy/${id}/enable`);
}
/**
* Disable a strategy
*/
async disableStrategy(id: string): Promise<ApiResponse<Strategy>> {
return this.client.post(`/api/strategy/${id}/disable`);
}
}

View file

@ -1,14 +0,0 @@
import { BaseApiClient } from './BaseApiClient';
import { BacktestClient } from './BacktestClient';
import { StrategyClient } from './StrategyClient';
export { BaseApiClient, BacktestClient, StrategyClient };
// Factory functions
export function createBacktestClient(baseUrl: string = 'http://localhost:4002'): BacktestClient {
return new BacktestClient(baseUrl);
}
export function createStrategyClient(baseUrl: string = 'http://localhost:4001'): StrategyClient {
return new StrategyClient(baseUrl);
}

View file

@ -1,17 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
"references": [
{ "path": "../config" },
{ "path": "../event-bus" },
{ "path": "../http-client" },
{ "path": "../types" },
{ "path": "../utils" },
]
}

View file

@ -10,7 +10,6 @@
{ "path": "../api-client" },
{ "path": "../event-bus" },
{ "path": "../http-client" },
{ "path": "../types" },
{ "path": "../utils" },
{ "path": "../utils" }
]
}

View file

@ -1,42 +0,0 @@
# Event Bus Library
A Redis-based event bus implementation for inter-service communication in the stock-bot project.
## Features
- Publish/subscribe pattern for asynchronous messaging
- Support for typed events based on `@stock-bot/types`
- Reliable message delivery
- Channel-based subscriptions
## Usage
```typescript
import { createEventBus } from '@stock-bot/event-bus';
import { MarketDataEvent } from '@stock-bot/types';
// Create an event bus instance
const eventBus = createEventBus({
redisHost: 'localhost',
redisPort: 6379
});
// Subscribe to market data events
eventBus.subscribe('market.data', async (event: MarketDataEvent) => {
console.log(`Received price update for ${event.data.symbol}: ${event.data.price}`);
});
// Publish an event
await eventBus.publish('market.data', {
type: 'MARKET_DATA',
data: {
symbol: 'AAPL',
price: 150.25,
bid: 150.20,
ask: 150.30,
volume: 1000000,
timestamp: new Date()
},
timestamp: new Date()
});
```

View file

@ -1,22 +0,0 @@
{
"name": "@stock-bot/event-bus",
"version": "1.0.0",
"description": "Event bus implementation for inter-service communication",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"clean": "rm -rf dist",
"test": "jest"
},
"dependencies": {
"@stock-bot/types": "*",
"ioredis": "^5.3.2"
},
"devDependencies": {
"@types/jest": "^29.5.2",
"jest": "^29.5.0",
"typescript": "^5.4.5"
}
}

View file

@ -1,131 +0,0 @@
import Redis from 'ioredis';
import { Event } from '@stock-bot/types';
export type EventHandler<T extends Event = Event> = (event: T) => Promise<void> | void;
export interface EventBusConfig {
redisHost: string;
redisPort: number;
redisPassword?: string;
}
/**
* Event Bus for publishing and subscribing to events in the system
* Provides reliable message delivery and pattern-based subscriptions
*/
export class EventBus {
private publisher: Redis;
private subscriber: Redis;
private handlers: Map<string, EventHandler[]>;
private isConnected: boolean = false;
constructor(private config: EventBusConfig) {
this.publisher = new Redis({
host: config.redisHost,
port: config.redisPort,
password: config.redisPassword,
});
this.subscriber = new Redis({
host: config.redisHost,
port: config.redisPort,
password: config.redisPassword,
});
this.handlers = new Map<string, EventHandler[]>();
this.setupConnectionHandlers();
}
/**
* Set up Redis connection event handlers
*/
private setupConnectionHandlers(): void {
this.publisher.on('connect', () => {
console.log('Publisher connected to Redis');
this.isConnected = true;
});
this.publisher.on('error', (err) => {
console.error('Publisher Redis error', err);
this.isConnected = false;
});
this.subscriber.on('connect', () => {
console.log('Subscriber connected to Redis');
});
this.subscriber.on('error', (err) => {
console.error('Subscriber Redis error', err);
});
this.subscriber.on('message', (channel, message) => {
try {
const event = JSON.parse(message) as Event;
this.processEvent(channel, event);
} catch (err) {
console.error('Error processing event', err);
}
});
}
/**
* Process an incoming event by calling all registered handlers
*/
private processEvent(channel: string, event: Event): void {
const handlers = this.handlers.get(channel) || [];
handlers.forEach(handler => {
try {
handler(event);
} catch (err) {
console.error(`Error in event handler for ${channel}:`, err);
}
});
}
/**
* Publish an event to the specified channel
*/
public async publish(channel: string, event: Event): Promise<void> {
if (!this.isConnected) {
throw new Error('Not connected to Redis');
}
await this.publisher.publish(channel, JSON.stringify(event));
}
/**
* Subscribe to events on a specific channel
*/
public subscribe(channel: string, handler: EventHandler): () => void {
if (!this.handlers.has(channel)) {
this.handlers.set(channel, []);
this.subscriber.subscribe(channel);
}
const handlers = this.handlers.get(channel)!;
handlers.push(handler);
// Return unsubscribe function
return () => {
const index = handlers.indexOf(handler);
if (index >= 0) {
handlers.splice(index, 1);
}
if (handlers.length === 0) {
this.handlers.delete(channel);
this.subscriber.unsubscribe(channel);
}
};
}
/**
* Close connections
*/
public async close(): Promise<void> {
await this.publisher.quit();
await this.subscriber.quit();
this.isConnected = false;
}
}

View file

@ -1,8 +0,0 @@
import { EventBus, EventBusConfig, EventHandler } from './EventBus';
export { EventBus, EventBusConfig, EventHandler };
// Convenience function to create an event bus with the default configuration
export function createEventBus(config: EventBusConfig): EventBus {
return new EventBus(config);
}

View file

@ -1,19 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": false,
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"],
"references": [
{ "path": "../api-client" },
{ "path": "../config" },
{ "path": "../http-client" },
{ "path": "../types" },
{ "path": "../utils" },
]
}

View file

@ -1,187 +0,0 @@
# @stock-bot/http-client
High-performance HTTP client for Stock Bot microservices built on Bun's native fetch API.
## Features
- **Ultra-fast performance** - Built on Bun's native fetch implementation
- **Connection pooling** - Efficiently manages connections to prevent overwhelming servers
- **Automatic retries** - Handles transient network errors with configurable retry strategies
- **Timeout management** - Prevents requests from hanging indefinitely
- **Streaming support** - Efficient handling of large responses
- **TypeScript support** - Full type safety for all operations
- **Metrics & monitoring** - Built-in performance statistics
## Installation
```bash
bun add @stock-bot/http-client
```
## Basic Usage
```typescript
import { BunHttpClient } from '@stock-bot/http-client';
// Create a client
const client = new BunHttpClient({
baseURL: 'https://api.example.com',
timeout: 5000,
retries: 3
});
// Make requests
async function fetchData() {
try {
// GET request
const response = await client.get('/users');
console.log(response.data);
// POST request with data
const createResponse = await client.post('/users', {
name: 'John Doe',
email: 'john@example.com'
});
console.log(createResponse.data);
} catch (error) {
console.error('Request failed:', error.message);
}
}
// Close when done
await client.close();
```
## Advanced Configuration
```typescript
const client = new BunHttpClient({
baseURL: 'https://api.example.com',
timeout: 10000,
retries: 3,
retryDelay: 1000,
maxConcurrency: 20,
keepAlive: true,
headers: {
'User-Agent': 'StockBot/1.0',
'Authorization': 'Bearer token'
},
validateStatus: (status) => status >= 200 && status < 300
});
```
## Connection Pooling
The HTTP client automatically manages connection pooling with smart limits:
```typescript
// Get connection statistics
const stats = client.getStats();
console.log(`Active connections: ${stats.activeConnections}`);
console.log(`Success rate: ${stats.successfulRequests / (stats.successfulRequests + stats.failedRequests)}`);
console.log(`Average response time: ${stats.averageResponseTime}ms`);
// Health check
const health = await client.healthCheck();
if (health.healthy) {
console.log('HTTP client is healthy');
} else {
console.log('HTTP client is degraded:', health.details);
}
```
## Event Handling
```typescript
// Listen for specific events
client.on('response', ({ host, response }) => {
console.log(`Response from ${host}: ${response.status}`);
});
client.on('error', ({ host, error }) => {
console.log(`Error from ${host}: ${error.message}`);
});
client.on('retryAttempt', (data) => {
console.log(`Retrying request (${data.attempt}/${data.config.retries}): ${data.error.message}`);
});
```
## API Reference
### BunHttpClient
Main HTTP client class with connection pooling and retry support.
#### Methods
- `request(config)`: Make a request with full configuration options
- `get(url, config?)`: Make a GET request
- `post(url, data?, config?)`: Make a POST request with data
- `put(url, data?, config?)`: Make a PUT request with data
- `patch(url, data?, config?)`: Make a PATCH request with data
- `delete(url, config?)`: Make a DELETE request
- `head(url, config?)`: Make a HEAD request
- `options(url, config?)`: Make an OPTIONS request
- `getStats()`: Get connection statistics
- `healthCheck()`: Check health of the client
- `close()`: Close all connections
- `setBaseURL(url)`: Update the base URL
- `setDefaultHeaders(headers)`: Update default headers
- `setTimeout(timeout)`: Update default timeout
- `create(config)`: Create a new instance with different config
### Request Configuration
```typescript
interface RequestConfig {
url: string;
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
headers?: Record<string, string>;
body?: any;
timeout?: number;
retries?: number;
validateStatus?: (status: number) => boolean;
metadata?: Record<string, any>;
}
```
### Response Object
```typescript
interface HttpResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
config: RequestConfig;
timing: {
start: number;
end: number;
duration: number;
};
}
```
## Error Handling
```typescript
try {
const response = await client.get('/resource-that-might-fail');
processData(response.data);
} catch (error) {
if (error instanceof TimeoutError) {
console.log('Request timed out');
} else if (error instanceof RetryExhaustedError) {
console.log(`Request failed after ${error.config.retries} retries`);
} else if (error instanceof HttpClientError) {
console.log(`HTTP error: ${error.status} - ${error.message}`);
} else {
console.log('Unexpected error', error);
}
}
```
## License
MIT

View file

@ -1,11 +0,0 @@
# HTTP Client Library Bun Test Configuration
[test]
# Test configuration
timeout = 5000
# Enable TypeScript paths resolution
[bun]
paths = {
"@/*" = ["./src/*"]
}

View file

@ -1,91 +0,0 @@
// Example usage of the @stock-bot/http-client library
import { BunHttpClient } from '../src';
async function main() {
// Create a client instance
const client = new BunHttpClient({
baseURL: 'https://api.polygon.io',
timeout: 10000,
retries: 2,
retryDelay: 500,
headers: {
'X-API-Key': process.env.POLYGON_API_KEY || 'demo'
}
});
// Add event listeners for monitoring
client.on('response', ({host, response}) => {
console.log(`📦 Response from ${host}: ${response.status} (${response.timing.duration.toFixed(2)}ms)`);
});
client.on('error', ({host, error}) => {
console.error(`❌ Error from ${host}: ${error.message}`);
});
client.on('retryAttempt', ({attempt, config, delay}) => {
console.warn(`⚠️ Retry ${attempt}/${config.retries} for ${config.url} in ${delay}ms`);
});
try {
console.log('Fetching market data...');
// Make a GET request
const tickerResponse = await client.get('/v3/reference/tickers', {
headers: {
'Accept': 'application/json'
}
});
console.log(`Found ${tickerResponse.data.results.length} tickers`);
console.log(`First ticker: ${JSON.stringify(tickerResponse.data.results[0], null, 2)}`);
// Make a request that will fail
try {
await client.get('/non-existent-endpoint');
} catch (error) {
console.log('Expected error caught:', error.message);
}
// Multiple parallel requests
console.log('Making parallel requests...');
const [aaplData, msftData, amznData] = await Promise.all([
client.get('/v2/aggs/ticker/AAPL/range/1/day/2023-01-01/2023-01-15'),
client.get('/v2/aggs/ticker/MSFT/range/1/day/2023-01-01/2023-01-15'),
client.get('/v2/aggs/ticker/AMZN/range/1/day/2023-01-01/2023-01-15')
]);
console.log('Parallel requests completed:');
console.log(`- AAPL: ${aaplData.status}, data points: ${aaplData.data.results?.length || 0}`);
console.log(`- MSFT: ${msftData.status}, data points: ${msftData.data.results?.length || 0}`);
console.log(`- AMZN: ${amznData.status}, data points: ${amznData.data.results?.length || 0}`);
// Get client statistics
const stats = client.getStats();
console.log('\nClient Stats:');
console.log(`- Active connections: ${stats.activeConnections}`);
console.log(`- Total connections: ${stats.totalConnections}`);
console.log(`- Successful requests: ${stats.successfulRequests}`);
console.log(`- Failed requests: ${stats.failedRequests}`);
console.log(`- Average response time: ${stats.averageResponseTime.toFixed(2)}ms`);
console.log(`- Requests per second: ${stats.requestsPerSecond.toFixed(2)}`);
// Health check
const health = await client.healthCheck();
console.log(`\nClient health: ${health.healthy ? 'HEALTHY' : 'DEGRADED'}`);
console.log(`Health details: ${JSON.stringify(health.details, null, 2)}`);
} catch (error) {
console.error('Error in example:', error);
} finally {
// Always close the client when done to clean up resources
await client.close();
console.log('HTTP client closed');
}
}
// Run the example
main().catch(err => {
console.error('Example failed:', err);
process.exit(1);
});

View file

@ -1,34 +0,0 @@
{
"name": "@stock-bot/http-client",
"version": "1.0.0",
"description": "High-performance HTTP client for Stock Bot using Bun's native fetch",
"main": "src/index.ts",
"type": "module",
"scripts": {
"build": "tsc",
"test": "bun test",
"lint": "eslint src/**/*.ts",
"type-check": "tsc --noEmit"
},
"dependencies": {
"eventemitter3": "^5.0.1"
},
"devDependencies": {
"@types/node": "^20.11.0",
"typescript": "^5.3.0",
"eslint": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^6.19.0",
"@typescript-eslint/parser": "^6.19.0",
"bun-types": "^1.2.15"
},
"keywords": [
"http-client",
"fetch",
"bun",
"performance",
"connection-pooling"
],
"exports": {
".": "./src/index.ts"
}
}

View file

@ -1,182 +0,0 @@
import { describe, test, expect, mock, beforeEach, afterEach } from "bun:test";
import { BunHttpClient, HttpClientError, TimeoutError } from "../src";
// Mock GlobalFetch to avoid making real network requests
const mockFetchSuccess = mock(() =>
Promise.resolve(new Response(
JSON.stringify({ result: "success" }),
{ status: 200, headers: { "content-type": "application/json" } }
))
);
const mockFetchFailure = mock(() =>
Promise.resolve(new Response(
JSON.stringify({ error: "Not found" }),
{ status: 404, headers: { "content-type": "application/json" } }
))
);
const mockFetchTimeout = mock(() => {
return new Promise((_, reject) => {
setTimeout(() => {
const error = new Error("Timeout");
error.name = "AbortError";
reject(error);
}, 10);
});
});
describe("BunHttpClient", () => {
let client: BunHttpClient;
const originalFetch = global.fetch;
beforeEach(() => {
// Create a fresh client for each test
client = new BunHttpClient({
baseURL: "https://api.example.com",
timeout: 1000,
retries: 1
});
});
afterEach(async () => {
// Cleanup after each test
await client.close();
global.fetch = originalFetch;
});
test("should make successful GET requests", async () => {
global.fetch = mockFetchSuccess;
const response = await client.get("/users");
expect(response.status).toBe(200);
expect(response.data).toEqual({ result: "success" });
expect(mockFetchSuccess).toHaveBeenCalledTimes(1);
});
test("should handle failed requests", async () => {
global.fetch = mockFetchFailure;
try {
await client.get("/missing");
expect("Should have thrown").toBe("But didn't");
} catch (error) {
expect(error).toBeInstanceOf(HttpClientError);
expect(error.status).toBe(404);
}
expect(mockFetchFailure).toHaveBeenCalledTimes(1);
});
test("should handle request timeouts", async () => {
global.fetch = mockFetchTimeout;
try {
await client.get("/slow");
expect("Should have thrown").toBe("But didn't");
} catch (error) {
expect(error).toBeInstanceOf(TimeoutError);
}
});
test("should build full URLs properly", async () => {
global.fetch = mockFetchSuccess;
await client.get("/users/123");
expect(mockFetchSuccess).toHaveBeenCalledWith(
"https://api.example.com/users/123",
expect.objectContaining({
method: "GET"
})
);
});
test("should make POST requests with body", async () => {
global.fetch = mockFetchSuccess;
const data = { name: "John", email: "john@example.com" };
await client.post("/users", data);
expect(mockFetchSuccess).toHaveBeenCalledWith(
"https://api.example.com/users",
expect.objectContaining({
method: "POST",
body: JSON.stringify(data)
})
);
});
test("should provide convenience methods for all HTTP verbs", async () => {
global.fetch = mockFetchSuccess;
await client.get("/users");
await client.post("/users", { name: "Test" });
await client.put("/users/1", { name: "Updated" });
await client.patch("/users/1", { status: "active" });
await client.delete("/users/1");
await client.head("/users");
await client.options("/users");
expect(mockFetchSuccess).toHaveBeenCalledTimes(7);
});
test("should merge config options correctly", async () => {
global.fetch = mockFetchSuccess;
await client.get("/users", {
headers: { "X-Custom": "Value" },
timeout: 5000
});
expect(mockFetchSuccess).toHaveBeenCalledWith(
"https://api.example.com/users",
expect.objectContaining({
headers: expect.objectContaining({
"X-Custom": "Value"
})
})
);
});
test("should handle absolute URLs", async () => {
global.fetch = mockFetchSuccess;
await client.get("https://other-api.com/endpoint");
expect(mockFetchSuccess).toHaveBeenCalledWith(
"https://other-api.com/endpoint",
expect.anything()
);
});
test("should update configuration", async () => {
global.fetch = mockFetchSuccess;
client.setBaseURL("https://new-api.com");
client.setDefaultHeaders({ "Authorization": "Bearer token" });
client.setTimeout(2000);
await client.get("/resource");
expect(mockFetchSuccess).toHaveBeenCalledWith(
"https://new-api.com/resource",
expect.objectContaining({
headers: expect.objectContaining({
"Authorization": "Bearer token"
})
})
);
});
test("should get connection stats", async () => {
global.fetch = mockFetchSuccess;
await client.get("/users");
const stats = client.getStats();
expect(stats).toHaveProperty("successfulRequests", 1);
expect(stats).toHaveProperty("activeConnections");
expect(stats).toHaveProperty("averageResponseTime");
});
});

View file

@ -1,199 +0,0 @@
import { EventEmitter } from 'eventemitter3';
import {
HttpClientConfig,
RequestConfig,
HttpResponse,
ConnectionStats,
HttpClientError,
TimeoutError
} from './types';
import { ConnectionPool } from './ConnectionPool';
import { RetryHandler } from './RetryHandler';
export class BunHttpClient extends EventEmitter {
private connectionPool: ConnectionPool;
private retryHandler: RetryHandler;
private defaultConfig: Required<HttpClientConfig>;
constructor(config: HttpClientConfig = {}) {
super();
this.defaultConfig = {
baseURL: '',
timeout: 30000,
headers: {},
retries: 3,
retryDelay: 1000,
maxConcurrency: 10,
keepAlive: true,
validateStatus: (status: number) => status < 400,
...config
};
this.connectionPool = new ConnectionPool({
maxConnections: this.defaultConfig.maxConcurrency,
maxConnectionsPerHost: Math.ceil(this.defaultConfig.maxConcurrency / 4),
keepAlive: this.defaultConfig.keepAlive,
maxIdleTime: 60000,
connectionTimeout: this.defaultConfig.timeout
});
this.retryHandler = new RetryHandler({
maxRetries: this.defaultConfig.retries,
baseDelay: this.defaultConfig.retryDelay,
maxDelay: 30000,
exponentialBackoff: true
});
// Forward events from connection pool and retry handler
this.connectionPool.on('response', (data) => this.emit('response', data));
this.connectionPool.on('error', (data) => this.emit('error', data));
this.retryHandler.on('retryAttempt', (data) => this.emit('retryAttempt', data));
this.retryHandler.on('retrySuccess', (data) => this.emit('retrySuccess', data));
this.retryHandler.on('retryExhausted', (data) => this.emit('retryExhausted', data));
}
async request<T = any>(config: RequestConfig): Promise<HttpResponse<T>> {
const fullConfig = this.mergeConfig(config);
return this.retryHandler.execute(async () => {
const startTime = performance.now();
try {
// Add timing metadata
fullConfig.metadata = {
...fullConfig.metadata,
startTime
};
const response = await this.connectionPool.request(fullConfig);
return response as HttpResponse<T>;
} catch (error: any) {
// Convert fetch errors to our error types
if (error.name === 'AbortError') {
throw new TimeoutError(fullConfig, fullConfig.timeout || this.defaultConfig.timeout);
}
// Re-throw as HttpClientError if not already
if (!(error instanceof HttpClientError)) {
const httpError = new HttpClientError(
error.message || 'Request failed',
error.code,
error.status,
error.response,
fullConfig
);
throw httpError;
}
throw error;
}
}, fullConfig);
}
// Convenience methods
async get<T = any>(url: string, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'GET' });
}
async post<T = any>(url: string, data?: any, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'POST', body: data });
}
async put<T = any>(url: string, data?: any, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'PUT', body: data });
}
async patch<T = any>(url: string, data?: any, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'PATCH', body: data });
}
async delete<T = any>(url: string, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'DELETE' });
}
async head<T = any>(url: string, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'HEAD' });
}
async options<T = any>(url: string, config?: Partial<RequestConfig>): Promise<HttpResponse<T>> {
return this.request<T>({ ...config, url, method: 'OPTIONS' });
}
private mergeConfig(config: RequestConfig): RequestConfig {
return {
...config,
timeout: this.defaultConfig.timeout,
retries: this.defaultConfig.retries,
headers: { ...this.defaultConfig.headers, ...config.headers },
validateStatus: this.defaultConfig.validateStatus,
url: this.buildUrl(config.url),
};
}
private buildUrl(url: string): string {
if (url.startsWith('http://') || url.startsWith('https://')) {
return url;
}
if (this.defaultConfig.baseURL) {
const baseURL = this.defaultConfig.baseURL.replace(/\/$/, '');
const path = url.replace(/^\//, '');
return `${baseURL}/${path}`;
}
return url;
}
// Configuration methods
setBaseURL(baseURL: string): void {
this.defaultConfig.baseURL = baseURL;
}
setDefaultHeaders(headers: Record<string, string>): void {
this.defaultConfig.headers = { ...this.defaultConfig.headers, ...headers };
}
setTimeout(timeout: number): void {
this.defaultConfig.timeout = timeout;
}
setMaxConcurrency(maxConcurrency: number): void {
this.defaultConfig.maxConcurrency = maxConcurrency;
}
// Statistics and monitoring
getStats(): ConnectionStats {
return this.connectionPool.getStats();
}
async healthCheck(): Promise<{ healthy: boolean; details: any }> {
return this.connectionPool.healthCheck();
}
// Lifecycle management
async close(): Promise<void> {
await this.connectionPool.close();
this.removeAllListeners();
}
// Create a new instance with different configuration
create(config: HttpClientConfig): BunHttpClient {
const mergedConfig = { ...this.defaultConfig, ...config };
return new BunHttpClient(mergedConfig);
}
// Interceptor-like functionality through events
onRequest(handler: (config: RequestConfig) => RequestConfig | Promise<RequestConfig>): void {
this.on('beforeRequest', handler);
}
onResponse(handler: (response: HttpResponse) => HttpResponse | Promise<HttpResponse>): void {
this.on('afterResponse', handler);
}
onError(handler: (error: any) => void): void {
this.on('requestError', handler);
}
}

View file

@ -1,331 +0,0 @@
import { EventEmitter } from 'eventemitter3';
import type {
ConnectionPoolConfig,
ConnectionStats,
QueuedRequest,
RequestConfig
} from './types';
export class ConnectionPool extends EventEmitter {
private activeConnections = new Map<string, number>();
private requestQueue: QueuedRequest[] = [];
private stats = {
totalConnections: 0,
activeRequests: 0,
successfulRequests: 0,
failedRequests: 0,
totalResponseTime: 0,
requestCount: 0,
startTime: Date.now()
};
private isProcessingQueue = false;
private queueProcessor?: NodeJS.Timeout;
constructor(private config: ConnectionPoolConfig) {
super();
this.startQueueProcessor();
}
async request(requestConfig: RequestConfig): Promise<any> {
return new Promise((resolve, reject) => {
const host = this.extractHost(requestConfig.url);
const queuedRequest: QueuedRequest = {
id: this.generateRequestId(),
config: requestConfig,
resolve,
reject,
timestamp: Date.now(),
retryCount: 0,
host
};
this.requestQueue.push(queuedRequest);
this.processQueue();
});
}
private async processQueue(): Promise<void> {
if (this.isProcessingQueue || this.requestQueue.length === 0) {
return;
}
this.isProcessingQueue = true;
while (this.requestQueue.length > 0) {
const request = this.requestQueue.shift()!;
try {
const currentConnections = this.activeConnections.get(request.host) || 0;
// Check per-host connection limits
if (currentConnections >= this.config.maxConnectionsPerHost) {
this.requestQueue.unshift(request);
break;
}
// Check global connection limit
const totalActive = Array.from(this.activeConnections.values())
.reduce((sum, count) => sum + count, 0);
if (totalActive >= this.config.maxConnections) {
this.requestQueue.unshift(request);
break;
}
// Execute the request
this.executeRequest(request);
} catch (error) {
request.reject(error);
}
}
this.isProcessingQueue = false;
}
private async executeRequest(request: QueuedRequest): Promise<void> {
const { host, config } = request;
// Increment active connections
this.activeConnections.set(host, (this.activeConnections.get(host) || 0) + 1);
this.stats.activeRequests++;
const startTime = performance.now();
try {
// Build the full URL
const url = this.buildUrl(config.url, config);
// Create abort controller for timeout
const controller = new AbortController();
const timeoutId = config.timeout ? setTimeout(() => {
controller.abort();
}, config.timeout) : undefined;
// Make the fetch request
const response = await fetch(url, {
method: config.method || 'GET',
headers: this.buildHeaders(config.headers),
body: this.buildBody(config.body),
signal: controller.signal,
// Bun-specific optimizations
keepalive: this.config.keepAlive,
});
if (timeoutId) {
clearTimeout(timeoutId);
}
// Check if response is considered successful
const isSuccess = config.validateStatus
? config.validateStatus(response.status)
: response.status < 400;
if (!isSuccess) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
// Parse response data
const data = await this.parseResponse(response);
const endTime = performance.now();
const duration = endTime - startTime;
// Update stats
this.updateStats(true, duration);
// Build response object
const httpResponse = {
data,
status: response.status,
statusText: response.statusText,
headers: this.parseHeaders(response.headers),
config,
timing: {
start: startTime,
end: endTime,
duration
}
};
this.emit('response', { host, response: httpResponse });
request.resolve(httpResponse);
} catch (error: any) {
const endTime = performance.now();
const duration = endTime - startTime;
this.updateStats(false, duration);
this.emit('error', { host, error, config });
request.reject(error);
} finally {
// Decrement active connections
this.activeConnections.set(host, Math.max(0, (this.activeConnections.get(host) || 0) - 1));
this.stats.activeRequests = Math.max(0, this.stats.activeRequests - 1);
}
}
private buildUrl(url: string, config: RequestConfig): string {
// If URL is already absolute, return as-is
if (url.startsWith('http://') || url.startsWith('https://')) {
return url;
}
// If no base URL in config, assume it's a relative URL that needs a protocol
if (!url.startsWith('/')) {
url = '/' + url;
}
return url;
}
private buildHeaders(headers?: Record<string, string>): HeadersInit {
return {
'User-Agent': 'StockBot-HttpClient/1.0',
'Accept': 'application/json',
'Content-Type': 'application/json',
...headers
};
}
private buildBody(body: any): BodyInit | undefined {
if (!body) return undefined;
if (typeof body === 'string') return body;
if (body instanceof FormData || body instanceof Blob) return body;
if (body instanceof ArrayBuffer || body instanceof Uint8Array) return body;
return JSON.stringify(body);
}
private async parseResponse(response: Response): Promise<any> {
const contentType = response.headers.get('content-type') || '';
if (contentType.includes('application/json')) {
return await response.json();
}
if (contentType.includes('text/')) {
return await response.text();
}
return await response.arrayBuffer();
}
private parseHeaders(headers: Headers): Record<string, string> {
const result: Record<string, string> = {};
headers.forEach((value, key) => {
result[key] = value;
});
return result;
}
private extractHost(url: string): string {
try {
if (url.startsWith('http://') || url.startsWith('https://')) {
const urlObj = new URL(url);
return urlObj.host;
}
return 'default';
} catch {
return 'default';
}
}
private generateRequestId(): string {
return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private updateStats(success: boolean, responseTime: number): void {
this.stats.requestCount++;
this.stats.totalResponseTime += responseTime;
if (success) {
this.stats.successfulRequests++;
} else {
this.stats.failedRequests++;
}
}
private startQueueProcessor(): void {
this.queueProcessor = setInterval(() => {
if (this.requestQueue.length > 0) {
this.processQueue();
}
}, 10); // Process queue every 10ms for better responsiveness
}
getStats(): ConnectionStats {
const totalActive = Array.from(this.activeConnections.values())
.reduce((sum, count) => sum + count, 0);
const averageResponseTime = this.stats.requestCount > 0
? this.stats.totalResponseTime / this.stats.requestCount
: 0;
const utilization = this.config.maxConnections > 0
? totalActive / this.config.maxConnections
: 0;
const elapsedTimeSeconds = (Date.now() - this.stats.startTime) / 1000;
const requestsPerSecond = elapsedTimeSeconds > 0
? this.stats.requestCount / elapsedTimeSeconds
: 0;
return {
activeConnections: totalActive,
totalConnections: this.stats.totalConnections,
successfulRequests: this.stats.successfulRequests,
failedRequests: this.stats.failedRequests,
averageResponseTime,
connectionPoolUtilization: utilization,
requestsPerSecond
};
}
async close(): Promise<void> {
// Stop queue processor
if (this.queueProcessor) {
clearInterval(this.queueProcessor);
this.queueProcessor = undefined;
}
// Wait for pending requests to complete (with timeout)
const timeout = 30000; // 30 seconds
const startTime = Date.now();
while (this.requestQueue.length > 0 && Date.now() - startTime < timeout) {
await new Promise(resolve => setTimeout(resolve, 100));
}
// Reject remaining requests
while (this.requestQueue.length > 0) {
const request = this.requestQueue.shift()!;
request.reject(new Error('Connection pool closing'));
}
// Clear connections
this.activeConnections.clear();
this.removeAllListeners();
this.emit('closed');
}
async healthCheck(): Promise<{ healthy: boolean; details: any }> {
const stats = this.getStats();
const queueSize = this.requestQueue.length;
const healthy =
stats.connectionPoolUtilization < 0.9 && // Less than 90% utilization
queueSize < 100 && // Queue not too large
stats.averageResponseTime < 5000; // Average response time under 5 seconds
return {
healthy,
details: {
stats,
queueSize,
activeHosts: Array.from(this.activeConnections.keys()),
config: this.config
},
};
}
}

View file

@ -1,130 +0,0 @@
import { EventEmitter } from 'eventemitter3';
import {
RetryConfig,
RequestConfig,
HttpResponse,
RetryExhaustedError
} from './types';
import { TimeoutError } from './types';
export class RetryHandler extends EventEmitter {
private config: Required<RetryConfig>;
constructor(config: Partial<RetryConfig> = {}) {
super();
this.config = {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 30000,
exponentialBackoff: true,
retryCondition: this.defaultRetryCondition,
...config
};
}
async execute<T>(
operation: () => Promise<HttpResponse<T>>,
requestConfig: RequestConfig
): Promise<HttpResponse<T>> {
let lastError: any;
let attempt = 0;
while (attempt <= this.config.maxRetries) {
try {
const result = await operation();
if (attempt > 0) {
this.emit('retrySuccess', {
requestConfig,
attempt,
result
});
}
return result;
} catch (error) {
lastError = error;
attempt++;
// Check if we should retry
if (
attempt > this.config.maxRetries ||
!this.config.retryCondition(error)
) {
break;
}
// Calculate delay
const delay = this.calculateDelay(attempt);
this.emit('retryAttempt', {
requestConfig,
attempt,
error,
delay
});
// Wait before retry
await this.delay(delay);
}
}
// All retries exhausted
const finalError = new RetryExhaustedError(requestConfig, attempt, lastError);
this.emit('retryExhausted', {
requestConfig,
attempts: attempt,
finalError
});
throw finalError;
}
private calculateDelay(attempt: number): number {
if (!this.config.exponentialBackoff) {
return this.config.baseDelay;
}
// Exponential backoff with jitter
const exponentialDelay = this.config.baseDelay * Math.pow(2, attempt - 1);
const jitter = Math.random() * 0.1 * exponentialDelay; // 10% jitter
const totalDelay = Math.min(exponentialDelay + jitter, this.config.maxDelay);
return Math.floor(totalDelay);
}
private delay(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
private defaultRetryCondition(error: any): boolean {
// Network errors
if (error.code === 'ECONNRESET' ||
error.code === 'ECONNREFUSED' ||
error.code === 'ETIMEDOUT' ||
error.code === 'ENOTFOUND') {
return true;
}
// HTTP status codes that should be retried
const retryableStatuses = [408, 429, 500, 502, 503, 504];
if (error.status && retryableStatuses.includes(error.status)) {
return true;
}
// Timeout errors
if (error instanceof TimeoutError) {
return true;
}
return false;
}
updateConfig(config: Partial<RetryConfig>): void {
this.config = { ...this.config, ...config };
}
getConfig(): RetryConfig {
return { ...this.config };
}
}

View file

@ -1,25 +0,0 @@
// Main exports
export { BunHttpClient } from './BunHttpClient';
export { ConnectionPool } from './ConnectionPool';
export { RetryHandler } from './RetryHandler';
// Type exports
export type {
HttpClientConfig,
RequestConfig,
HttpResponse,
ConnectionPoolConfig,
ConnectionStats,
QueuedRequest,
RetryConfig
} from './types';
// Error exports
export {
HttpClientError,
TimeoutError,
RetryExhaustedError
} from './types';
// Default export for convenience
export { BunHttpClient as default } from './BunHttpClient';

View file

@ -1,104 +0,0 @@
// Type definitions for the HTTP client
export interface HttpClientConfig {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
retries?: number;
retryDelay?: number;
maxConcurrency?: number;
keepAlive?: boolean;
validateStatus?: (status: number) => boolean;
}
export interface RequestConfig {
url: string;
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
headers?: Record<string, string>;
body?: any;
timeout?: number;
retries?: number;
metadata?: Record<string, any>;
validateStatus?: (status: number) => boolean;
}
export interface HttpResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
config: RequestConfig;
timing: {
start: number;
end: number;
duration: number;
};
}
export interface ConnectionPoolConfig {
maxConnections: number;
maxConnectionsPerHost: number;
keepAlive: boolean;
maxIdleTime: number;
connectionTimeout: number;
}
export interface ConnectionStats {
activeConnections: number;
totalConnections: number;
successfulRequests: number;
failedRequests: number;
averageResponseTime: number;
connectionPoolUtilization: number;
requestsPerSecond: number;
}
export interface QueuedRequest {
id: string;
config: RequestConfig;
resolve: (value: HttpResponse) => void;
reject: (error: any) => void;
timestamp: number;
retryCount: number;
host: string;
}
export interface RetryConfig {
maxRetries: number;
baseDelay: number;
maxDelay: number;
exponentialBackoff: boolean;
retryCondition?: (error: any) => boolean;
}
export class HttpClientError extends Error {
constructor(
message: string,
public code?: string,
public status?: number,
public response?: any,
public config?: RequestConfig
) {
super(message);
this.name = 'HttpClientError';
}
}
export class TimeoutError extends HttpClientError {
constructor(config: RequestConfig, timeout: number) {
super(`Request timeout after ${timeout}ms`, 'TIMEOUT', undefined, undefined, config);
this.name = 'TimeoutError';
}
}
export class RetryExhaustedError extends HttpClientError {
constructor(config: RequestConfig, attempts: number, lastError: any) {
super(
`Request failed after ${attempts} attempts: ${lastError.message}`,
'RETRY_EXHAUSTED',
lastError.status,
lastError.response,
config
);
this.name = 'RetryExhaustedError';
}
}

View file

@ -1,18 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true,
"declarationMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
"references": [
{ "path": "../api-client" },
{ "path": "../config" },
{ "path": "../event-bus" },
{ "path": "../types" },
{ "path": "../utils" },
]
}

View file

@ -10,7 +10,6 @@
],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
"references": [
{ "path": "../config" },
{ "path": "../types" }
{ "path": "../config" }
]
}

View file

@ -20,7 +20,6 @@
{ "path": "../api-client" },
{ "path": "../event-bus" },
{ "path": "../http-client" },
{ "path": "../types" },
{ "path": "../utils" },
{ "path": "../config" },
{ "path": "../logger" },

View file

@ -1,28 +0,0 @@
# Shared Types Library
This library contains domain-specific TypeScript type definitions used across the stock-bot project.
## Directory Structure
- `market/` - Market data structures (OHLCV, OrderBook, etc.)
- `trading/` - Trading types (Orders, Positions, etc.)
- `strategy/` - Strategy and signal types
- `events/` - Event definitions for the event bus
- `api/` - Common API request/response types
- `config/` - Configuration type definitions
## Usage
```typescript
import { OHLCV, MarketData } from '@stock-bot/types';
// Use the types
const marketData: MarketData = {
symbol: 'AAPL',
price: 150.25,
bid: 150.20,
ask: 150.30,
volume: 1000000,
timestamp: new Date()
};
```

View file

@ -1,23 +0,0 @@
{
"name": "@stock-bot/types",
"version": "1.0.0",
"description": "Domain-specific shared TypeScript definitions for the trading bot",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"clean": "rm -rf dist",
"test": "echo \"No tests yet\""
},
"devDependencies": {
"typescript": "^5.4.5"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js"
}
}
}

View file

@ -1,44 +0,0 @@
// Service Types
export interface ServiceConfig {
name: string;
version: string;
environment: 'development' | 'staging' | 'production';
port?: number;
dependencies?: string[];
}
export interface ApiHealthStatus {
service: string;
status: 'healthy' | 'unhealthy' | 'degraded';
timestamp: Date;
details?: Record<string, any>;
}
// API Response Types
export interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
timestamp: Date;
}
export interface PaginatedResponse<T> {
data: T[];
total: number;
page: number;
limit: number;
hasNext: boolean;
}
// HTTP Response standards
export interface ErrorResponse {
status: number;
code: string;
message: string;
details?: any;
}
export interface SuccessResponse<T> {
status: number;
data: T;
}

View file

@ -1,5 +0,0 @@
// Communication and Messaging Types
export * from './websocket';
export * from './subscriptions';
export * from './messages';
export * from './protocols';

View file

@ -1,152 +0,0 @@
// Message Queue and Event Types
export interface EventBusMessage {
id: string;
type: string;
source: string;
timestamp: Date;
data: any;
metadata?: MessageMetadata;
headers?: Record<string, string>;
correlationId?: string;
causationId?: string;
}
export interface MessageMetadata {
version?: string;
schemaVersion?: string;
contentType?: string;
encoding?: string;
priority?: MessagePriority;
retryCount?: number;
maxRetries?: number;
expiresAt?: Date;
partitionKey?: string;
}
export enum MessagePriority {
LOW = 'low',
NORMAL = 'normal',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface QueueMessage extends EventBusMessage {
queueName: string;
routingKey?: string;
deliveryAttempts: number;
firstDeliveryAt?: Date;
lastDeliveryAt?: Date;
deadLetterReason?: string;
}
export interface MessageBatch {
id: string;
messages: EventBusMessage[];
batchSize: number;
createdAt: Date;
expiresAt?: Date;
metadata?: Record<string, any>;
}
export interface MessageHandler {
id: string;
name: string;
eventTypes: string[];
handler: (message: EventBusMessage) => Promise<void>;
config: HandlerConfig;
status: HandlerStatus;
metrics: HandlerMetrics;
}
export interface HandlerConfig {
concurrency?: number;
retryAttempts?: number;
retryDelay?: number;
deadLetterQueue?: string;
timeout?: number;
batchSize?: number;
filters?: MessageFilter[];
}
export enum HandlerStatus {
ACTIVE = 'active',
PAUSED = 'paused',
ERROR = 'error',
STOPPED = 'stopped'
}
export interface HandlerMetrics {
messagesProcessed: number;
messagesSuccess: number;
messagesError: number;
avgProcessingTime: number;
lastProcessed: Date;
errorRate: number;
}
export interface MessageFilter {
field: string;
operator: 'equals' | 'not_equals' | 'contains' | 'regex' | 'in' | 'not_in';
value: any;
logicalOperator?: 'AND' | 'OR';
}
export interface DeadLetterMessage extends QueueMessage {
originalQueue: string;
failureReason: string;
failureTimestamp: Date;
retryHistory: RetryAttempt[];
}
export interface RetryAttempt {
attemptNumber: number;
timestamp: Date;
error: string;
duration: number;
}
export interface MessageProducer {
id: string;
name: string;
producerType: 'service' | 'scheduler' | 'webhook' | 'batch';
config: ProducerConfig;
status: ProducerStatus;
metrics: ProducerMetrics;
}
export interface ProducerConfig {
batchSize?: number;
batchTimeout?: number;
compression?: boolean;
partitioning?: PartitioningConfig;
serialization?: SerializationConfig;
}
export interface PartitioningConfig {
enabled: boolean;
keyField?: string;
strategy: 'hash' | 'round_robin' | 'custom';
partitionCount?: number;
}
export interface SerializationConfig {
format: 'json' | 'avro' | 'protobuf' | 'msgpack';
compression?: 'gzip' | 'snappy' | 'lz4';
schema?: string;
}
export enum ProducerStatus {
ACTIVE = 'active',
PAUSED = 'paused',
ERROR = 'error',
STOPPED = 'stopped'
}
export interface ProducerMetrics {
messagesSent: number;
messagesSuccess: number;
messagesError: number;
avgLatency: number;
throughputPerSecond: number;
lastSent: Date;
}

View file

@ -1,163 +0,0 @@
// Protocol and Integration Types
export interface HttpRequest {
method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
url: string;
headers?: Record<string, string>;
body?: any;
timeout?: number;
retries?: number;
metadata?: Record<string, any>;
validateStatus?: (status: number) => boolean;
}
export interface HttpResponse<T = any> {
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
config: HttpRequest;
timing: RequestTiming;
}
export interface RequestTiming {
start: number;
end: number;
duration: number;
dns?: number;
tcp?: number;
tls?: number;
request?: number;
firstByte?: number;
download?: number;
}
export interface ApiEndpoint {
id: string;
name: string;
baseUrl: string;
path: string;
method: string;
authentication?: ProtocolAuthenticationMethod;
rateLimit?: RateLimitInfo;
timeout: number;
retryPolicy: RetryPolicy;
headers?: Record<string, string>;
queryParams?: Record<string, string>;
}
export interface ProtocolAuthenticationMethod {
type: 'none' | 'apikey' | 'bearer' | 'basic' | 'oauth2' | 'custom';
config: AuthConfig;
}
export interface AuthConfig {
apiKey?: string;
token?: string;
username?: string;
password?: string;
clientId?: string;
clientSecret?: string;
scope?: string[];
tokenUrl?: string;
refreshToken?: string;
customHeaders?: Record<string, string>;
}
export interface RateLimitInfo {
requestsPerSecond: number;
requestsPerMinute: number;
requestsPerHour: number;
burstLimit: number;
windowMs: number;
}
export interface RetryPolicy {
enabled: boolean;
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
backoffMultiplier: number;
jitter: boolean;
retryOn: RetryCondition[];
}
export interface RetryCondition {
type: 'status_code' | 'timeout' | 'network_error' | 'rate_limit' | 'custom';
values?: number[];
condition?: string;
}
export interface ProtocolConfig {
name: string;
version: string;
transport: 'http' | 'websocket' | 'tcp' | 'udp' | 'grpc';
serialization: 'json' | 'protobuf' | 'avro' | 'msgpack' | 'xml';
compression?: 'gzip' | 'deflate' | 'brotli' | 'snappy'; encryption?: EncryptionConfig;
healthCheck: ProtocolHealthCheckConfig;
}
export interface EncryptionConfig {
enabled: boolean;
algorithm?: string;
keySize?: number;
mode?: string;
certificatePath?: string;
privateKeyPath?: string;
}
export interface ProtocolHealthCheckConfig {
enabled: boolean;
path?: string;
interval: number;
timeout: number;
healthyThreshold: number;
unhealthyThreshold: number;
}
export interface ServiceEndpointConfig {
serviceName: string;
version: string;
endpoints: ApiEndpoint[];
baseConfig: ProtocolServiceConfig;
healthCheck: ProtocolHealthCheckConfig;
}
export interface ProtocolServiceConfig {
timeout: number;
retries: number;
circuitBreaker?: CircuitBreakerConfig;
loadBalancer?: LoadBalancerConfig;
monitoring?: MonitoringConfig;
}
export interface CircuitBreakerConfig {
enabled: boolean;
failureThreshold: number;
timeout: number;
halfOpenMaxCalls: number;
halfOpenTimeout: number;
}
export interface LoadBalancerConfig {
strategy: 'round_robin' | 'weighted' | 'least_connections' | 'random';
healthCheckEnabled: boolean;
targets: LoadBalancerTarget[];
}
export interface LoadBalancerTarget {
url: string;
weight?: number;
enabled: boolean;
metadata?: Record<string, any>;
}
export interface MonitoringConfig {
metricsEnabled: boolean;
tracingEnabled: boolean;
loggingEnabled: boolean;
alertingEnabled: boolean;
customMetrics?: string[];
}
// Re-export from config for convenience
export type { HttpClientConfig } from '../config/networking';

View file

@ -1,200 +0,0 @@
// Subscription Management Types
export type DataType = 'tick' | 'candle' | 'trade' | 'order' | 'quote' | 'level2' | 'quotes' | 'trades' | 'orderbook' | 'candles' | 'news' | 'fundamentals' | 'options' | 'futures' | 'crypto';
export enum SubscriptionPriority {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface SubscriptionRequest {
id: string;
clientId: string;
symbols: string[];
dataTypes: DataType[];
filters?: SubscriptionFilter;
throttle?: ThrottleConfig;
delivery: DeliveryConfig;
priority?: SubscriptionPriority;
metadata?: Record<string, any>;
}
export interface SubscriptionFilter {
symbols?: string[];
priceRange?: PriceRange;
volumeRange?: VolumeRange;
timeRange?: TimeRange;
custom?: Record<string, any>;
}
export interface PriceRange {
min?: number;
max?: number;
}
export interface VolumeRange {
min?: number;
max?: number;
}
export interface TimeRange {
start?: Date;
end?: Date;
}
export interface ThrottleConfig {
maxMessagesPerSecond?: number;
maxBatchSize?: number;
bufferTimeMs?: number;
}
export interface DeliveryConfig {
method: DeliveryMethod;
endpoint?: string;
options?: DeliveryOptions;
}
export enum DeliveryMethod {
WEBSOCKET = 'websocket',
HTTP_PUSH = 'http_push',
QUEUE = 'queue',
STREAM = 'stream'
}
export interface DeliveryOptions {
guaranteedDelivery?: boolean;
compression?: boolean;
encryption?: boolean;
authentication?: AuthenticationMethod;
headers?: Record<string, string>;
}
export enum AuthenticationMethod {
NONE = 'none',
API_KEY = 'api_key',
BEARER_TOKEN = 'bearer_token',
OAUTH = 'oauth',
MUTUAL_TLS = 'mutual_tls'
}
export interface SubscriptionResponse {
id: string;
status: SubscriptionStatus;
message?: string;
details?: SubscriptionDetails;
}
export enum SubscriptionStatus {
ACTIVE = 'active',
PENDING = 'pending',
PAUSED = 'paused',
CANCELLED = 'cancelled',
FAILED = 'failed'
}
export interface SubscriptionDetails {
subscribedSymbols: string[];
subscribedDataTypes: DataType[];
activeFilters: SubscriptionFilter;
performance: CommunicationSubscriptionMetrics;
}
export interface CommunicationSubscriptionMetrics {
messagesReceived: number;
messagesDropped: number;
averageLatency: number;
throughput: number;
errorRate: number;
lastActivity: Date;
}
export interface SubscriptionConfig {
maxSubscriptionsPerClient: number;
defaultThrottleConfig: ThrottleConfig;
allowedDataTypes: DataType[];
supportedDeliveryMethods: DeliveryMethod[];
subscriptionTimeout: number;
}
export interface UnsubscribeRequest {
subscriptionId: string;
clientId: string;
reason?: string;
}
export interface BulkSubscriptionRequest {
requests: SubscriptionRequest[];
batchId?: string;
failurePolicy: BatchFailurePolicy;
}
export enum BatchFailurePolicy {
FAIL_ALL = 'fail_all',
FAIL_PARTIAL = 'fail_partial',
IGNORE_ERRORS = 'ignore_errors'
}
export interface BatchSubscriptionResponse {
batchId: string;
responses: SubscriptionResponse[];
summary: BatchSummary;
}
export interface BatchSummary {
totalRequests: number;
successfulSubscriptions: number;
failedSubscriptions: number;
errors: string[];
}
export interface SubscriptionUpdate {
subscriptionId: string;
updates: Partial<SubscriptionRequest>;
clientId: string;
}
export interface SubscriptionEvent {
type: SubscriptionEventType;
subscriptionId: string;
clientId: string;
timestamp: Date;
data?: any;
}
export enum SubscriptionEventType {
CREATED = 'created',
UPDATED = 'updated',
CANCELLED = 'cancelled',
ERROR = 'error',
DATA_RECEIVED = 'data_received'
}
export interface FilterRule {
field: string;
operator: FilterOperator;
value: any;
validation?: ValidationRule;
}
export enum FilterOperator {
EQUALS = 'equals',
NOT_EQUALS = 'not_equals',
GREATER_THAN = 'greater_than',
LESS_THAN = 'less_than',
GREATER_EQUAL = 'greater_equal',
LESS_EQUAL = 'less_equal',
IN = 'in',
NOT_IN = 'not_in',
CONTAINS = 'contains',
REGEX = 'regex'
}
export interface ValidationRule {
pattern?: string;
min?: number;
max?: number;
enum?: any[];
custom?: string;
}

View file

@ -1,134 +0,0 @@
// WebSocket Communication Types
export interface WebSocketMessage {
type: MessageType;
id?: string;
timestamp: number;
payload: any;
metadata?: Record<string, any>;
correlationId?: string;
}
export enum MessageType {
SUBSCRIBE = 'subscribe',
UNSUBSCRIBE = 'unsubscribe',
DATA = 'data',
ERROR = 'error',
HEARTBEAT = 'heartbeat',
STATUS = 'status',
ACK = 'ack',
PING = 'ping',
PONG = 'pong'
}
export interface WebSocketSubscribeMessage extends WebSocketMessage {
type: MessageType.SUBSCRIBE;
payload: SubscriptionPayload;
}
export interface WebSocketUnsubscribeMessage extends WebSocketMessage {
type: MessageType.UNSUBSCRIBE;
payload: UnsubscriptionPayload;
}
export interface WebSocketDataMessage extends WebSocketMessage {
type: MessageType.DATA;
payload: DataPayload;
}
export interface WebSocketErrorMessage extends WebSocketMessage {
type: MessageType.ERROR;
payload: ErrorPayload;
}
export interface WebSocketStatusMessage extends WebSocketMessage {
type: MessageType.STATUS;
payload: StatusPayload;
}
export interface SubscriptionPayload {
symbols: string[];
dataTypes: string[];
filters?: WebSocketSubscriptionFilter;
throttle?: WebSocketThrottleConfig;
delivery?: WebSocketDeliveryConfig;
}
export interface UnsubscriptionPayload {
subscriptionId?: string;
symbols?: string[];
dataTypes?: string[];
}
export interface DataPayload {
dataType: string;
symbol?: string;
data: any;
sequence?: number;
source?: string;
}
export interface ErrorPayload {
code: string;
message: string;
details?: Record<string, any>;
retryable?: boolean;
}
export interface StatusPayload {
status: 'connected' | 'disconnected' | 'reconnecting' | 'error';
message?: string;
timestamp: number;
metadata?: Record<string, any>;
}
export interface WebSocketSubscriptionFilter {
priceRange?: { min: number; max: number };
volumeThreshold?: number;
exchanges?: string[];
symbols?: string[];
timeframe?: string;
custom?: Record<string, any>;
}
export interface WebSocketThrottleConfig {
maxUpdatesPerSecond: number;
aggregationWindow?: number;
bufferSize?: number;
}
export interface WebSocketDeliveryConfig {
method: 'websocket' | 'webhook' | 'eventbus' | 'queue';
endpoint?: string;
format: 'json' | 'protobuf' | 'avro' | 'msgpack';
compression?: 'gzip' | 'deflate' | 'brotli';
batchSize?: number;
batchDelay?: number;
}
export interface WebSocketConnection {
id: string;
clientId: string;
sessionId: string;
connectedAt: Date;
lastActivity: Date;
status: ConnectionStatus;
subscriptions: Set<string>;
metadata: ConnectionMetadata;
}
export enum ConnectionStatus {
CONNECTING = 'connecting',
CONNECTED = 'connected',
DISCONNECTING = 'disconnecting',
DISCONNECTED = 'disconnected',
ERROR = 'error'
}
export interface ConnectionMetadata {
userAgent?: string;
ipAddress?: string;
origin?: string;
protocol?: string;
version?: string;
features?: string[];
}

View file

@ -1,60 +0,0 @@
// Database Configuration Types
export interface DatabaseConfig {
host: string;
port: number;
database: string;
username?: string;
password?: string;
connectionTimeout?: number;
ssl?: boolean;
}
export interface PostgresConfig extends DatabaseConfig {
maxConnections?: number;
idleTimeoutMs?: number;
connectionTimeoutMs?: number;
statementTimeout?: number;
schema?: string;
}
export interface MongoDbConfig extends DatabaseConfig {
authSource?: string;
replicaSet?: string;
readPreference?: 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest';
writeConcern?: string;
retryWrites?: boolean;
journal?: boolean;
}
export interface QuestDbConfig extends DatabaseConfig {
httpPort?: number;
pgPort?: number;
requestTimeout?: number;
retryAttempts?: number;
tlsEnabled?: boolean;
defaultDatabase?: string;
}
export interface RedisConfig {
host: string;
port: number;
password?: string;
database?: number;
maxRetries?: number;
retryDelay?: number;
connectTimeout?: number;
commandTimeout?: number;
poolSize?: number;
tls?: boolean;
enableKeepAlive?: boolean;
}
export interface ConnectionPoolConfig {
minConnections: number;
maxConnections: number;
acquireTimeoutMs: number;
createTimeoutMs: number;
destroyTimeoutMs: number;
idleTimeoutMs: number;
reapIntervalMs: number;
}

View file

@ -1,6 +0,0 @@
// Configuration Types - Shared across all services
export * from './database';
export * from './monitoring';
export * from './logging';
export * from './security';
export * from './networking';

View file

@ -1,48 +0,0 @@
// Logging Configuration Types
export interface LoggingConfig {
level: 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
format: 'json' | 'simple' | 'combined';
console: boolean;
file: boolean;
filePath?: string;
maxSize?: string;
maxFiles?: number;
timestamp?: boolean;
callerInfo?: boolean;
silentModules?: string[];
verboseModules?: string[];
serviceName?: string;
serviceVersion?: string;
environment?: string;
}
export interface LokiConfig {
host: string;
port: number;
url?: string;
username?: string;
password?: string;
tenantId?: string;
pushTimeout?: number;
batchSize?: number;
batchWait?: number;
retentionPeriod?: string;
maxChunkAge?: string;
tlsEnabled?: boolean;
tlsInsecure?: boolean;
defaultLabels?: Record<string, string>;
serviceLabel?: string;
environmentLabel?: string;
flushIntervalMs?: number;
}
export interface LogEntry {
timestamp: Date;
level: string;
message: string;
service: string;
environment: string;
metadata?: Record<string, any>;
error?: string;
stackTrace?: string;
}

View file

@ -1,48 +0,0 @@
// Monitoring and Metrics Configuration Types
export interface PrometheusConfig {
host: string;
port: number;
url?: string;
username?: string;
password?: string;
scrapeInterval: string;
evaluationInterval: string;
retentionTime: string;
tlsEnabled?: boolean;
tlsInsecure?: boolean;
}
export interface GrafanaConfig {
host: string;
port: number;
url?: string;
adminUser: string;
adminPassword: string;
allowSignUp?: boolean;
secretKey?: string;
databaseType: 'mysql' | 'postgres' | 'sqlite3';
databaseUrl?: string;
disableGravatar?: boolean;
enableGzip?: boolean;
}
export interface AlertManagerConfig {
host: string;
port: number;
webhookUrl?: string;
smtpHost?: string;
smtpPort?: number;
smtpUsername?: string;
smtpPassword?: string;
slackWebhookUrl?: string;
}
export interface MetricsConfig {
enabled: boolean;
port: number;
path: string;
collectDefaultMetrics?: boolean;
prefix?: string;
labels?: Record<string, string>;
buckets?: number[];
}

View file

@ -1,50 +0,0 @@
// Networking and Communication Configuration Types
import { CorsConfig } from './security';
export interface ServerConfig {
host: string;
port: number;
maxConnections?: number;
keepAliveTimeout?: number;
bodyParserLimit?: string;
compression?: boolean;
gracefulShutdownTimeout?: number;
}
export interface WebSocketConfig {
enabled: boolean;
port?: number;
path?: string;
heartbeatInterval?: number;
maxConnections?: number;
compression?: boolean;
cors?: CorsConfig;
}
export interface HttpClientConfig {
baseURL?: string;
timeout?: number;
headers?: Record<string, string>;
retries?: number;
retryDelay?: number;
maxConcurrency?: number;
keepAlive?: boolean;
validateStatus?: (status: number) => boolean;
}
export interface RetryConfig {
maxRetries: number;
baseDelay: number;
maxDelay: number;
exponentialBackoff: boolean;
retryCondition?: (error: any) => boolean;
}
export interface CircuitBreakerConfig {
enabled: boolean;
failureThreshold: number;
recoveryTimeout: number;
monitoringPeriod: number;
expectedFailureRate: number;
}

View file

@ -1,46 +0,0 @@
// Security Configuration Types
export interface AuthenticationConfig {
jwtSecret: string;
jwtExpiresIn: string;
refreshTokenExpiresIn: string;
passwordMinLength: number;
passwordRequireNumbers: boolean;
passwordRequireSpecialChars: boolean;
passwordRequireUppercase: boolean;
passwordRequireLowercase: boolean;
maxLoginAttempts: number;
lockoutDurationMinutes: number;
}
export interface TlsConfig {
enabled: boolean;
certFile?: string;
keyFile?: string;
caFile?: string;
skipVerify?: boolean;
minVersion?: string;
cipherSuites?: string[];
}
export interface ApiKeyConfig {
type: 'apikey' | 'oauth' | 'basic' | 'jwt';
credentials: Record<string, string>;
expiresIn?: string;
permissions?: string[];
}
export interface CorsConfig {
origins: string[];
methods: string[];
headers: string[];
credentials?: boolean;
maxAge?: number;
}
export interface RateLimitConfig {
windowMs: number;
maxRequests: number;
skipSuccessfulRequests?: boolean;
skipFailedRequests?: boolean;
keyGenerator?: string;
}

View file

@ -1,6 +0,0 @@
// Data Processing and Pipeline Types
export * from './sources';
export * from './processors';
export * from './pipelines';
export * from './transformations';
export * from './quality';

View file

@ -1,181 +0,0 @@
import { AuthenticationConfig } from '../config/security';
import { ProcessingError } from './processors';
// Data Pipeline Types
export interface ProcessingPipeline {
id: string;
name: string;
description?: string;
version: string;
processors: PipelineProcessor[];
inputFilter: InputFilter;
outputTargets: OutputTargets;
schedule?: PipelineSchedule;
status: PipelineStatus;
metadata: PipelineMetadata;
}
export interface PipelineProcessor {
processorId: string;
order: number;
config?: Record<string, any>;
conditions?: ProcessingCondition[];
parallelBranches?: PipelineProcessor[][];
}
export interface ProcessingCondition {
field: string;
operator: 'equals' | 'not_equals' | 'contains' | 'regex' | 'greater_than' | 'less_than';
value: any;
logicalOperator?: 'AND' | 'OR';
}
export interface InputFilter {
symbols?: string[];
sources?: string[];
dataTypes?: string[];
timeRange?: TimeRange;
conditions?: ProcessingCondition[];
}
export interface TimeRange {
start?: Date;
end?: Date;
duration?: string;
timezone?: string;
}
export interface OutputTargets {
eventBus?: boolean;
database?: DatabaseTarget;
cache?: CacheTarget;
websocket?: WebSocketTarget;
dataProcessor?: ServiceTarget;
featureStore?: ServiceTarget;
file?: FileTarget;
api?: ApiTarget;
}
export interface DatabaseTarget {
enabled: boolean;
connectionId: string;
table: string;
batchSize?: number;
flushInterval?: number;
}
export interface CacheTarget {
enabled: boolean;
connectionId: string;
keyPattern: string;
ttl?: number;
compression?: boolean;
}
export interface WebSocketTarget {
enabled: boolean;
rooms?: string[];
filters?: Record<string, any>;
}
export interface ServiceTarget {
enabled: boolean;
serviceId: string;
endpoint: string;
batchSize?: number;
timeout?: number;
}
export interface FileTarget {
enabled: boolean;
path: string;
format: 'json' | 'csv' | 'parquet' | 'avro';
compression?: 'gzip' | 'bzip2' | 'lz4';
rotation?: FileRotation;
}
export interface FileRotation {
size?: string;
time?: string;
count?: number;
}
export interface ApiTarget {
enabled: boolean;
url: string;
method: string;
headers?: Record<string, string>;
authentication?: AuthenticationConfig;
}
export interface PipelineSchedule {
enabled: boolean;
cronExpression?: string;
interval?: string;
timezone?: string;
startDate?: Date;
endDate?: Date;
}
export enum PipelineStatus {
DRAFT = 'draft',
ACTIVE = 'active',
PAUSED = 'paused',
ERROR = 'error',
COMPLETED = 'completed',
ARCHIVED = 'archived'
}
export interface PipelineMetadata {
createdBy: string;
createdAt: Date;
updatedBy: string;
updatedAt: Date;
tags: string[];
documentation?: string;
changeLog?: ChangeLogEntry[];
}
export interface ChangeLogEntry {
version: string;
timestamp: Date;
author: string;
changes: string[];
breaking: boolean;
}
export interface PipelineExecution {
id: string;
pipelineId: string;
status: ExecutionStatus;
startTime: Date;
endTime?: Date;
recordsProcessed: number;
recordsSuccess: number;
recordsError: number;
errors: ProcessingError[];
metadata: ExecutionMetadata;
}
export enum ExecutionStatus {
PENDING = 'pending',
RUNNING = 'running',
COMPLETED = 'completed',
FAILED = 'failed',
CANCELLED = 'cancelled',
TIMEOUT = 'timeout'
}
export interface ExecutionMetadata {
triggeredBy: 'schedule' | 'manual' | 'event';
trigger?: string;
parameters?: Record<string, any>;
resources?: ResourceUsage;
}
export interface ResourceUsage {
cpuTimeMs: number;
memoryPeakMB: number;
diskIOBytes: number;
networkIOBytes: number;
}

View file

@ -1,103 +0,0 @@
// Data Processing Types
export interface DataProcessor {
id: string;
name: string;
type: ProcessorType;
enabled: boolean;
priority: number;
config: ProcessorConfig;
inputSchema?: DataSchema;
outputSchema?: DataSchema;
metrics: ProcessorMetrics;
}
export enum ProcessorType {
ENRICHMENT = 'enrichment',
VALIDATION = 'validation',
NORMALIZATION = 'normalization',
AGGREGATION = 'aggregation',
FILTER = 'filter',
TRANSFORMATION = 'transformation',
QUALITY_CHECK = 'quality_check',
DEDUPLICATION = 'deduplication'
}
export interface ProcessorConfig {
batchSize?: number;
timeoutMs?: number;
retryAttempts?: number;
parallelism?: number;
parameters?: Record<string, any>;
errorHandling?: ErrorHandlingConfig;
}
export interface ErrorHandlingConfig {
strategy: 'fail_fast' | 'skip_invalid' | 'retry' | 'quarantine';
maxErrors?: number;
quarantineLocation?: string;
notificationChannels?: string[];
}
export interface ProcessorMetrics {
recordsProcessed: number;
recordsSuccess: number;
recordsError: number;
avgProcessingTimeMs: number;
lastProcessed: Date;
errorRate: number;
throughputPerSecond: number;
}
export interface ProcessingError {
processorId: string;
pipelineId: string;
timestamp: Date;
inputData: any;
error: string;
stackTrace?: string;
severity: 'low' | 'medium' | 'high' | 'critical';
recoverable: boolean;
}
export interface DataSchema {
version: string;
fields: SchemaField[];
primaryKeys?: string[];
foreignKeys?: ForeignKey[];
indexes?: Index[];
constraints?: SchemaConstraint[];
}
export interface SchemaField {
name: string;
type: string;
nullable: boolean;
description?: string;
defaultValue?: any;
format?: string;
pattern?: string;
enum?: any[];
}
export interface ForeignKey {
fields: string[];
referencedTable: string;
referencedFields: string[];
onDelete?: 'cascade' | 'restrict' | 'set_null';
onUpdate?: 'cascade' | 'restrict' | 'set_null';
}
export interface Index {
name: string;
fields: string[];
unique: boolean;
type: 'btree' | 'hash' | 'gin' | 'gist';
}
export interface SchemaConstraint {
name: string;
type: 'check' | 'unique' | 'not_null' | 'range';
fields: string[];
condition?: string;
parameters?: Record<string, any>;
}

View file

@ -1,193 +0,0 @@
// Data Quality Types
export interface DataQuality {
id: string;
assetId: string;
overallScore: number;
dimensions: QualityDimension[];
rules: QualityRule[];
issues: QualityIssue[];
trend: QualityTrend;
lastAssessment: Date;
nextAssessment?: Date;
}
export interface QualityDimension {
name: QualityDimensionType;
score: number;
weight: number;
description: string;
metrics: QualityMetric[];
status: 'pass' | 'warn' | 'fail';
}
export enum QualityDimensionType {
COMPLETENESS = 'completeness',
ACCURACY = 'accuracy',
CONSISTENCY = 'consistency',
VALIDITY = 'validity',
UNIQUENESS = 'uniqueness',
TIMELINESS = 'timeliness',
INTEGRITY = 'integrity',
CONFORMITY = 'conformity',
RELEVANCE = 'relevance'
}
export interface QualityRule {
id: string;
name: string;
description: string;
dimension: QualityDimensionType;
type: QualityRuleType;
field?: string;
condition: string;
threshold: number;
severity: 'low' | 'medium' | 'high' | 'critical';
enabled: boolean;
metadata?: Record<string, any>;
}
export enum QualityRuleType {
NULL_CHECK = 'null_check',
RANGE_CHECK = 'range_check',
PATTERN_CHECK = 'pattern_check',
REFERENCE_CHECK = 'reference_check',
DUPLICATE_CHECK = 'duplicate_check',
FRESHNESS_CHECK = 'freshness_check',
OUTLIER_CHECK = 'outlier_check',
CUSTOM = 'custom'
}
export interface QualityMetric {
name: string;
value: number;
unit?: string;
threshold?: number;
status: 'pass' | 'warn' | 'fail';
timestamp: Date;
trend?: 'improving' | 'stable' | 'degrading';
}
export interface QualityIssue {
id: string;
ruleId: string;
severity: 'low' | 'medium' | 'high' | 'critical';
description: string;
field?: string;
affectedRows?: number;
sampleValues?: any[];
detectedAt: Date;
status: 'open' | 'acknowledged' | 'resolved' | 'false_positive';
assignee?: string;
resolution?: string;
resolvedAt?: Date;
impact?: QualityImpact;
}
export interface QualityImpact {
scope: 'field' | 'table' | 'dataset' | 'system';
affectedRecords: number;
downstreamAssets: string[];
businessImpact: 'low' | 'medium' | 'high' | 'critical';
estimatedCost?: number;
}
export interface QualityTrend {
timeframe: 'day' | 'week' | 'month' | 'quarter';
dataPoints: QualityDataPoint[];
trend: 'improving' | 'stable' | 'degrading';
changeRate: number;
projectedScore?: number;
}
export interface QualityDataPoint {
timestamp: Date;
score: number;
dimensionScores: Record<QualityDimensionType, number>;
issueCount: number;
rulesPassed: number;
rulesTotal: number;
}
export interface QualityProfile {
assetId: string;
fieldProfiles: FieldProfile[];
rowCount: number;
columnCount: number;
dataTypes: Record<string, string>;
nullCounts: Record<string, number>;
uniqueCounts: Record<string, number>;
profiledAt: Date;
}
export interface FieldProfile {
fieldName: string;
dataType: string;
nullCount: number;
uniqueCount: number;
minValue?: any;
maxValue?: any;
avgValue?: number;
medianValue?: number;
standardDeviation?: number;
topValues?: ValueFrequency[];
histogram?: HistogramBucket[];
}
export interface ValueFrequency {
value: any;
count: number;
percentage: number;
}
export interface HistogramBucket {
min: number;
max: number;
count: number;
percentage: number;
}
export interface QualityReport {
id: string;
assetId: string;
reportType: 'summary' | 'detailed' | 'trend' | 'comparison';
generatedAt: Date;
period: string;
summary: QualitySummary;
details?: QualityDetails;
recommendations?: QualityRecommendation[];
}
export interface QualitySummary {
overallScore: number;
scoreTrend: 'improving' | 'stable' | 'degrading';
totalIssues: number;
criticalIssues: number;
resolvedIssues: number;
rulesPassed: number;
rulesTotal: number;
}
export interface QualityDetails {
dimensionBreakdown: Record<QualityDimensionType, QualityDimension>;
topIssues: QualityIssue[];
ruleResults: QualityRuleResult[];
historicalTrend: QualityDataPoint[];
}
export interface QualityRuleResult {
ruleId: string;
ruleName: string;
status: 'pass' | 'fail';
score: number;
violations: number;
executionTime: number;
}
export interface QualityRecommendation {
type: 'rule_adjustment' | 'data_cleanup' | 'process_improvement' | 'monitoring';
priority: 'low' | 'medium' | 'high';
description: string;
impact: string;
effort: string;
steps: string[];
}

View file

@ -1,84 +0,0 @@
// Data Source Configuration Types
export interface DataSourceConfig {
id: string;
name: string;
type: 'websocket' | 'rest' | 'fix' | 'stream' | 'file' | 'database';
enabled: boolean;
priority: number;
rateLimit: DataRateLimitConfig;
connection: DataConnectionConfig;
subscriptions: SubscriptionConfig;
symbols: string[];
retryPolicy: RetryPolicyConfig;
healthCheck: HealthCheckConfig;
metadata?: Record<string, any>;
}
export interface DataRateLimitConfig {
requestsPerSecond: number;
burstLimit: number;
windowMs?: number;
}
export interface DataConnectionConfig {
url: string;
headers?: Record<string, string>;
queryParams?: Record<string, string>;
authentication?: DataAuthenticationConfig;
timeout?: number;
keepAlive?: boolean;
compression?: boolean;
}
export interface DataAuthenticationConfig {
type: 'apikey' | 'oauth' | 'basic' | 'jwt' | 'cert';
credentials: Record<string, string>;
refreshInterval?: number;
}
export interface SubscriptionConfig {
quotes: boolean;
trades: boolean;
orderbook: boolean;
candles: boolean;
news: boolean;
fundamentals?: boolean;
options?: boolean;
futures?: boolean;
}
export interface RetryPolicyConfig {
maxRetries: number;
backoffMultiplier: number;
maxBackoffMs: number;
enableJitter?: boolean;
}
export interface HealthCheckConfig {
intervalMs: number;
timeoutMs: number;
expectedLatencyMs: number;
failureThreshold?: number;
}
export interface DataSourceStatus {
id: string;
status: 'connected' | 'disconnected' | 'connecting' | 'error';
lastUpdate: Date;
connectionTime?: Date;
disconnectionTime?: Date;
errorCount: number;
messagesReceived: number;
latencyMs: number;
throughputPerSecond: number;
}
export interface DataSourceError {
sourceId: string;
timestamp: Date;
type: 'connection' | 'authentication' | 'ratelimit' | 'data' | 'timeout' | 'parsing';
message: string;
details?: Record<string, any>;
severity: 'low' | 'medium' | 'high' | 'critical';
recoverable: boolean;
}

View file

@ -1,119 +0,0 @@
// Data Transformation Types
export interface DataTransformation {
id: string;
name: string;
type: TransformationType;
description?: string;
code?: string;
inputFields: string[];
outputFields: string[];
logic: string;
parameters?: Record<string, any>;
validationRules?: ValidationRule[];
}
export enum TransformationType {
FILTER = 'filter',
AGGREGATE = 'aggregate',
JOIN = 'join',
UNION = 'union',
PIVOT = 'pivot',
UNPIVOT = 'unpivot',
SORT = 'sort',
DEDUPLICATE = 'deduplicate',
CALCULATE = 'calculate',
CAST = 'cast',
RENAME = 'rename',
SPLIT = 'split',
MERGE = 'merge',
NORMALIZE = 'normalize',
ENRICH = 'enrich'
}
export interface ValidationRule {
field: string;
type: ValidationType;
parameters?: Record<string, any>;
errorMessage?: string;
severity: 'warning' | 'error' | 'critical';
}
export enum ValidationType {
REQUIRED = 'required',
TYPE_CHECK = 'type_check',
RANGE = 'range',
PATTERN = 'pattern',
LENGTH = 'length',
UNIQUE = 'unique',
REFERENCE = 'reference',
CUSTOM = 'custom'
}
export interface TransformationRule {
id: string;
sourceField: string;
targetField: string;
transformation: string;
condition?: string;
parameters?: Record<string, any>;
}
export interface MappingRule {
sourceField: string;
targetField: string;
transformation?: string;
defaultValue?: any;
required: boolean;
}
export interface AggregationRule {
groupByFields: string[];
aggregations: AggregationFunction[];
having?: string;
windowFunction?: WindowFunction;
}
export interface AggregationFunction {
function: 'sum' | 'avg' | 'count' | 'min' | 'max' | 'first' | 'last' | 'stddev' | 'variance';
field: string;
alias?: string;
distinct?: boolean;
}
export interface WindowFunction {
type: 'row_number' | 'rank' | 'dense_rank' | 'lag' | 'lead' | 'first_value' | 'last_value';
partitionBy?: string[];
orderBy?: OrderByClause[];
frame?: WindowFrame;
}
export interface OrderByClause {
field: string;
direction: 'asc' | 'desc';
nulls?: 'first' | 'last';
}
export interface WindowFrame {
type: 'rows' | 'range';
start: FrameBoundary;
end: FrameBoundary;
}
export interface FrameBoundary {
type: 'unbounded_preceding' | 'current_row' | 'unbounded_following' | 'preceding' | 'following';
offset?: number;
}
export interface JoinRule {
type: 'inner' | 'left' | 'right' | 'full' | 'cross';
leftTable: string;
rightTable: string;
joinConditions: JoinCondition[];
selectFields?: string[];
}
export interface JoinCondition {
leftField: string;
rightField: string;
operator: '=' | '<>' | '<' | '>' | '<=' | '>=';
}

View file

@ -1,79 +0,0 @@
/**
* Application-specific error types
*/
import { BaseError, ErrorCategory, ErrorSeverity } from './base';
export interface ApplicationError extends BaseError {
applicationName: string;
version: string;
environment: string;
}
export interface ServiceError extends ApplicationError {
serviceName: string;
serviceVersion: string;
endpoint?: string;
}
export interface MarketDataError extends ServiceError {
symbol?: string;
exchange?: string;
dataType?: string;
timeframe?: string;
}
export interface TradingError extends ServiceError {
orderId?: string;
symbol?: string;
side?: 'buy' | 'sell';
quantity?: number;
price?: number;
}
export interface StrategyError extends ServiceError {
strategyId: string;
strategyName: string;
phase: StrategyPhase;
signal?: string;
}
export enum StrategyPhase {
INITIALIZATION = 'initialization',
ANALYSIS = 'analysis',
SIGNAL_GENERATION = 'signal_generation',
EXECUTION = 'execution',
MONITORING = 'monitoring',
CLEANUP = 'cleanup'
}
export interface DataProcessingError extends ServiceError {
pipelineId?: string;
stepId?: string;
inputData?: string;
processingStage: ProcessingStage;
}
export enum ProcessingStage {
INGESTION = 'ingestion',
VALIDATION = 'validation',
TRANSFORMATION = 'transformation',
ENRICHMENT = 'enrichment',
STORAGE = 'storage',
PUBLISHING = 'publishing'
}
export interface FeatureStoreError extends ServiceError {
featureGroupId?: string;
featureName?: string;
operation: FeatureOperation;
}
export enum FeatureOperation {
CREATE = 'create',
READ = 'read',
UPDATE = 'update',
DELETE = 'delete',
COMPUTE = 'compute',
SERVE = 'serve'
}

View file

@ -1,85 +0,0 @@
/**
* Base error handling types and interfaces
*/
export interface ErrorCode {
code: string;
category: ErrorCategory;
severity: ErrorSeverity;
retryable: boolean;
}
export enum ErrorCategory {
VALIDATION = 'validation',
AUTHENTICATION = 'authentication',
AUTHORIZATION = 'authorization',
NOT_FOUND = 'not_found',
CONFLICT = 'conflict',
RATE_LIMIT = 'rate_limit',
INTERNAL = 'internal',
EXTERNAL = 'external',
NETWORK = 'network',
TIMEOUT = 'timeout',
CONFIGURATION = 'configuration',
DATA = 'data'
}
export enum ErrorSeverity {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface BaseError {
id: string;
code: string;
message: string;
details?: Record<string, any>;
timestamp: Date;
category: ErrorCategory;
severity: ErrorSeverity;
retryable: boolean;
context?: ErrorContext;
stack?: string;
}
export interface ErrorContext {
service: string;
component: string;
operation: string;
userId?: string;
sessionId?: string;
requestId?: string;
traceId?: string;
correlationId?: string;
metadata?: Record<string, any>;
}
export interface ErrorResponse {
error: BaseError;
timestamp: Date;
path: string;
method: string;
statusCode: number;
}
export interface ErrorHandler {
handle(error: BaseError): Promise<void>;
canHandle(error: BaseError): boolean;
}
export interface ErrorRecovery {
strategy: RecoveryStrategy;
maxRetries: number;
backoffMs: number;
timeout: number;
}
export enum RecoveryStrategy {
RETRY = 'retry',
FALLBACK = 'fallback',
CIRCUIT_BREAKER = 'circuit_breaker',
GRACEFUL_DEGRADATION = 'graceful_degradation',
FAIL_FAST = 'fail_fast'
}

View file

@ -1,85 +0,0 @@
/**
* Business domain error types
*/
import { BaseError } from './base';
export interface BusinessError extends BaseError {
domain: BusinessDomain;
operation: string;
entityId?: string;
entityType?: string;
}
export enum BusinessDomain {
TRADING = 'trading',
MARKET_DATA = 'market_data',
PORTFOLIO = 'portfolio',
RISK_MANAGEMENT = 'risk_management',
STRATEGY = 'strategy',
EXECUTION = 'execution',
COMPLIANCE = 'compliance',
REPORTING = 'reporting'
}
export interface TradingBusinessError extends BusinessError {
symbol: string;
orderId?: string;
errorType: TradingErrorType;
}
export enum TradingErrorType {
INSUFFICIENT_FUNDS = 'insufficient_funds',
INVALID_SYMBOL = 'invalid_symbol',
MARKET_CLOSED = 'market_closed',
ORDER_REJECTED = 'order_rejected',
POSITION_LIMIT_EXCEEDED = 'position_limit_exceeded',
PRICE_OUT_OF_RANGE = 'price_out_of_range',
DUPLICATE_ORDER = 'duplicate_order'
}
export interface RiskManagementError extends BusinessError {
riskType: RiskType;
threshold?: number;
currentValue?: number;
riskLevel: RiskLevel;
}
export enum RiskType {
POSITION_SIZE = 'position_size',
CONCENTRATION = 'concentration',
VOLATILITY = 'volatility',
DRAWDOWN = 'drawdown',
EXPOSURE = 'exposure',
LEVERAGE = 'leverage',
VAR = 'var'
}
export enum RiskLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface ComplianceError extends BusinessError {
ruleId: string;
ruleName: string;
violationType: ComplianceViolationType;
complianceSeverity: BusinessComplianceSeverity;
}
export enum ComplianceViolationType {
REGULATORY = 'regulatory',
INTERNAL_POLICY = 'internal_policy',
RISK_LIMIT = 'risk_limit',
TRADING_RESTRICTION = 'trading_restriction',
REPORTING_REQUIREMENT = 'reporting_requirement'
}
export enum BusinessComplianceSeverity {
INFO = 'info',
WARNING = 'warning',
VIOLATION = 'violation',
BREACH = 'breach'
}

View file

@ -1,6 +0,0 @@
// Error handling types
export * from './base';
export * from './application';
export * from './validation';
export * from './network';
export * from './business';

View file

@ -1,75 +0,0 @@
/**
* Network and communication error types
*/
import { BaseError } from './base';
export interface NetworkError extends BaseError {
endpoint: string;
method: string;
statusCode?: number;
networkCode: NetworkErrorCode;
}
export enum NetworkErrorCode {
CONNECTION_TIMEOUT = 'connection_timeout',
READ_TIMEOUT = 'read_timeout',
CONNECTION_REFUSED = 'connection_refused',
DNS_RESOLUTION = 'dns_resolution',
SSL_HANDSHAKE = 'ssl_handshake',
PROXY_ERROR = 'proxy_error',
NETWORK_UNREACHABLE = 'network_unreachable',
RATE_LIMITED = 'rate_limited',
SERVICE_UNAVAILABLE = 'service_unavailable'
}
export interface HttpError extends NetworkError {
statusCode: number;
statusText: string;
headers?: Record<string, string>;
responseBody?: string;
}
export interface WebSocketError extends NetworkError {
connectionState: WebSocketState;
closeCode?: number;
closeReason?: string;
}
export enum WebSocketState {
CONNECTING = 'connecting',
OPEN = 'open',
CLOSING = 'closing',
CLOSED = 'closed',
ERROR = 'error'
}
export interface ApiError extends HttpError {
apiName: string;
apiVersion: string;
endpoint: string;
requestId?: string;
errorCode?: string;
errorMessage?: string;
}
export interface ExternalServiceError extends NetworkError {
serviceName: string;
serviceVersion?: string;
providerName: string;
circuitBreakerState?: CircuitBreakerState;
}
export enum CircuitBreakerState {
CLOSED = 'closed',
OPEN = 'open',
HALF_OPEN = 'half_open'
}
export interface RetryConfig {
maxRetries: number;
baseDelayMs: number;
maxDelayMs: number;
backoffMultiplier: number;
retryableErrors: NetworkErrorCode[];
}

View file

@ -1,72 +0,0 @@
/**
* Validation error types
*/
import { BaseError, ErrorCategory, ErrorSeverity } from './base';
export interface ValidationError extends BaseError {
field: string;
value?: any;
constraint: string;
validationType: ValidationType;
}
export enum ValidationType {
REQUIRED = 'required',
TYPE = 'type',
FORMAT = 'format',
RANGE = 'range',
LENGTH = 'length',
PATTERN = 'pattern',
CUSTOM = 'custom',
BUSINESS_RULE = 'business_rule'
}
export interface SchemaValidationError extends ValidationError {
schema: string;
schemaVersion: string;
path: string;
}
export interface DataValidationError extends ValidationError {
dataType: string;
expectedFormat: string;
actualFormat?: string;
}
export interface BusinessRuleValidationError extends ValidationError {
ruleId: string;
ruleName: string;
ruleDescription: string;
businessContext?: Record<string, any>;
}
export interface ValidationResult {
valid: boolean;
errors: ValidationError[];
warnings: ValidationWarning[];
}
export interface ValidationWarning {
field: string;
message: string;
code: string;
severity: 'low' | 'medium';
}
export interface ValidationRule {
id: string;
name: string;
description: string;
type: ValidationType;
constraint: any;
message: string;
enabled: boolean;
}
export interface ValidationConfig {
strict: boolean;
stopOnFirstError: boolean;
rules: ValidationRule[];
customValidators: Record<string, Function>;
}

View file

@ -1,60 +0,0 @@
import { MarketData } from '../market/market-data';
import { Order } from '../trading/orders';
import { TradingSignal } from '../strategy/strategy';
// Event Types
export interface MarketDataEvent {
type: 'MARKET_DATA';
data: MarketData;
timestamp: Date;
}
export interface OrderEvent {
type: 'ORDER_CREATED' | 'ORDER_FILLED' | 'ORDER_CANCELLED';
order: Order;
timestamp: Date;
}
export interface SignalEvent {
type: 'SIGNAL_GENERATED';
signal: TradingSignal;
timestamp: Date;
}
// Define more specific events
export interface RiskAlertEvent {
type: 'RISK_ALERT';
alertLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
message: string;
portfolioId?: string;
strategyId?: string;
timestamp: Date;
}
export interface SystemEvent {
type: 'SYSTEM_STARTUP' | 'SYSTEM_SHUTDOWN' | 'SERVICE_ERROR';
serviceName: string;
message?: string;
timestamp: Date;
}
// Data Processing Events
export interface DataPipelineEvent {
type: 'PIPELINE_CREATED' | 'PIPELINE_STARTED' | 'PIPELINE_COMPLETED' | 'PIPELINE_FAILED';
pipelineId: string;
pipelineName?: string;
timestamp: Date;
}
export interface DataJobEvent {
type: 'JOB_STARTED' | 'JOB_COMPLETED' | 'JOB_FAILED' | 'JOB_PROGRESS';
jobId: string;
pipelineId?: string;
progress?: number;
error?: string;
timestamp: Date;
}
export type TradingEvent = MarketDataEvent | OrderEvent | SignalEvent;
export type DataEvent = DataPipelineEvent | DataJobEvent;
export type Event = TradingEvent | RiskAlertEvent | SystemEvent | DataEvent;

View file

@ -1,110 +0,0 @@
/**
* Base feature store types
*/
export interface Feature {
id: string;
name: string;
description?: string;
dataType: FeatureDataType;
valueType: FeatureValueType;
tags: string[];
metadata: Record<string, any>;
createdAt: Date;
updatedAt: Date;
version: string;
status: FeatureStatus;
owner: string;
}
export enum FeatureDataType {
NUMERICAL = 'numerical',
CATEGORICAL = 'categorical',
BOOLEAN = 'boolean',
TEXT = 'text',
TIMESTAMP = 'timestamp',
ARRAY = 'array',
OBJECT = 'object'
}
export enum FeatureValueType {
INT32 = 'int32',
INT64 = 'int64',
FLOAT32 = 'float32',
FLOAT64 = 'float64',
STRING = 'string',
BYTES = 'bytes',
BOOL = 'bool',
UNIX_TIMESTAMP = 'unix_timestamp'
}
export enum FeatureStatus {
DRAFT = 'draft',
ACTIVE = 'active',
DEPRECATED = 'deprecated',
ARCHIVED = 'archived',
ERROR = 'error'
}
export interface FeatureValue {
featureId: string;
value: any;
timestamp: Date;
version?: string;
confidence?: number;
metadata?: Record<string, any>;
}
export interface FeatureVector {
entityId: string;
features: FeatureValue[];
timestamp: Date;
version?: string;
}
export interface FeatureQuery {
featureIds: string[];
entityIds: string[];
timestamp?: Date;
version?: string;
includeMetadata?: boolean;
}
export interface FeatureResponse {
vectors: FeatureVector[];
metadata: {
totalCount: number;
retrievedAt: Date;
version: string;
};
}
export interface FeatureComputation {
id: string;
featureId: string;
expression: string;
dependencies: string[];
schedule?: ComputationSchedule;
resources: ComputationResources;
status: ComputationStatus;
}
export interface ComputationSchedule {
cron: string;
timezone: string;
enabled: boolean;
}
export interface ComputationResources {
cpu: string;
memory: string;
timeout: number;
}
export enum ComputationStatus {
PENDING = 'pending',
RUNNING = 'running',
COMPLETED = 'completed',
FAILED = 'failed',
CANCELLED = 'cancelled'
}

View file

@ -1,124 +0,0 @@
/**
* Feature group types
*/
import { Feature, FeatureStatus } from './base';
export interface FeatureGroup {
id: string;
name: string;
description?: string;
features: Feature[];
tags: string[];
metadata: Record<string, any>;
createdAt: Date;
updatedAt: Date;
version: string;
status: FeatureStatus;
owner: string;
entityIdColumns: string[];
eventTimeColumn?: string;
source: FeatureGroupSource;
}
export interface FeatureGroupSource {
type: SourceType;
config: SourceConfig;
schedule?: SourceSchedule;
}
export enum SourceType {
BATCH = 'batch',
STREAMING = 'streaming',
REQUEST_RESPONSE = 'request_response',
PUSH = 'push'
}
export interface SourceConfig {
// Base source configuration
[key: string]: any;
}
export interface BatchSourceConfig extends SourceConfig {
dataSource: string;
query?: string;
path?: string;
format: DataFormat;
options?: Record<string, any>;
}
export interface StreamingSourceConfig extends SourceConfig {
topic: string;
bootstrapServers: string[];
consumerGroup: string;
format: DataFormat;
deserializer?: string;
}
export enum DataFormat {
PARQUET = 'parquet',
AVRO = 'avro',
JSON = 'json',
CSV = 'csv',
DELTA = 'delta',
ICEBERG = 'iceberg'
}
export interface SourceSchedule {
cron: string;
timezone: string;
enabled: boolean;
retryConfig: RetryConfig;
}
export interface RetryConfig {
maxRetries: number;
backoffMs: number;
maxBackoffMs: number;
backoffMultiplier: number;
}
export interface FeatureGroupStats {
featureGroupId: string;
totalFeatures: number;
activeFeatures: number;
lastUpdated: Date;
dataFreshness: Date;
recordCount: number;
storageSize: number;
computeCost: number;
}
export interface FeatureGroupVersion {
version: string;
featureGroupId: string;
createdAt: Date;
createdBy: string;
changes: FeatureGroupChange[];
status: VersionStatus;
}
export interface FeatureGroupChange {
type: ChangeType;
featureId?: string;
field: string;
oldValue?: any;
newValue?: any;
description?: string;
}
export enum ChangeType {
FEATURE_ADDED = 'feature_added',
FEATURE_REMOVED = 'feature_removed',
FEATURE_MODIFIED = 'feature_modified',
SCHEMA_CHANGED = 'schema_changed',
SOURCE_CHANGED = 'source_changed',
METADATA_UPDATED = 'metadata_updated'
}
export enum VersionStatus {
DRAFT = 'draft',
ACTIVE = 'active',
DEPRECATED = 'deprecated',
ARCHIVED = 'archived'
}

View file

@ -1,6 +0,0 @@
// Feature store and feature engineering types
export * from './base';
export * from './groups';
export * from './serving';
export * from './lineage';
export * from './monitoring';

View file

@ -1,131 +0,0 @@
/**
* Feature lineage and dependency tracking types
*/
export interface FeatureLineage {
featureId: string;
upstreamDependencies: LineageDependency[];
downstreamDependents: LineageDependency[];
dataFlow: DataFlowNode[];
lastUpdated: Date;
}
export interface LineageDependency {
id: string;
name: string;
type: DependencyType;
relationship: RelationshipType;
metadata?: Record<string, any>;
}
export enum DependencyType {
FEATURE = 'feature',
FEATURE_GROUP = 'feature_group',
DATA_SOURCE = 'data_source',
TRANSFORMATION = 'transformation',
MODEL = 'model',
PIPELINE = 'pipeline'
}
export enum RelationshipType {
DERIVES_FROM = 'derives_from',
DEPENDS_ON = 'depends_on',
TRANSFORMS = 'transforms',
AGGREGATES = 'aggregates',
JOINS = 'joins',
FILTERS = 'filters'
}
export interface DataFlowNode {
id: string;
name: string;
type: NodeType;
operation: string;
inputs: string[];
outputs: string[];
properties: Record<string, any>;
}
export enum NodeType {
SOURCE = 'source',
TRANSFORMATION = 'transformation',
AGGREGATION = 'aggregation',
JOIN = 'join',
FILTER = 'filter',
SINK = 'sink'
}
export interface LineageQuery {
featureId: string;
direction: LineageDirection;
depth?: number;
includeMetadata?: boolean;
filters?: LineageFilter[];
}
export enum LineageDirection {
UPSTREAM = 'upstream',
DOWNSTREAM = 'downstream',
BOTH = 'both'
}
export interface LineageFilter {
field: string;
operator: FilterOperator;
value: any;
}
export enum FilterOperator {
EQUALS = 'equals',
NOT_EQUALS = 'not_equals',
CONTAINS = 'contains',
STARTS_WITH = 'starts_with',
IN = 'in',
NOT_IN = 'not_in'
}
export interface LineageAnalysis {
featureId: string;
impactAnalysis: ImpactAnalysis;
riskAssessment: RiskAssessment;
recommendations: LineageRecommendation[];
}
export interface ImpactAnalysis {
affectedFeatures: string[];
affectedModels: string[];
affectedPipelines: string[];
estimatedImpactScore: number;
criticalityLevel: CriticalityLevel;
}
export enum CriticalityLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface RiskAssessment {
breakageRisk: number;
dataQualityRisk: number;
performanceRisk: number;
complianceRisk: number;
overallRisk: number;
}
export interface LineageRecommendation {
type: RecommendationType;
priority: number;
description: string;
actionItems: string[];
estimatedEffort: string;
}
export enum RecommendationType {
OPTIMIZATION = 'optimization',
RISK_MITIGATION = 'risk_mitigation',
REFACTORING = 'refactoring',
DEPRECATION = 'deprecation',
ENHANCEMENT = 'enhancement'
}

View file

@ -1,157 +0,0 @@
/**
* Feature monitoring and observability types
*/
export interface FeatureMonitoring {
featureId: string;
monitoringConfig: MonitoringConfig;
alerts: FeatureAlert[];
metrics: FeatureMetrics;
status: MonitoringStatus;
}
export interface MonitoringConfig {
enabled: boolean;
samplingRate: number;
alertThresholds: AlertThreshold[];
monitoringWindows: MonitoringWindow[];
customChecks: CustomCheck[];
}
export interface AlertThreshold {
metric: string;
operator: ThresholdOperator;
value: number;
severity: AlertSeverity;
window: string;
}
export enum ThresholdOperator {
GREATER_THAN = 'gt',
LESS_THAN = 'lt',
GREATER_THAN_OR_EQUAL = 'gte',
LESS_THAN_OR_EQUAL = 'lte',
EQUALS = 'eq',
NOT_EQUALS = 'ne'
}
export enum AlertSeverity {
INFO = 'info',
WARNING = 'warning',
ERROR = 'error',
CRITICAL = 'critical'
}
export interface MonitoringWindow {
name: string;
duration: string;
aggregation: AggregationType;
}
export enum AggregationType {
SUM = 'sum',
AVERAGE = 'average',
MIN = 'min',
MAX = 'max',
COUNT = 'count',
PERCENTILE = 'percentile'
}
export interface CustomCheck {
id: string;
name: string;
expression: string;
frequency: string;
enabled: boolean;
}
export interface FeatureAlert {
id: string;
featureId: string;
type: AlertType;
severity: AlertSeverity;
message: string;
triggeredAt: Date;
resolvedAt?: Date;
status: AlertStatus;
metadata: Record<string, any>;
}
export enum AlertType {
DATA_DRIFT = 'data_drift',
SCHEMA_CHANGE = 'schema_change',
QUALITY_DEGRADATION = 'quality_degradation',
PERFORMANCE_ISSUE = 'performance_issue',
FRESHNESS_VIOLATION = 'freshness_violation',
CUSTOM = 'custom'
}
export enum AlertStatus {
ACTIVE = 'active',
ACKNOWLEDGED = 'acknowledged',
RESOLVED = 'resolved',
SUPPRESSED = 'suppressed'
}
export interface FeatureMetrics {
featureId: string;
timestamp: Date;
qualityMetrics: QualityMetrics;
performanceMetrics: PerformanceMetrics;
usageMetrics: UsageMetrics;
distributionMetrics: DistributionMetrics;
}
export interface QualityMetrics {
completeness: number;
accuracy: number;
consistency: number;
validity: number;
uniqueness: number;
nullRate: number;
outlierRate: number;
}
export interface PerformanceMetrics {
computeTimeMs: number;
memoryUsageMB: number;
throughputRps: number;
errorRate: number;
p50LatencyMs: number;
p95LatencyMs: number;
p99LatencyMs: number;
}
export interface UsageMetrics {
requestCount: number;
uniqueConsumers: number;
avgRequestsPerConsumer: number;
popularityScore: number;
lastAccessedAt: Date;
}
export interface DistributionMetrics {
mean: number;
median: number;
stddev: number;
min: number;
max: number;
skewness: number;
kurtosis: number;
percentiles: Record<string, number>;
histogram: HistogramBin[];
}
export interface HistogramBin {
lowerBound: number;
upperBound: number;
count: number;
frequency: number;
}
export enum MonitoringStatus {
ACTIVE = 'active',
PAUSED = 'paused',
ERROR = 'error',
DISABLED = 'disabled'
}

View file

@ -1,134 +0,0 @@
/**
* Feature serving and retrieval types
*/
import { FeatureVector, FeatureQuery } from './base';
export interface FeatureStore {
name: string;
type: FeatureStoreType;
config: FeatureStoreConfig;
capabilities: FeatureStoreCapabilities;
}
export enum FeatureStoreType {
ONLINE = 'online',
OFFLINE = 'offline',
HYBRID = 'hybrid'
}
export interface FeatureStoreConfig {
connectionString?: string;
credentials?: Record<string, any>;
caching?: CachingConfig;
performance?: PerformanceConfig;
}
export interface CachingConfig {
enabled: boolean;
ttlSeconds: number;
maxSize: number;
strategy: CacheStrategy;
}
export enum CacheStrategy {
LRU = 'lru',
LFU = 'lfu',
TTL = 'ttl',
WRITE_THROUGH = 'write_through',
WRITE_BEHIND = 'write_behind'
}
export interface PerformanceConfig {
maxConcurrentRequests: number;
timeoutMs: number;
batchSize: number;
compressionEnabled: boolean;
}
export interface FeatureStoreCapabilities {
supportsPointInTimeCorrectness: boolean;
supportsStreaming: boolean;
supportsBatch: boolean;
supportsTransactions: boolean;
supportsVersioning: boolean;
maxFeatureVectorSize: number;
}
export interface FeatureServingRequest {
query: FeatureQuery;
options?: ServingOptions;
metadata?: Record<string, any>;
}
export interface ServingOptions {
consistencyLevel: ConsistencyLevel;
maxLatencyMs?: number;
fallbackStrategy?: FallbackStrategy;
includeStatistics?: boolean;
}
export enum ConsistencyLevel {
EVENTUAL = 'eventual',
STRONG = 'strong',
BOUNDED_STALENESS = 'bounded_staleness'
}
export enum FallbackStrategy {
DEFAULT_VALUES = 'default_values',
CACHED_VALUES = 'cached_values',
COMPUTED_VALUES = 'computed_values',
FAIL_FAST = 'fail_fast'
}
export interface FeatureServingResponse {
vectors: FeatureVector[];
statistics?: ServingStatistics;
metadata: {
requestId: string;
servedAt: Date;
latencyMs: number;
sourceStore: string;
};
}
export interface ServingStatistics {
cacheHitRate: number;
avgLatencyMs: number;
errorRate: number;
throughputRps: number;
}
export interface OnlineServingConfig {
lowLatencyStores: string[];
fallbackStores: string[];
caching: CachingConfig;
circuitBreaker: CircuitBreakerConfig;
}
export interface CircuitBreakerConfig {
enabled: boolean;
failureThreshold: number;
timeoutMs: number;
resetTimeoutMs: number;
}
export interface OfflineServingConfig {
batchSize: number;
parallelism: number;
outputFormat: string;
partitioning: PartitioningConfig;
}
export interface PartitioningConfig {
columns: string[];
strategy: PartitioningStrategy;
buckets?: number;
}
export enum PartitioningStrategy {
HASH = 'hash',
RANGE = 'range',
LIST = 'list',
TIME = 'time'
}

View file

@ -1,282 +0,0 @@
// Access Control and Security Types
export interface AccessPolicy {
id: string;
name: string;
description?: string;
rules: AccessRule[];
scope: AccessScope;
enabled: boolean;
metadata?: Record<string, any>;
}
export interface AccessRule {
id: string;
name: string;
subjects: AccessSubject[];
actions: AccessAction[];
resources: AccessResource[];
conditions?: AccessCondition[];
effect: AccessEffect;
priority: number;
}
export interface AccessSubject {
type: SubjectType;
identifier: string;
attributes?: Record<string, any>;
}
export enum SubjectType {
USER = 'user',
GROUP = 'group',
ROLE = 'role',
SERVICE = 'service',
APPLICATION = 'application'
}
export interface AccessAction {
type: ActionType;
scope?: string[];
}
export enum ActionType {
READ = 'read',
WRITE = 'write',
DELETE = 'delete',
EXECUTE = 'execute',
ADMIN = 'admin',
AUDIT = 'audit'
}
export interface AccessResource {
type: ResourceType;
identifier: string;
attributes?: Record<string, any>;
}
export enum ResourceType {
DATASET = 'dataset',
TABLE = 'table',
COLUMN = 'column',
FILE = 'file',
API = 'api',
SERVICE = 'service',
FUNCTION = 'function'
}
export interface AccessCondition {
type: ConditionType;
operator: ConditionOperator;
value: any;
}
export enum ConditionType {
TIME = 'time',
IP_ADDRESS = 'ip_address',
LOCATION = 'location',
DEVICE = 'device',
CLASSIFICATION = 'classification',
CUSTOM = 'custom'
}
export enum ConditionOperator {
EQUALS = 'equals',
NOT_EQUALS = 'not_equals',
IN = 'in',
NOT_IN = 'not_in',
GREATER_THAN = 'greater_than',
LESS_THAN = 'less_than',
CONTAINS = 'contains',
REGEX = 'regex'
}
export enum AccessEffect {
ALLOW = 'allow',
DENY = 'deny'
}
export interface AccessScope {
environments: string[];
regions: string[];
organizations: string[];
projects: string[];
}
export interface AccessRequest {
id: string;
subject: AccessSubject;
action: AccessAction;
resource: AccessResource;
context: AccessContext;
timestamp: Date;
status: RequestStatus;
}
export interface AccessContext {
ipAddress?: string;
userAgent?: string;
location?: GeoLocation;
device?: DeviceInfo;
session?: SessionInfo;
additional?: Record<string, any>;
}
export interface GeoLocation {
country: string;
region: string;
city: string;
latitude: number;
longitude: number;
}
export interface DeviceInfo {
id: string;
type: DeviceType;
os: string;
browser?: string;
trusted: boolean;
}
export enum DeviceType {
DESKTOP = 'desktop',
MOBILE = 'mobile',
TABLET = 'tablet',
SERVER = 'server',
IOT = 'iot'
}
export interface SessionInfo {
id: string;
startTime: Date;
lastActivity: Date;
authenticated: boolean;
mfaVerified: boolean;
}
export enum RequestStatus {
PENDING = 'pending',
APPROVED = 'approved',
DENIED = 'denied',
EXPIRED = 'expired',
REVOKED = 'revoked'
}
export interface AccessAuditLog {
id: string;
timestamp: Date;
subject: AccessSubject;
action: AccessAction;
resource: AccessResource;
decision: AccessDecision;
reason: string;
context: AccessContext;
}
export interface AccessDecision {
effect: AccessEffect;
policies: string[];
evaluationTime: number;
cached: boolean;
}
export interface AccessDataClassification {
level: ClassificationLevel;
categories: DataCategory[];
handling: HandlingRequirement[];
retention: AccessRetentionPolicy;
sensitivity: SensitivityMarking[];
}
export enum ClassificationLevel {
PUBLIC = 'public',
INTERNAL = 'internal',
CONFIDENTIAL = 'confidential',
RESTRICTED = 'restricted',
SECRET = 'secret',
TOP_SECRET = 'top_secret'
}
export enum DataCategory {
PII = 'pii',
PHI = 'phi',
FINANCIAL = 'financial',
TRADE_SECRET = 'trade_secret',
INTELLECTUAL_PROPERTY = 'intellectual_property',
REGULATORY = 'regulatory'
}
export interface HandlingRequirement {
type: HandlingType;
mandatory: boolean;
description: string;
}
export enum HandlingType {
ENCRYPTION_AT_REST = 'encryption_at_rest',
ENCRYPTION_IN_TRANSIT = 'encryption_in_transit',
ACCESS_LOGGING = 'access_logging',
BACKUP_RESTRICTION = 'backup_restriction',
GEOGRAPHIC_RESTRICTION = 'geographic_restriction',
TIME_RESTRICTION = 'time_restriction'
}
export interface AccessRetentionPolicy {
period: RetentionPeriod;
disposal: DisposalMethod;
exceptions: RetentionException[];
}
export interface RetentionPeriod {
duration: number;
unit: AccessTimeUnit;
triggers: RetentionTrigger[];
}
export enum AccessTimeUnit {
DAYS = 'days',
WEEKS = 'weeks',
MONTHS = 'months',
YEARS = 'years'
}
export enum RetentionTrigger {
CREATION_DATE = 'creation_date',
LAST_ACCESS = 'last_access',
BUSINESS_EVENT = 'business_event',
LEGAL_HOLD = 'legal_hold'
}
export enum DisposalMethod {
SOFT_DELETE = 'soft_delete',
HARD_DELETE = 'hard_delete',
ANONYMIZATION = 'anonymization',
ENCRYPTION_KEY_DESTRUCTION = 'encryption_key_destruction'
}
export interface RetentionException {
reason: string;
period: RetentionPeriod;
approver: string;
expiration: Date;
}
export interface SensitivityMarking {
type: MarkingType;
value: string;
scope: MarkingScope;
}
export enum MarkingType {
CLASSIFICATION = 'classification',
HANDLING = 'handling',
DISSEMINATION = 'dissemination',
CUSTOM = 'custom'
}
export enum MarkingScope {
DATASET = 'dataset',
FIELD = 'field',
RECORD = 'record',
VALUE = 'value'
}

View file

@ -1,253 +0,0 @@
/**
* Data catalog and metadata types
*/
export interface DataAsset {
id: string;
name: string;
type: AssetType;
description?: string;
tags: string[];
schema: DataSchema;
location: AssetLocation;
metadata: AssetMetadata;
governance: GovernanceInfo;
createdAt: Date;
updatedAt: Date;
version: string;
}
export enum AssetType {
TABLE = 'table',
VIEW = 'view',
DATASET = 'dataset',
FEATURE_GROUP = 'feature_group',
MODEL = 'model',
PIPELINE = 'pipeline',
REPORT = 'report',
API = 'api'
}
export interface DataSchema {
columns: ColumnDefinition[];
primaryKeys: string[];
foreignKeys: ForeignKey[];
indexes: IndexDefinition[];
constraints: ConstraintDefinition[];
}
export interface ColumnDefinition {
name: string;
dataType: string;
nullable: boolean;
defaultValue?: any;
description?: string;
tags: string[];
constraints: string[];
statistics?: ColumnStatistics;
}
export interface ColumnStatistics {
distinctCount: number;
nullCount: number;
minValue?: any;
maxValue?: any;
avgLength?: number;
topValues: ValueCount[];
}
export interface ValueCount {
value: any;
count: number;
frequency: number;
}
export interface ForeignKey {
columnNames: string[];
referencedTable: string;
referencedColumns: string[];
name?: string;
}
export interface IndexDefinition {
name: string;
columns: string[];
type: IndexType;
unique: boolean;
}
export enum IndexType {
BTREE = 'btree',
HASH = 'hash',
BITMAP = 'bitmap',
FULLTEXT = 'fulltext'
}
export interface ConstraintDefinition {
name: string;
type: ConstraintType;
columns: string[];
expression?: string;
}
export enum ConstraintType {
PRIMARY_KEY = 'primary_key',
FOREIGN_KEY = 'foreign_key',
UNIQUE = 'unique',
CHECK = 'check',
NOT_NULL = 'not_null'
}
export interface AssetLocation {
type: LocationType;
uri: string;
connection: string;
path?: string;
format?: string;
options?: Record<string, any>;
}
export enum LocationType {
DATABASE = 'database',
FILE_SYSTEM = 'file_system',
OBJECT_STORE = 'object_store',
STREAMING = 'streaming',
API_ENDPOINT = 'api_endpoint'
}
export interface AssetMetadata {
businessContext: BusinessContext;
technicalContext: TechnicalContext;
qualityProfile: QualityProfile;
usage: UsageProfile;
lineage: LineageInfo;
}
export interface QualityProfile {
completeness: number;
accuracy: number;
consistency: number;
validity: number;
freshness: number;
lastAssessed: Date;
}
export interface UsageProfile {
accessCount: number;
lastAccessed: Date;
popularQueries: string[];
topUsers: string[];
usagePattern: UsagePattern;
}
export enum UsagePattern {
BATCH = 'batch',
STREAMING = 'streaming',
INTERACTIVE = 'interactive',
MIXED = 'mixed'
}
export interface LineageInfo {
upstream: DataLineageNode[];
downstream: DataLineageNode[];
transformations: TransformationInfo[];
lastUpdated: Date;
}
export interface DataLineageNode {
id: string;
type: NodeType;
name: string;
path: string;
system: string;
}
export enum NodeType {
SOURCE = 'source',
TARGET = 'target',
TRANSFORM = 'transform',
VIEW = 'view',
TABLE = 'table',
FILE = 'file'
}
export interface TransformationInfo {
id: string;
type: string;
description: string;
code?: string;
parameters?: Record<string, any>;
}
export interface BusinessContext {
domain: string;
subdomain?: string;
businessOwner: string;
businessDescription?: string;
businessRules: string[];
criticalityLevel: CriticalityLevel;
}
export enum CriticalityLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface TechnicalContext {
dataOwner: string;
maintainer: string;
technology: string;
updateFrequency: UpdateFrequency;
retentionPolicy: RetentionPolicy;
backupPolicy: BackupPolicy;
}
export enum UpdateFrequency {
REAL_TIME = 'real_time',
STREAMING = 'streaming',
HOURLY = 'hourly',
DAILY = 'daily',
WEEKLY = 'weekly',
MONTHLY = 'monthly',
YEARLY = 'yearly',
MANUAL = 'manual'
}
export interface RetentionPolicy {
retentionPeriod: string;
archiveAfter?: string;
deleteAfter?: string;
retentionReason: string;
}
export interface BackupPolicy {
enabled: boolean;
frequency: string;
retentionPeriod: string;
location: string;
}
export interface GovernanceInfo {
classification: DataClassification;
sensitivityLevel: SensitivityLevel;
accessPolicy: string;
complianceRequirements: string[];
dataProtectionMeasures: string[];
approvalWorkflow?: string;
}
export enum DataClassification {
PUBLIC = 'public',
INTERNAL = 'internal',
CONFIDENTIAL = 'confidential',
RESTRICTED = 'restricted'
}
export enum SensitivityLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}

View file

@ -1,183 +0,0 @@
// Compliance and Regulatory Types
export interface CompliancePolicy {
id: string;
name: string;
description?: string;
regulation: RegulationType;
requirements: ComplianceRequirement[];
scope: ComplianceScope;
enabled: boolean;
metadata?: Record<string, any>;
}
export enum RegulationType {
SOX = 'sox',
GDPR = 'gdpr',
CCPA = 'ccpa',
HIPAA = 'hipaa',
PCI_DSS = 'pci_dss',
SOC2 = 'soc2',
ISO27001 = 'iso27001',
CUSTOM = 'custom'
}
export interface ComplianceRequirement {
id: string;
name: string;
description: string;
controls: ComplianceControl[];
severity: ComplianceSeverity;
mandatory: boolean;
}
export enum ComplianceSeverity {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface ComplianceControl {
id: string;
type: ControlType;
implementation: ControlImplementation;
verification: ControlVerification;
status: ControlStatus;
}
export enum ControlType {
PREVENTIVE = 'preventive',
DETECTIVE = 'detective',
CORRECTIVE = 'corrective',
COMPENSATING = 'compensating'
}
export interface ControlImplementation {
automated: boolean;
frequency: ControlFrequency;
responsible: string[];
documentation: string[];
}
export enum ControlFrequency {
CONTINUOUS = 'continuous',
DAILY = 'daily',
WEEKLY = 'weekly',
MONTHLY = 'monthly',
QUARTERLY = 'quarterly',
ANNUALLY = 'annually',
ON_DEMAND = 'on_demand'
}
export interface ControlVerification {
method: VerificationMethod;
evidence: EvidenceType[];
frequency: ControlFrequency;
responsible: string[];
}
export enum VerificationMethod {
AUTOMATED_TEST = 'automated_test',
MANUAL_REVIEW = 'manual_review',
AUDIT = 'audit',
WALKTHROUGH = 'walkthrough',
OBSERVATION = 'observation'
}
export enum EvidenceType {
SCREENSHOT = 'screenshot',
LOG_FILE = 'log_file',
DOCUMENT = 'document',
REPORT = 'report',
ATTESTATION = 'attestation',
SYSTEM_OUTPUT = 'system_output'
}
export enum ControlStatus {
EFFECTIVE = 'effective',
INEFFECTIVE = 'ineffective',
NOT_TESTED = 'not_tested',
DEFICIENT = 'deficient',
NOT_APPLICABLE = 'not_applicable'
}
export interface ComplianceScope {
systems: string[];
processes: string[];
dataTypes: string[];
locations: string[];
timeframe: TimeFrame;
}
export interface TimeFrame {
start: Date;
end: Date;
ongoing: boolean;
}
export interface ComplianceAssessment {
id: string;
policyId: string;
timestamp: Date;
assessor: string;
status: AssessmentStatus;
findings: ComplianceFinding[];
recommendations: ComplianceRecommendation[];
score: number;
}
export enum AssessmentStatus {
COMPLIANT = 'compliant',
NON_COMPLIANT = 'non_compliant',
PARTIALLY_COMPLIANT = 'partially_compliant',
NOT_ASSESSED = 'not_assessed'
}
export interface ComplianceFinding {
id: string;
requirementId: string;
controlId: string;
severity: ComplianceSeverity;
description: string;
evidence: string[];
remediation: string;
dueDate?: Date;
status: FindingStatus;
}
export enum FindingStatus {
OPEN = 'open',
IN_PROGRESS = 'in_progress',
CLOSED = 'closed',
DEFERRED = 'deferred',
ACCEPTED_RISK = 'accepted_risk'
}
export interface ComplianceRecommendation {
id: string;
priority: RecommendationPriority;
description: string;
implementation: string;
effort: EffortLevel;
impact: ImpactLevel;
}
export enum RecommendationPriority {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
URGENT = 'urgent'
}
export enum EffortLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high'
}
export enum ImpactLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high'
}

View file

@ -1,6 +0,0 @@
// Data governance and metadata management types
export * from './catalog';
export * from './quality';
export * from './lifecycle';
export * from './compliance';
export * from './access';

View file

@ -1,160 +0,0 @@
// Data Lifecycle Management Types
export interface LifecyclePolicy {
id: string;
name: string;
description?: string;
rules: LifecycleRule[];
scope: LifecycleScope;
enabled: boolean;
metadata?: Record<string, any>;
}
export interface LifecycleRule {
id: string;
name: string;
condition: LifecycleCondition;
actions: LifecycleAction[];
priority: number;
enabled: boolean;
}
export interface LifecycleCondition {
age?: AgeCriteria;
size?: SizeCriteria;
usage?: UsageCriteria;
tags?: TagCriteria;
custom?: string;
}
export interface AgeCriteria {
unit: LifecycleTimeUnit;
value: number;
}
export enum LifecycleTimeUnit {
DAYS = 'days',
WEEKS = 'weeks',
MONTHS = 'months',
YEARS = 'years'
}
export interface SizeCriteria {
unit: SizeUnit;
value: number;
}
export enum SizeUnit {
BYTES = 'bytes',
KB = 'kb',
MB = 'mb',
GB = 'gb',
TB = 'tb'
}
export interface UsageCriteria {
accessCount: number;
lastAccessed: Date;
}
export interface TagCriteria {
tags: Record<string, string>;
operator: TagOperator;
}
export enum TagOperator {
AND = 'and',
OR = 'or',
NOT = 'not'
}
export interface LifecycleAction {
type: LifecycleActionType;
config: LifecycleActionConfig;
}
export enum LifecycleActionType {
ARCHIVE = 'archive',
DELETE = 'delete',
COMPRESS = 'compress',
MIGRATE = 'migrate',
NOTIFY = 'notify',
CUSTOM = 'custom'
}
export interface LifecycleActionConfig {
destination?: string;
notification?: NotificationConfig;
compression?: CompressionConfig;
migration?: MigrationConfig;
custom?: Record<string, any>;
}
export interface NotificationConfig {
recipients: string[];
subject: string;
template: string;
}
export interface CompressionConfig {
algorithm: CompressionAlgorithm;
level: number;
}
export enum CompressionAlgorithm {
GZIP = 'gzip',
BZIP2 = 'bzip2',
LZ4 = 'lz4',
ZSTD = 'zstd'
}
export interface MigrationConfig {
destination: string;
preserveMetadata: boolean;
verification: boolean;
}
export interface LifecycleScope {
datasets?: string[];
collections?: string[];
tags?: Record<string, string>;
pattern?: string;
}
export interface LifecycleExecution {
id: string;
policyId: string;
timestamp: Date;
status: ExecutionStatus;
summary: ExecutionSummary;
details: ExecutionDetail[];
}
export enum ExecutionStatus {
PENDING = 'pending',
RUNNING = 'running',
COMPLETED = 'completed',
FAILED = 'failed',
CANCELLED = 'cancelled'
}
export interface ExecutionSummary {
totalItems: number;
processedItems: number;
failedItems: number;
duration: number;
}
export interface ExecutionDetail {
itemId: string;
action: LifecycleActionType;
status: ItemStatus;
message?: string;
timestamp: Date;
}
export enum ItemStatus {
SUCCESS = 'success',
FAILED = 'failed',
SKIPPED = 'skipped'
}

View file

@ -1,107 +0,0 @@
// Data Quality Management Types
export interface DataQualityProfile {
id: string;
name: string;
description?: string;
rules: DataQualityRule[];
thresholds: QualityThreshold[];
schedule?: QualitySchedule;
enabled: boolean;
metadata?: Record<string, any>;
}
export interface DataQualityRule {
id: string;
name: string;
type: QualityRuleType;
condition: string;
severity: QualitySeverity;
message?: string;
enabled: boolean;
}
export enum QualityRuleType {
COMPLETENESS = 'completeness',
UNIQUENESS = 'uniqueness',
VALIDITY = 'validity',
CONSISTENCY = 'consistency',
ACCURACY = 'accuracy',
TIMELINESS = 'timeliness',
CUSTOM = 'custom'
}
export enum QualitySeverity {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export interface QualityThreshold {
metric: string;
operator: ThresholdOperator;
value: number;
severity: QualitySeverity;
}
export enum ThresholdOperator {
GREATER_THAN = 'gt',
GREATER_THAN_EQUAL = 'gte',
LESS_THAN = 'lt',
LESS_THAN_EQUAL = 'lte',
EQUAL = 'eq',
NOT_EQUAL = 'ne'
}
export interface QualitySchedule {
cron: string;
timezone: string;
enabled: boolean;
}
export interface QualityReport {
id: string;
profileId: string;
datasetId: string;
timestamp: Date;
status: QualityStatus;
metrics: QualityMetrics;
violations: QualityViolation[];
summary: QualitySummary;
}
export enum QualityStatus {
PASSED = 'passed',
WARNING = 'warning',
FAILED = 'failed',
ERROR = 'error'
}
export interface QualityMetrics {
completeness: number;
uniqueness: number;
validity: number;
consistency: number;
accuracy: number;
timeliness: number;
overall: number;
}
export interface QualityViolation {
ruleId: string;
ruleName: string;
severity: QualitySeverity;
count: number;
percentage: number;
samples?: any[];
message: string;
}
export interface QualitySummary {
totalRecords: number;
validRecords: number;
invalidRecords: number;
score: number;
status: QualityStatus;
}

View file

@ -1,115 +0,0 @@
// Export all types from their respective domains
// Market Data Types
export * from './market/market-data';
// Trading Types
export * from './trading/orders';
// Strategy Types
export * from './strategy/strategy';
export * from './strategy/backtest';
// Events
export * from './events/events';
// API Types - Use aliases to avoid conflicts
export {
ServiceConfig,
ApiHealthStatus,
ApiResponse,
PaginatedResponse,
ErrorResponse as ApiErrorResponse,
SuccessResponse
} from './api/api';
// Configuration Types (Core config only to avoid conflicts)
export * from './config/database';
export * from './config/logging';
export * from './config/security';
// Monitoring Types - Use aliases to avoid conflicts
export {
HealthStatus,
HealthCheckConfig as MonitoringHealthCheckConfig,
DependencyHealth,
HealthMetrics,
ReadinessCheck,
LivenessCheck
} from './monitoring/health';
export * from './monitoring/metrics';
// Data Processing Types - Use aliases to avoid conflicts
export {
DataSourceConfig,
DataRateLimitConfig,
DataConnectionConfig,
DataAuthenticationConfig,
SubscriptionConfig as DataSubscriptionConfig,
RetryPolicyConfig
} from './data/sources';
export * from './data/processors';
// Communication Types - Main subscription system preferred
export * from './communication/subscriptions';
export * from './communication/messages';
// Error Handling Types - Use aliases to avoid conflicts
export {
BaseError,
ErrorContext,
ErrorResponse as BaseErrorResponse,
ErrorCode,
ErrorSeverity as BaseErrorSeverity
} from './errors/base';
export {
ValidationError,
ValidationRule as ErrorValidationRule,
SchemaValidationError,
BusinessRuleValidationError
} from './errors/validation';
export * from './errors/network';
export * from './errors/business';
export * from './errors/application';
// Governance Types - Catalog types with alias to avoid conflicts
export {
DataAsset,
AssetType,
DataSchema as CatalogDataSchema,
ColumnDefinition,
ColumnStatistics,
ValueCount,
ForeignKey as CatalogForeignKey,
IndexDefinition,
IndexType,
ConstraintDefinition,
ConstraintType,
AssetLocation,
LocationType,
AssetMetadata,
QualityProfile,
UsageProfile,
UsagePattern,
LineageInfo,
DataLineageNode,
NodeType,
TransformationInfo,
BusinessContext,
CriticalityLevel,
TechnicalContext,
UpdateFrequency,
RetentionPolicy as CatalogRetentionPolicy,
BackupPolicy,
GovernanceInfo,
DataClassification as CatalogDataClassification,
SensitivityLevel
} from './governance/catalog';
// All modules successfully enabled - conflicts resolved with type renaming and aliases
export * from './communication/websocket';
export * from './communication/protocols';
export * from './governance/quality';
export * from './governance/lifecycle';
export * from './governance/compliance';
export * from './governance/access';

View file

@ -1,109 +0,0 @@
// Market Data Types
export interface MarketDataTick {
symbol: string;
timestamp: number;
price: number;
volume: number;
bid?: number;
ask?: number;
bidSize?: number;
askSize?: number;
source: string;
exchange?: string;
lastTradeSize?: number;
dayHigh?: number;
dayLow?: number;
dayOpen?: number;
prevClose?: number;
change?: number;
changePercent?: number;
}
export interface MarketDataCandle {
symbol: string;
timestamp: number;
open: number;
high: number;
low: number;
close: number;
volume: number;
timeframe: string;
source: string;
exchange?: string;
vwap?: number;
trades?: number;
}
export interface MarketDataTrade {
id: string;
symbol: string;
timestamp: number;
price: number;
size: number;
side: 'buy' | 'sell';
source: string;
exchange?: string;
conditions?: string[];
}
export interface MarketDataOrder {
id: string;
symbol: string;
timestamp: number;
side: 'buy' | 'sell';
price: number;
size: number;
source: string;
exchange?: string;
orderType?: 'market' | 'limit' | 'stop';
level?: number;
}
// Legacy types for backward compatibility
export interface OHLCV {
symbol: string;
timestamp: Date;
open: number;
high: number;
low: number;
close: number;
volume: number;
}
export interface MarketData {
symbol: string;
price: number;
bid: number;
ask: number;
volume: number;
timestamp: Date;
}
export interface OrderBook {
symbol: string;
bids: [number, number][]; // [price, size]
asks: [number, number][]; // [price, size]
timestamp: Date;
}
// Fundamental Data Types
export interface CompanyFundamentals {
symbol: string;
marketCap: number;
peRatio?: number;
pbRatio?: number;
roe?: number;
revenue: number;
netIncome: number;
lastUpdated: Date;
}
export interface NewsItem {
id: string;
headline: string;
summary: string;
sentiment: number; // -1 to 1
symbols: string[];
source: string;
publishedAt: Date;
}

View file

@ -1,83 +0,0 @@
// Alert and Notification Types
export interface Alert {
id: string;
ruleId: string;
severity: 'info' | 'warning' | 'error' | 'critical';
title: string;
message: string;
timestamp: Date;
resolved: boolean;
resolvedAt?: Date;
metadata?: Record<string, any>;
source: string;
tags?: string[];
}
export interface AlertRule {
id: string;
name: string;
metric: string;
condition: 'gt' | 'lt' | 'eq' | 'ne' | 'gte' | 'lte';
threshold: number;
duration: number;
enabled: boolean;
severity?: 'info' | 'warning' | 'error' | 'critical';
description?: string;
labels?: Record<string, string>;
annotations?: Record<string, string>;
}
export interface AlertChannel {
id: string;
name: string;
type: 'email' | 'slack' | 'webhook' | 'pagerduty' | 'discord';
config: AlertChannelConfig;
enabled: boolean;
filters?: AlertFilter[];
}
export interface AlertChannelConfig {
url?: string;
token?: string;
channel?: string;
username?: string;
password?: string;
headers?: Record<string, string>;
template?: string;
}
export interface AlertFilter {
field: string;
operator: 'equals' | 'contains' | 'regex' | 'not_equals';
value: string;
}
export interface NotificationConfig {
enabled: boolean;
channels: AlertChannel[];
defaultChannel: string;
retryAttempts: number;
retryDelay: number;
batchSize: number;
batchDelay: number;
}
export interface AlertHistory {
alertId: string;
action: 'triggered' | 'resolved' | 'acknowledged' | 'silenced';
timestamp: Date;
user?: string;
reason?: string;
metadata?: Record<string, any>;
}
export interface AlertSummary {
total: number;
critical: number;
error: number;
warning: number;
info: number;
resolved: number;
active: number;
timeRange: string;
}

View file

@ -1,52 +0,0 @@
// Health Check Types
export interface HealthStatus {
service: string;
status: 'healthy' | 'degraded' | 'unhealthy';
timestamp: Date;
uptime: number;
version: string;
dependencies: DependencyHealth[];
metrics: HealthMetrics;
message?: string;
details?: Record<string, any>;
}
export interface DependencyHealth {
name: string;
status: 'healthy' | 'unhealthy';
latencyMs?: number;
error?: string;
lastChecked?: Date;
version?: string;
}
export interface HealthMetrics {
connectionsActive: number;
messagesPerSecond: number;
errorRate: number;
avgLatencyMs: number;
memoryUsageMB?: number;
cpuUsagePercent?: number;
}
export interface HealthCheckConfig {
intervalMs: number;
timeoutMs: number;
retries: number;
enabledChecks: string[];
endpoints: Record<string, string>;
}
export interface ReadinessCheck {
name: string;
check: () => Promise<boolean>;
timeout: number;
critical: boolean;
}
export interface LivenessCheck {
name: string;
check: () => Promise<boolean>;
timeout: number;
restartOnFailure: boolean;
}

View file

@ -1,5 +0,0 @@
// Health Check and Monitoring Types
export * from './health';
export * from './metrics';
export * from './alerts';
export * from './system';

View file

@ -1,131 +0,0 @@
// Metrics Collection Types
export interface Metric {
name: string;
type: 'counter' | 'gauge' | 'histogram' | 'summary';
value: number;
labels?: Record<string, string>;
timestamp: Date;
unit?: string;
description?: string;
}
export interface MetricPoint {
timestamp: number;
value: number;
labels?: Record<string, string>;
}
export interface TimeSeriesMetric {
name: string;
points: MetricPoint[];
retentionMs: number;
}
export interface AggregatedMetrics {
totalMessages: number;
messagesPerSecond: number;
averageLatency: number;
errorRate: number;
activeConnections: number;
activeSubscriptions: number;
cacheHitRate: number;
uptime: number;
timestamp: string;
dataSources: Map<string, DataSourceMetrics>;
processing: ProcessingMetrics;
subscriptions: MonitoringSubscriptionMetrics;
}
export interface DataSourceMetrics {
sourceId: string;
timestamp: Date;
connections: ConnectionMetrics;
messages: MessageMetrics;
latency: LatencyMetrics;
bandwidth: BandwidthMetrics;
}
export interface ConnectionMetrics {
active: number;
total: number;
failed: number;
}
export interface MessageMetrics {
received: number;
processed: number;
errors: number;
dropped: number;
}
export interface LatencyMetrics {
avgMs: number;
p50Ms: number;
p95Ms: number;
p99Ms: number;
}
export interface BandwidthMetrics {
inboundBytesPerSecond: number;
outboundBytesPerSecond: number;
}
export interface ProcessingMetrics {
totalProcessed: number;
processedPerSecond: number;
processingLatency: number;
errorCount: number;
queueDepth: number;
processorMetrics: Map<string, any>;
}
export interface MonitoringSubscriptionMetrics {
totalSubscriptions: number;
activeClients: number;
messagesSent: number;
sendRate: number;
bandwidthUsage: number;
}
export interface SystemMetrics {
uptime: number;
memory: MemoryMetrics;
cpu: CpuMetrics;
network: NetworkMetrics;
disk: DiskMetrics;
timestamp: string;
}
export interface MemoryMetrics {
used: number;
total: number;
free: number;
heapUsed: number;
heapTotal: number;
external: number;
}
export interface CpuMetrics {
user: number;
system: number;
idle: number;
usage: number;
}
export interface NetworkMetrics {
bytesIn: number;
bytesOut: number;
packetsIn: number;
packetsOut: number;
errors: number;
}
export interface DiskMetrics {
used: number;
total: number;
free: number;
readOps: number;
writeOps: number;
readBytes: number;
writeBytes: number;
}

View file

@ -1,57 +0,0 @@
import { ApiKeyConfig } from '../config/security';
import { RetryConfig } from '../config/networking';
// System and Service Integration Types
export interface ServiceHealth {
serviceId: string;
status: 'healthy' | 'degraded' | 'unhealthy' | 'unreachable';
lastCheck: number;
responseTime: number;
errorCount: number;
version?: string;
metadata?: Record<string, any>;
}
export interface IntegrationMetrics {
totalRequests: number;
successfulRequests: number;
failedRequests: number;
averageResponseTime: number;
lastRequestTime: number;
errorRate: number;
uptime: number;
}
export interface ServiceIntegration {
serviceName: string;
endpoint: string;
healthCheck: string;
authentication?: ApiKeyConfig;
retryPolicy: RetryConfig;
timeout?: number;
enabled: boolean;
}
export interface ServiceEndpoint {
id: string;
name: string;
url: string;
method: string;
headers?: Record<string, string>;
timeout: number;
retries: number;
healthCheck?: boolean;
}
export interface ServiceRegistry {
services: Map<string, ServiceEndpoint>;
lastUpdated: Date;
version: string;
}
export interface ServiceDiscovery {
provider: 'consul' | 'etcd' | 'kubernetes' | 'static';
config: Record<string, any>;
refreshInterval: number;
healthCheckInterval: number;
}

View file

@ -1,53 +0,0 @@
// Trading Signal Types
import { SignalType } from './strategy';
export interface Signal {
symbol: string;
type: SignalType;
strength: number; // 0-1
price: number;
timestamp: Date;
strategyId: string;
metadata?: Record<string, any>;
}
export interface BacktestConfig {
strategyId: string;
startDate: Date;
endDate: Date;
symbols: string[];
initialCapital: number;
parameters: Record<string, any>;
}
export interface BacktestResult {
id: string;
strategyId: string;
startDate: Date;
endDate: Date;
symbols: string[];
initialCapital: number;
finalCapital: number;
totalReturn: number;
annualizedReturn: number;
maxDrawdown: number;
sharpeRatio: number;
trades: BacktestTrade[];
dailyPerformance: DailyPerformance[];
}
export interface BacktestTrade {
symbol: string;
side: 'BUY' | 'SELL';
quantity: number;
price: number;
timestamp: Date;
pnl?: number;
}
export interface DailyPerformance {
date: Date;
portfolioValue: number;
dailyPnL: number;
dailyReturn: number;
}

View file

@ -1,28 +0,0 @@
// Strategy Types
export type SignalType = 'BUY' | 'SELL' | 'HOLD';
export interface TradingSignal {
symbol: string;
type: SignalType;
strength: number; // 0-1
price: number;
timestamp: Date;
strategyId: string;
metadata?: Record<string, any>;
}
export interface Strategy {
id: string;
name: string;
description: string;
isActive: boolean;
riskLimits: RiskLimits;
parameters: Record<string, any>;
}
export interface RiskLimits {
maxPositionSize: number;
maxDailyLoss: number;
maxDrawdown: number;
allowedSymbols?: string[];
}

View file

@ -1,35 +0,0 @@
// Trading Types
export type OrderSide = 'BUY' | 'SELL';
export type OrderType = 'MARKET' | 'LIMIT' | 'STOP' | 'STOP_LIMIT';
export type OrderStatus = 'PENDING' | 'FILLED' | 'PARTIALLY_FILLED' | 'CANCELLED' | 'REJECTED';
export interface Order {
id: string;
symbol: string;
side: OrderSide;
type: OrderType;
quantity: number;
price?: number;
stopPrice?: number;
status: OrderStatus;
timestamp: Date;
strategyId: string;
}
export interface Position {
symbol: string;
quantity: number;
averagePrice: number;
marketValue: number;
unrealizedPnL: number;
timestamp: Date;
}
export interface Portfolio {
cash: number;
totalValue: number;
positions: Position[];
dayPnL: number;
totalPnL: number;
timestamp: Date;
}

View file

@ -1,17 +0,0 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
"references": [
{ "path": "../api-client" },
{ "path": "../config" },
{ "path": "../event-bus" },
{ "path": "../http-client" },
{ "path": "../utils" },
]
}

View file

@ -14,6 +14,5 @@
{ "path": "../config" },
{ "path": "../event-bus" },
{ "path": "../http-client" },
{ "path": "../types" },
]
}

52
package-lock.json generated
View file

@ -21,50 +21,6 @@
"node": ">=18.0.0"
}
},
"apps/core-services/market-data-gateway": {
"version": "1.0.0",
"dependencies": {
"@stock-bot/config": "*",
"@stock-bot/types": "*",
"hono": "^4.6.3",
"ioredis": "^5.4.1",
"ws": "^8.18.0"
},
"devDependencies": {
"@types/ws": "^8.5.12",
"bun-types": "^1.2.15"
}
},
"apps/core-services/risk-guardian": {
"version": "1.0.0",
"dependencies": {
"@stock-bot/config": "*",
"@stock-bot/types": "*",
"hono": "^4.6.3",
"ioredis": "^5.4.1",
"ws": "^8.18.0"
},
"devDependencies": {
"@types/ws": "^8.5.12",
"bun-types": "^1.2.15"
}
},
"apps/intelligence-services/strategy-orchestrator": {
"version": "1.0.0",
"dependencies": {
"@stock-bot/config": "*",
"@stock-bot/types": "*",
"hono": "^4.6.3",
"ioredis": "^5.4.1",
"node-cron": "^3.0.3",
"ws": "^8.18.0"
},
"devDependencies": {
"@types/node-cron": "^3.0.11",
"@types/ws": "^8.5.12",
"bun-types": "^1.2.15"
}
},
"apps/interface-services/trading-dashboard": {
"version": "0.0.0",
"dependencies": {
@ -7960,20 +7916,12 @@
"name": "@stock-bot/config",
"version": "1.0.0",
"dependencies": {
"@stock-bot/types": "*",
"dotenv": "^16.4.5"
},
"devDependencies": {
"@types/node": "^20.12.12",
"typescript": "^5.4.5"
}
},
"packages/types": {
"name": "@stock-bot/types",
"version": "1.0.0",
"devDependencies": {
"typescript": "^5.4.5"
}
}
}
}

View file

@ -39,13 +39,13 @@
"exclude": [
"node_modules",
"dist"
], "references": [
],
"references": [
{ "path": "./libs/api-client" },
{ "path": "./libs/config" },
{ "path": "./libs/event-bus" },
{ "path": "./libs/http-client" },
{ "path": "./libs/logger" },
{ "path": "./libs/types" },
{ "path": "./libs/utils" },
]