¿Sobrevive una verificación pendiente al reinicio de la aplicación?
Su servicio de incorporación crea una sesión de verificación alojada, la guarda como pendiente con una fecha límite y el proceso se reinicia antes de que llegue cualquier callback. La decisión: ¿el estado local es lo bastante duradero para que el proceso reiniciado retome la misma sesión, o hay que crear otra? Este artículo recorre el fixture sintético, donde un segundo proceso que abre el mismo archivo SQLite ve la misma fila pendiente, la misma fecha límite y el mismo contador de concesiones. También muestra lo que un reinicio no debe hacer: crear una sesión duplicada, inventar una aprobación o consultar a un proveedor. Todo es un ejemplo local y sintético; no verifica firmas reales ni concede permisos reales.
curl https://gridzen.ai/console/api/quickstart/trial \
-H 'Content-Type: application/json' \
-d '{"task": "identity_onboarding", "scenario": "success"}'El problema: un reinicio entre la creación y el callback
En la incorporación de identidad alojada hay un intervalo entre crear una sesión y conocer su resultado. Un despliegue, un fallo o la reprogramación de un contenedor pueden caer en ese intervalo. Si el estado pendiente vivía solo en memoria, el proceso reiniciado no tiene registro de la sesión. Siguen dos atajos malos: crear una sesión nueva, de modo que el usuario quizá verifique dos veces y compitan dos callbacks, o tratar el registro ausente como terminado y dejar pasar al usuario. La decisión del lector es más acotada de lo que parece: confirmar que el almacenamiento duradero, no la memoria del proceso, es dueño del estado pendiente, y que el proceso reiniciado lee ese estado antes de actuar. El fixture responde a esto solo para un caso: el mismo archivo de base de datos SQLite, reabierto por una nueva instancia de Identity.
Lo que el fixture implementa realmente
El ejemplo descargable guarda las sesiones en una tabla SQLite con id, tenant, subject, status, deadline, granted, grants, policy_version y allow_action, además de una tabla events con clave por sesión y evento para deduplicar. Construir Identity con una ruta ejecuta CREATE TABLE IF NOT EXISTS, así que reabrir un archivo existente conserva sus filas en vez de reiniciarlas. create inserta una fila pendiente con deadline igual a ahora más timeout; llamar de nuevo a create con el mismo id genera un error de integridad de SQLite en lugar de reemplazarla en silencio, y el punto de entrada de línea de comandos lo informa como existing_fixture. read devuelve status, deadline, permission_granted, grant_count, policy_version y allow_action guardados, siempre con live_permission_changed en false. Solo se aceptan callbacks sintéticos: los ids de evento deben empezar por fixture-, mode debe ser synthetic_fixture y source fixture_callback; cualquier otra cosa genera PRODUCTION_SIGNATURE_VERIFIER_NOT_IMPLEMENTED. La prueba de reinicio se ejecuta con las pruebas unitarias de reinicio y recuperación por timeout nombradas en la guía. Esto es distinto de la prueba HTTP anónima de tres escenarios, que tampoco es el ejemplo telefónico descargable de cuatro ramas.
Escenario hipotético resuelto
Hipotéticamente, el proceso A abre un archivo de base de datos y llama a create en el instante 0 con el timeout por defecto de 60 segundos. La salida de creación es mode synthetic_fixture, state simulated, session fixture-session, un hosted_link en un dominio example.invalid, link_executable false y next send_real_provider_link_only_after_authorization. Luego el proceso A se detiene. El proceso B abre un nuevo Identity sobre el mismo archivo y llama a read: status pending, deadline 60, permission_granted false, grant_count 0. No se perdió nada y no existe una segunda sesión. Rama uno: llega un evento sintético Approved en el instante 1 con policy true. La salida esperada es status approved, deadline 60, permission_granted true, grant_count 1, live_permission_changed false, policy_version 1, allow_action true. Entregar otra vez el mismo id de evento devuelve valores idénticos, con grant_count todavía en 1. Rama dos: no llega ningún callback y el proceso B llama a recover en el instante 61. Se espera status expired, deadline 60, permission_granted false, grant_count 0, next review_or_authorized_provider_refresh, provider_polled false. Un evento posterior sobre una sesión expirada la deja expirada.
Manejo de fallos que sigue siendo del llamador
El fixture expone errores; su aplicación decide qué hacer con ellos. Un read de un id de sesión que no está en la base de datos genera SESSION_NOT_FOUND, lo que tras un reinicio suele significar que el proceso abrió otro archivo, por ejemplo una ruta temporal nueva o un volumen de contenedor nuevo. Trátelo como un fallo de configuración que debe alertar, no como motivo para crear una sesión nueva en silencio. Un evento cuyo tenant o subject no coinciden con la fila guardada, o que nombra una sesión desconocida, genera BINDING_MISMATCH y no cambia nada. recover expira localmente y nunca consulta a un proveedor; en una integración real el siguiente paso es revisión humana o una actualización de estado autorizada, que usted debe construir y que este ejemplo no establece. Un callback ausente nunca se convierte en aprobación.
Diseño de aplicación propuesto, no comportamiento implementado
Para producción proponemos mantener la base de datos en un almacenamiento que sobreviva al proceso, ejecutar al arrancar un barrido que lea las sesiones pending, review y unknown y llame a un equivalente de recover para las que superaron su fecha límite, y negarse a arrancar si falta la base de datos esperada. También necesitaría validación de firmas específica del proveedor y una conciliación de estado acotada. Nada de esto está en el fixture. Del mismo modo, permission_granted en el fixture es un registro local; el permiso sintético del fixture no es un permiso de negocio real, y un estado Approved no es permiso incondicional para actuar sobre un usuario real.
Lista de aceptación
Antes de decidir si una integración en sandbox encaja: ejecute las pruebas de reinicio y de recuperación por timeout y compruebe que ambas pasan; confirme que una segunda instancia sobre el mismo archivo lee pending con deadline 60 y grant_count 0; confirme que repetir create no reemplaza la fila; confirme que un evento duplicado mantiene grant_count en 1; confirme que recover tras la fecha límite devuelve expired con provider_polled false; confirme que una sesión desconocida produce SESSION_NOT_FOUND en read y BINDING_MISMATCH en event; y deje por escrito que la verificación de firmas, la actualización con el proveedor y los permisos reales siguen sin construirse. Que las pruebas pasen demuestra solo el manejo del estado local, no el éxito en producción.
Ejecutar el ejemplo sintético comprobado
Descargue y extraiga https://gridzen.ai/downloads/verification-delivery.zip, entre en verification_delivery y ejecute con Python 3.10+. El ejemplo local no hace llamadas de red. Use una base nueva para otra prueba de identidad.
python3 delivery.py identity --db /tmp/gridzen-article-fixture.sqliteFuentes y alcance
https://gridzen.ai/guides/missing-verification-webhook/ https://gridzen.ai/guides/current-capabilities/ Basado en las fuentes comprobadas y el ejemplo local; las reglas propuestas son recomendaciones de diseño, no comportamiento de producción demostrado. Redacción asistida por IA con revisión independiente.
Probar por separado tres resultados del sandbox Crear una cuenta para continuar la integración
Una descarga no demuestra una ejecución correcta. Los ejemplos locales y el sandbox en línea se prueban por separado.