Skip to content

Formularios y Gestión de Perfiles

Los formularios en Kuenta son la base para recopilar información de personas naturales y jurídicas. Esta guía explica cómo funcionan los formularios, cómo se configuran, y cómo controlar qué campos pueden editar los usuarios.

Guía Práctica: Para ejemplos completos de integración con código, consulta la Guía de Integración de Perfiles.

Conceptos Clave

Tipos de Formularios

Kuenta maneja dos tipos principales de formularios según el tipo de entidad:

TipoDescripciónCategorías
NaturalFormularios para personas naturales (individuos)0-10
LegalFormularios para personas jurídicas (empresas)15-21

Jerarquía de Formularios

Configuración (Organization)
├── NaturalBasicFormID → Formulario básico natural
├── LegalBasicFormID → Formulario básico legal
├── Formularios personalizados naturales
└── Formularios personalizados legales

Formulario Básico vs Formularios Personalizados

  • Formulario Básico: El formulario principal configurado por la organización para recopilar información esencial. Cada marca blanca define cuál es su formulario básico mediante NaturalBasicFormID y LegalBasicFormID.

  • Formularios Personalizados: Formularios adicionales creados para recopilar información específica según el producto crediticio o proceso de negocio.

Importante: El "formulario básico" no es un conjunto predefinido de campos del sistema. Es el formulario específico que cada organización ha configurado como su formulario base.

Estructura de un Formulario

Form (Formulario)

json
{
  "ID": "uuid",
  "name": "Información Personal",
  "description": "Datos personales del solicitante",
  "type": "natural",
  "fields": [
    { "ID": "uuid", "fieldID": "uuid", "actived": true, "required": true }
  ]
}

FormField (Campo de Formulario)

Representa la asociación entre un formulario y un campo maestro:

json
{
  "ID": "uuid",
  "formID": "uuid",
  "fieldID": "uuid",
  "actived": true,
  "required": true,
  "onlyAdmin": false,
  "order": 1
}

Field (Campo Maestro)

Los campos maestros definen la estructura de los datos:

json
{
  "ID": "uuid",
  "name": "firstName",
  "label": "Primer Nombre",
  "type": "text",
  "category": 1,
  "validation": {
    "pattern": "^[a-zA-ZáéíóúÁÉÍÓÚñÑ ]+$",
    "maxLength": 100
  }
}

Control de Edición de Perfil (ProfileEditScope)

La configuración profileEditScope permite a las organizaciones controlar qué campos pueden editar los usuarios cuando actualizan su perfil desde su cuenta.

Valores de profileEditScope

ValorComportamiento
all (defecto)Los usuarios pueden editar todos los campos de todos los formularios configurados (básico + personalizados)
baseLos usuarios solo pueden editar campos del formulario básico configurado

Caso de Uso

Escenario: Una organización recopila información financiera detallada (ingresos, gastos, activos) durante el proceso de solicitud de crédito, pero no quiere que el usuario pueda modificar esos datos después del registro.

Solución:

  1. Configurar el formulario básico con solo los campos esenciales (nombre, email, teléfono)
  2. Crear formularios personalizados para la información financiera
  3. Establecer profileEditScope = "base"

Resultado: Los usuarios pueden actualizar sus datos de contacto, pero la información financiera permanece inmutable.

Configuración via API

bash
# Actualizar profileEditScope
PUT /organization/{entityid}/config/{configid}
Content-Type: application/json

{
  "profileEditScope": "base"
}

Comportamiento del Frontend

Cuando el frontend carga el formulario para edición de perfil:

typescript
// El endpoint respeta profileEditScope automáticamente
GET /entities/{entityid}/config/forms?type=natural

// Para forzar solo el formulario básico (ignora profileEditScope)
GET /entities/{entityid}/config/forms?type=natural&name=base

API de Formularios

Endpoints Principales

MétodoEndpointDescripción
GET/config/formsListar formularios de la configuración propia
POST/config/formsCrear un nuevo formulario
GET/config/forms/{formid}Obtener un formulario específico
PUT/config/forms/{formid}Actualizar un formulario
DELETE/config/forms/{formid}Eliminar un formulario
GET/entities/{entityid}/config/formsObtener formularios de una marca blanca
GET/config/master/forms/fieldsListar todos los campos maestros disponibles

Obtener Formularios para Edición de Perfil

bash
# Obtener todos los formularios naturales (respeta profileEditScope)
GET /entities/{entityid}/config/forms?type=natural

# Obtener solo el formulario básico (ignora profileEditScope)
GET /entities/{entityid}/config/forms?type=natural&name=base

# Obtener formularios legales
GET /entities/{entityid}/config/forms?type=legal

Respuesta:

json
{
  "status": "success",
  "data": {
    "form": {
      "ID": "uuid",
      "name": "Formulario Combinado",
      "fields": [
        {
          "ID": "uuid",
          "fieldID": "uuid",
          "actived": true,
          "required": true,
          "field": {
            "name": "firstName",
            "label": "Primer Nombre",
            "type": "text"
          }
        }
      ]
    }
  }
}

Obtener Campos con Metadata

Para obtener campos con información de permisos (onlyAdmin):

bash
# Campos únicos con metadata
GET /config/form/fields

# Campo específico con metadata
GET /config/form/fields/{fieldid}

Flujo de Actualización de Perfil

1. Cargar Formulario

javascript
// Frontend solicita formulario según el tipo de perfil
const response = await fetch(`/entities/${configOrgId}/config/forms?type=natural`);
const { data: { form } } = await response.json();

2. Construir Formulario Dinámico

javascript
// Iterar sobre campos activos
form.fields
  .filter(f => f.actived)
  .forEach(formField => {
    const field = formField.field;
    // Crear control de formulario según field.type
  });

3. Enviar Actualización

javascript
// Solo enviar campos que fueron "preguntados" (missingFields)
const payload = {
  natural: {
    firstName: "Juan",
    lastName: "Pérez",
    // Solo campos del formulario cargado
  },
  missingFields: form.fields.map(f => ({
    fieldID: f.fieldID,
    name: f.field.name
  }))
};

await fetch(`/debtor/${debtorId}/profile`, {
  method: 'PUT',
  body: JSON.stringify(payload)
});

Campos Numéricos

Manejo de Campos Vacíos

Cuando el frontend envía campos numéricos vacíos, el backend los procesa correctamente:

Valor EnviadoComportamiento Backend
"" (string vacío)Convertido a null
nullAceptado como nulo
0Aceptado como cero
"1000.50"Parseado a decimal

Lista de Campos Numéricos

Los siguientes campos son tratados como numéricos:

Ingresos:

  • incomeMonthly, variableIncome, otherIncome, spouseIncome

Gastos:

  • expenses, otherExpenses

Patrimonio:

  • assets, liabilities, worth

Ahorros:

  • mandatorySaving, christmasSaving, voluntarySaving, housingSaving, etc.

Otros:

  • mortgageCommercialValue, pledgeCommercialValue, vehicleValue, etc.

Campos Solo Admin (onlyAdmin)

Algunos campos pueden marcarse como onlyAdmin: true, lo que significa:

  • No visibles para el usuario final
  • Solo editables por administradores de la organización
  • Se filtran automáticamente en la respuesta de la API según el rol del usuario
json
{
  "fieldID": "uuid",
  "actived": true,
  "required": false,
  "onlyAdmin": true,
  "field": {
    "name": "internalScore",
    "label": "Score Interno"
  }
}

Campos Personalizados (customFields)

Además de los campos estándar, las organizaciones pueden crear campos personalizados:

json
{
  "profile": {
    "firstName": "Juan",
    "customFields": {
      "codigoEmpleado": "EMP-12345",
      "departamento": {
        "value": "ventas",
        "label": "Departamento de Ventas"
      },
      "certificaciones": [
        { "value": "pmp", "label": "PMP Certified" },
        { "value": "scrum", "label": "Scrum Master" }
      ]
    }
  }
}

Límites de Campos Personalizados

AspectoLímite
Nombre del campoMáximo 100 caracteres
Valor simpleMáximo 1000 caracteres
Valores múltiplesMáximo 50 elementos, 500 caracteres c/u
Caracteres prohibidosComillas y caracteres especiales en nombres

Mejores Prácticas

1. Diseño de Formularios

  • Agrupa campos relacionados en el mismo formulario
  • Usa el formulario básico solo para datos esenciales
  • Crea formularios específicos por producto crediticio

2. Control de Acceso

  • Marca campos sensibles como onlyAdmin
  • Usa profileEditScope: "base" para datos inmutables post-registro
  • Revisa regularmente qué campos son editables

3. Validación

  • Define validaciones en el campo maestro (Field)
  • Valida tanto en frontend como backend
  • Usa required: true solo para campos realmente obligatorios

4. Migración y Cambios

  • Los cambios en formularios no afectan datos existentes
  • Agrega nuevos campos como opcionales primero
  • Planifica migraciones para cambios en campos requeridos

Solución de Problemas

Error: "Campo no encontrado en formulario"

Causa: El campo existe en customFields del perfil pero no está en los formularios de la marca blanca actual.

Solución: Verificar que los formularios de la organización incluyan el campo necesario.

Error: "Failed on 'numeric' tag"

Causa: El frontend envía string vacío "" para un campo decimal.

Solución: El backend ahora convierte automáticamente strings vacíos a null. Si persiste, verificar que el endpoint use BindJSONWithCleanup.

Los campos no aparecen en el formulario de edición

Verificar:

  1. El campo tiene actived: true en el formulario
  2. El profileEditScope permite esos campos
  3. El campo no está marcado como onlyAdmin: true (si el usuario no es admin)
  4. El tipo de formulario (natural/legal) coincide con el tipo de perfil