PulseBoard es un tablero Kanban colaborativo inspirado en Linear, con persistencia real en PostgreSQL, sincronización en tiempo real sobre Socket.IO+Redis, autenticación con Clerk (o modo mock para desarrollo), rate limiting y pruebas E2E con Playwright.
- Auth y protección de rutas:
middleware.ts+ páginas/signiny/signup. - Board persistente: creación y movimiento de tareas en DB (Prisma).
- Realtime productivo: sync de tareas, presencia y cursor colaborativo.
- Hardening: validación runtime de entorno con Zod + rate limiting en API y sockets.
- Performance: virtualización por columna con
@tanstack/react-virtual. - QA: CI con
lint,build,realtime:buildytest:e2e.
flowchart LR
U[Usuario] --> W[Web Next.js App Router]
W --> API[Route Handlers /api/tasks]
API --> PG[(PostgreSQL)]
API --> REDIS[(Redis)]
W <--> RT[realtime-service Socket.IO]
RT <--> REDIS
W --> AUTH[Clerk]
CI[GitHub Actions] --> W
CI --> RT
app/: App Router, UI y Route Handlers.components/: UI shared + board virtualizado/dnd.lib/: env, auth runtime, rate limit, mapeos de dominio.shared/realtime-events.ts: contratos tipados compartidos web/realtime.prisma/: schema, seed y utilidades de DB.realtime-service/: servicio Socket.IO con Dockerfile propio.tests/e2e/: pruebas Playwright (auth, persistencia, realtime).artifacts/lighthouse/: reportes de Lighthouse en producción.
Usar .env.example como plantilla base.
| Variable | Requerida | Uso |
|---|---|---|
NODE_ENV |
Sí | Entorno Node |
NEXT_PUBLIC_APP_NAME |
Sí | Nombre público de app |
NEXT_PUBLIC_APP_URL |
Sí | URL pública web |
NEXT_PUBLIC_REALTIME_SERVICE_URL |
Sí | URL pública del servicio realtime |
REALTIME_SERVICE_URL |
Sí | URL interna/servidor para realtime |
REALTIME_PORT |
Sí | Puerto del servicio realtime |
DATABASE_URL |
Sí | Conexión Prisma/PostgreSQL |
DIRECT_URL |
Opcional | URL directa para migraciones Prisma |
REDIS_URL |
Sí | Redis para adapter + rate limits |
NEXT_PUBLIC_AUTH_PROVIDER |
Sí | mock o clerk |
MOCK_DB_ENABLED |
Sí | true o false |
CLERK_SECRET_KEY |
Condicional | Obligatoria cuando NEXT_PUBLIC_AUTH_PROVIDER=clerk |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY |
Condicional | Obligatoria cuando NEXT_PUBLIC_AUTH_PROVIDER=clerk |
NEXT_PUBLIC_CLERK_SIGN_IN_URL |
Sí | Ruta pública de login |
NEXT_PUBLIC_CLERK_SIGN_UP_URL |
Sí | Ruta pública de registro |
RATE_LIMIT_API_WINDOW_MS |
Sí | Ventana de rate limit HTTP |
RATE_LIMIT_API_MAX |
Sí | Máximo requests HTTP por ventana |
RATE_LIMIT_SOCKET_WINDOW_MS |
Sí | Ventana de rate limit WS |
RATE_LIMIT_SOCKET_MAX |
Sí | Máximo eventos WS por ventana |
- Instalar dependencias.
npm install
npm --prefix realtime-service install- Crear entorno local.
cp .env.example .env.local- Levantar infraestructura base (PostgreSQL + Redis).
docker compose up -d db redis- Preparar DB.
npm run prisma:generate
npm run prisma:push
npm run prisma:seed- Ejecutar web + realtime.
npm run dev
npm run realtime:dev- URLs locales.
- Web:
http://localhost:3000 - Realtime health:
http://localhost:4001/health
docker build -t pulseboard-web .docker build -t pulseboard-realtime ./realtime-servicedocker compose up --buildGET /api/tasksPOST /api/tasksPATCH /api/tasks/:taskId/move
- Cliente -> servidor:
workspace:join,task:moved,presence:cursor - Servidor -> clientes:
task:moved,presence:joined,presence:left,presence:cursor
Payloads compartidos en shared/realtime-events.ts para evitar drift entre cliente y servidor.
Se implementaron boundaries loading.tsx y error.tsx en rutas críticas del workspace:
/app/w/[workspaceId]/board/app/w/[workspaceId]/list/app/w/[workspaceId]/reports/app/w/[workspaceId]/activity/app/w/[workspaceId]/calendar/app/w/[workspaceId]/task/[taskId]
- Dependencia:
@tanstack/react-virtualenpackage.json. - Implementación activa en
components/board-view.tsxvíauseVirtualizer. - Objetivo: mantener DOM acotado y scroll fluido en columnas con 100+ tareas.
npm run lint
npm run build
npm run realtime:build
npm run test:e2etests/e2e/auth.spec.tstests/e2e/board-persistence.spec.tstests/e2e/realtime-sync.spec.ts
/.github/workflows/ci.yml bloquea merge si falla cualquier etapa.
Comando reproducible:
npm run lighthouse:prodArtefactos versionados:
artifacts/lighthouse/production-2026-03-14.report.htmlartifacts/lighthouse/production-2026-03-14.report.jsonartifacts/lighthouse/production-2026-03-14.report.summary.json
Scores reales (fetchTime: 2026-03-14T05:46:25Z, URL auditada https://pulseboard-kanban-linear.vercel.app/):
- Performance:
99 - Accessibility:
100 - Best Practices:
96 - SEO:
100
Cumplimiento de umbrales solicitados:
- Performance
>= 85: OK - Accessibility
>= 90: OK - Best Practices
>= 90: OK
- El script
scripts/run-lighthouse.mjsprioriza Lighthouse CLI y, por estabilidad en Windows, recupera el reporte generado aunque el proceso termine conEPERMal limpiar carpeta temporal de Chrome. - Si falla CLI sin reporte válido, hace fallback a PageSpeed Insights.