📋 MVP Estricto - Alcance y Límites
⚠️ IMPORTANTE: Leer Antes de Codear
Este documento define EXACTAMENTE qué implementar y qué NO implementar.
🎯 Filosofía del MVP Estricto
Regla de Oro: Si no está en la documentación, NO se implementa.
Problema del pasado: El proyecto falló porque se agregaron "mejoras" no solicitadas:
- ❌ Cache innecesario
- ❌ Optimizaciones prematuras
- ❌ Features "porque suenan bien"
- ❌ Complejidad no requerida
Resultado: Proyecto enorme, difícil de mantener, IA no podía continuar.
Solución: MVP ESTRICTO que se apega al 100% a lo documentado.
✅ Qué SÍ Implementar
Funcionalidades Core (documentadas)
Fase 0: Infraestructura
- ✅ Configuración de Next.js 16 con Turbopack (estructura estándar)
- ✅ Clerk Authentication (configuración básica)
- ✅ Prisma + Supabase (PostgreSQL con Realtime futuro)
- ✅ Core Layer (rbac.ts, errors.ts, db.ts, auth.ts, validations.ts)
- ✅ Helper de validación de fechas (validateHackathonDates, validateDateExtension)
- ✅ Cron job para cambios de estado automáticos
- ✅ Users Module (queries, actions, validations, types)
- ✅ Configuración de testing (Vitest)
- ✅ Sentry (monitoreo de errores básico)
Fase 1: Hackathons
- ✅ CRUD completo de hackathons
- ✅ Sistema de criterios de evaluación
- ✅ Registro de participantes (HackathonParticipation)
- ✅ Estados del ciclo de vida (DRAFT → FINISHED)
- ✅ Panel de organizador (stats básicas)
Fase 2: Equipos y Evaluación
- ✅ Sistema de equipos con códigos de invitación
- ✅ Submissions de proyectos
- ✅ Asignación de jueces (manual + automática)
- ✅ Sistema de scoring por criterio
- ✅ Leaderboard con puntaje ponderado
Fase 3: Sponsors
- ✅ Gestión de organizaciones
- ✅ Sistema de sponsorships (con tiers)
- ✅ Challenges de sponsors
- ✅ Shortlist de proyectos
Features Técnicas Requeridas
RBAC:
- ✅ hasRole(), requireRole() en core/rbac.ts
- ✅ Verificación en CADA Server Action
- ✅ 5 roles: PARTICIPANT, JUDGE, ORGANIZER, ADMIN, SPONSOR
Validaciones:
- ✅ Zod schemas para TODOS los inputs
- ✅ Validación en servidor (Server Actions)
- ❌ NO validación duplicada en cliente
Testing:
- ✅ Tests de validations (Zod schemas)
- ✅ Tests de queries (DB operations)
- ✅ Tests de actions (Server Actions)
- ✅ Objetivo: 80% coverage mínimo
Error Handling:
- ✅ captureError() función en core/errors.ts
- ✅ Envío a Sentry
- ✅ Try-catch en todas las Server Actions
Notificaciones:
- ✅ Email notifications (solo Clerk)
- ❌ NO notificaciones in-app (para MVP)
Funcionalidades Específicas:
- ✅ Participants pueden editar submission hasta
submissionDeadline - ✅ ORGANIZER puede alargar fechas de fase SIGUIENTE (+7 días máx, solo extender) usando
validateDateExtension() - ✅ Validación de orden de fechas en creación/edición usando
validateHackathonDates() - ✅ SPONSOR ve leaderboard final y perfiles de shortlist
- ✅ Cambios de estado automáticos por cron job (solo hackathons publicados)
- ✅ Publicar hackathon es manual y solo si
now >= registrationOpensAt(cron no publica DRAFTs) - ✅ Juez no ve scores ajenos durante JUDGING; puede verlos en FINISHED
- ✅ Bloquear asignar JUDGE si el usuario ya participa en ese hackathon
- ✅ Equipos: create/join/leave solo hasta
submissionDeadline; si equipo no tiene submission y queda vacío se elimina inmediato; si tiene submission, el último miembro no puede salir - ✅ Contacto con equipos vía botón (email Clerk) sin exponer correos a sponsors
❌ Qué NO Implementar
Features NO Documentadas
NO agregar estas "mejoras":
- ❌ Sistema de notificaciones in-app (solo email para MVP)
- ❌ Sistema de comentarios públicos en submissions
- ❌ Chat entre participantes
- ❌ Sistema de badges/achievements
- ❌ Analytics avanzados/dashboards complejos
- ❌ Export de datos (PDF, CSV) - Futuro
- ❌ Webhooks o API REST pública
- ❌ Integración con GitHub API (para repos)
- ❌ Sistema de "likes" o reacciones
- ❌ Judge puede rechazar evaluar proyecto (pendiente diseño)
Optimizaciones NO Requeridas
NO agregar estas optimizaciones prematuras:
- ❌ React Query / TanStack Query
- ❌ Cache de Redis
- ❌ Optimistic UI updates
- ❌ Infinite scroll / Paginación compleja
- ❌ Virtualización de listas
- ❌ Image optimization avanzada
- ❌ CDN para assets
- ❌ Service Workers / PWA
- ❌ Web Workers
- ❌ Memoization excesiva
Features Frontend NO Necesarias
NO implementar:
- ❌ Dark mode / Light mode
- ❌ Tema customizable
- ❌ Animaciones complejas
- ❌ Skeleton loaders elaborados
- ❌ Toast notifications fancy
- ❌ Modals con animaciones
- ❌ Drag & drop
- ❌ Rich text editor
- ❌ File upload con preview
- ❌ Autocomplete avanzado
Librerías NO Instalar
# ❌ NO instalar ninguna de estas
pnpm add react-query
pnpm add @tanstack/react-query
pnpm add redis
pnpm add ioredis
pnpm add framer-motion
pnpm add react-hot-toast
pnpm add sonner
pnpm add @dnd-kit/core
pnpm add react-dropzone
pnpm add tiptap
pnpm add slate
pnpm add recharts
pnpm add @tremor/react
📏 Límites Técnicos Estrictos
Caching
Solo usar el cache nativo de Next.js 16:
// ✅ PERMITIDO: Cache automático de Next.js
export async function getHackathons() {
// Next.js cachea automáticamente
return await db.hackathon.findMany();
}
// ✅ PERMITIDO: revalidatePath cuando hay cambios
export async function createHackathon() {
// ...
revalidatePath('/hackathons');
}
// ❌ NO HACER: Cache personalizado
// NO instalar Redis, NO usar React Query
Regla: Si Next.js no lo cachea por defecto, NO necesitamos cache extra.
Consultas a la Base de Datos
Queries simples y directas:
// ✅ CORRECTO: Query directa
export async function getHackathon(slug: string) {
return await db.hackathon.findUnique({
where: { slug },
include: {
criteria: true,
participations: {
include: { profile: true }
}
}
});
}
// ❌ INCORRECTO: Optimizaciones prematuras
// NO hacer batching manual, NO usar DataLoader
// NO hacer query optimization prematura
Regla: Query directo con Prisma. Si es lento, ya optimizaremos (pero probablemente no será necesario).
Server Actions
Patrón estándar, sin extras:
// ✅ CORRECTO: Server Action estándar
'use server';
export async function createHackathon(formData: FormData) {
try {
// 1. Auth
const user = await getCurrentUser();
requireRole(user, ['ORGANIZER']);
// 2. Validate
const validated = createHackathonSchema.parse({
name: formData.get('name'),
slug: formData.get('slug'),
// ...
});
// 3. Create
await db.hackathon.create({ data: validated });
// 4. Revalidate
revalidatePath('/hackathons');
return { success: true };
} catch (error) {
captureError(error);
return { success: false, error: error.message };
}
}
// ❌ NO agregar: rate limiting, queue systems, retry logic, etc.
Testing
Solo lo necesario para 80% coverage:
// ✅ CORRECTO: Tests básicos pero completos
describe('createHackathon', () => {
it('should create hackathon with valid data');
it('should reject if not ORGANIZER');
it('should validate required fields');
});
// ❌ NO HACER: Tests excesivos
// NO hacer snapshot testing
// NO hacer visual regression testing
// NO hacer performance testing
🎯 Checklist por Feature
Antes de implementar CUALQUIER feature, preguntar:
¿Está en la Documentación?
- ¿Está explícitamente mencionada en ARCHITECTURE.md?
- ¿Está en el ROADMAP.md?
- ¿Está en el modelo de datos (Prisma schema)?
Si NO a alguna: ❌ NO implementar
¿Es Necesaria para el MVP?
- ¿Sin esto el core NO funciona?
- ¿Es un feature crítico del negocio?
- ¿Está en las 4 fases definidas?
Si NO a alguna: ❌ NO implementar
¿Es una "Mejora"?
- ¿Estoy agregando cache porque "es mejor"?
- ¿Estoy agregando optimización porque "debería"?
- ¿Estoy agregando feature porque "sería útil"?
Si SÍ a alguna: ❌ STOP - NO implementar
📊 Alcance por Fase
Fase 0 - Alcance Estricto
Queries (users module):
// ✅ Implementar SOLO estas
getUserByClerkId(userId: string)
getProfileById(id: string)
listProfiles(filters?: { role?: Role; limit?: number })
Actions (users module):
// ✅ Implementar SOLO estas
createProfile(formData: FormData)
updateUserRole(profileId: string, newRole: Role)
NO agregar:
- ❌ updateProfile (no está en Fase 0)
- ❌ deleteProfile (no necesario)
- ❌ searchUsers (no necesario)
- ❌ getUserStats (no necesario)
Fase 1 - Alcance Estricto
Hackathons - Lo Mínimo Necesario:
// ✅ Queries
getHackathon(slug: string)
getHackathonById(id: string)
listHackathons(filters?: { status?: HackathonStatus[] })
getOrganizerHackathons(userId: string)
// ✅ Actions
createHackathon(formData: FormData)
updateHackathon(id: string, formData: FormData)
deleteHackathon(id: string)
registerForHackathon(hackathonId: string)
unregisterFromHackathon(hackathonId: string)
// ✅ Criteria
addCriterion(hackathonId: string, data: CriterionInput)
updateCriterion(id: string, data: CriterionInput)
deleteCriterion(id: string)
NO agregar:
- ❌ Duplicate hackathon
- ❌ Archive hackathon
- ❌ Clone hackathon
- ❌ Bulk operations
- ❌ Import/export
Fase 2 - Alcance Estricto
Teams - Lo Esencial:
// ✅ Actions
createTeam(hackathonId: string, data: CreateTeamInput)
joinTeam(inviteCode: string)
leaveTeam(teamId: string)
NO agregar:
- ❌ Kick member
- ❌ Transfer ownership
- ❌ Team chat
- ❌ Team settings
Evaluation - Lo Documentado:
// ✅ Actions
assignJudge(hackathonId: string, judgeId: string)
submitScore(submissionId: string, criterionId: string, value: number, comment?: string)
NO agregar:
- ❌ Score history
- ❌ Score comparison
- ❌ Judge analytics
- ❌ Consensus scoring
Fase 3 - Alcance Estricto
Sponsors - Lo Básico:
// ✅ Actions
createOrganization(data: CreateOrgInput)
createChallenge(sponsorshipId: string, data: ChallengeInput)
shortlistSubmission(submissionId: string, notes?: string)
NO agregar:
- ❌ Organization settings
- ❌ Member invitations
- ❌ Challenge analytics
- ❌ Custom benefits builder
🚨 Señales de Alerta
Estás Saliéndote del MVP Si...
- 🚨 Estás instalando una librería que no está en el ROADMAP
- 🚨 Estás creando un archivo que no está documentado
- 🚨 Estás agregando una tabla a Prisma que no está en el schema
- 🚨 Estás pensando "esto haría mejor la app"
- 🚨 Estás diciendo "ya que estamos, agreguemos..."
- 🚨 Estás optimizando algo que ni siquiera está lento
- 🚨 El código tiene más de 200 líneas y hace más de una cosa
Preguntas para Auto-Revisar
- ¿Esto está documentado? Si no → STOP
- ¿Esto es necesario ahora? Si no → STOP
- ¿Esto está en la fase actual? Si no → STOP
- ¿Esto es core o "mejora"? Si mejora → STOP
- ¿Puedo explicar por qué es necesario? Si no → STOP
✅ Criterios de Éxito
Un Feature Está Completo Cuando:
- ✅ Hace lo que dice la documentación
- ✅ Tiene tests (80% coverage)
- ✅ Tiene RBAC checks (si aplica)
- ✅ Tiene validaciones Zod
- ✅ Tiene error handling
- ✅ Funciona en la UI (formulario simple)
- ✅ NO tiene extras no documentados
Una Fase Está Completa Cuando:
- ✅ Todos los features documentados funcionan
- ✅ Tests pasan (>80% coverage)
- ✅ No hay errores en Sentry inesperados
- ✅ Checklist del ROADMAP está 100% ✓
- ✅ NO se agregaron features extra
📝 Proceso de Implementación
Antes de Codear
- Leer la documentación del feature
- Identificar EXACTAMENTE qué se necesita
- NO agregar "por si acaso"
- Preguntar si hay duda: ¿Está documentado?
Durante el Desarrollo
- Implementar SOLO lo documentado
- Usar patrones establecidos (Server Actions, etc.)
- Tests desde el inicio
- NO optimizar prematuramente
Después de Implementar
- Verificar checklist del ROADMAP
- Correr tests (deben pasar)
- Probar en UI (debe funcionar)
- Si funciona → STOP, pasar al siguiente
🎯 Mantra del MVP Estricto
"Si no está documentado, no se implementa"
"Funcional y simple > Perfecto y complejo"
"Terminar el MVP > Hacer el MVP perfecto"
"80% coverage > 100% coverage con features a medias"
📋 Documento de Referencia Rápida
¿Puedo Agregar Cache?
❌ NO, a menos que esté documentado
¿Puedo Instalar Esta Librería?
❌ NO, a menos que esté en ROADMAP.md
¿Puedo "Mejorar" Esto?
❌ NO, si funciona, déjalo
¿Puedo Optimizar Esto?
❌ NO, a menos que esté documentado o sea lento (>3s)
¿Está Documentado Este Feature?
✅ Buscar en: ARCHITECTURE.md, ROADMAP.md, Prisma schema ❌ Si no está → NO implementar
¿Es Necesario para el Core?
✅ Si sin esto no funciona → implementar ❌ Si es "nice to have" → NO implementar
Última Actualización: 30 de diciembre, 2025
Versión: 1.0 - MVP Estricto
Regla de Oro: Documentación = Verdad absoluta