Saltar a contenido

Guion de demostración (MVP) — Finance en Azure

Estás en el paso 3 de la ruta

Antes: Onboarding y Arquitectura Azure. Después, profundidad en Identidad y APIM.

Portal (entrada principal — Front Door):
https://ep-finance-dev-gfayg5axbhd7h5hf.z02.azurefd.net/

APIM (gateway API):
https://apim-eai-dev-fz1d.azure-api.net
(requiere JWT Entra + grupo Finance.User o Finance.Reviewer)

APIM Developer Portal (OpenAPI / Try it):
https://apim-eai-dev-fz1d.developer.azure-api.net

Recurso Cómo
Health Portal (proxy) o APIM · /api/platform/health
OpenAPI / Try it Developer Portal; local :8001/docs
PDFs demo data/sample/finance/
Borde / WAF Front Door

Fallback debug (ACA directo): https://ca-eai-finance-web-dev.nicebush-01b1fe1e.mexicocentral.azurecontainerapps.io/ — sesión MSAL distinta al host AFD.

flowchart LR
  A[Health API] --> B[Portal cola HITL]
  B --> C[PDF en detalle]
  C --> D[Approve/Reject]
  D --> E[Chat off-topic → rechazo]
  E --> F[Chat OC/umbral → tools]

Último smoke automatizado: 2026-09-09 — PASS (API).
Re-ejecutar API: pwsh scripts/smoke-finance-azure.ps1
UI: portal ACA o cd apps/finance-web && npm run dev.
Onboarding: getting-started.md.


Antes de la demo (2 min)

  1. Abrir el portal y confirmar login Entra (si aplica). Cold start ACA: 30–60s.
  2. Confirmar health vía portal/APIM: sql=azure-sql, blob=ok, documentIntelligence=configured.
  3. Tener a mano los 3 PDFs:
  4. invoice-demo-auto-approve.pdf
  5. invoice-demo-hitl-threshold.pdf
  6. invoice-demo-inactive-supplier.pdf

Escenario A1 — Auto-aprobación (happy path)

Mensaje: “Factura bajo umbral, proveedor activo, OC válida → el motor aprueba sin humano.”

  1. POST /api/finance/invoices/upload
  2. file: invoice-demo-auto-approve.pdf
  3. invoiceNumber: único, ej. INV-DEMO-AUTO-YYYYMMDD
  4. supplierTaxId: 900123456
  5. purchaseOrderId: PO-90219
  6. Copiar invoiceId.
  7. POST /api/finance/invoices/{invoiceId}/process
  8. Esperado: status=Approved, requiresHumanReview=false, reglas FIN-001…005 = PASSED.
  9. GET .../audit → timeline con upload, DI/extract, tools, rules, InvoiceApproved.

Escenario A2 — HITL por umbral > USD 50k (FIN-005)

Mensaje: “Misma plataforma, pero el monto dispara revisión humana determinística (no el LLM).”

  1. Upload invoice-demo-hitl-threshold.pdf
  2. invoiceNumber único
  3. supplierTaxId: 901222333
  4. purchaseOrderId: PO-90500
  5. processRequires Human Review, FIN-005 = FAILED.
  6. POST .../approve body:
    { "comment": "OK para pago demo", "user": "finance.reviewer@company.com" }
    
  7. Esperado: status=Approved + evento HumanDecision en audit.

Escenario A3 — Proveedor inactivo (FIN-001)

  1. Upload invoice-demo-inactive-supplier.pdf
  2. supplierTaxId: 800999888
  3. purchaseOrderId: PO-90100
  4. processRequires Human Review, FIN-001 FAILED (“Inactive”).

Escenario A4 — Tools REST (agente / Foundry)

Sin UI todavía; mostrar en Swagger o curl:

Tool Endpoint
get_purchase_order GET /api/finance/tools/purchase-orders/PO-90219
validate_invoice_amount POST /api/finance/tools/validate-invoice-amount
check_duplicate_invoice POST /api/finance/tools/check-duplicate-invoice

Ejemplo validate:

{
  "purchaseOrderId": "PO-90219",
  "invoiceAmount": 8000,
  "invoiceTotal": 8000,
  "currency": "USD"
}

Esperado: valid=true, withinPoAmount=true.


Escenario B — RR.HH. (pendiente E3/E4)

  1. Login como HR.User (cuando exista Entra + front)
  2. Preguntar: ¿Cuál es la política de trabajo remoto?
  3. MCP HR → AI Search → respuesta con fuente

(Aún no desplegado en Azure.)


Escenario A2b — Authz HITL Reviewer vs User (2026-09-10)

Mensaje: “Solo Finance.Reviewer puede decidir; Finance.User ve la cola pero no aprueba.”

Prerrequisito: portal vía APIM + Entra; grupos Finance.Reviewer / Finance.User.

Pasada Reviewer

  1. Usuario en Finance.Reviewer (y opcionalmente User) → Sign in.
  2. Abrir factura en Requires Human Review.
  3. Esperado: botones Aprobar / Rechazar / Devolver activos; decisión → Approved/Rejected/Returned + HumanDecision con la identidad del token (no el demo hardcodeado).

Pasada solo User (mismo UPN o segundo usuario)

  1. Quitar temporalmente del grupo Reviewer (dejar User):
    az ad group member remove --group "Finance.Reviewer" --member-id <objectId-usuario>
    
  2. Logout → Login (renovar JWT; sin esto el token viejo sigue trayendo groups).
  3. Misma factura HITL → botones deshabilitados + mensaje de solo Reviewer.
  4. (Opcional) POST APIM …/approve con Bearer del User → 403 (required-claims / API).
  5. Restaurar Reviewer y Logout → Login otra vez:
    az ad group member add --group "Finance.Reviewer" --member-id <objectId-usuario>
    

Evidencia DEV (2026-09-10): pasadas A/B con santiago.vanegas@honneservices.com (toggle grupo Reviewer). Pipelines TF #20260910.10, API #20260910.7, web #20260910.11 OK.


Escenario A5 — Chat Foundry sobre factura HITL

Tras A2 (factura ya procesada / aprobada):

  1. POST /api/finance/chat con un mensaje que fuerce tools, p. ej. PO de esa factura, validate amount y check duplicate del invoiceNumber.
  2. Esperado: mode=foundry-agent, toolsUsed con resultados alineados a REST/SQL (no inventados).

Resultado smoke (2026-09-09 + authz 2026-09-10)

Check Resultado
Health (SQL / Blob / DI) OK (0.6.1)
Auto-approve PDF Approved, FIN-001…005 PASSED
HITL >50k + approve Review → Approved + HumanDecision
Inactive supplier Review, FIN-001 FAILED (script smoke-finance-azure.ps1)
Tools REST (PO / amount / duplicate) OK
E2 + chat HITL (INV-E2CHAT-HITL-* → PO-90500) PASS — 3 tools + reply alineado a REST
HITL Reviewer vs User (A2b) PASS — Reviewer decide; User UI bloqueada / APIM 403

Notas:

  • Usar invoice numbers únicos en cada corrida (evitar FIN-004).
  • Preferir form invoiceNumber en upload (el API no deja que DI pise números de demo).
  • Versión reportada en health al smoke: ver respuesta live en /api/platform/health.
  • Chat: host loop ejecuta function tools contra SQL (toolsUsed en la respuesta).
  • Authz: tras cambiar membresía de grupo Entra, siempre Logout → Login.

Fuera de alcance de esta demo

  • KPIs dashboard en Finance Web
  • MCP suppliers binding Foundry→ACA (opcional)
  • ACA finance-api detrás de APIM vía IP allowlist (FQDN directo 403); external_enabled=false pendiente de VNet
  • Escenario B RR.HH. (E3)
  • Assignment required en Enterprise app (opcional Entra)