Sources (Adaptadores de Lectura)
Los sources son adaptadores que leen datos de sistemas externos. Actualmente hay dos tipos implementados.
Tipos de Sources
classDiagram
class SourceAdapter {
<<interface>>
+name: string
+connect(): Promise~void~
+getData(entity, options): Promise~RowData[]~
+fetchOne(entity, pk): Promise~RowData|null~
+getPrimaryKey(entity): string[]
+supports(entity): boolean
+close(): Promise~void~
}
class MssqlSourceAdapter {
-pool: ConnectionPool
-entities: Record
+connect()
+getData()
+fetchOne()
}
class HttpSourceAdapter {
-config: HttpConfig
-entities: Record
+connect()
+getData()
+fetchOne()
}
SourceAdapter <|.. MssqlSourceAdapter
SourceAdapter <|.. HttpSourceAdapter
MSSQL Source
Lee datos de SQL Server (Tango).
Configuración
// src/config/sources/tango.ts
export const tangoSource: MssqlSourceConfig = {
name: 'tango',
type: 'mssql-source',
config: {
server: process.env.MSSQL_SERVER || 'localhost',
port: parseInt(process.env.MSSQL_PORT || '1433'),
database: process.env.MSSQL_DATABASE || 'tango',
user: process.env.MSSQL_USER || 'sa',
password: process.env.MSSQL_PASSWORD || '',
},
entities: {
articulos: {
table: 'WEBVIEW',
primaryKey: ['CODIGO'],
},
clientes: {
table: 'WEBCLIENTE',
primaryKey: ['Cod Cliente'],
},
pedidos: {
table: 'WMS_Pedidos',
primaryKey: ['Nro. Pedido'],
},
// ... más entities
},
};
Entity Config
| Propiedad | Tipo | Descripción |
|---|---|---|
table |
string | Nombre de la tabla/vista |
primaryKey |
string[] | Campos que forman la PK |
condition |
string? | WHERE adicional |
join |
string? | JOINs adicionales |
staticData |
RowData[]? | Datos estáticos (sin query) |
Ejemplo con Condición
Ejemplo con Datos Estáticos
categorias: {
table: '__STATIC__',
primaryKey: ['codigo'],
staticData: [
{ codigo: '99', descripcion: 'SIN CATEGORÍA', titulo: 'SIN CATEGORÍA' }
],
}
HTTP Source
Lee datos de APIs REST (ej: WMS).
Configuración
// src/config/sources/wms-source.ts
export const wmsSource: HttpSourceConfig = {
name: 'wms-source',
type: 'http-source',
config: {
baseUrl: process.env.WMS_API_URL || 'http://localhost:8888',
timeout: 30000,
headers: {
'X-API-KEY': process.env.WMS_API_KEY || '',
},
},
entities: {
pedidosPreparados: {
endpoint: 'pedidos/preparados',
dateField: 'fechaNovedad',
responsePath: '[0]',
primaryKey: ['idERP'],
queryParams: {
sin_sincronizar: 1,
},
},
},
};
Entity Config HTTP
| Propiedad | Tipo | Descripción |
|---|---|---|
endpoint |
string | Path del endpoint |
primaryKey |
string[] | Campos que forman la PK |
dateField |
string? | Campo para filtro incremental |
responsePath |
string? | Path para extraer datos (ej: [0], data.items) |
queryParams |
Record? | Query params adicionales |
Response Path
Permite extraer datos de respuestas anidadas:
// Respuesta: [[{...}, {...}]]
responsePath: '[0]' // Extrae el primer array
// Respuesta: { data: { items: [...] } }
responsePath: 'data.items'
Múltiples Instancias
Para ambientes dev/prod, crear sources separados:
// tango.ts (producción)
export const tangoSource: MssqlSourceConfig = {
name: 'tango',
config: {
server: process.env.MSSQL_SERVER,
// ...
},
// ...
};
// tango-development.ts
export const tangoDevelopmentSource: MssqlSourceConfig = {
name: 'tango-development',
config: {
server: process.env.MSSQL_DEVELOPMENT_SERVER,
// ...
},
entities: {
'articulos-dev': { table: 'WEBVIEW', ... },
'clientes-dev': { table: 'WEBCLIENTE', ... },
},
};
Pool de Conexiones
Cada source MSSQL debe usar new sql.ConnectionPool() en lugar de sql.connect() para evitar compartir conexiones entre instancias.
// ✅ Correcto
this.pool = new sql.ConnectionPool(config);
await this.pool.connect();
// ❌ Incorrecto (pool global compartido)
this.pool = await sql.connect(config);
Agregar Nuevo Source
- Crear archivo de configuración en
src/config/sources/ - Exportar en
src/config/sources/index.ts - El registry lo detecta automáticamente por el
type