Onboarding Guide

LeadPilot SaaS

Guía de incorporación para desarrolladores nuevos — arquitectura, convenciones y puntos de entrada del repositorio monorepo.

Repositorio: leadpilot-app
Stack: Next.js 14 + Express 4 + Prisma
Generado por: CULTIVA IA / onboarding-de-codebase
Fecha: 2026-06-18
📋
Overview del Proyecto
Qué es LeadPilot y a quién sirve
Tipo
SaaS B2B
Agencias de marketing digital
Arquitectura
Monorepo
Turborepo · 2 apps · 2 packages
Deploy
Vercel + Railway
CI/CD via GitHub Actions
LeadPilot es una plataforma SaaS B2B que permite a agencias de marketing crear y gestionar campañas de prospección multicanal (email + LinkedIn). Los usuarios enriquecen leads con IA, definen secuencias de outreach y miden la conversión por canal desde un dashboard centralizado. El repo contiene el frontend Next.js 14 (App Router) y la API Express 4, conectados a PostgreSQL 15 vía Prisma ORM y protegidos con autenticación Clerk.
🔧
Tech Stack
Tecnologías detectadas en package.json, turbo.json y configs
Capa Tecnología Versión Rol en el proyecto
Lenguaje TypeScript 5.4 Lenguaje principal en todos los paquetes
Frontend Next.js 14.2 App Router · RSC · Server Actions
UI shadcn/ui + Tailwind 3.4 Sistema de componentes + estilos utilitarios
Backend Express 4.18 REST API, desplegada en Railway
ORM Prisma 5.14 Modelos, migraciones y cliente type-safe
Base de datos PostgreSQL 15 Persistencia principal (Railway managed)
Auth Clerk 5.x JWT + webhooks de usuario
Monorepo Turborepo 2.x Build pipeline + caché distribuida
Testing Vitest + Playwright 1.6 / 1.44 Unit/integration (Vitest) · E2E (Playwright)
CI/CD GitHub Actions ci.yml (test+lint) · deploy.yml (Vercel/Railway)
🏗️
Arquitectura
Monorepo con frontend BFF + API separada
Cliente
Browser
HTTPS
Frontend · Vercel
apps/web
Next.js 14 App Router
BFF / Server
Route Handlers
app/api/
Next.js BFF layer
API · Railway
apps/api
Express 4 REST
Base de datos
PostgreSQL 15
via Prisma ORM
Patrón
Monorepo + BFF
Frontend actúa como BFF (Backend for Frontend), delegando lógica pesada a la API Express.
API Style
REST
Endpoints versionados bajo /api/v1/. Validación con Zod en cada handler.
Auth Flow
Clerk JWT
El frontend obtiene el JWT de Clerk y lo envía como Bearer en todas las peticiones a la API.
Shared Code
packages/shared
Tipos TypeScript compartidos entre web y api. Sin lógica de negocio en este paquete.
🚪
Key Entry Points
Archivos donde empezar a leer según la tarea
apps/api/src/index.ts
Inicializa Express, monta middleware global (auth, rate-limit, cors) y registra los routers. Punto de partida para entender el servidor.
apps/api/src/routes/
Cada recurso tiene su archivo de rutas (campaigns.routes.ts, leads.routes.ts). Las rutas apuntan a controllers.
apps/web/app/layout.tsx
Envuelve toda la app con ClerkProvider, ThemeProvider y el layout global. Punto de entrada del frontend.
apps/api/prisma/schema.prisma
Source of truth del esquema de base de datos. Leerlo antes de tocar cualquier query o servicio.
apps/web/lib/api-client.ts
Wrapper tipado de fetch que inyecta el JWT de Clerk y maneja errores HTTP. Usar siempre en lugar de fetch directo.
.github/workflows/ci.yml
Define los pasos de lint, test y build que se ejecutan en cada PR. Referencia para saber qué debe pasar localmente antes de pushear.
📁
Mapa de Directorios
Top-level + 2 niveles — sin node_modules, dist, .next
apps/web/app/(dashboard)/ Páginas autenticadas del dashboard FRONTEND
apps/web/app/(auth)/ Páginas públicas: login, register, forgot-password FRONTEND
apps/web/app/api/ Route Handlers (BFF): proxy + transformación para el cliente FRONTEND
apps/web/components/ui/ Componentes shadcn/ui base (no modificar directamente)
apps/web/components/campaigns/ Componentes de dominio: CampaignCard, CampaignForm, etc.
apps/web/lib/ Utilidades: api-client.ts, auth.ts, utils.ts, constants.ts
apps/api/src/routes/ Definición de rutas por recurso API
apps/api/src/controllers/ Manejo HTTP: req/res/validación, delega a services API
apps/api/src/services/ Lógica de negocio pura, sin dependencias HTTP API
apps/api/src/repositories/ Acceso a datos: queries Prisma encapsuladas API
apps/api/src/middleware/ Auth (Clerk JWT), rate-limit, validación Zod, error handler
apps/api/prisma/ schema.prisma + migrations/ — source of truth del modelo de datos
packages/shared/ Tipos TypeScript compartidos entre web y api SHARED
packages/config/ ESLint, Prettier, tsconfig base — no tocar sin revisar impacto
.github/workflows/ ci.yml (lint+test) · deploy.yml (Vercel + Railway)
🔄
Ciclo de una Request
Traza: "Listar campañas de un workspace" — de entrada a respuesta
1
Componente React (Server Component)
apps/web
app/(dashboard)/campaigns/page.tsx llama a lib/api-client.ts con GET /api/v1/campaigns, adjuntando el JWT de Clerk.
2
Middleware de Auth
apps/api
middleware/auth.ts verifica el JWT con el SDK de Clerk. Si es válido, adjunta req.userId y req.workspaceId al request.
3
Router → Controller
apps/api
routes/campaigns.routes.ts despacha a controllers/campaigns.controller.ts → listCampaigns(). Validación del query con Zod antes de continuar.
4
Service (Lógica de Negocio)
apps/api
services/campaigns.service.ts → getCampaignsForWorkspace() aplica reglas de negocio: filtros por plan, paginación, orden por defecto.
5
Repository (Acceso a Datos)
apps/api
repositories/campaigns.repository.ts ejecuta prisma.campaign.findMany({ where: { workspaceId } }) y devuelve los datos tipados.
6
Respuesta JSON → Render
apps/web
El controller devuelve res.json({ data: campaigns, meta: { total, page } }). El Server Component hidrata con los datos y React renderiza la lista.
📐
Convenciones Detectadas
Patrones que ya sigue el codebase — seguirlos sin excepción
📝 Naming
  • Archivos: kebab-case para todos (campaign-card.tsx)
  • Componentes React: PascalCase (CampaignCard)
  • Variables/funciones: camelCase
  • Tipos TS: PascalCase con sufijo de dominio (CampaignDTO)
  • Tests: *.test.ts junto al archivo fuente, E2E en tests/e2e/
⚠️ Error Handling
  • API: Error handler centralizado en middleware/error-handler.ts
  • Los controllers lanzan instancias de AppError (clase custom)
  • No usar try/catch en controllers — el handler lo captura
  • Frontend: Errores de fetch en api-client.ts devuelven Result<T, ApiError>
🌿 Git Workflow
  • Branches: feat/, fix/, chore/, refactor/
  • Commits: Conventional Commits (feat: add campaign cloning)
  • PRs: Squash merge a main, al menos 1 review
  • Los PRs deben pasar CI (lint + test) antes de mergear
🧪 Testing
  • Unit: Vitest en services y repositories
  • Integration: Vitest con DB en memoria (Prisma + SQLite)
  • E2E: Playwright en apps/web/tests/e2e/
  • Cobertura mínima configurada: 80% en services
Tareas Comunes
Comandos desde la raíz del monorepo
🚀
Dev — Todo en paralelo
pnpm dev
🏗️
Build producción
pnpm build
🧪
Tests unitarios
pnpm test
🎭
Tests E2E (Playwright)
pnpm test:e2e
🔍
Lint + type-check
pnpm lint && pnpm check-types
🗄️
Migración de DB
pnpm --filter api prisma migrate dev
🌱
Seed de datos
pnpm --filter api prisma db seed
🔎
Prisma Studio (UI de BD)
pnpm --filter api prisma studio
🔍
Dónde Mirar
Referencia rápida por tipo de tarea
Si quiero… Archivo / Carpeta
Añadir un endpoint de API apps/api/src/routes/ + controllers/ + services/
Añadir una tabla o campo a la BD apps/api/prisma/schema.prisma
Añadir una página al dashboard apps/web/app/(dashboard)/
Crear un componente de UI reutilizable apps/web/components/ui/ (shadcn) o components/[dominio]/
Llamar a la API desde el frontend apps/web/lib/api-client.ts
Cambiar la lógica de autenticación apps/api/src/middleware/auth.ts + apps/web/lib/auth.ts
Añadir un tipo compartido packages/shared/src/types/
Modificar el pipeline de CI/CD .github/workflows/ci.yml o deploy.yml
Añadir un test unitario Junto al archivo fuente: [archivo].test.ts
Añadir un test E2E apps/web/tests/e2e/
Cambiar config de ESLint/Prettier/TS packages/config/ — cuidado: afecta a todo el monorepo
🤖
CLAUDE.md Generado
Archivo listo para colocar en la raíz del repo
CLAUDE.md ✓ Listo para usar
# Project Instructions — LeadPilot # Generated by CULTIVA IA / onboarding-de-codebase · 2026-06-18 ## Tech Stack - TypeScript 5.4 en todos los paquetes - Frontend: Next.js 14 App Router + shadcn/ui + Tailwind (apps/web) - Backend: Express 4 REST API (apps/api) - Base de datos: PostgreSQL 15 via Prisma 5 ORM - Auth: Clerk (JWT + webhooks) - Monorepo: Turborepo + pnpm workspaces ## Build & Run - Dev: pnpm dev (lanza web + api en paralelo) - Build: pnpm build - Lint: pnpm lint - Type-check: pnpm check-types ## Testing - Unit/integration: pnpm test (Vitest) - E2E: pnpm test:e2e (Playwright) - Cobertura mínima: 80% en services - Patrón de test: [archivo].test.ts junto al fuente, E2E en apps/web/tests/e2e/ ## Code Style - Archivos: kebab-case (campaign-card.tsx) - Componentes: PascalCase (CampaignCard) - Tipos: PascalCase con sufijo de dominio (CampaignDTO) - Error handling en API: lanzar AppError, NO try/catch en controllers - HTTP desde frontend: usar SIEMPRE lib/api-client.ts, nunca fetch directo ## Database - Migración: pnpm --filter api prisma migrate dev - Seed: pnpm --filter api prisma db seed - UI: pnpm --filter api prisma studio - Source of truth del esquema: apps/api/prisma/schema.prisma ## Project Structure apps/web/ → Frontend Next.js 14 apps/api/ → Backend Express 4 apps/api/prisma/ → Esquema + migraciones packages/shared/ → Tipos TS compartidos (sin lógica de negocio) packages/config/ → ESLint, Prettier, tsconfig base ## Conventions - Commits: Conventional Commits (feat: ... / fix: ... / chore: ...) - Branches: feat/, fix/, chore/, refactor/ - PRs: squash merge a main, 1 review mínimo, CI verde obligatorio - Tipos compartidos van en packages/shared/, no duplicar entre apps