CultivaLeads CRM

Task Execution Graph for AI Agents — app.cultivaleads.io
Schema v1.1 · Local overlay
✓ Verified 2026-06-14
🔒 login_required 🍪 COOKIE_API 6 páginas mapeadas 3 workflows 3 pitfalls conocidos
6
Páginas
3
Workflows
9
Acciones
3
Pitfalls
📄 SITE.md
schema v1.1 source: local
---
schema_version: 1
site: app.cultivaleads.io
last_verified: 2026-06-14
source: local
login_required: true
auth_strategy: COOKIE_API   # sesión cookie 24h, email/password
---

## Overview
CultivaLeads es un CRM SaaS B2B para gestión de leads y pipelines de ventas.
Requiere sesión activa para todas las rutas (redirige a /login si no autenticado).

## Top-level routes
- /dashboard    → pages/dashboard.md
- /leads        → pages/leads-list.md
- /leads/import → pages/leads-import.md
- /leads/new    → pages/leads-new.md   # draft — no explorado completamente
- /leads/:id    → pages/lead-detail.md
- /reports      → pages/reports.md
- /settings     → sin cobertura — agent debe explorar
- /billing      → sin cobertura — agent debe explorar

## Common goals
- Capturar leads vía CSV masivo  → workflows/capture-lead.md
- Actualizar estado de un lead   → workflows/update-lead-status.md
- Exportar reporte de pipeline   → workflows/export-report.md

## Site-wide pitfalls
- Requiere auth activa para TODAS las rutas (ver pitfalls.md)
- El menú "Más acciones" solo aparece al hover sobre la fila de lead
- Evitar paths /m/* (versión móvil, DOM diferente)
📑 pages/ — Páginas Mapeadas
6 páginas
Tabla de rutas
URL Pattern page_id Propósito Cubierto
/dashboard dashboard KPIs + resumen del pipeline ✓ Cubierto
/leads leads-list Listado filtrable con acciones masivas ✓ Cubierto
/leads/import leads-import Importación masiva CSV ✓ Cubierto
/leads/new leads-new Formulario de lead manual ⚠ Draft
/leads/:id lead-detail Ficha individual con historial ✓ Cubierto
/reports reports Generador de reportes PDF ✓ Cubierto
pages/leads-import.md — Detalle
---
schema_version: 1
page_id: leads-import
url_patterns:
  - https://app.cultivaleads.io/leads/import
purpose: importar leads en bloque desde archivo CSV
last_verified: 2026-06-14
source: local
---
Visual anchors — página de importación
Tipo Anchor Estabilidad
a11y role=main, heading "Importar Leads" Alta
testid [data-testid="csv-upload-zone"] Alta
selector_pattern input[accept=".csv,text/csv"] Media
pattern dropzone con borde dashed visible Baja
Acciones en leads-import
action:open_import_page Form B compact
pre
on /leads, logged_in
do
click [data-testid="import-btn"] OR hover row → click "Importar CSV" in [data-testid="more-actions-menu"]
post
URL is /leads/import AND [data-testid="csv-upload-zone"] visible
fail
menu not visible after hover | /login redirect | button_not_found
recover
navigate directly to /leads/import; if 403 → session expired, re-auth first
evidence
opencli browser session-01 find "Importar CSV" + state
action:upload_csv_file Crítica — sin adapter
pre
on /leads/import AND csv-upload-zone visible AND csv_file_path ready
do: opencli browser set_file input[accept=".csv,text/csv"] <csv_file_path>
    || drag-and-drop file onto [data-testid="csv-upload-zone"]
post
preview table renders with ≥1 row AND "N leads detectados" text appears
fail
error "formato no soportado" | preview empty | upload spinner loops >10s
recover
verify CSV encoding is UTF-8; if spinner loops: refresh page, retry once; if persists: escalate
evidence
opencli browser session-01 network (observed multipart/form-data POST /api/v1/leads/import/preview)
action:confirm_import
pre
preview table visible AND no validation errors shown
do
click role=button name="Confirmar importación"
post
success banner "X leads importados" visible OR redirect to /leads with toast
fail
validation errors list appears | button disabled | HTTP 422
recover
read validation errors; fix CSV; repeat upload_csv_file
evidence
opencli browser session-01 click + network
pages/lead-detail.md — Acciones de estado
action:update_lead_status Adapter disponible
pre
on /leads/:id, lead_id known, logged_in, new_status ∈ {Nuevo, Contactado, Calificado, Perdido}
do: opencli cultivaleads lead update-status <lead_id> <new_status>
    || click [data-testid="status-dropdown"] → select option matching new_status
post
status badge updates to new_status within 2s; activity log entry created
fail
adapter typed_error | HTTP 409 conflict | status badge unchanged
recover
adapter_health_update: opencli cultivaleads lead update-status -> suspect; fallback to DOM dropdown
evidence
opencli cultivaleads lead update-status + opencli browser session-02 state
pages/reports.md — Exportar PDF
action:generate_pipeline_report Sin adapter — browser only
pre
on /reports, logged_in, date_range selected, NO export modal currently open
do
select date range via [data-testid="date-range-picker"]; click role=button name="Generar reporte"
post
modal with preview appears AND "Descargar PDF" button visible
fail
prev modal still open (blocks new one) | date-range-picker not responding | spinner >15s
recover
if prev modal open: click [role=button][aria-label="Cerrar"] first; see pitfall:export_modal_blocking
evidence
opencli browser session-03 analyze + network (POST /api/v1/reports/generate)
workflows/ — Flujos de Tarea
3 workflows
workflows/capture-lead.md
intent: importar leads masivamente desde CSV externo
sin adapter propio
Goal
Cargar un archivo CSV con ≥1 leads y confirmar la importación masiva en CultivaLeads. Aplica cuando el usuario tiene una lista externa de prospectos.

State Signature
entry: logged_in, csv_file_path available
success: toast "N leads importados" visible en /leads
Best Path — Browser (sin adapter)
1. navigate /leads/import (action:open_import_page)
2. action:upload_csv_file in pages/leads-import.md
3. action:confirm_import in pages/leads-import.md

Fallback
Si /leads/import falla con 404: crear leads uno a uno via /leads/new (más lento, ~N turns).

Avoid
• No intentar la ruta móvil /m/leads/import — DOM diferente
• No usar drag-drop como first intent (inestable en headless)
workflows/update-lead-status.md
intent: cambiar el estado de un lead conocido
adapter healthy
Best Path — Adapter
opencli cultivaleads lead update-status <id> <status>
estimated_turns: 1

Preconditions
lead_id known · logged_in
status ∈ {Nuevo, Contactado, Calificado, Perdido}
Fallback path (on_adapter_fail)
on_adapter_fail:
  - adapter_health_update:
      opencli cultivaleads lead update-status
      -> suspect
  - opencli browser state (verify URL)
  - if not on /leads/:id: navigate /leads/:id
  - action:update_lead_status in
    pages/lead-detail.md (DOM fallback)
estimated_turns: 4
Stale markers
• Menú de estados cambia opciones (rebrand de "Calificado" → "Cualificado") · status dropdown moved to sidebar panel
workflows/export-report.md
intent: exportar reporte de pipeline como PDF
sin adapter
Best Path — Browser Only
1. Navigate /reports
2. Dismiss any open export modal first (see pitfall:export_modal_blocking)
3. action:generate_pipeline_report in pages/reports.md
4. click "Descargar PDF" in modal → file download

State Signature
entry: /reports, logged_in, no modal open
mid: modal visible with preview
success: file download triggered (browser network: GET /api/v1/reports/:id/pdf)
Re-entry Checkpoints
on /reports, no modal → start step 3
modal visible + preview rendered → start step 4
modal visible + spinner → wait 5s then check network

State Validation
Network request GET /api/v1/reports/:id/pdf returns 200 + Content-Type: application/pdf

Avoid
No abrir el modal mientras otro está abierto (bloqueo silencioso).
⚠️ pitfalls.md
3 pitfalls verificados
pitfall:hidden_import_button
trigger:agent navega /leads y busca botón "Importar CSV" directamente visible
symptom:button_not_found; agent falla al intentar click sobre elemento inexistente
workaround:hacer hover sobre fila lead → esperar apertura de menú "Más acciones" → clickar "Importar CSV"; o navegar directamente a /leads/import
verified_at: 2026-06-14
pitfall:export_modal_blocking
trigger:agent intenta generar nuevo reporte mientras un modal de exportación anterior sigue abierto
symptom:botón "Generar reporte" no responde; nuevo modal no aparece (bloqueado silenciosamente)
workaround:antes de generar, verificar ausencia de modal via `opencli browser find "Cerrar"`; si existe, cerrar con role=button aria-label="Cerrar"
verified_at: 2026-06-14
pitfall:session_expiry_redirect
trigger:agent ejecuta acción >24h después de la última autenticación
symptom:redirect a /login con parámetro ?next=<original_url>; acciones previas silenciadas
workaround:detectar URL /login en cada estado post-acción; re-autenticar y navegar de vuelta a ?next URL; reintentar acción original
verified_at: 2026-06-14
Nota de scope: Los pitfalls anteriores son de nivel task-executor (acciones que el agente ejecuta). Los bugs internos del adaptador (ej. rotación de queryId en la API) se documentan en ~/.opencli/sites/app.cultivaleads.io/notes.md, no aquí.
🔌 apis.md — Endpoints Observados
source: local
endpoint:leads_import_preview
triggers_on_pages: [leads-import]
triggered_by_actions: [upload_csv_file]
contract_strength: internal-unstable
notes: multipart POST /api/v1/leads/import/preview — responde preview array sin persistir
endpoint:leads_import_confirm
triggers_on_pages: [leads-import]
triggered_by_actions: [confirm_import]
contract_strength: internal-unstable
endpoint:leads_list_v1
triggers_on_pages: [leads-list, dashboard]
triggered_by_actions: [page_load, apply_filter]
contract_strength: visible-ui (usado por adapter opencli cultivaleads leads list)
endpoint:report_generate
triggers_on_pages: [reports]
triggered_by_actions: [generate_pipeline_report]
contract_strength: internal-unstable
notes: POST /api/v1/reports/generate → returns report_id; luego GET /api/v1/reports/:id/pdf para descarga
Regla: Este archivo solo contiene endpoint_id ↔ trigger mappings. URL, params y response shapes viven exclusivamente en ~/.opencli/sites/app.cultivaleads.io/endpoints.json. No duplicar esquemas aquí.
📁 Estructura de archivos generada
Storage Model v1.1
~/.opencli/sites/app.cultivaleads.io/
├── sitemap/
│ ├── SITE.md~320 tok↑ local overlay
│ ├── pages/
│ │ ├── dashboard.md~280 tok
│ │ ├── leads-list.md~540 tok
│ │ ├── leads-import.md~680 tok≤800 ✓
│ │ ├── lead-detail.md~470 tok
│ │ ├── reports.md~390 tok
│ │ └── draft-leads-new.md⚠ draft, no explorado completo
│ ├── workflows/
│ │ ├── capture-lead.md~420 tok
│ │ ├── update-lead-status.md~380 tok
│ │ └── export-report.md~460 tok
│ ├── pitfalls.md~290 tok
│ └── apis.md~310 tok
├── endpoints.jsonsource of truth para URL/params/response
└── notes.mdadapter-internal bugs (no van a sitemap)
Two-layer model: La overlay local (~/.opencli) gana ante el global seed (sitemaps/app.cultivaleads.io/). Promover a global solo tras revisión. Drafts SIEMPRE dentro de sitemap/, nunca en el nivel padre.