Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2.9 KiB
Conectores de datos externos — contrato v1
El sistema no se conecta directo a las bases de datos de los clientes. En cada servidor origen se instala un conector: una API HTTP de solo lectura que expone tablas elegidas. El sistema habla siempre el mismo contrato, sin importar la tecnología de origen (FoxPro, SQL Server, Excel…).
| Conector | Carpeta | Estado |
|---|---|---|
| FoxPro (DBF/FPT/CDX) | foxpro/ |
1.0.0 |
Reglas que todo conector debe cumplir
- Solo lectura. Únicamente
GET; cualquier otro método →405. Nunca escribe en el origen. - Token Bearer (
Authorization: Bearer <token>). El conector guarda solo el SHA-256; el sistema guarda el token cifrado (AES-256-GCM). Se admiten varios hashes para rotar sin cortar. - Lista de IPs permitidas (backend del sistema), en el conector y en el firewall del servidor.
- El administrador del origen decide qué sale: tablas permitidas, campos permitidos y campos
denegados (sueldos, claves…). Lo no permitido no existe para el sistema (
404/400). - Sin SQL ni rutas libres: tablas y campos se validan contra la lista real del origen.
- Protege al origen: límite de peticiones por minuto, lecturas simultáneas, tamaño de página
y tiempo máximo por petición. Responde
429/503en vez de cargar el servidor. - Log de acceso sin tokens ni valores buscados (pueden ser datos personales).
Endpoints
| Método y ruta | Respuesta |
|---|---|
GET /v1/health |
{ ok, connector, contract: "v1", version, time } |
GET /v1/sources |
{ sources: [{ id, name }] } — carpetas/bases configuradas |
GET /v1/sources/:source/tables |
{ tables: [{ name, records, fields, version, modifiedAt }] } |
GET /v1/sources/:source/tables/:table/schema |
{ table, records, version, modifiedAt, fields: [{ name, type, size, decimals }] } |
GET /v1/sources/:source/tables/:table/rows |
{ table, version, modifiedAt, total, offset, limit, fields, rows } |
Parámetros de rows:
fields=A,Bcolumnas a devolver (por defecto todas las permitidas).limit(1…máximo del conector, def. 100) yoffsetpara paginar.q=textoyqFields=A,B: contiene, sin distinguir mayúsculas ni tildes.eq.CAMPO=valor: igualdad exacta (sin distinguir mayúsculas). Se pueden combinar varios.includeDeleted=1: incluye los registros marcados como borrados (_deleted).
Cada fila trae _recno (posición en el origen). version cambia cuando el origen se modifica:
el sistema la compara para saber si hace falta volver a sincronizar.
Tipos de dato en JSON: texto recortado (vacío → null), números, booleanos, fecha YYYY-MM-DD,
fecha-hora ISO 8601.
Errores: { error: "mensaje" } con 400 parámetro inválido, 401 token, 403 IP, 404
fuente/tabla, 405 método, 423 tabla bloqueada en el origen, 429 exceso de peticiones,
503 conector ocupado, 500 error interno (detalle solo en el log del conector).