# Integración de GBDS

## Introducción

Este manual describe brevemente cada flujo estándar del GBDS como una secuencia de llamadas API, que son solicitudes HTTP/HTTPS a un servidor GBDS. Para referencia completa de las llamadas de la API del GBDS, consulte el manual [Especificación de la API GBDS](https://docs.griaule.com/apis/).

El GBDS provee notificaciones asíncronas para operaciones demoradas. Los flujos de notificación están detallados en el [Manual de Flujos de Notificación](/gbs/es/integracion-de-gbds/notifier.md).

La autenticación para todas las llamadas de API se realiza presentando un token válido. Un nuevo token puede ser creado con la llamada [createToken](https://gitbook.griaule.com/apis/gbds-4/tokens#post-tokens). Un token puede y debe ser usado para múltiples llamadas. Crear un nuevo token antes de cada llamada afecta negativamente el rendimiento del sistema.

Todos los diagramas en este manual siguen esta convención:

![Convenciones de Diagrama](/files/020fc785b9730ba84a81c1d8f633c6e6be24c006)

Además, el GBDS sigue un índice para identificación biométrica, según se representa en la tabla a continuación:

| Índice | Biometría                                      |
| ------ | ---------------------------------------------- |
| 0      | Meñique Izquierdo                              |
| 1      | Anular Izquierdo                               |
| 2      | Medio Izquierdo                                |
| 3      | Índice Izquierdo                               |
| 4      | Pulgar Izquierdo                               |
| 5      | Pulgar Derecho                                 |
| 6      | Índice Derecho                                 |
| 7      | Medio Derecho                                  |
| 8      | Anular Derecho                                 |
| 9      | Meñique Derecho                                |
| 10     | Rostro                                         |
| 13     | Iris Izquierda                                 |
| 14     | Iris Derecha                                   |
| 20     | Firma                                          |
| 31     | Interdigital de la Palma Izquierda             |
| 32     | Tenar de la Palma Izquierda                    |
| 33     | Hipotenar de la Palma Izquierda                |
| 34     | Interdigital de la Palma Derecha               |
| 35     | Tenar de la Palma Derecha                      |
| 36     | Hipotenar de la Palma Derecha                  |
| 40     | Palma Izquierda Completa                       |
| 41     | Writer de la Palma Izquierda                   |
| 45     | Palma Derecha Completa                         |
| 46     | Writer de la Palma Derecha                     |
| 200    | Palma Izquierda de Recién Nacidos              |
| 210    | Palma Derecha de Recién Nacidos                |
| 900    | Control de Secuencia - Meñique Izquierdo       |
| 901    | Control de Secuencia - Anular Izquierdo        |
| 902    | Control de Secuencia - Medio Izquierdo         |
| 903    | Control de Secuencia - Índice Izquierdo        |
| 904    | Control de Secuencia - Pulgar Izquierdo        |
| 905    | Control de Secuencia - Pulgar Derecho          |
| 906    | Control de Secuencia - Índice Derecho          |
| 907    | Control de Secuencia - Medio Derecho           |
| 908    | Control de Secuencia - Anular Derecho          |
| 909    | Control de Secuencia - Meñique Derecho         |
| 940    | Control de Secuencia - Cuatro Dedos Izquierdos |
| 941    | Control de Secuencia - Cuatro Dedos Derechos   |
| 942    | Control de Secuencia - Dos Pulgares            |

## Flujo de Registro (Enroll)

En este caso, el usuario quiere insertar una nueva persona en el ABIS. Para ello, el usuario realiza una llamada [enroll](https://gitbook.griaule.com/apis/gbds-4/people#post-people) (una solicitud *POST* para el endpoint */gbds/v2/people*).

![Flujo de Registro](/files/8ede317bfad10dc09a2b984a538a64b8385283f3)

Una llamada de enroll bien formada devolverá una respuesta HTTP con un ID único de transacción (*tguid*) como **data.tguid** y una cadena de estado en **data.status**.

El **tguid** será usado para identificar esta transacción en llamadas futuras y notificaciones asíncronas.

El usuario será [notificado](/gbs/es/integracion-de-gbds/notifier.md) cuando el GBDS concluya el procesamiento de la transacción. El usuario también puede consultar el estado de la transacción con la llamada [getTransaction](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions-tguid) (una solicitud *GET* para el endpoint */gbds/v2/people/transactions/{tguid}*).

Si la transacción se completa con éxito (estado *ENROLLED*), un identificador único de persona (**pguid**) será generado para operaciones de consulta como *getPerson*.

El estado de una transacción de registro puede ser:

**ENQUEUED**

> La transacción fue encolada para procesamiento.

**PROCESSING**

> La transacción está siendo procesada.

**FAILED**

> La transacción de registro no pudo ser completada. Esta situación es consecuencia del manejo de una excepción o del control de calidad.

**EXCEPTION**

> El registro generó al menos una excepción, y la transacción permanecerá en este estado hasta que la excepción sea tratada (por la aplicación GBS ETR o programáticamente).

**PENDING**

> El registro falló en el control automático de calidad, y la transacción permanecerá en este estado hasta que se realice el análisis de calidad (por la aplicación GBS MIR o programáticamente).

**ENROLLED**

> El registro se completó con éxito, y la transacción está asociada a un identificador único de persona válido (**pguid**), que puede ser obtenido con la llamada *getTransaction*.

**REFUSED**

> La transacción entrante fue rechazada por haber hecho match con otra transacción asociada a una o más excepciones activas pendientes.

## Flujo de Actualización (Update)

En este caso, el usuario desea actualizar los datos asociados a una persona ya existente en el ABIS. Si el usuario no tiene el identificador de persona (**pguid**), debe obtenerlo usando una clave biográfica o un identificador de transacción (**tguid**):

* Para obtener un **pguid** a partir de claves biográficas, el usuario debe llamar [getPGuidUsingKeys](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid-1) (una solicitud *GET* para el endpoint */gbds/v2/people/pguid*).
* Para obtener el **pguid** asociado a un **tguid** conocido, el usuario debe llamar [getTransaction](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions-tguid).

Para realizar la actualización, el usuario debe llamar [update](https://gitbook.griaule.com/apis/gbds-4/people#put-people-pguid) (una solicitud *PUT* para el endpoint */gbds/v2/people/{pguid}*).

![Flujo de Actualización](/files/843365b7de0d0ae39155affbcacba18ec10a6995)

Una llamada de actualización bien formada devolverá una respuesta HTTP con un identificador único de transacción (*tguid*) como **data.tguid** y una cadena de estado en **data.status**.

Llamadas de actualización que modifiquen datos biométricos serán procesadas de modo similar a transacciones de registro (Enroll), pudiendo generar excepciones y análisis de calidad (estado *EXCEPTION* y *PENDING*), y generarán notificaciones para quien inició la transacción. El estado de la transacción también puede ser consultado con llamadas *getTransaction*.

Llamadas de actualización que modifiquen solo datos biográficos serán procesadas de forma síncrona. La respuesta HTTP contendrá solo un estado *OK* o *ERROR*.

## Flujo de Verificación

En este caso, el usuario desea realizar una búsqueda de *Verificación* (1:1), comparando datos biométricos con una persona específica en el ABIS. El objetivo de la búsqueda debe ser identificado por un único **pguid** o por una clave biográfica.

Para realizar la verificación, el usuario debe llamar [search](https://gitbook.griaule.com/apis/gbds-4/searches#post-people-searches) (una solicitud *POST* para el endpoint */gbds/v2/people/searches*). El perfil objetivo de la comparación debe ser dado por una clave biográfica en el parámetro **data.keys** o por un *pguid* en **data.pguids**.

![Flujo de Verificación](/files/d51c2240b26afacab8981898d939d49120ae11cc)

La respuesta HTTP traerá el resultado de la verificación en el campo **data.status**, que puede ser:

**MATCH**

> Los datos biométricos proporcionados hicieron match con el registro de la persona en el ABIS.

**NOT\_MATCH**

> Los datos biométricos proporcionados no hicieron match con el registro de la persona en el ABIS.

**PERSON\_NOT\_FOUND**

> La persona objetivo (**pguid** o clave biográfica) no fue encontrada en la base de datos.

Un identificador de transacción (**data.tguid**) también será devuelto, y mayores detalles sobre la operación de verificación pueden obtenerse con la llamada [getSearchResult](https://gitbook.griaule.com/apis/gbds-4/searches#get-people-searches-tguid) (una solicitud *GET* para el endpoint */gbds/v2/people/searches/{tguid}*).

### Verificación con Múltiples GUIDs

El endpoint `/gbds/v2/people/searches` permite solicitudes de verificación con múltiples PGUIDs o múltiples UGUIDs en el caso de verificación de latentes.

Esto permite algunas nuevas características:

1. Verificación de varios PGUIDs
   * Valida verificación con lista de pguids. Solo si `isUlSearch` está definido como `false`.
   * Valida verificación con lista de claves, usando el atributo `keys`.
     * La lista filtra solo una persona.
     * Esta característica es válida solo si `isUlSearch` está definido como `false`.
2. Verificación de varios UGUIDs usando `isUlSearch=true`.
   * Usa el atributo `uguids` como una lista de strings.
   * Valida la verificación con esta lista de uguid. Solo si `isUlSearch` está definido como `true`.
3. Búsqueda de latente en pguids/uguids
   * La búsqueda de latente estará activada si `isLatentSearch` definido como `true` para búsqueda de pguids. Para búsqueda de uguids el valor es siempre `true`.

## Flujo de Identificación

En este caso, el usuario desea realizar una búsqueda de *Identificación* (1:N), comparando datos biométricos contra varios (posiblemente todos) registros en el ABIS.

Para realizar la identificación, el usuario debe llamar [search](https://gitbook.griaule.com/apis/gbds-4/searches#post-people-searches) (una solicitud *POST* para el endpoint */gbds/v2/people/searches*) dejando vacíos los parámetros **data.keys** y **data.pguids**.

{% hint style="warning" %}
En el caso de una búsqueda de identificación, el atributo `matcher` **DEBE** debe ser definido como `DEFAULT`. Usar el valor `MOBILE` resultará en el retorno de un error al usuario.
{% endhint %}

![Flujo de Identificación](/files/09dfa8e339247ce26ca11c5b98afbd85f5fe9fba)

Búsquedas de identificación son realizadas de forma asíncrona. Una llamada de búsqueda exitosa devolverá una respuesta HTTP con un identificador de transacción (**data.tguid**) y un estado (**data.status**).

El usuario recibirá una notificación cuando la búsqueda sea concluida. El usuario también puede consultar el estado de la transacción con la llamada [getSearchResult](https://gitbook.griaule.com/apis/gbds-4/searches#get-people-searches-tguid) (una solicitud *GET* para el endpoint */gbds/v2/people/searches/{tguid}*).

El estado de la transacción de búsqueda puede ser:

**ENQUEUED**

> La búsqueda está encolada, y aún no ha comenzado a procesarse.

**PREPARED**, **PROCESSING**

> Estos valores indican que la búsqueda está siendo procesada.

**MATCH**

> La búsqueda fue procesada, y al menos un match fue encontrado. Los matches son devueltos en el campo **data.cadidates** de la respuesta a *getSearchResult*.

**NOT\_MATCH**

> La búsqueda fue procesada y ningún match fue encontrado.

**PERSON\_NOT\_FOUND**

> El dominio de búsqueda estaba vacío: los filtros especificados, como lista de pguids y/o filtros de etiquetas resultaron en un conjunto vacío de candidatos.

## Flujos de Recuperación de Registro

Esta sección presentará los flujos para recuperar información de perfiles usando el GBDS. Para opciones avanzadas de filtrado en las llamadas de `listPeople` y `listTransactions`, consulte el Manual [Usando Wildcards para Recuperar Información del GBDS](#usando-coringas-para-recuperar-informacao-do-gbds).

### Recuperando el Registro de una Única Persona

Para obtener los datos más actuales asociados a una persona específica, el usuario debe llamar [getPerson](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid) (una solicitud *GET* para el endpoint */gbds/v2/people/{pguid}*).

![Flujo de getPerson](/files/12a4c01f0fc2f0de4833276c2bbaa67957a4243a)

La respuesta HTTP contendrá los datos biográficos de la persona y la transacción de registro (Enroll) más reciente asociada a ella.

### Obteniendo el Pguid a partir de Claves Biográficas

Para obtener el identificador único de una persona (**pguid**) a partir de una clave biográfica, el usuario debe llamar [getPguidUsingKeys](https://gitbook.griaule.com/apis/gbds-4/people#get-people-pguid-1) (una solicitud *GET* para el endpoint */gbds/v2/people/pguid*).

![Flujo de getPguidUsingKeys](/files/5099702165d297ced86ef3807c5e8882941ee1f0)

### Obteniendo el Pguid a partir de Datos Biográficos

Para obtener una lista de identificadores de persona (**pguids**) que hacen match con datos biográficos (y no solo claves), el usuario puede llamar [listPeople](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list) (una solicitud *POST* para el endpoint */gbds/v2/people/list*).

![Flujo de listPeople](/files/f45a9246e749de938e186247db901b952b44d8cc)

{% hint style="info" %}
Es posible realizar una llamada de listPeople proporcionando solamente el `valor` que será usado para filtrar por clave o biográfico.

Este formato de solicitud solo puede usarse para listas filtradas por claves o biográficos. Si el criterio de filtrado es cualquier otro campo, debe ser especificado en el formato de `campo:valor`.
{% endhint %}

#### Criterios de Campo Restriction

Es posible realizar una llamada de [listPeople](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list) proporcionando los criterios para filtrar la lista retornada. El campo `restriction` debe contener un array de objetos que varían de acuerdo con el tipo de dato (representado por el campo `type`) usado como parámetro de filtrado. Cada llamada puede contener una o más restricciones, los tipos aceptados son: **BIOGRAPHIC**, **DATE**, **KEY** y **LABEL**. Los objetos para cada tipo están listados abajo:

* **BIOGRAPHIC**:

| Campo                                    | Requerido                                                                                     | Tipo                                  |
| ---------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------- |
| type                                     | Sí. El valor DEBE ser BIOGRAPHIC                                                              | String                                |
| id                                       | Sí                                                                                            | String                                |
| value                                    | Sí                                                                                            | String                                |
| exists                                   | Sí. Por defecto true.                                                                         | Boolean                               |
| <p>matchMode<br><br><br><br><br><br></p> | <p>Por defecto EXACT. Enum:<br>- START<br>- EXACT<br>- ANYWHERE<br>- END<br>- NOT\_EQUALS</p> | <p>String<br><br><br><br><br><br></p> |

* **DATE**:

| Campo     | Requerido                       | Tipo   |
| --------- | ------------------------------- | ------ |
| type      | Sí. El valor DEBE ser DATE      | String |
| startTime | Sí. Debe estar en milisegundos. | String |
| endTime   | No. Debe estar en milisegundos  | String |

* **KEY**:

| Campo                                    | Requerido                                                                                     | Tipo                                  |
| ---------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------- |
| type                                     | Sí. El valor DEBE ser KEY                                                                     | String                                |
| id                                       | Sí                                                                                            | String                                |
| value                                    | Sí                                                                                            | String                                |
| exists                                   | Sí. Por defecto true.                                                                         | Boolean                               |
| <p>matchMode<br><br><br><br><br><br></p> | <p>Por defecto EXACT. Enum:<br>- START<br>- EXACT<br>- ANYWHERE<br>- END<br>- NOT\_EQUALS</p> | <p>String<br><br><br><br><br><br></p> |

* **LABEL**:

| Campo  | Requerido                 | Tipo    |
| ------ | ------------------------- | ------- |
| type   | Sí. El valor DEBE ser KEY | String  |
| label  | Sí                        | String  |
| exists | Sí. Por defecto true.     | Boolean |

## Flujo de Transacciones Rechazadas (*REFUSED*)

El resultado *REFUSED* ocurrirá en actualizaciones y registros cuando una nueva transacción haga match con una transacción existente que esté asociada a una excepción biométrica pendiente.

### Transacciones Síncronas

Cuando una transacción es sometida a una operación síncrona, la respuesta contendrá un campo `data.status` con el valor *REFUSED*:

```json
{
	"data":
	{
		"status":"REFUSED",
		"tguid": "string"
	}
}
```

### Transacciones Asíncronas

En el caso de una transacción de registro sometida asincrónicamente, la respuesta contendrá un campo `data.status` con el valor *ENQUEUED*:

```json
{
	"data":
	{
		"status":"ENQUEUED",
		"tguid": "string"
	}
}
```

#### Recibiendo la Notificación

Cuando el GBDS finaliza el procesamiento de una transacción, el *GBS Notifier* envía una notificación a un *endpoint* configurado con el TGUID y el resultado del procesamiento (*estado*) de la transacción. Si la transacción es rechazada, el *Notifier* mandará una notificación en el formato:

```json
{
	"operation": "ENROLL",
	"tguid": "string",
	"status": "REFUSED"
}
```

o

```json
{
	"operation": "UPDATE",
	"tguid": "string",
	"status": "REFUSED"
}
```

{% hint style="warning" %}
Después de recibir la notificación de una transacción rechazada (*REFUSED*), una llamada de *getTransaction* debe ser sometida al GBDS con el TGUID como parámetro para que se puedan obtener los detalles que involucran la transacción y sus excepciones.

La operación de *getTransaction* es descrita en la próxima sección, mientras que la información sobre cómo tratar una transacción rechazada se describe en la sección [Tratando una Transacción Rechazada](#tratando-uma-transacao-recusada-refused).
{% endhint %}

#### Realizando Consulta Activa

Para realizar consulta activa para obtener los resultados de una transacción, una llamada de *getTransaction* deberá ser sometida al GBDS con el TGUID del registro como un parámetro con el siguiente *endpoint*:

`http://<ip>:8085/gbds/v2/people/transactions/{tguid}`

El resultado de esta llamada contendrá un campo `data.status` con el valor *REFUSED*, como se muestra en el ejemplo abajo:

```json
{
	"data":
	{
		"tguid": "string",
		"pguid": "string",
		"status": "REFUSED",
		"timestamp": 0,
		"progress": 0,
		"Candidates": [],
		"Person": {},
		"qualityAnalysis": {},
		"failReason": "Enroll matches 2 person(s) that are already involved in a pending exception. PGUIDs: 75ABF575-6825-41D7-A2A7-2C0D64CF9FE7, B393C481-C0AF-456C-9155-1510AFDC7D86",
		"isCurrentTransaction": false
	}
}
```

### Tratando una Transacción Rechazada (REFUSED)

Como se mencionó previamente, una transacción rechazada ocurre cuando un perfil entrante hace match con uno existente que está vinculado a una excepción activa. Cuando una transacción finaliza con este estado, el perfil entrante es descartado y una nueva transacción debe ser sometida para ese perfil después de que las excepciones activas pendientes sean tratadas.

Después de identificar el registro rechazado y ejecutar las llamadas de *getTransaction*, el campo *`failReason`* de la respuesta de *getTransaction* contendrá los PGUIDs del perfil de referencia con los que el perfil entrante hizo match. La cantidad de PGUIDs retornada en la respuesta es ilimitada y separada por comas.

Después de que todas las excepciones sean tratadas, el registro rechazado puede ser re-sometido.

El flujo de trabajo completo para resolver registros rechazados es:

{% hint style="warning" %}
El mismo flujo de trabajo puede usarse para resolver actualizaciones rechazadas usando los comandos equivalentes.
{% endhint %}

**Ejemplo:**

1. Registro 1 - Genera TGUID 1 y PGUID 1;
   1. TGUID 1 - crea una excepción biométrica con un PGUID 0 ya existente;
   2. La aplicación es notificada con:

      ```json
      {
      	"operation": "ENROLL",
      	"tguid": "<TGUID 1>",
      	"status": "EXCEPTION"
      }
      ```
   3. Guarde TGUID 1 y PGUID 1
2. La aplicación ejecuta GET /gbds/v2/exceptions/{tguid}
   1. Y la respuesta es:

      ```json
      {
      	"data": [
      		{
      			"transactionTimestamp": 0,
      			"match": {
      				"matchedPersonPguid": "PGUID 0",
      				"matchedPersonTguid": "TGUID 0",
      				"biometricMatches": []
      			}
      		}
      	],
      	"pagination": {
      		"total": 0,
      		"count": 0,
      		"pageSize": 0,
      		"currentPage": 0,
      		"totalPages": 0
      	}
      }
      ```
   2. Cree y guarde un mapeo artificial del PGUID 0 al PGUID 1 / TGUID 1
3. Registro 2 - TGUID 2;
   1. TGUID 2 hace match con PGUID 0;
   2. TGUID 2 - recibe el estado *REFUSED* porque hizo match con el PGUID 0 que ya estaba vinculado a una excepción;

      ```json
      {
      	"data": {
      		"tguid": "string",
      		"pguid": "string",
      		"status": "REFUSED",
      		"timestamp": 0,
      		"progress": 0,
      		"Candidates": [],
      		"Person": {},
      		"qualityAnalysis": {},
      		"failReason": "Enroll matches 1 person(s) that are already involved in a pending exception. PGUIDs: PGUID 0",
      		"isCurrentTransaction": false
      	}
      }
      ```
4. Guarde el PGUID `<PGUID 0>` asociado con TGUID 2;
   1. Actualice el mapeo indicando que PGUID 0 / PGUID 1 / TGUID 1 / TGUID 2 están vinculados
5. Un examinador resuelve la excepción generada en el Paso 1:
   1. La aplicación es notificada con:

      ```json
      {
      	"operation": "TREAT_EXCEPTION",
      	"tguid": "<TGUID 1>",
      	"status": "OK",
      	"treatment": "TREATMENT_OPTION"
      }
      ```
6. Envíe un nuevo registro para el TGUID 2.

{% hint style="warning" %}
Es posible que un PGUID que hizo match tenga múltiples excepciones vinculadas a él. En ese escenario, todas las excepciones para el PGUID deben ser tratadas antes de intentar re-someter el registro o la actualización rechazada.
{% endhint %}

Es importante mencionar que el flujo de trabajo arriba debe ser implementado para completar automáticamente las transacciones sin ninguna intervención manual.

En otras palabras, para obtener el resultado final de esta transacción (TGUID 2), es necesario esperar la notificación del *GBS Notifier* informando el tratamiento de la excepción para la excepción existente (TGUID 1) y ejecutar la llamada de *getTransaction* para recuperar la información sobre los PGUIDs que hicieron match del GBDS (vea las secciones [Recibiendo la Notificación](#recebendo-a-notificacao) y [Realizando Consulta Activa](#realizando-consulta-ativa)).

## Usando Wildcards para Recuperar Información del GBDS

Cuando se recupera información del GBDS usando [List Transactions](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions) y [List People](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list), es posible usar operadores wildcard para filtrar los resultados.

Cuando se realiza una llamada de [List Transactions](https://gitbook.griaule.com/apis/gbds-4/transaction#get-people-transactions) usando el parámetro `qualityStatus`, los campos `key`, `biographic`, y `label` pueden ser filtrados usando operadores wildcard.

Los operadores wildcard se describen abajo:

### List Transactions

#### Sufijos

Los campos key o biographic pueden contener un `id:value` o `id|value`, como por ejemplo `Name:John Doe`, donde se pueden insertar cuatro sufijos.

* **\[anywhere]**: Este es el sufijo por defecto, si ninguno es escrito, este será seleccionado. En este caso, la aplicación buscará por el id o valor proporcionado en cualquier parte de la cadena.

  > Ejemplo: Si la clave es `name[anywhere]:rob`, se buscarán nombres (name) como "Robbin" apellidos (surname) "Robarts".
* **\[atstart]**: Si este sufijo es usado, la aplicación buscará por el id o valor proporcionado al inicio de la cadena.

  > Ejemplo: Si la clave es `passportNumber:123[atstart]`, se buscarán números de pasaporte que comiencen con 123 y devolverá todos los casos válidos.
* **\[atend]**: Si este sufijo es usado, la aplicación buscará por el id o valor proporcionado al final de la cadena.

  > Ejemplo: Si la clave es `passportNumber:123[atend]`, se buscarán números de pasaporte que terminen con 123. `name[atend]:son` buscará nombres (name) y apellidos (surname) que terminen con "son".
* **\[exact]**: Si este sufijo es usado, la aplicación buscará por coincidencias idénticas a lo proporcionado en la cadena de búsqueda.

  > Ejemplo: Si la clave es `passportNumber:123[exact]`, se buscarán números de pasaporte que sean exactamente iguales a 123.

{% hint style="warning" %}
Estos operadores wildcard son **SUFIJOS**, por lo tanto deben ser insertados DESPUÉS del ID y/o DESPUÉS del VALOR.
{% endhint %}

{% hint style="info" %}
Adicionalmente, id y valor pueden tener sufijos distintos para cada uno, por lo que es posible tener operaciones como: `name[exact]:rob[atstart]`, donde se buscarán campos que estén nombrados exactamente `name` por valores que comiencen con "rob".
{% endhint %}

#### Prefijos

El campo de biográficos también puede tener un prefijo. Este prefijo puede usarse solo en el PRIMER biográfico, antes del `id`. Otros prefijos serán ignorados. Este prefijo definirá qué operación lógica la aplicación ejecutará entre **TODOS** los campos biográficos y de claves. Los valores aceptados son `[and]` y `[or]`, siendo el primero el valor por defecto.

> Ejemplo: Si el biográfico es `[or]id:value`, se ejecutará una operación OR en todas las claves y biográficos, como: (Key1 OR Biographic1 OR Biographic2).

Este prefijo puede combinarse con un sufijo, por lo que valores como `[or]id:value[exact]` son aceptados.

### List People

Cuando se realiza una llamada de [List People](https://gitbook.griaule.com/apis/gbds-4/people#post-people-list), el parámetro `operator` puede ser tanto `and` o `or`. El operador seleccionado será aplicado en las comparaciones entre `key`, `biographic` y `label`. Luego, una comparación `and` se hará con el valor de data deseado para el filtrado de los datos.

Ejemplo: Si el operador seleccionado es `or`, la comparación para filtrar los datos será: ((Key1 OR Biographic1 OR Biographic2 OR Label1) AND Date).

#### Restrictions matchMode

Dentro del objeto de restricciones (restrictions), es posible seleccionar uno de cinco `matchMode` cuando la restricción sea un Biográfico o una Clave. Los posibles valores y sus operaciones están listados a continuación.

{% hint style="danger" %}
Todo lo que no sea una letra, un número o un guión bajo es un separador. Un separador entre números o letras causará la tokenización de la palabra/número completo en todos los modos, excepto EXACT y NOT\_EQUALS.
{% endhint %}

{% hint style="warning" %}
En el valor del filtro de restricción, solo el espacio en blanco \`\` \`\` es un delimitador y tokenizará las palabras/números. Este comportamiento no ocurre en EXACT y NOT\_EQUALS.
{% endhint %}

{% hint style="warning" %}
El parámetro de búsqueda es sensible a caracteres especiales en letras, como â, é, ñ y otros.
{% endhint %}

{% stepper %}
{% step %}

#### EXACT

La operación *exact* busca todo el valor proporcionado. El uso de *exact* no tokenizará la expresión restringida. Este modo diferencia mayúsculas de minúsculas.

* Ejemplo: La llamada debe devolver el valor "Jose Arruda". Usar EXACT con "Jose" o "Arruda" funcionará para devolver el valor deseado.

{% hint style="info" %}
Búsquedas como "Jo" o "rrud" no devolverán Jose Arruda.
{% endhint %}

* Ejemplo 2: La llamada debe devolver un valor numérico de un documento, como "123456". Usando EXACT el valor DEBE ser "123456".

{% hint style="info" %}
Búsquedas con el valor "123" o "456" no devolverán el valor correcto.
{% endhint %}

{% hint style="warning" %}
Si el valor se almacena con un separador, el separador deberá estar en el valor de la restricción.
{% endhint %}
{% endstep %}

{% step %}

#### START

La operación de *start* filtrará los valores tokenizando cada palabra o conjunto de números dividido por un separador.

* Ejemplo: Si el usuario está restringiendo START al valor "Jo", algunos resultados posibles pueden ser:

  ```default
  Jose Arruda
  John Doe
  Marie Johnson
  ```
* Ejemplo 2: En caso de que el usuario esté restringiendo START al valor "Jose Arruda", algunos resultados posibles pueden ser:

  ```default
  Jose Arruda
  Jose Silva
  Pedro Thomas Arruda
  ```
* Ejemplo 3: Si el usuario está restringiendo START al valor "123", algunos resultados posibles pueden ser:

  ```default
  1234567
  123.456
  456-123
  a-b 123
  ```
* Ejemplo 4: Si el usuario está restringiendo START al valor "123.456", algunos resultados posibles pueden ser:

  ```default
  123.456
  123.456.789-90
  ```

{% endstep %}

{% step %}

#### ANYWHERE

La operación en *anywhere* buscará el valor en cualquier parte de la palabra o número.

* Ejemplo: Si la restricción del usuario es ANYWHERE para el valor "Jo", algunos resultados posibles pueden ser:

  ```default
  Jose Arruda
  Major
  Pejorative
  Banjo
  ```
* Ejemplo 2: Buscar "12" puede devolver:

  ```default
  123456
  641256
  114-4312
  a-b 123
  ```
* Ejemplo 3: Si la restricción del usuario es ANYWHERE para el valor "Jo Ru", algunos resultados posibles pueden ser:

  ```default
  Jose Arruda
  Ruth Silva
  Havier Russel
  ```

{% endstep %}

{% step %}

#### END

La operación *end* buscará el valor al FINAL del token. Como START, esta operación tokenizará las palabras/números por cada separador.

* Ejemplo: Si la restricción del usuario END para el valor "son", algunos resultados posibles pueden ser:

  ```default
  Eric Johnson
  Hudson Santos
  ```
* Ejemplo 2: Si el usuario está restringiendo END al valor "Jose Arruda", algunos resultados posibles pueden ser:

  ```default
  Jose Arruda
  Jose Silva
  Pedro Thomas Arruda
  Arruda Bastos
  ```
* Ejemplo 3: Si el usuario está restringiendo END al valor "123", algunos resultados posibles pueden ser:

  ```default
  4567123
  123.456
  456-123
  a-b 123
  ```
* Ejemplo 4: Si el usuario está restringiendo END al valor "123.456", algunos resultados posibles pueden ser:

  ```default
  123.456
  789.123.456
  ```

{% endstep %}

{% step %}

#### NOT\_EQUALS

La operación *Not equals* funciona de modo inverso a la operación EXACT. Filtrará y DESCARTARÁ coincidencias exactas con el valor proporcionado y mostrará TODOS LOS DEMÁS valores. Este modo distingue entre mayúsculas y minúsculas.

* Ejemplo: Usar NOT\_EQUALS con el valor "Jose" puede devolver:

  ```default
  John Doe
  Marie Johnson
  Josemar Rodrigues
  ```
* Ejemplo 2: Usar NOT\_EQUALS con el valor "123" puede devolver:

  ```default
  4567123
  123456
  ```

{% endstep %}
{% endstepper %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.griaule.com/gbs/es/integracion-de-gbds/gbsintegration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
