# Test Flow - Mercantil Reclamos Demo

## Prerrequisitos

1. Estar en la raiz del proyecto:

```bash
cd /home/dunmagno/cognigy-merncantil
```

2. Tener Node.js disponible.

3. Tener acceso Cognigy configurado localmente para los scripts que consultan o prueban endpoints Cognigy.

4. Tener el backend demo corriendo:

```bash
PORT=3001 npm start
```

5. Si Cognigy necesita acceder al backend local, exponerlo con Cloudflare:

```bash
npx -y cloudflared tunnel --url http://127.0.0.1:3001 --protocol http2 --no-autoupdate
```

6. Confirmar que las tools Cognigy apuntan a la URL publica vigente del tunel.

URL usada en la ultima verificacion:

```text
https://locator-scan-fotos-continues.trycloudflare.com
```

## Prueba 1 - Validar backend local

Ejecutar:

```bash
curl -sS http://127.0.0.1:3001/health
```

Resultado esperado:

```json
{
  "ok": true,
  "service": "mercantil-demo"
}
```

## Prueba 2 - Validar backend por tunel publico

Ejecutar:

```bash
curl -sS https://locator-scan-fotos-continues.trycloudflare.com/health
```

Resultado esperado:

```json
{
  "ok": true,
  "service": "mercantil-demo"
}
```

## Prueba 3 - Resetear estado demo

Ejecutar:

```bash
curl -sS -X POST https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/reset
```

Luego verificar:

```bash
curl -sS https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/state
```

Resultado esperado:

```json
{
  "ok": true,
  "state": {
    "namespace": "mercantil",
    "nextClaimSequence": 1,
    "claims": 0
  }
}
```

## Prueba 4 - Probar extraccion desde texto OCR

Ejecutar:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/ticket/extract \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "ticketText": "Comprobante: Farmacia Demo, monto Bs 125.30, fecha 08/07/2026 14:35, tarjeta **** **** **** 4821, referencia 987654321, autorizacion 654321."
  }'
```

Resultado esperado:

- `ok: true`
- `merchant: "Farmacia Demo"`
- `amount: 125.3`
- `currency: "VES"`
- `date: "08/07/2026"`
- `time: "14:35"`
- `cardLast4: "4821"`
- `referenceMasked` y `authorizationMasked` enmascarados
- sin PAN completo, CVV, PIN, OTP ni URL cruda

## Prueba 4A - Probar OCR real de Cognigy con imagen local

El ticket de prueba local esta en:

```text
OCR/test_para_OCR.jpeg
```

El backend expone archivos de `OCR/` por la ruta publica:

```text
https://locator-scan-fotos-continues.trycloudflare.com/ocr/test_para_OCR.jpeg
```

Primero validar que Cognigy puede descargar la imagen:

```bash
curl -sS -o /tmp/mercantil-ocr-test.jpeg \
  https://locator-scan-fotos-continues.trycloudflare.com/ocr/test_para_OCR.jpeg
```

Resultado esperado:

```text
HTTP 200
content-type: image/jpeg
```

Para probar el OCR del AI Agent por REST, enviar el mensaje con `inputAttachments` en `data`. El formato importante es:

```json
{
  "inputAttachments": [
    {
      "url": "https://locator-scan-fotos-continues.trycloudflare.com/ocr/test_para_OCR.jpeg",
      "name": "test_para_OCR.jpeg",
      "type": "image"
    }
  ]
}
```

Ejemplo usando el Cognigy MCP `talk_to_agent`:

```text
endpointUrl:
https://endpoint-trial.cognigy.ai/aa798a7a5373f8c7efd6b58b3ab0beeb7f48e2323684f642c70682df61f58e07

message:
Quiero reclamar un consumo rechazado. Mi OTP es 123456. Usa la imagen adjunta del comprobante para extraer los datos OCR y crear el reclamo.

data:
{
  "inputAttachments": [
    {
      "url": "https://locator-scan-fotos-continues.trycloudflare.com/ocr/test_para_OCR.jpeg",
      "name": "test_para_OCR.jpeg",
      "type": "image"
    }
  ],
  "attachments": [
    {
      "url": "https://locator-scan-fotos-continues.trycloudflare.com/ocr/test_para_OCR.jpeg",
      "name": "test_para_OCR.jpeg",
      "type": "image"
    }
  ],
  "channel": "rest-ocr-test"
}
```

Resultado verificado:

```text
Comercio: CECOSESOLA LARA EL C / ENTRO BQTO / LARA
Monto: 87.079,04 VES
Fecha: 04/07/2026
Hora: 11:15
Moneda: VES
Ultimos 4 de la tarjeta: 9956
Confianza OCR: valor devuelto por el agente, por ejemplo 0.98
Reclamo creado: MC-2026-000001
```

Nota: enviar solo `attachments` puede no activar el procesamiento OCR en el REST endpoint. Incluir `inputAttachments` con `type: "image"`.

Para este ticket, el monto aparece en la imagen como `MONTObs. 87.079,04`. El parser backend normaliza ese formato como `87079.04`, y el AI Agent debe mostrarlo al cliente como `87.079,04 VES` o equivalente.

## Prueba 5 - Probar flujo backend completo por API

1. Verificar identidad:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/identity/verify \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"whatsapp:+584121234567","otp":"123456"}'
```

Resultado esperado:

```text
identityVerified: true
```

2. Extraer ticket usando el comando de la prueba 4.

3. Evaluar reglas con el ticket extraido:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/rules/evaluate \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "identityVerified": true,
    "issueType": "consumo rechazado no decidido por motor de reglas",
    "ticket": {
      "ok": true,
      "merchant": "Farmacia Demo",
      "amount": 125.3,
      "currency": "VES",
      "date": "08/07/2026",
      "time": "14:35",
      "cardLast4": "4821",
      "confidence": 0.92
    }
  }'
```

Resultado esperado:

```text
decision: needs_human
ruleCode: RULE_ENGINE_UNABLE_TO_DECIDE
claimStatus: needs_human
```

4. Crear reclamo:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/claims \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "userId": "whatsapp:+584121234567",
    "channel": "whatsapp",
    "identity": {
      "identityVerified": true,
      "customerIdMasked": "****4567"
    },
    "ticket": {
      "ok": true,
      "merchant": "Farmacia Demo",
      "amount": 125.3,
      "currency": "VES",
      "date": "08/07/2026",
      "time": "14:35",
      "cardLast4": "4821",
      "confidence": 0.92
    },
    "rules": {
      "decision": "needs_human",
      "ruleCode": "RULE_ENGINE_UNABLE_TO_DECIDE",
      "claimStatus": "needs_human"
    }
  }'
```

Resultado esperado:

```text
claimId: MC-2026-000001
status: needs_human
```

5. Construir resumen de handover:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/handover-summary \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"claimId":"MC-2026-000001"}'
```

Resultado esperado:

- `ok: true`
- `customAttributes.mc_claimId: "MC-2026-000001"`
- `customAttributes.mc_ruleDecision: "needs_human"`
- `customAttributes.mc_cardLast4: "4821"`
- sin datos sensibles

## Prueba 6 - Probar AI Agent por REST

Endpoint REST:

```text
https://endpoint-trial.cognigy.ai/aa798a7a5373f8c7efd6b58b3ab0beeb7f48e2323684f642c70682df61f58e07
```

Mensaje sugerido:

```text
Quiero reclamar un consumo rechazado. Mi OTP es 123456. Comprobante: Farmacia Demo, monto Bs 125.30, fecha 08/07/2026 14:35, tarjeta **** **** **** 4821, referencia 987654321, autorizacion 654321.
```

Resultado esperado:

- El agente verifica identidad.
- Extrae comercio `Farmacia Demo`.
- Extrae monto `Bs 125,30`.
- Extrae ultimos 4 de tarjeta `4821`.
- Crea un reclamo `MC-2026-NNNNNN`.
- Indica que el caso requiere especialista humano.

Nota: para pruebas con adjuntos, usar URLs reales alcanzables. No usar URLs ficticias.

## Prueba 7 - Probar AI Agent por NiCE CXone

Usar el script reutilizable:

```bash
node scripts/test_cognigy_nice_endpoint.js \
  --endpoint-id 6a4e8ad3d9543729fbb4266e \
  --session-id mercantil-nice-test-001 \
  --user-id whatsapp:+584121234567 \
  --text "Quiero reclamar un consumo rechazado. Mi OTP es 123456. Comprobante: Farmacia Demo, monto Bs 125.30, fecha 08/07/2026 14:35, tarjeta **** **** **** 4821, referencia 987654321, autorizacion 654321."
```

Resultado esperado:

- HTTP `200`
- `body.outputs` con respuestas del agente
- comercio `Farmacia Demo`
- monto `Bs 125,30`
- ultimos 4 de tarjeta `4821`
- numero de reclamo `MC-2026-NNNNNN`
- mensaje de escalamiento a especialista humano

Importante:

- No probar el endpoint NiCE con un `curl` generico sin `verify-token`.
- El script lee el verify token desde Cognigy y no lo imprime.

## Prueba 7A - Probar subida de imagen desde navegador

El Webchat oficial de Cognigy puede mostrar `Upload Failed` si no hay un File Storage Provider real configurado en el endpoint. Para probar el OCR como usuario desde navegador sin credenciales Azure/AWS/GCS, usar la pagina demo del backend:

```text
https://locator-scan-fotos-continues.trycloudflare.com/ocr-test
```

Pasos:

1. Abrir la URL en el navegador.
2. Dejar o ajustar el mensaje:

```text
Quiero reclamar un consumo rechazado. Mi OTP es 123456. Usa la imagen adjunta del comprobante para extraer comercio, monto, fecha, hora y tarjeta.
```

3. Seleccionar una imagen local del comprobante.
4. Hacer clic en `Probar OCR`.

Resultado esperado:

```text
Comercio: CECOSESOLA LARA EL C
Monto: 87.079,04 VES
Fecha: 04/07/2026
Hora: 11:15
Tarjeta: ****9956
ID de reclamo: MC-2026-...
```

Esta pagina guarda la imagen temporalmente en memoria del backend demo, la expone por `/uploads/...` y llama al endpoint REST de Cognigy con `data.inputAttachments`.

Para que el Webchat oficial soporte upload real, configurar en Cognigy Endpoint > Webchat Behavior > Attachment Upload:

```text
Allow Attachment Upload: enabled
File Storage Provider: Azure, AWS o Google Cloud
Connection: conexion valida del proveedor elegido
```

Sin esa conexion, el upload falla aunque el icono de adjuntar aparezca.

## Prueba 8 - Validar privacidad del endpoint NiCE

Consultar el endpoint con Cognigy MCP o script/API directa y confirmar:

```text
channel: niceCXOne
storeDataPayload: false
maskLogging: true
maskAnalytics: true
maskIPAddress: true
inputTransformerEnabled: true
outputTransformerEnabled: true
```

No imprimir ni guardar el `verifyToken`.

## Prueba 9 - Casos negativos

### Sin comprobante

Enviar al backend:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/ticket/extract \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{}'
```

Resultado esperado:

```text
ok: false
code: MISSING_TICKET_ATTACHMENT
confidence: 0
```

### OTP incorrecto

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/identity/verify \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"userId":"whatsapp:+584121234567","otp":"999999"}'
```

Resultado esperado:

```text
ok: false
identityVerified: false
code: INVALID_OTP
```

### Intento de datos sensibles

Enviar ticket con PAN completo, CVV, PIN u OTP:

```bash
curl -sS -X POST \
  https://locator-scan-fotos-continues.trycloudflare.com/bank/mercantil/demo/ticket/extract \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "ticketText": "Comercio: Demo, monto Bs 50.00, tarjeta 4111111111114821, CVV: 123, PIN: 9876, OTP: 123456"
  }'
```

Resultado esperado:

- No debe aparecer PAN completo.
- No debe aparecer CVV.
- No debe aparecer PIN.
- No debe aparecer OTP.
- La tarjeta debe quedar limitada a `cardLast4`.

## Prueba 10 - Ejecutar suite automatizada

Ejecutar:

```bash
npm test
npm run check
```

Resultado esperado:

```text
npm test: all tests pass
npm run check: no syntax errors
```

## Criterios de aceptacion

El flujo se considera correcto si:

- El backend responde por local y por tunel.
- El AI Agent usa las cinco tools.
- Se crea un reclamo `MC-YYYY-NNNNNN`.
- Los casos de regla no decidida terminan en `needs_human`.
- El handover summary contiene solo atributos `mc_*` seguros.
- NiCE responde HTTP 200 usando `scripts/test_cognigy_nice_endpoint.js`.
- No se exponen PAN completo, CVV, PIN, OTP, contrasenas, URLs crudas ni texto OCR completo.
- `npm test` y `npm run check` pasan.
