Skip to content

ImagFlow — Modelo de Datos

Base de Datos

  • Nombre: imagy_flow
  • Usuario: imagy_flow_app (NOBYPASSRLS)
  • RLS: Habilitado en todas las tablas con tenant_id

Diagrama ER

Tablas

flows

Definicion de un flujo (metadata, no la configuracion de pasos).

ColumnaTipoDescripcion
idUUID PKIdentificador unico
nameVARCHAR(255)Nombre del flujo
slugVARCHAR(100) UNIQUESlug URL-friendly
descriptionTEXTDescripcion
is_templateBOOLEANSi es un template reutilizable
template_categoryVARCHAR(100)Categoria del template (nullable)
source_flow_idUUID FKFlujo origen si fue duplicado (nullable)
is_activeBOOLEANSi esta activo
row_versionINTConcurrencia optimista
created_atTIMESTAMPTZFecha de creacion
updated_atTIMESTAMPTZUltima modificacion
created_byUUIDActor que lo creo

Nota: Esta tabla NO tiene tenant_id — los flujos son globales (creados por platform admin). La asignacion a tenants se hace via flow_assignments.

flow_versions

Version inmutable de un flujo con toda su configuracion.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
flow_idUUID FKFlujo padre
version_numberINTNumero secuencial (1, 2, 3...)
statusVARCHAR(20)draft, published, archived, discarded
metadataJSONBMetadata adicional
row_versionINTConcurrencia optimista
created_atTIMESTAMPTZFecha de creacion
published_atTIMESTAMPTZCuando se publico (nullable)
archived_atTIMESTAMPTZCuando se archivo (nullable)
published_byUUIDQuien publico (nullable)

flow_steps

Pasos configurados en una version del flujo.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
flow_version_idUUID FKVersion del flujo
step_orderINTOrden de ejecucion (1, 2, 3...)
step_typeVARCHAR(50)form, liveness, card_capture, signature, validation, custom
nameVARCHAR(255)Nombre del paso
descriptionTEXTDescripcion
provider_config_idUUID FKProveedor a usar (nullable para form)
step_configJSONBConfiguracion especifica del tipo de paso
max_attemptsINTReintentos permitidos (default 1)
cooldown_secondsINTEspera entre reintentos (default 0)

flow_rules

Reglas de decision configuradas en una version.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
flow_version_idUUID FKVersion del flujo
evaluation_orderINTOrden de evaluacion
nameVARCHAR(255)Nombre de la regla
descriptionTEXTDescripcion
conditionJSONBExpresion evaluable (ver estructura de condiciones)
action_typeVARCHAR(50)approve, reject, flag, notify, escalate
action_configJSONBConfiguracion de la accion
is_activeBOOLEANSi esta activa

provider_configs

Configuracion de proveedores externos.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
service_typeVARCHAR(50)liveness, ocr, biometric, signature, demographic, registry, sms, storage
provider_nameVARCHAR(255)Nombre legible
provider_codeVARCHAR(100) UNIQUECodigo unico del proveedor
connection_configJSONBConfiguracion de conexion (encrypted)
failover_provider_idUUID FKProveedor de failover (nullable)
failover_conditionsJSONBCondiciones para activar failover
is_activeBOOLEANSi esta activo
row_versionINTConcurrencia optimista
created_atTIMESTAMPTZFecha de creacion

Nota: connection_config contiene API keys y secrets. Se almacena cifrado (KMS) y solo el Provider Gateway puede descifrarlo.

flow_assignments

Asignacion de flujos publicados a tenants/organizaciones.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
tenant_idUUIDTenant al que se asigna (RLS)
organization_idUUIDOrganizacion especifica (nullable = todo el tenant)
flow_idUUID FKFlujo asignado
flow_version_idUUID FKVersion especifica asignada
is_activeBOOLEANSi la asignacion esta activa
assigned_atTIMESTAMPTZFecha de asignacion
assigned_byUUIDQuien asigno

requests

Solicitudes (instancias de ejecucion de un flujo).

ColumnaTipoDescripcion
idUUID PKIdentificador unico
tenant_idUUIDTenant (RLS)
organization_idUUIDOrganizacion (nullable)
flow_version_idUUID FKVersion del flujo que se ejecuta
statusVARCHAR(30)Estado actual del ciclo de vida
access_tokenVARCHAR(255) UNIQUEToken para acceso publico
subject_dataJSONBDatos del sujeto (identificador, nombre)
metadataJSONBMetadata adicional (origen, canal)
row_versionINTConcurrencia optimista
created_atTIMESTAMPTZFecha de creacion
expires_atTIMESTAMPTZFecha de expiracion
completed_atTIMESTAMPTZFecha de completado (nullable)

request_attempts

Intentos de ejecucion de cada paso.

ColumnaTipoDescripcion
idUUID PKIdentificador unico
request_idUUID FKSolicitud padre
step_idUUID FKPaso ejecutado
attempt_numberINTNumero de intento (1, 2, 3...)
statusVARCHAR(20)success, failure, timeout
request_dataJSONBDatos enviados al proveedor
response_dataJSONBRespuesta del proveedor
provider_codeVARCHAR(100)Proveedor usado (puede ser failover)
duration_msINTDuracion en milisegundos
created_atTIMESTAMPTZTimestamp del intento

enrichment_results

Resultados de procesos asincronos (post-captura).

ColumnaTipoDescripcion
idUUID PKIdentificador unico
request_idUUID FKSolicitud padre
process_typeVARCHAR(50)ocr, biometric_match, demographic, signature
statusVARCHAR(20)pending, processing, completed, failed
provider_codeVARCHAR(100)Proveedor que proceso
result_dataJSONBResultado del procesamiento
duration_msINTDuracion en milisegundos
created_atTIMESTAMPTZCuando se creo
completed_atTIMESTAMPTZCuando se completo (nullable)

Tablas de Soporte

idempotency_keys

sql
CREATE TABLE idempotency_keys (
    key VARCHAR(255) NOT NULL,
    tenant_id UUID NOT NULL,
    response_status INT NOT NULL,
    response_body JSONB NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    expires_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + INTERVAL '24 hours',
    PRIMARY KEY (key, tenant_id)
);

processed_events

sql
CREATE TABLE processed_events (
    event_id UUID PRIMARY KEY,
    event_type VARCHAR(100) NOT NULL,
    processed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    source VARCHAR(100) NOT NULL
);

RLS Policies

sql
-- Tablas globales (sin RLS): flows, flow_versions, flow_steps, flow_rules,
-- flow_async_processes, flow_notification_configs, provider_configs
-- Razon: son gestionadas por platform admin, no pertenecen a un tenant

-- Tablas con RLS (por tenant):
ALTER TABLE flow_assignments ENABLE ROW LEVEL SECURITY;
ALTER TABLE requests ENABLE ROW LEVEL SECURITY;
ALTER TABLE request_attempts ENABLE ROW LEVEL SECURITY;
ALTER TABLE enrichment_results ENABLE ROW LEVEL SECURITY;

CREATE POLICY tenant_isolation ON flow_assignments
    FOR ALL USING (tenant_id = get_current_tenant_id());

CREATE POLICY tenant_isolation ON requests
    FOR ALL USING (tenant_id = get_current_tenant_id());

-- Control plane (platform admin sin tenant context)
CREATE POLICY control_plane ON flow_assignments
    FOR ALL USING (
        current_setting('app.current_tenant_id', true) IS NULL
        OR current_setting('app.current_tenant_id', true) = ''
    );

Indices

sql
-- Busqueda de flujos
CREATE INDEX idx_flows_slug ON flows(slug);
CREATE INDEX idx_flows_template ON flows(is_template) WHERE is_template = true;

-- Busqueda de versiones
CREATE INDEX idx_flow_versions_flow_status ON flow_versions(flow_id, status);

-- Busqueda de solicitudes
CREATE INDEX idx_requests_tenant_status ON requests(tenant_id, status);
CREATE INDEX idx_requests_access_token ON requests(access_token);
CREATE INDEX idx_requests_expires ON requests(expires_at) WHERE status IN ('created', 'in_progress');

-- Busqueda de asignaciones
CREATE INDEX idx_flow_assignments_tenant ON flow_assignments(tenant_id, is_active);

-- Limpieza
CREATE INDEX idx_idempotency_expires ON idempotency_keys(expires_at);
CREATE INDEX idx_processed_events_date ON processed_events(processed_at);

Sesion de Ejecucion (Valkey)

La sesion de ejecucion se almacena en Valkey (no en PostgreSQL) para acceso rapido:

json
{
  "key": "tenant:{tenant_id}:execution:{access_token}",
  "ttl": "matches request.expires_at",
  "value": {
    "request_id": "uuid",
    "flow_version_id": "uuid",
    "current_step_index": 2,
    "steps": [
      {
        "step_id": "uuid",
        "step_type": "liveness",
        "status": "completed",
        "attempts_used": 1,
        "max_attempts": 3
      },
      {
        "step_id": "uuid",
        "step_type": "card_capture",
        "status": "in_progress",
        "attempts_used": 0,
        "max_attempts": 3
      }
    ],
    "started_at": "2026-05-18T10:30:00Z",
    "version": 5
  }
}
  • version: para optimistic locking (previene doble-ejecucion concurrente)
  • ttl: se sincroniza con request.expires_at
  • Se crea al primer acceso del usuario final
  • Se elimina al completar o expirar

Reimagine Tech LLC — Documentacion Interna