# Dependency Inversion Principle (DIP) Interfaces

Este directorio contiene las interfaces para implementar el Principio de Inversión de Dependencias (DIP) en el trading-platform backend.

## Estructura

```
interfaces/
├── cache.interface.ts           # Interface para servicios de cache
├── http-client.interface.ts     # Interface para clientes HTTP
├── index.ts                     # Export central de todas las interfaces
└── services/
    ├── auth.interface.ts        # Interfaces para servicios de autenticación
    └── trading.interface.ts     # Interfaces para servicios de trading
```

## Propósito

Las interfaces permiten:

1. **Desacoplamiento**: Los servicios dependen de abstracciones, no de implementaciones concretas
2. **Testabilidad**: Facilita crear mocks para pruebas unitarias
3. **Mantenibilidad**: Cambios en implementaciones no afectan a los consumidores
4. **Flexibilidad**: Permite cambiar implementaciones sin modificar el código cliente

## Interfaces Disponibles

### Core Infrastructure

#### `ICache`
Interface para operaciones de caché con TTL.

**Métodos principales:**
- `get<T>(key: string): T | null`
- `set<T>(key: string, data: T, ttlSeconds?: number): void`
- `getOrSet<T>(key: string, fetcher: () => Promise<T>, ttlSeconds?: number): Promise<T>`
- `delete(key: string): boolean`
- `clear(): void`

**Implementación actual:** `CacheService` y `MarketDataCache` en `/modules/trading/services/cache.service.ts`

#### `IHttpClient`
Interface para clientes HTTP basados en Axios.

**Métodos principales:**
- `get<T>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>`
- `post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<AxiosResponse<T>>`
- `isAvailable(): Promise<boolean>`

**Implementaciones actuales:**
- `LLMAgentClient` en `/shared/clients/llm-agent.client.ts`
- `MLEngineClient` en `/shared/clients/ml-engine.client.ts`
- `TradingAgentsClient` en `/shared/clients/trading-agents.client.ts`

### Authentication Services

#### `ITokenService`
Interface para gestión de tokens JWT y sesiones.

**Métodos principales:**
- `generateAccessToken(user: User): string`
- `verifyAccessToken(token: string): JWTPayload | null`
- `createSession(...): Promise<{ session: Session; tokens: AuthTokens }>`
- `refreshSession(refreshToken: string): Promise<AuthTokens | null>`
- `revokeSession(sessionId: string, userId: string): Promise<boolean>`

**Implementación actual:** `TokenService` en `/modules/auth/services/token.service.ts`

#### `IEmailService`
Interface para autenticación por email/password.

**Métodos principales:**
- `register(data: RegisterEmailRequest, ...): Promise<{ userId: string; message: string }>`
- `login(data: LoginEmailRequest, ...): Promise<AuthResponse>`
- `sendVerificationEmail(userId: string, email: string): Promise<void>`
- `verifyEmail(token: string): Promise<{ success: boolean; message: string }>`
- `resetPassword(token: string, newPassword: string): Promise<{ message: string }>`

**Implementación actual:** `EmailService` en `/modules/auth/services/email.service.ts`

#### `IOAuthService`
Interface para autenticación OAuth (Google, GitHub, etc.).

**Métodos principales:**
- `getAuthorizationUrl(provider: string, state: string): string`
- `handleCallback(provider: string, code: string, state: string, ...): Promise<AuthResponse>`

**Implementación actual:** `OAuthService` en `/modules/auth/services/oauth.service.ts`

#### `ITwoFactorService`
Interface para autenticación de dos factores (TOTP).

**Métodos principales:**
- `generateTOTPSecret(userId: string): Promise<{ secret: string; qrCode: string }>`
- `enableTOTP(userId: string, code: string): Promise<{ success: boolean; backupCodes: string[] }>`
- `verifyTOTP(userId: string, code: string): Promise<boolean>`

**Implementación actual:** `TwoFactorService` en `/modules/auth/services/twofa.service.ts`

#### `IPhoneService`
Interface para autenticación por SMS.

**Métodos principales:**
- `sendVerificationCode(phoneNumber: string): Promise<{ success: boolean }>`
- `verifyPhoneNumber(phoneNumber: string, code: string): Promise<{ success: boolean; token?: string }>`
- `loginWithPhone(phoneNumber: string, code: string): Promise<AuthResponse>`

**Implementación actual:** `PhoneService` en `/modules/auth/services/phone.service.ts`

### Trading Services

#### `IBinanceService`
Interface para cliente de API de Binance.

**Métodos principales:**
- `getServerTime(): Promise<number>`
- `getExchangeInfo(symbols?: string[]): Promise<ExchangeInfo>`
- `getKlines(symbol: string, interval: Interval, options?): Promise<Kline[]>`
- `get24hrTicker(symbol?: string): Promise<Ticker24h | Ticker24h[]>`
- `getPrice(symbol?: string): Promise<...>`
- `getOrderBook(symbol: string, limit?: number): Promise<OrderBook>`
- `subscribeKlines(symbol: string, interval: Interval): void`
- `subscribeTicker(symbol: string): void`

**Implementación actual:** `BinanceService` en `/modules/trading/services/binance.service.ts`

#### `IMarketService`
Interface para fachada de datos de mercado.

**Métodos principales:**
- `initialize(): Promise<void>`
- `getKlines(symbol: string, interval: Interval, options?): Promise<CandlestickData[]>`
- `getPrice(symbol: string): Promise<MarketPrice>`
- `getPrices(symbols?: string[]): Promise<MarketPrice[]>`
- `getTicker(symbol: string): Promise<MarketTicker>`
- `getWatchlist(symbols: string[]): Promise<WatchlistItem[]>`
- `getSymbolInfo(symbol: string): MarketSymbol | undefined`
- `searchSymbols(query: string, limit?: number): MarketSymbol[]`

**Implementación actual:** `MarketService` en `/modules/trading/services/market.service.ts`

## Uso con ServiceFactory

```typescript
import { ServiceFactory, ServiceKeys } from '@/shared/factories';
import type { ITokenService } from '@/shared/interfaces';

// En inicialización de la aplicación
import { tokenService } from '@/modules/auth/services/token.service';
ServiceFactory.register<ITokenService>(ServiceKeys.TOKEN_SERVICE, tokenService);

// En los servicios que necesitan dependencias
class AuthController {
  private tokenService: ITokenService;

  constructor() {
    this.tokenService = ServiceFactory.getRequired<ITokenService>(ServiceKeys.TOKEN_SERVICE);
  }

  async login(req: Request, res: Response) {
    const tokens = await this.tokenService.createSession(...);
    // ...
  }
}
```

## Migración de Singletons

Para migrar servicios singleton existentes:

1. **Crear interface** (si no existe)
2. **Implementar interface en clase existente**
3. **Registrar en ServiceFactory** (en app initialization)
4. **Actualizar consumidores** para usar ServiceFactory en lugar de importar singleton directamente

### Ejemplo de Migración

**Antes:**
```typescript
// token.service.ts
export class TokenService { ... }
export const tokenService = new TokenService();

// auth.controller.ts
import { tokenService } from './token.service';
```

**Después:**
```typescript
// token.service.ts
import type { ITokenService } from '@/shared/interfaces';

export class TokenService implements ITokenService { ... }
export const tokenService = new TokenService();

// index.ts (app initialization)
ServiceFactory.register<ITokenService>(ServiceKeys.TOKEN_SERVICE, tokenService);

// auth.controller.ts
import { ServiceFactory, ServiceKeys } from '@/shared/factories';
import type { ITokenService } from '@/shared/interfaces';

const tokenService = ServiceFactory.getRequired<ITokenService>(ServiceKeys.TOKEN_SERVICE);
```

## Testing

Las interfaces facilitan el testing con mocks:

```typescript
import { ServiceFactory, ServiceKeys } from '@/shared/factories';
import type { ITokenService } from '@/shared/interfaces';

describe('AuthController', () => {
  beforeEach(() => {
    // Mock implementation
    const mockTokenService: ITokenService = {
      generateAccessToken: jest.fn().mockReturnValue('mock-token'),
      createSession: jest.fn().mockResolvedValue({ ... }),
      // ... otros métodos
    };

    ServiceFactory.register<ITokenService>(ServiceKeys.TOKEN_SERVICE, mockTokenService);
  });

  afterEach(() => {
    ServiceFactory.clear();
  });

  it('should create session on login', async () => {
    // Test con mock
  });
});
```

## Próximos Pasos

1. Implementar interfaces en servicios existentes
2. Registrar servicios en ServiceFactory durante la inicialización
3. Actualizar consumidores para usar ServiceFactory
4. Crear tests unitarios con mocks
5. Documentar servicios adicionales según sea necesario
