Saltar al contenido principal

🎯 Plan de Implementación Incremental - PuntoHack MVP

⚠️ Filosofía: Un Módulo a la Vez, 100% Completo

Regla de Oro: NO avanzar al siguiente módulo hasta que el actual esté:

  • ✅ Implementado completamente
  • ✅ Probado (tests >80% coverage)
  • ✅ Verificado funcionando
  • ✅ Documentado

Objetivo: Evitar el caos de múltiples módulos a medias. Cada módulo debe ser una base sólida para el siguiente.


📋 Orden de Implementación (Por Dependencias)

Core Layer

Users Module

Hackathons Module

Teams Module ──┐
↓ │
Submissions ────┤
↓ │
Evaluation ────┤
↓ │
Sponsors ───────┘

🏗️ MÓDULO 0: Core Layer (Base de Todo)

Objetivo: Infraestructura fundamental que todos los módulos usarán.

Checklist de Completitud

1. Configuración Inicial

  • Proyecto Next.js 16 creado con Turbopack
  • TypeScript configurado (strict mode)
  • Tailwind CSS 4 configurado
  • ESLint + Prettier configurados
  • Estructura de carpetas base creada

2. Database Setup

  • Proyecto Supabase creado
  • Connection string configurado en .env
  • Prisma inicializado
  • Schema básico (solo Profile model por ahora)
  • Migración ejecutada (pnpm prisma db push)
  • Prisma Studio funciona

3. Core Files (5 archivos)

src/core/db.ts

  • Prisma Client singleton implementado
  • Test de conexión funciona

src/core/auth.ts

  • Clerk configurado
  • getCurrentUser() implementado
  • Middleware de autenticación configurado
  • Test básico funciona

src/core/rbac.ts

  • hasRole() implementado
  • requireRole() implementado
  • Type User definido
  • Tests de RBAC pasan

src/core/errors.ts

  • captureError() implementado
  • Sentry configurado (o mock para dev)
  • Test básico funciona

src/core/validations.ts

  • validateHackathonDates() implementado
  • validateDateExtension() implementado
  • hackathonDatesSchema (Zod) creado
  • Tests de validaciones pasan

4. Testing Setup

  • Vitest configurado
  • tests/setup.ts creado
  • tests/test-utils.tsx creado
  • Tests de Core Layer pasan (>80% coverage)

5. UI Mínima

  • Landing page (/) básica
  • Páginas de auth (/sign-in, /sign-up) con Clerk
  • Layout principal con ClerkProvider

✅ Criterio de Completitud Módulo 0

DEBE funcionar:

  • getCurrentUser() retorna usuario autenticado
  • requireRole() bloquea acceso no autorizado
  • validateHackathonDates() valida orden de fechas
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript
  • ✅ Prisma se conecta a Supabase

NO avanzar hasta que TODO esto funcione.


👤 MÓDULO 1: Users Module

Dependencias: Core Layer ✅

Objetivo: Gestión completa de usuarios y perfiles.

Checklist de Completitud

1. Schema Prisma

  • Model Profile completo en schema
  • Enum Role definido
  • Relaciones básicas definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/users/queries.ts

  • getUserByClerkId(userId: string)
  • getProfileById(id: string)
  • listProfiles(filters?: { role?: Role; limit?: number })
  • Tests de queries pasan

src/modules/users/actions.ts

  • createProfile(formData: FormData) - Server Action
    • Valida RBAC (cualquiera puede crear su perfil)
    • Valida con Zod
    • Crea Profile en DB
    • Revalida cache
  • updateUserRole(profileId: string, newRole: Role) - Server Action
    • Valida RBAC (solo ADMIN/ORGANIZER)
    • Valida que ADMIN solo puede asignar ADMIN
    • Actualiza role
    • Revalida cache
  • Tests de actions pasan

src/modules/users/validations.ts

  • createProfileSchema (Zod)
  • updateUserRoleSchema (Zod)
  • Tests de validaciones pasan

src/modules/users/types.ts

  • Types TypeScript exportados
  • Types usados en queries/actions

3. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validations (100% coverage)
  • Tests de RBAC (solo ADMIN puede cambiar roles)
  • Coverage total >80%

4. UI Funcional

  • /onboarding - Formulario crear perfil
    • HTML nativo + Server Action
    • Validación solo servidor
    • Redirige a /dashboard después
  • /dashboard - Panel básico (redirección por rol)
  • /admin/users - Tabla de usuarios (solo ADMIN)
    • Lista usuarios
    • Dropdown cambiar rol (Client Component mínimo)
    • Server Action actualiza rol

✅ Criterio de Completitud Módulo 1

DEBE funcionar:

  • ✅ Usuario puede crear perfil en onboarding
  • ✅ Admin puede ver lista de usuarios
  • ✅ Admin puede cambiar roles
  • ✅ RBAC bloquea acciones no autorizadas
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


🎪 MÓDULO 2: Hackathons Module

Dependencias: Core Layer ✅, Users Module ✅

Objetivo: CRUD completo de hackathons con criterios y estados.

Checklist de Completitud

1. Schema Prisma

  • Model Hackathon completo
  • Model Criterion completo
  • Model HackathonParticipation completo
  • Enum HackathonStatus definido
  • Relaciones definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/hackathons/queries.ts

  • getHackathon(slug: string)
  • getHackathonById(id: string)
  • listHackathons(filters?: { status?: HackathonStatus[] })
  • getOrganizerHackathons(userId: string)
  • Tests de queries pasan

src/modules/hackathons/actions.ts

  • createHackathon(formData: FormData)
    • RBAC: solo ORGANIZER/ADMIN
    • Valida orden de fechas con validateHackathonDates()
    • Crea Hackathon + Criteria en transaction
    • Revalida cache
  • updateHackathon(id: string, formData: FormData)
    • RBAC: solo ORGANIZER/ADMIN (owner)
    • Valida fechas
    • Actualiza
  • deleteHackathon(id: string)
    • RBAC: solo ORGANIZER/ADMIN (owner)
    • Soft delete o hard delete
  • registerForHackathon(hackathonId: string)
    • RBAC: solo PARTICIPANT
    • Valida estado REGISTRATION
    • Valida fechas de registro
    • Crea HackathonParticipation
  • unregisterFromHackathon(hackathonId: string)
    • RBAC: solo PARTICIPANT
    • Elimina participation
  • addCriterion(hackathonId: string, data: CriterionInput)
  • updateCriterion(id: string, data: CriterionInput)
  • deleteCriterion(id: string)
  • Tests de actions pasan

src/modules/hackathons/validations.ts

  • createHackathonSchema (Zod)
  • criterionSchema (Zod)
  • Integración con validateHackathonDates()
  • Tests de validaciones pasan

src/modules/hackathons/types.ts

  • Types TypeScript exportados

3. Cron Job

  • src/app/api/cron/update-hackathon-states/route.ts implementado
  • vercel.json configurado
  • CRON_SECRET en variables de entorno
  • Test manual del cron funciona

4. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validaciones (100% coverage)
  • Tests de RBAC
  • Tests de validación de fechas
  • Coverage total >80%

5. UI Funcional

  • /hackathons - Lista pública
    • Filtro por status
    • Server Component
  • /hackathons/[slug] - Detalle público
    • Muestra info del hackathon
    • Botón "Registrarse" (si PARTICIPANT y REGISTRATION)
  • /admin/hackathons/create - Crear hackathon
    • Formulario HTML + Server Action
    • Campos: name, slug, description, fechas, criterios
    • Validación de fechas en servidor
  • /admin/hackathons/[slug] - Editar hackathon
    • Formulario pre-llenado
    • Server Action actualiza
  • /admin/hackathons/[slug]/dashboard - Panel organizador
    • Stats básicas (participantes, equipos, submissions)
    • Lista de participantes

✅ Criterio de Completitud Módulo 2

DEBE funcionar:

  • ✅ ORGANIZER puede crear hackathon completo
  • ✅ Participantes pueden registrarse
  • ✅ Cron job cambia estados automáticamente
  • ✅ Validación de fechas funciona
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


👥 MÓDULO 3: Teams Module

Dependencias: Core Layer ✅, Users Module ✅, Hackathons Module ✅

Objetivo: Sistema de equipos con códigos de invitación.

Checklist de Completitud

1. Schema Prisma

  • Model Team completo
  • Model TeamMember completo
  • Relaciones definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/teams/queries.ts

  • getTeamById(id: string)
  • getTeamByCode(code: string)
  • getUserTeam(hackathonId: string, userId: string)
  • listTeamsByHackathon(hackathonId: string)
  • Tests de queries pasan

src/modules/teams/actions.ts

  • createTeam(hackathonId: string, data: CreateTeamInput)
    • RBAC: solo PARTICIPANT
    • Valida que usuario está registrado en hackathon
    • Valida que no tiene otro equipo
    • Valida fechas (solo hasta submissionDeadline)
    • Genera código único
    • Crea Team + TeamMember
  • joinTeam(inviteCode: string)
    • RBAC: solo PARTICIPANT
    • Valida código existe
    • Valida cupo disponible
    • Valida fechas
    • Crea TeamMember
  • leaveTeam(teamId: string)
    • RBAC: solo PARTICIPANT (miembro del equipo)
    • Valida fechas
    • Si equipo queda vacío y sin submission → elimina Team
    • Si equipo tiene submission → no permite salir al último miembro
    • Elimina TeamMember
  • Tests de actions pasan

src/modules/teams/validations.ts

  • createTeamSchema (Zod)
  • joinTeamSchema (Zod)
  • Tests de validaciones pasan

src/modules/teams/types.ts

  • Types TypeScript exportados

3. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validaciones (100% coverage)
  • Tests de reglas de negocio (leave team, empty team)
  • Coverage total >80%

4. UI Funcional

  • /hackathons/[slug]/teams - Gestión de equipos
    • Tab "Crear equipo" (formulario)
    • Tab "Unirse a equipo" (input código)
    • Muestra código de invitación
  • /hackathons/[slug]/my-team - Mi equipo
    • Lista miembros
    • Botón "Salir del equipo" (hasta deadline)

✅ Criterio de Completitud Módulo 3

DEBE funcionar:

  • ✅ Participantes pueden crear equipos
  • ✅ Participantes pueden unirse con código
  • ✅ Participantes pueden salir (con reglas de negocio)
  • ✅ Códigos de invitación únicos
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


📝 MÓDULO 4: Submissions Module

Dependencias: Core Layer ✅, Users Module ✅, Hackathons Module ✅, Teams Module ✅

Objetivo: Sistema de envío y edición de proyectos.

Checklist de Completitud

1. Schema Prisma

  • Model Submission completo
  • Relación con Challenge (opcional)
  • Relaciones definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/submissions/queries.ts

  • getSubmissionById(id: string)
  • getSubmissionByTeam(teamId: string)
  • listSubmissionsByHackathon(hackathonId: string)
  • Tests de queries pasan

src/modules/submissions/actions.ts

  • createSubmission(hackathonId: string, data: CreateSubmissionInput)
    • RBAC: solo PARTICIPANT (miembro del equipo)
    • Valida estado RUNNING
    • Valida now < submissionDeadline
    • Valida tamaño equipo >= minTeamSize
    • Valida equipo no tiene submission previa
    • Crea Submission
  • updateSubmission(id: string, data: UpdateSubmissionInput)
    • RBAC: solo PARTICIPANT (miembro del equipo)
    • Valida now < submissionDeadline
    • Valida estado != JUDGING/FINISHED
    • Actualiza Submission
  • Tests de actions pasan

src/modules/submissions/validations.ts

  • createSubmissionSchema (Zod)
  • updateSubmissionSchema (Zod)
  • Tests de validaciones pasan

src/modules/submissions/types.ts

  • Types TypeScript exportados

3. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validaciones (100% coverage)
  • Tests de bloqueo después de deadline
  • Coverage total >80%

4. UI Funcional

  • /hackathons/[slug]/submit - Enviar submission
    • Formulario HTML + Server Action
    • Campos: title, description, repoUrl, demoUrl, challengeId (opcional)
    • Countdown a deadline
    • Botón "Editar" desaparece después de deadline
  • /hackathons/[slug]/submission - Ver/editar submission
    • Vista de solo lectura después de deadline

✅ Criterio de Completitud Módulo 4

DEBE funcionar:

  • ✅ Equipos pueden enviar proyectos
  • ✅ Equipos pueden editar hasta deadline
  • ✅ Bloqueo después de deadline funciona
  • ✅ Una submission por equipo (constraint DB)
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


⚖️ MÓDULO 5: Evaluation Module

Dependencias: Core Layer ✅, Users Module ✅, Hackathons Module ✅, Teams Module ✅, Submissions Module ✅

Objetivo: Sistema de evaluación con scoring ponderado y leaderboard.

Checklist de Completitud

1. Schema Prisma

  • Model HackathonJudge completo
  • Model Score completo
  • Relaciones definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/evaluation/queries.ts

  • getHackathonSubmissionsForJudge(hackathonId: string, judgeId: string)
  • getScoresBySubmission(submissionId: string)
  • getScoresByJudge(judgeId: string, submissionId: string)
  • calculateLeaderboard(hackathonId: string) - Cálculo ponderado
  • Tests de queries pasan

src/modules/evaluation/actions.ts

  • assignJudge(hackathonId: string, judgeId: string)
    • RBAC: solo ORGANIZER/ADMIN
    • Valida que judge no es participante del hackathon
    • Crea HackathonJudge
  • submitScore(submissionId: string, criterionId: string, value: number, comment?: string)
    • RBAC: solo JUDGE
    • Valida asignación existe
    • Valida hackathon en estado JUDGING
    • Valida value entre 0 y maxScore
    • UPSERT Score (unique constraint)
  • Tests de actions pasan

src/modules/evaluation/validations.ts

  • submitScoreSchema (Zod)
  • Tests de validaciones pasan

src/modules/evaluation/types.ts

  • Types TypeScript exportados
  • Type LeaderboardEntry

3. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validaciones (100% coverage)
  • Tests de cálculo de leaderboard (ponderado)
  • Tests de aislamiento de scores (juez no ve otros)
  • Coverage total >80%

4. UI Funcional

  • /admin/hackathons/[slug]/judges - Asignar jueces
    • Lista de profiles con role JUDGE
    • Checkbox seleccionar jueces
    • Server Action asigna
  • /judge/hackathons/[slug] - Panel de juez
    • Lista submissions del hackathon asignado
    • Solo visible cuando estado JUDGING
  • /judge/hackathons/[slug]/evaluate/[submissionId] - Evaluar
    • Formulario por criterio
    • Input numérico (0-maxScore)
    • Textarea comentario opcional
    • Server Action guarda scores
  • /hackathons/[slug]/leaderboard - Leaderboard público
    • Solo visible cuando estado FINISHED
    • Muestra ranking con puntaje ponderado

✅ Criterio de Completitud Módulo 5

DEBE funcionar:

  • ✅ ORGANIZER puede asignar jueces
  • ✅ Jueces pueden evaluar submissions
  • ✅ Leaderboard calcula correctamente (ponderado)
  • ✅ Juez no ve scores ajenos durante JUDGING
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


🏆 MÓDULO 6: Sponsors Module

Dependencias: Core Layer ✅, Users Module ✅, Hackathons Module ✅, Teams Module ✅, Submissions Module ✅

Objetivo: Sistema de sponsors, challenges y shortlist.

Checklist de Completitud

1. Schema Prisma

  • Model Organization completo
  • Model OrganizationMember completo
  • Model Sponsorship completo
  • Model Challenge completo
  • Model ShortlistItem completo
  • Enums definidos
  • Relaciones definidas
  • Migración ejecutada

2. Module Files (4 archivos)

src/modules/sponsors/queries.ts

  • getOrganizationById(id: string)
  • getSponsorshipsByHackathon(hackathonId: string)
  • getChallengesBySponsorship(sponsorshipId: string)
  • getSubmissionsByChallenge(challengeId: string)
  • getShortlistByOrganization(organizationId: string)
  • Tests de queries pasan

src/modules/sponsors/actions.ts

  • createOrganization(data: CreateOrgInput)
    • RBAC: solo SPONSOR/ADMIN
    • Crea Organization + OrganizationMember (owner)
  • createSponsorship(hackathonId: string, data: CreateSponsorshipInput)
    • RBAC: solo SPONSOR (miembro de org)
    • Crea Sponsorship
  • createChallenge(sponsorshipId: string, data: CreateChallengeInput)
    • RBAC: solo SPONSOR (miembro de org)
    • Crea Challenge
  • shortlistSubmission(submissionId: string, organizationId: string, challengeId: string, notes?: string)
    • RBAC: solo SPONSOR (miembro de org)
    • Valida submission eligió su challenge
    • Crea ShortlistItem (unique constraint)
  • Tests de actions pasan

src/modules/sponsors/validations.ts

  • createOrganizationSchema (Zod)
  • createSponsorshipSchema (Zod)
  • createChallengeSchema (Zod)
  • Tests de validaciones pasan

src/modules/sponsors/types.ts

  • Types TypeScript exportados

3. Testing

  • Tests de queries (100% coverage)
  • Tests de actions (100% coverage)
  • Tests de validaciones (100% coverage)
  • Tests de RBAC
  • Coverage total >80%

4. UI Funcional

  • /sponsor/organizations/create - Crear organización
  • /sponsor/sponsorships/create - Crear sponsorship
  • /sponsor/challenges/create - Crear challenge
  • /sponsor/challenges/[id]/submissions - Ver submissions del challenge
  • /sponsor/shortlist - Ver shortlist
    • Botón "Contactar equipo" (email vía Clerk)

✅ Criterio de Completitud Módulo 6

DEBE funcionar:

  • ✅ Sponsors pueden crear organizaciones
  • ✅ Sponsors pueden crear sponsorships y challenges
  • ✅ Sponsors pueden shortlist proyectos
  • ✅ Sponsors pueden contactar equipos
  • ✅ Tests pasan con >80% coverage
  • ✅ No hay errores de TypeScript

NO avanzar hasta que TODO esto funcione.


📊 Proceso de Verificación Después de Cada Módulo

Checklist de Verificación

Antes de marcar un módulo como "completo", verificar:

  1. Código:

    • Todos los archivos del módulo implementados
    • No hay errores de TypeScript
    • No hay errores de ESLint
    • Código sigue convenciones del proyecto
  2. Tests:

    • Tests pasan (pnpm test)
    • Coverage >80% (pnpm test:coverage)
    • Tests de RBAC incluidos
    • Tests de validaciones incluidos
  3. Funcionalidad:

    • UI funciona (probar manualmente)
    • Server Actions funcionan
    • RBAC bloquea acciones no autorizadas
    • Validaciones funcionan
  4. Base de Datos:

    • Schema actualizado
    • Migración ejecutada
    • No hay errores de Prisma
  5. Documentación:

    • Código comentado donde es necesario
    • Funciones complejas documentadas

Comando de Verificación Rápida

# Ejecutar después de cada módulo
pnpm type-check # Verificar TypeScript
pnpm lint # Verificar ESLint
pnpm test # Ejecutar tests
pnpm test:coverage # Verificar coverage
pnpm build # Verificar que compila

🚨 Reglas Estrictas

❌ NO Hacer

  1. NO empezar un módulo nuevo si el anterior no está 100% completo
  2. NO implementar features de múltiples módulos a la vez
  3. NO saltar tests "por ahora"
  4. NO avanzar con errores de TypeScript
  5. NO implementar features no documentadas

✅ SÍ Hacer

  1. completar un módulo antes de pasar al siguiente
  2. escribir tests desde el inicio
  3. verificar que todo funciona antes de avanzar
  4. seguir el orden de dependencias
  5. pedir ayuda si hay dudas

📝 Notas de Implementación

Orden de Archivos Dentro de Cada Módulo

  1. Schema Prisma (si aplica)
  2. Types (types.ts)
  3. Validations (validations.ts)
  4. Queries (queries.ts)
  5. Actions (actions.ts)
  6. Tests (paralelo con implementación)
  7. UI (al final, cuando todo funciona)

Patrón de Server Action

Siempre seguir este patrón:

'use server';

export async function myAction(formData: FormData) {
try {
// 1. Auth
const user = await getCurrentUser();
if (!user) throw new Error('Unauthorized');

// 2. RBAC
requireRole(user, ['ORGANIZER']);

// 3. Validate
const validated = schema.parse(data);

// 4. Business Logic
const result = await db.model.create({ data: validated });

// 5. Revalidate
revalidatePath('/path');

return { success: true, data: result };
} catch (error) {
captureError(error, { context: 'myAction' });
return { success: false, error: error.message };
}
}

🎯 Resumen del Plan

Módulo 0: Core Layer          → Base de todo
Módulo 1: Users → Depende de Core
Módulo 2: Hackathons → Depende de Core + Users
Módulo 3: Teams → Depende de Core + Users + Hackathons
Módulo 4: Submissions → Depende de Core + Users + Hackathons + Teams
Módulo 5: Evaluation → Depende de todos los anteriores
Módulo 6: Sponsors → Depende de Core + Users + Hackathons + Teams + Submissions

Total estimado: 4-5 semanas (siguiendo este orden estricto)


Última Actualización: 30 de diciembre, 2025
Versión: 1.0 - Plan de Implementación Incremental
Filosofía: Un módulo a la vez, 100% completo antes de avanzar