FAQ y troubleshooting
¿Cómo bumpeo la versión del SDK en mi producto?
Sección titulada «¿Cómo bumpeo la versión del SDK en mi producto?»Si el producto usa GitHub dep:
{ "dependencies": { "emafhir": "github:emahealth/emafhir#v0.6.0" }}Cambiá el tag, corré npm install, corré tests. Cuando el SDK se
publique a npm registry, será npm install emafhir@0.6.0.
¿Qué pasa si el IG cambia su canonical URL?
Sección titulada «¿Qué pasa si el IG cambia su canonical URL?»Vault Wave 4 permite editar emashared.countries.ig_canonical_base. Lo
que ocurre después:
Cero redeploy de productos. Cero bump de SDK. La única acción es
opcional: Vault puede llamar resolver.invalidate() vía un endpoint
admin para forzar refresh inmediato sin esperar el TTL.
¿Cómo manejo errores de validación?
Sección titulada «¿Cómo manejo errores de validación?»Depende del tipo:
| Error | Comportamiento |
|---|---|
validateRun / validateCurp etc. devuelve { valid: false } | Silencioso. Tu UI maneja el feedback. |
injectMeta falla (ProfileResolver miss) | Throw. El write se aborta. |
applyAutoTranslate falla (network, sin ConceptMap) | logger.warn. El write procede sin enriquecer. |
FhirError genérico (4xx, 5xx de Aidbox) | Throw con e.isNotFound, e.isConflict, e.issues (OperationOutcome). |
try { await fhir.create(patient);} catch (e) { if (e.isConflict) { // Versión optimistic lock — re-read y reintentar } else if (e.isNotFound) { // Resource padre no existe } else { // Error genérico — log + bubble }}Errores típicos
Sección titulada «Errores típicos»| Error | Causa | Diagnóstico |
|---|---|---|
ProfileResolver: country 'XX' not found or inactive | emashared.countries no tiene fila con code='XX' y is_active=true | Vault Wave 4 → revisar el row del país |
Failed to fetch countries: … | ProfileResolver no puede leer Supabase | Verificar permisos de la key Supabase sobre el schema emashared |
prepareForWrite: injectMeta failed | Async meta-inject falló (timeout Supabase, red) | Logs del worker; reintentar; verificar healthcheck del ProfileResolver |
EmaFhirClientConfig.supabase undefined | Falta el peer dep en el producto consumidor | Pasar supabase: SupabaseClient al constructor |
$translate timeout | Endpoint $translate de Aidbox lento | El warning aparece en logs; la escritura igual procede sin enriquecer |
¿Cómo migro de createClient() a createEmaClient()?
Sección titulada «¿Cómo migro de createClient() a createEmaClient()?»// Antes (legacy, todavía soportado)import { createClient } from 'emafhir';const fhir = createClient({ baseUrl, auth });
// Después (Wave 1)import { createEmaClient } from 'emafhir';const fhir = createEmaClient({ tenant, supabase });Cambios necesarios:
- Agregar peer dep:
npm install @supabase/supabase-js. - Construir el
Tenantobject conid,country,aidbox(clientId, clientSecret decrypted, organizationId, tokenUrl). - Pasar el
SupabaseClientya creado del lado del producto.
A partir de ahí, todos los create() y update() ganan meta-inyección
automática.
¿Qué pasa si llegan 100 writes simultáneos y el cache está vacío?
Sección titulada «¿Qué pasa si llegan 100 writes simultáneos y el cache está vacío?»ProfileResolver tiene in-flight dedup: la primera request inicia una promesa al Supabase, las demás esperan esa misma promesa. Resultado: 1 query a Supabase, no 100.
Está testado explícitamente (decisión F053).
¿El SDK funciona en Cloudflare Workers?
Sección titulada «¿El SDK funciona en Cloudflare Workers?»Sí — es uno de los runtime targets primarios. ESM-only, fetch nativo, zero deps en runtime. También funciona en Deno, Bun y Node 18+.
¿Puedo usar el SDK desde el browser?
Sección titulada «¿Puedo usar el SDK desde el browser?»No es el caso de uso. El SDK requiere las credenciales OAuth2 del tenant — esas deben quedar en el server. Los productos cliente exponen sus propios endpoints autenticados que internamente usan el SDK.
¿Por qué meta.profile no lleva versión?
Sección titulada «¿Por qué meta.profile no lleva versión?»Decisión arquitectónica (ADR-0002): el canonical apunta al perfil
(ej. .../StructureDefinition/Patient) y Aidbox FAR resuelve la versión
activa al validar. Esto permite bumpear el IG sin tener que actualizar
el SDK ni los productos consumidores. Si en el futuro hace falta pinear
una versión, va en un meta.tag aparte (urn:ema:ig-version).
¿Por qué los validadores no consultan al SII / RENAPO / SAT / RENIEC?
Sección titulada «¿Por qué los validadores no consultan al SII / RENAPO / SAT / RENIEC?»Porque mezclar checksum (validez estructural) con existencia (validez real) en una sola función esconde latencia y falsa-fiabilidad. El SDK sólo valida estructura; si un producto necesita confirmar existencia, hace su propio call a la API correspondiente.