removed doodoo projects, getting ready for restructuring
This commit is contained in:
parent
674112af05
commit
5c64b1ccf8
82 changed files with 5 additions and 8917 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
|
|
|
|||
|
|
@ -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}`);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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 }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
@ -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`);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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" },
|
||||
]
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
{ "path": "../api-client" },
|
||||
{ "path": "../event-bus" },
|
||||
{ "path": "../http-client" },
|
||||
{ "path": "../types" },
|
||||
{ "path": "../utils" },
|
||||
{ "path": "../utils" }
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
});
|
||||
```
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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" },
|
||||
]
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
# HTTP Client Library Bun Test Configuration
|
||||
|
||||
[test]
|
||||
# Test configuration
|
||||
timeout = 5000
|
||||
|
||||
# Enable TypeScript paths resolution
|
||||
[bun]
|
||||
paths = {
|
||||
"@/*" = ["./src/*"]
|
||||
}
|
||||
|
|
@ -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);
|
||||
});
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
});
|
||||
});
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
|
@ -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" },
|
||||
]
|
||||
}
|
||||
|
|
@ -10,7 +10,6 @@
|
|||
],
|
||||
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
|
||||
"references": [
|
||||
{ "path": "../config" },
|
||||
{ "path": "../types" }
|
||||
{ "path": "../config" }
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
{ "path": "../api-client" },
|
||||
{ "path": "../event-bus" },
|
||||
{ "path": "../http-client" },
|
||||
{ "path": "../types" },
|
||||
{ "path": "../utils" },
|
||||
{ "path": "../config" },
|
||||
{ "path": "../logger" },
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
};
|
||||
```
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// Communication and Messaging Types
|
||||
export * from './websocket';
|
||||
export * from './subscriptions';
|
||||
export * from './messages';
|
||||
export * from './protocols';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
// Data Processing and Pipeline Types
|
||||
export * from './sources';
|
||||
export * from './processors';
|
||||
export * from './pipelines';
|
||||
export * from './transformations';
|
||||
export * from './quality';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>;
|
||||
}
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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: '=' | '<>' | '<' | '>' | '<=' | '>=';
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
// Error handling types
|
||||
export * from './base';
|
||||
export * from './application';
|
||||
export * from './validation';
|
||||
export * from './network';
|
||||
export * from './business';
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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>;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
// Health Check and Monitoring Types
|
||||
export * from './health';
|
||||
export * from './metrics';
|
||||
export * from './alerts';
|
||||
export * from './system';
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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[];
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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" },
|
||||
]
|
||||
}
|
||||
|
|
@ -14,6 +14,5 @@
|
|||
{ "path": "../config" },
|
||||
{ "path": "../event-bus" },
|
||||
{ "path": "../http-client" },
|
||||
{ "path": "../types" },
|
||||
]
|
||||
}
|
||||
|
|
|
|||
52
package-lock.json
generated
52
package-lock.json
generated
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue