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)¶
- Abrir el portal y confirmar login Entra (si aplica). Cold start ACA: 30–60s.
- Confirmar health vía portal/APIM:
sql=azure-sql,blob=ok,documentIntelligence=configured. - Tener a mano los 3 PDFs:
invoice-demo-auto-approve.pdfinvoice-demo-hitl-threshold.pdfinvoice-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.”
POST /api/finance/invoices/upload- file:
invoice-demo-auto-approve.pdf invoiceNumber: único, ej.INV-DEMO-AUTO-YYYYMMDDsupplierTaxId:900123456purchaseOrderId:PO-90219- Copiar
invoiceId. POST /api/finance/invoices/{invoiceId}/process- Esperado:
status=Approved,requiresHumanReview=false, reglas FIN-001…005 = PASSED. 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).”
- Upload
invoice-demo-hitl-threshold.pdf invoiceNumberúnicosupplierTaxId:901222333purchaseOrderId:PO-90500process→ Requires Human Review, FIN-005 = FAILED.POST .../approvebody:- Esperado:
status=Approved+ eventoHumanDecisionen audit.
Escenario A3 — Proveedor inactivo (FIN-001)¶
- Upload
invoice-demo-inactive-supplier.pdf supplierTaxId:800999888purchaseOrderId:PO-90100process→ Requires 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:
Esperado: valid=true, withinPoAmount=true.
Escenario B — RR.HH. (pendiente E3/E4)¶
- Login como
HR.User(cuando exista Entra + front) - Preguntar: ¿Cuál es la política de trabajo remoto?
- 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¶
- Usuario en Finance.Reviewer (y opcionalmente User) → Sign in.
- Abrir factura en Requires Human Review.
- Esperado: botones Aprobar / Rechazar / Devolver activos; decisión →
Approved/Rejected/Returned+HumanDecisioncon la identidad del token (no el demo hardcodeado).
Pasada solo User (mismo UPN o segundo usuario)¶
- Quitar temporalmente del grupo Reviewer (dejar User):
- Logout → Login (renovar JWT; sin esto el token viejo sigue trayendo
groups). - Misma factura HITL → botones deshabilitados + mensaje de solo Reviewer.
- (Opcional)
POSTAPIM…/approvecon Bearer del User → 403 (required-claims/ API). - Restaurar Reviewer y Logout → Login otra vez:
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):
POST /api/finance/chatcon un mensaje que fuerce tools, p. ej. PO de esa factura, validate amount y check duplicate delinvoiceNumber.- Esperado:
mode=foundry-agent,toolsUsedcon 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
invoiceNumberen 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 (
toolsUseden 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=falsependiente de VNet - Escenario B RR.HH. (E3)
- Assignment required en Enterprise app (opcional Entra)