LeadFlow AI — Plan de Orquestación MVP

orch-build-mvp · SDD v1.0 → MVP funcional · Next.js 14 + Supabase + Tailwind
Agentes IA 4 slices verticales 2 gates de aprobación TDD + Playwright
Slices verticales
4
extremo a extremo
Iteraciones GAN est.
8
máx 15 · umbral 7.0
Gates de aprobación
2
plan + pre-commit
Commits generados
6
feat + test + chore
Fase 0 — Análisis del SDD
📌 Decisiones bloqueadas (locked)
Auth via Supabase magic link (sin contraseñas)
Stack: Next.js 14 App Router, TypeScript estricto
Scoring v1: heurístico (sin ML), reglas en JSON configurable
Deploy en Vercel (tier gratuito)
Base de datos: Supabase (PostgreSQL + RLS)
🗂 Features extraídas del SDD
Autenticación y gestión de sesión
Dashboard de leads con tabla filtrable
Engine de scoring heurístico configurable
Vista detalle de lead + historial de actividad
Integración webhook (formulario web → lead)
Notificaciones por email (lead hot)
Pipeline de fases
P0
Lectura del SDD ✓ Completado
Extraídas 6 features, 5 decisiones bloqueadas. Scope confirmado: SaaS B2B de scoring de leads para equipos de ventas PYME. Sin cambios al design brief.
→ features.json · locked-decisions.md
P1
Ordenación en cortes verticales finos ✓ Completado
4 slices verticales ordenados por valor y dependencia. Slice 1 es el camino feliz completo: login → ver leads → ver score.
→ slice-plan.md (ver abajo ⬇)
P2
Gate 1 — Aprobación del plan de slices 🔒 Gate
Pausa para que el equipo revise el orden de slices, estime esfuerzo y confirme el scope de la demo. El pipeline no avanza hasta aprobación explícita.
🔒
P3
Scaffold del Slice 1 ▶ Activo
Genera estructura de proyecto, configura Supabase client, tablas iniciales con RLS, layout de Next.js y rutas protegidas. El GAN harness se inicializa con spec.md + eval-rubric.md derivados del SDD.
→ gan-harness/spec.md · gan-harness/eval-rubric.md · scaffold/
P4–5
Bucle GAN — Generator → Evaluator ⏳ Pendiente
/gan-build "Auth + leads dashboard + heuristic scoring" --skip-planner --max-iterations 15 --pass-threshold 7.0 --eval-mode playwright

El generador produce código; el evaluador lo prueba con Playwright y puntúa contra el rubric. El loop itera hasta superar 7.0/10 o plateau.
→ gan-harness/feedback/feedback-NNN.md · score-history.json
P6
Gate 2 — Pre-commit review 🔒 Gate
Review final antes de hacer commit. El security-reviewer se activa automáticamente porque el slice toca autenticación (trigger: Supabase Auth). Aprobación confirmada → commits separados por slice.
🔒
Gates de aprobación
🔒
Gate 1 — Aprobación del plan de slices
El pipeline se detiene aquí. El equipo debe revisar y confirmar el plan antes de que empiece el scaffold.
¿El orden de slices refleja la prioridad de la demo?
¿Todas las decisiones bloqueadas son correctas?
¿Scope del Slice 1 es alcanzable en 3 días?
¿Las dependencias entre slices son correctas?
🔐
Gate 2 — Pre-commit (+ security review automático)
Activado porque el Slice 1 toca autenticación. El security-reviewer escanea el diff antes de permitir el commit.
Score GAN ≥ 7.0 (superado: 7.8/10)
Tests Playwright: 100% pass en happy path
Security review: sin vulnerabilidades críticas
RLS policies en Supabase verificadas
No hay secrets en el código (audit limpio)
Slices verticales — Plan completo
S1
Auth + Dashboard de Leads + Scoring básico
~3 días · Activo
Frontend
Página /login con magic link form
Callback de auth y redirect
Layout con sidebar (Tailwind)
Tabla de leads con columnas: nombre, empresa, score, estado
Badge de score (rojo/amarillo/verde)
Backend / API
Supabase Auth config (magic link)
Tabla leads con RLS (solo su org)
API Route GET /api/leads
Función calculateScore(lead)
Reglas de scoring en scoring-rules.json
Tests
Playwright: happy path login → tabla
Unit: calculateScore() con 5 casos
Integration: GET /api/leads con RLS
Test: redirect sin auth → /login
En construcción ahora mismo
S2
Vista detalle de lead + historial de actividad
~2 días · Pendiente
Frontend
Página /leads/[id] con perfil completo
Timeline de actividad (visitas, clics)
Panel lateral con desglose de score
Backend / API
Tabla lead_events
API Route GET /api/leads/[id]
Recalcular score al añadir evento
Tests
Playwright: navegar a detalle desde tabla
Unit: recalcular score con evento nuevo
S3
Webhook de ingesta + formulario web → lead
~1.5 días · Pendiente
Frontend
Página /settings/integrations
Snippet copiable para embed
Backend / API
POST /api/webhook/lead (autenticado por secret)
Normalización de payload
Score inicial automático
Tests
Integration: POST webhook → lead en DB
Seguridad: rechazar sin secret
S4
Notificaciones por email — lead "hot"
~1 día · Pendiente
Frontend
Toggle en /settings/notifications
Umbral configurable (default: score ≥ 75)
Backend / API
Supabase Edge Function trigger
Resend API para envío de email
Template HTML del email
Tests
Unit: trigger solo cuando score ≥ umbral
Mock Resend en tests
Bucle GAN — Iteraciones del Slice 1 (simuladas)
📋
Spec + Rubric
Del SDD v1.0
→ gan-harness/
⚙️
Generator
Produce código
por iteración
🎭
Playwright
Ejecuta tests
E2E + UI
🎯
Evaluador
Puntúa vs rubric
≥ 7.0 → pass
📝
Feedback
feedback-NNN.md
→ siguiente iter.
Iter. 1
4.5
Iter. 2
5.8
Iter. 3
6.5
Iter. 4
7.2
Iter. 5 ✓
7.8
✓ Umbral superado (7.8 ≥ 7.0) en iteración 5 de 15 — Gate 2 desbloqueado
Artefacto generado — scoring-rules.json + calculateScore()
lib/scoring/calculateScore.ts
TypeScript
// Auto-generado por gan-generator · iter-5 · score 7.8/10
import rules from './scoring-rules.json'
import { Lead, ScoringResult } from '@/types'

export function calculateScore(lead: Lead): ScoringResult {
  let score = 0
  const breakdown: Record<string, number> = {}

  // Regla 1: Tamaño de empresa
  const sizeRule = rules.company_size.find(
    r => lead.employees >= r.min && lead.employees <= r.max
  )
  if (sizeRule) {
    score += sizeRule.points
    breakdown['company_size'] = sizeRule.points
  }

  // Regla 2: Actividad reciente (visitas últimos 7 días)
  const recentVisits = lead.events.filter(
    e => e.type === 'page_view' &&
    Date.now() - new Date(e.timestamp).getTime() < 7 * 24 * 3600 * 1000
  ).length
  const activityScore = Math.min(recentVisits * rules.activity.points_per_visit, rules.activity.max)
  score += activityScore
  breakdown['recent_activity'] = activityScore

  // Regla 3: Cargo del contacto
  const titleMatch = rules.job_titles.find(
    t => lead.jobTitle?.toLowerCase().includes(t.keyword)
  )
  if (titleMatch) {
    score += titleMatch.points
    breakdown['job_title'] = titleMatch.points
  }

  return {
    total: Math.min(score, 100),
    tier: score >= 75 ? 'hot' : score >= 45 ? 'warm' : 'cold',
    breakdown
  }
}
Commits generados (Slice 1)
a1b2c3d
chorescaffold: next.js 14 + supabase + tailwind setup
Estructura base, .env.local.example, supabase/migrations/001_leads.sql
e4f5g6h
featauth: magic link login con supabase auth
app/login/page.tsx · app/auth/callback/route.ts · middleware.ts (ruta protegida)
i7j8k9l
featleads: tabla de leads filtrable con score badge
app/leads/page.tsx · components/LeadsTable.tsx · components/ScoreBadge.tsx
m1n2o3p
featscoring: engine heurístico configurable por reglas JSON
lib/scoring/calculateScore.ts · lib/scoring/scoring-rules.json · app/api/leads/route.ts
q4r5s6t
testslice-1: playwright e2e + unit tests (coverage 87%)
e2e/auth.spec.ts · e2e/leads-dashboard.spec.ts · __tests__/calculateScore.test.ts
u7v8w9x
featsecurity: rls policies leads table + audit ok
supabase/migrations/002_rls.sql · [security-reviewer: sin vulnerabilidades críticas]