😤 El ProblemaThe Problem
OventLabs es una fábrica de software impulsada por agentes de IA. Construimos apps para clientes usando OpenClaw, sub-agentes y un stack moderno. Pero teníamos un problema clásico: los clientes no sabían qué estaba pasando con su proyecto.
OventLabs is an AI-agent-powered software factory. We build apps for clients using OpenClaw, sub-agents, and a modern stack. But we had a classic problem: clients had no idea what was happening with their project.
Todo era por WhatsApp y email. "¿Ya está listo?" "¿Qué llevan?" "¿Cuándo me lo entregan?" — eso no escala. Necesitábamos un portal donde el cliente pudiera:
Everything was over WhatsApp and email. "Is it ready?" "What's the progress?" "When will you deliver?" — that doesn't scale. We needed a portal where clients could:
- 🔐 Autenticarse sin contraseña (magic links)
- 📝 Hacer onboarding con un wizard inteligente
- 🤖 Ver su alcance generado por IA automáticamente
- 📊 Trackear requerimientos en tiempo real
- 🔐 Authenticate without passwords (magic links)
- 📝 Onboard through a smart wizard
- 🤖 See their AI-generated scope automatically
- 📊 Track requirements in real time
El reto: construir todo esto en 1 día. No en un sprint de 2 semanas. Un. Solo. Día. 🚀
The challenge: build all of this in 1 day. Not a 2-week sprint. One. Single. Day. 🚀
🏗️ La ArquitecturaThe Architecture
Decisión clave: no construir un backend separado. OventHub vive dentro del mismo Next.js 15 que ya servía la landing de agents.oventlabs.com. API routes, Prisma, auth — todo en el mismo deploy.
Key decision: don't build a separate backend. OventHub lives inside the same Next.js 15 app that already served the agents.oventlabs.com landing. API routes, Prisma, auth — all in a single deploy.
¿Por qué? Un solo deploy, infraestructura compartida, cero costo extra.
Why? Single deploy, shared infra, zero extra cost.
Client → agents.oventlabs.com → Nginx → Docker (Next.js :3001)
↓
Prisma → PostgreSQL
↓
GitHub Copilot API (AI)
⚡ Frontend + BackendFrontend + Backend
Next.js 15 con React 19. API routes para auth, onboarding, AI y requirements. Un solo container Docker.
Next.js 15 with React 19. API routes for auth, onboarding, AI and requirements. Single Docker container.
🗄️ Base de DatosDatabase
Prisma ORM + PostgreSQL corriendo en el container tenk-postgres. Compartido con otros proyectos en la misma EC2.
Prisma ORM + PostgreSQL running in the tenk-postgres container. Shared with other projects on the same EC2.
🔐 Magic Link Auth (sin contraseñas)Magic Link Auth (no passwords)
Nada de contraseñas. El flujo es brutal en su simplicidad:
No passwords. The flow is brutally simple:
Ingresa email → recibe magic link → click → JWT → logged in. Así de fácil.
Enter email → receive magic link → click → JWT → logged in. That easy.
- Token expira en 15 minutos
- JWT válido por 7 días
- SMTP via Hostinger (
ventas@corporativotruckdriver.com) - Token expires in 15 minutes
- JWT valid for 7 days
- SMTP via Hostinger (
ventas@corporativotruckdriver.com)
const token = crypto.randomUUID();
await prisma.magicLink.create({
data: {
email,
token,
expiresAt: new Date(Date.now() + 15 * 60 * 1000)
}
});
await sendEmail(email, `${APP_URL}/api/auth/verify?token=${token}`);
Resultado: cero fricción para el cliente. No necesita recordar contraseñas, no necesita "forgot password". Entra con un click.
Result: zero friction for the client. No passwords to remember, no "forgot password". One-click access.
📝 Onboarding como Funnel de LeadsOnboarding as a Lead Funnel
El onboarding no es solo "llena tu perfil". Es un funnel de calificación de leads disfrazado de wizard bonito. 4 pasos:
Onboarding isn't just "fill your profile". It's a lead qualification funnel disguised as a pretty wizard. 4 steps:
1️⃣ PerfilProfile
Nombre, empresa, rol, teléfono. Lo básico para saber quién eres.
Name, company, role, phone. The basics to know who you are.
2️⃣ MetodologíaMethodology
Tipo de proyecto, presupuesto, urgencia. Calificación automática.
Project type, budget, urgency. Automatic qualification.
3️⃣ Descripción del ProblemaProblem Description
El cliente describe su problema en texto libre. Esto alimenta al AI para generar el alcance.
The client describes their problem in free text. This feeds the AI to generate the scope.
4️⃣ ConfirmaciónConfirmation
Resumen → Crear proyecto → Trigger automático de generación de alcance con IA. 🤖
Summary → Create project → Automatic trigger for AI scope generation. 🤖
UI: Glassmorphism con dark theme. El wizard se siente premium y profesional. El cliente no siente que está llenando un formulario aburrido.
UI: Glassmorphism with dark theme. The wizard feels premium and professional. The client doesn't feel like they're filling out a boring form.
🤖 Generación de Alcance con IA ($0 de costo)AI Scope Generation ($0 cost)
Esta es la parte favorita. Cuando el cliente completa el onboarding, la IA genera automáticamente un documento de alcance completo. Y lo mejor: cuesta $0.
This is the favorite part. When the client completes onboarding, the AI automatically generates a complete scope document. And the best part: it costs $0.
¿Cómo? Usamos la GitHub Copilot API — ya pagamos la suscripción. El flujo de tokens:
How? We use the GitHub Copilot API — we already pay the subscription. The token flow:
GITHUB_COPILOT_TOKEN (ghu_*)
→ Exchange for temp API token
→ Call chat/completions
→ Model: claude-opus-4.5
→ SSE streaming response
El scope generado incluye: info del proyecto, contexto, tabla de requerimientos funcionales (RF-001, RF-002...), stack tecnológico, entregables y timeline.
The generated scope includes: project info, context, functional requirements table (RF-001, RF-002...), tech stack, deliverables, and timeline.
const res = await fetch(
"https://api.individual.githubcopilot.com/chat/completions",
{
headers: { Authorization: `Bearer ${apiToken}` },
body: JSON.stringify({
model: "claude-opus-4.5",
messages: [...],
stream: true
})
}
);
💰 Costo: $0. El modelo Claude Opus 4.5 corre via Copilot API, incluido en la suscripción. No OpenAI, no Anthropic direct, no billing sorpresa.
💰 Cost: $0. The Claude Opus 4.5 model runs via Copilot API, included in the subscription. No OpenAI, no Anthropic direct, no surprise billing.
📊 Auto-parseo de RequerimientosAuto-parsing Requirements
La IA genera una tabla markdown con requerimientos (RF-001, RF-002...). Un parser automático extrae esos requerimientos del documento de alcance y crea registros en la base de datos.
The AI generates a markdown table with requirements (RF-001, RF-002...). An automatic parser extracts those requirements from the scope document and creates records in the database.
AI Scope Document (markdown)
→ Parser extracts RF-XXX rows
→ Requirement records in DB
→ Status: pendiente → en_desarrollo → qa → entregado
→ Priority: alta | media | baja
→ Comments per requirement (mini ticket system)
Cada requerimiento se convierte en un mini ticket. El cliente puede ver el estado, la prioridad y agregar comentarios. Es como un Jira simplificado pero integrado directamente en su portal.
Each requirement becomes a mini ticket. The client can see the status, priority, and add comments. It's like a simplified Jira but integrated directly into their portal.
🤖 Desarrollo Multi-AgenteMulti-Agent Development
Esto no se construyó en un IDE con café y keyboard shortcuts. Se construyó con OpenClaw — un ejército de agentes de IA trabajando en paralelo.
This wasn't built in an IDE with coffee and keyboard shortcuts. It was built with OpenClaw — an army of AI agents working in parallel.
🔗 oventhub-integrate
Fusionó el backend standalone dentro del portfolio Next.js. Migration de rutas, schemas, y middleware.
Merged the standalone backend into the portfolio Next.js. Route, schema, and middleware migration.
📝 oventhub-onboarding
Construyó el wizard de 4 pasos en 5 minutos. Con glassmorphism, validaciones y dark theme.
Built the 4-step wizard in 5 minutes. With glassmorphism, validations and dark theme.
🎨 oventhub-dark-modal
Arregló CSS vars en todas las páginas del hub. El dark theme consistente es más difícil de lo que parece.
Fixed CSS vars across all hub pages. Consistent dark theme is harder than it looks.
⚡ Anti-AgileAnti-Agile
Same day deploy. Zero sprints. Zero ceremonies. Zero standups. Solo resultados.
Same day deploy. Zero sprints. Zero ceremonies. Zero standups. Just results.
💥 Lecciones Aprendidas / GotchasLessons Learned / Gotchas
No todo fue miel sobre hojuelas. Estas son las trampas reales que nos mordieron:
Not everything was smooth sailing. These are the real traps that bit us:
🔥 Port mapping hell: -p 3001:3001 NO -p 3001:3000. Si tu app escucha en 3001 dentro del container, mapea 3001:3001. Parece obvio. Causó 502s múltiples veces.
🔥 Port mapping hell: -p 3001:3001 NOT -p 3001:3000. If your app listens on 3001 inside the container, map 3001:3001. Seems obvious. Caused 502s multiple times.
🔥 Docker --env-file incluye quotes literalmente: si pones DB_URL="postgres://..." en tu .env, Docker lo lee con las comillas incluidas. No pongas comillas alrededor de los valores.
🔥 Docker --env-file includes quotes literally: if you put DB_URL="postgres://..." in your .env, Docker reads it with the quotes included. Don't put quotes around values.
⚠️ react-markdown no bundlea en Next.js standalone → switcheamos a marked. Menos features, pero funciona en el output standalone sin drama.
⚠️ react-markdown doesn't bundle in Next.js standalone → switched to marked. Fewer features, but works in standalone output without drama.
⚠️ CSS vars como canales RGB: --ov-bg: 15 23 42 con rgb(var(--ov-bg)) funciona. Hex fallbacks rompen el dark theme. Mantén consistencia.
⚠️ CSS vars as RGB channels: --ov-bg: 15 23 42 with rgb(var(--ov-bg)) works. Hex fallbacks break the dark theme. Stay consistent.
📝 Visit counter usa file store → necesita volume mount en cada recreación de container. Si no, pierdes el conteo.
📝 Visit counter uses file store → needs volume mount on every container recreate. Otherwise, you lose the count.
📝 Copilot API model ID: claude-opus-4.5 (con punto). NO claude-opus-4-5 (con guión). Un carácter de diferencia = request fallido.
📝 Copilot API model ID: claude-opus-4.5 (with dot). NOT claude-opus-4-5 (with hyphen). One character difference = failed request.
🛠️ Stack FinalFinal Stack
- ⚡ Next.js 15 + React 19
- 🎨 Tailwind CSS 4 + Glassmorphism
- 🗄️ Prisma + PostgreSQL
- 🤖 GitHub Copilot API (Claude Opus 4.5)
- 🐳 Docker + EC2 + Nginx + ALB
- 📧 Nodemailer + Hostinger SMTP
- 🧠 OpenClaw (multi-agent orchestration)
🚀 ¿Qué sigue?What's next?
- 🎛️ Panel de admin para actualizar estados de requerimientos
- 🔔 Notificaciones en tiempo real cuando cambie un status
- 📎 Archivos adjuntos por requerimiento
- 💳 Integración con Stripe para cobros y pagos
- 🎛️ Admin panel for requirement status updates
- 🔔 Real-time notifications when a status changes
- 📎 File attachments per requirement
- 💳 Stripe integration for billing and payments
El punto: un MVP funcional con auth, onboarding, AI scope gen y tracking — en producción — en 1 día. No perfecto, pero real. Iteramos después.
The point: a functional MVP with auth, onboarding, AI scope gen and tracking — in production — in 1 day. Not perfect, but real. We iterate later.