📋 Plan de Ejecución - Módulo 2: Hackathons Module
Fecha de Creación: 2025-01-XX
Estado: 📝 Planificado
Dependencias: ✅ Core Layer, ✅ Users Module
🎯 Objetivo del Módulo
Implementar el CRUD completo de hackathons con:
- Gestión de estados automáticos (cron job)
- Validación de fechas estricta
- Sistema de criterios de evaluación
- Registro de participantes
- Panel de organizador
📊 Análisis de Requerimientos
1. Schema Prisma (3 modelos + 1 enum)
Model Hackathon
model Hackathon {
id String @id @default(cuid())
name String
slug String @unique
description String @db.Text
status HackathonStatus @default(DRAFT)
// Fechas (orden estricto requerido)
registrationOpensAt DateTime
registrationClosesAt DateTime
startsAt DateTime
endsAt DateTime
submissionDeadline DateTime
judgingStartsAt DateTime
judgingEndsAt DateTime
// Configuración
maxTeamSize Int @default(5)
minTeamSize Int @default(1)
// Relaciones
participations HackathonParticipation[]
criteria Criterion[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([slug])
@@index([status])
}
Enum HackathonStatus
enum HackathonStatus {
DRAFT // Borrador, no visible
REGISTRATION // Abierto a registro
RUNNING // En curso
JUDGING // En evaluación
FINISHED // Finalizado
}
Model Criterion
model Criterion {
id String @id @default(cuid())
hackathonId String
name String
description String? @db.Text
weight Int @default(1) // 1-10
maxScore Int @default(10)
hackathon Hackathon @relation(fields: [hackathonId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([hackathonId])
}
Model HackathonParticipation
model HackathonParticipation {
id String @id @default(cuid())
hackathonId String
profileId String
hackathon Hackathon @relation(fields: [hackathonId], references: [id], onDelete: Cascade)
profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
@@unique([hackathonId, profileId])
@@index([hackathonId])
@@index([profileId])
}
2. Funcionalidades Core Requeridas
Queries (4 funciones)
getHackathon(slug: string)- Obtener por slug (público)getHackathonById(id: string)- Obtener por IDlistHackathons(filters?: { status?: HackathonStatus[] })- Listar con filtrosgetOrganizerHackathons(userId: string)- Hackathons de un organizador
Actions (8 Server Actions)
-
createHackathon(data: CreateHackathonInput)- RBAC: ORGANIZER/ADMIN
- Validar fechas con
validateHackathonDates() - Crear Hackathon + Criterios en transaction
- Estado inicial: DRAFT
-
updateHackathon(id: string, data: UpdateHackathonInput)- RBAC: ORGANIZER/ADMIN (owner)
- Validar fechas
- Si está en curso, usar
validateDateExtension()para extensiones
-
deleteHackathon(id: string)- RBAC: ORGANIZER/ADMIN (owner)
- Hard delete (cascade en relaciones)
-
publishHackathon(id: string)- RBAC: ORGANIZER/ADMIN (owner)
- Validar: tiene criterios, tiene jueces,
now >= registrationOpensAt - Cambiar estado: DRAFT → REGISTRATION
-
registerForHackathon(hackathonId: string)- RBAC: PARTICIPANT
- Validar: estado REGISTRATION, fechas válidas, no duplicado
- Crear HackathonParticipation
-
unregisterFromHackathon(hackathonId: string)- RBAC: PARTICIPANT
- Eliminar HackathonParticipation
-
addCriterion(hackathonId: string, data: CriterionInput)- RBAC: ORGANIZER/ADMIN (owner)
- Crear Criterion
-
updateCriterion(id: string, data: CriterionInput)- RBAC: ORGANIZER/ADMIN (owner del hackathon)
- Actualizar Criterion
-
deleteCriterion(id: string)- RBAC: ORGANIZER/ADMIN (owner del hackathon)
- Eliminar Criterion
Validations (Zod Schemas)
createHackathonSchema- Validar creaciónupdateHackathonSchema- Validar actualizacióncriterionSchema- Validar criterio- Integración con
validateHackathonDates()yvalidateDateExtension()
Cron Job
src/app/api/cron/update-hackathon-states/route.ts- Cambiar estados automáticamente cada minuto
- Solo hackathons publicados (no DRAFT)
3. UI Funcional (5 páginas)
-
/hackathons- Lista pública- Server Component
- Filtro por status
- Mostrar hackathons publicados
-
/hackathons/[slug]- Detalle público- Server Component
- Información completa 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 en servidor
-
/admin/hackathons/[slug]- Editar hackathon- Formulario pre-llenado
- Server Action actualiza
- Soporte para extensiones de fechas
-
/admin/hackathons/[slug]/dashboard- Panel organizador- Stats: participantes, equipos, submissions
- Lista de participantes
🗂️ Plan de Ejecución por Fases
FASE 1: Schema y Migración (Prioridad: CRÍTICA)
Objetivo: Definir y migrar el schema de base de datos
Tareas:
-
✅ Actualizar
prisma/schema.prisma- Agregar enum
HackathonStatus - Agregar model
Hackathoncon todos los campos - Agregar model
Criterion - Agregar model
HackathonParticipation - Definir relaciones y índices
- Agregar
onDelete: Cascadedonde corresponda
- Agregar enum
-
✅ Ejecutar migración
pnpm prisma migrate dev --name add_hackathons_module -
✅ Verificar schema en Prisma Studio
pnpm prisma studio
Criterio de Completitud:
- Schema completo y sin errores
- Migración ejecutada exitosamente
- Relaciones funcionando correctamente
Tiempo Estimado: 30-45 minutos
FASE 2: Module Files - Core (Prioridad: CRÍTICA)
Objetivo: Implementar la lógica core del módulo (queries, validations, types)
2.1 Types (src/modules/hackathons/types.ts)
Tareas:
- Definir tipos TypeScript
HackathonWithRelations(con criterios, participaciones)CreateHackathonInputUpdateHackathonInputCriterionInputHackathonFilters
Criterio de Completitud:
- Todos los tipos exportados
- Tipos usados en queries/actions
Tiempo Estimado: 15 minutos
2.2 Validations (src/modules/hackathons/validations.ts)
Tareas:
-
Crear
createHackathonSchema(Zod)- name, slug, description
- Fechas (usar
hackathonDatesSchemadecore/validations.ts) - maxTeamSize, minTeamSize
- Criterios (array opcional)
-
Crear
updateHackathonSchema(Zod)- Campos opcionales
- Validación de fechas
-
Crear
criterionSchema(Zod)- name, description, weight (1-10), maxScore
-
Crear
publishHackathonSchema(Zod)- Validar que tiene criterios y jueces
Criterio de Completitud:
- Todos los schemas creados
- Integración con
validateHackathonDates()funcionando - Tests de validaciones pasando
Tiempo Estimado: 45 minutos
2.3 Queries (src/modules/hackathons/queries.ts)
Tareas:
-
Implementar
getHackathon(slug: string)- Incluir criterios y participaciones
- Retornar null si no existe
-
Implementar
getHackathonById(id: string)- Similar a getHackathon pero por ID
-
Implementar
listHackathons(filters?: { status?: HackathonStatus[] })- Filtro por status
- Ordenar por createdAt desc
- Incluir criterios count
-
Implementar
getOrganizerHackathons(userId: string)- Obtener hackathons donde el usuario es organizador
- Incluir stats básicas
Criterio de Completitud:
- Todas las queries implementadas
- Tests de queries pasando (100% coverage)
Tiempo Estimado: 1 hora
FASE 3: Actions - CRUD Básico (Prioridad: ALTA)
Objetivo: Implementar acciones básicas de CRUD
3.1 createHackathon
Tareas:
- Validar RBAC (ORGANIZER/ADMIN)
- Validar datos con Zod
- Validar fechas con
validateHackathonDates() - Crear Hackathon + Criterios en transaction
- Revalidar cache
- Retornar hackathon creado
Criterio de Completitud:
- RBAC funcionando
- Validación de fechas funcionando
- Transaction funcionando
- Test pasando
Tiempo Estimado: 1 hora
3.2 updateHackathon
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner)
- Validar datos con Zod
- Si está en curso, usar
validateDateExtension() - Si no está en curso, usar
validateHackathonDates() - Actualizar hackathon
- Revalidar cache
Criterio de Completitud:
- RBAC funcionando
- Validación de extensiones funcionando
- Test pasando
Tiempo Estimado: 1 hora
3.3 deleteHackathon
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner)
- Verificar que no tiene participaciones activas (opcional, o permitir cascade)
- Eliminar hackathon (cascade elimina criterios y participaciones)
- Revalidar cache
Criterio de Completitud:
- RBAC funcionando
- Cascade funcionando
- Test pasando
Tiempo Estimado: 30 minutos
FASE 4: Actions - Criterios (Prioridad: ALTA)
Objetivo: Implementar gestión de criterios
4.1 addCriterion
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner)
- Validar datos con Zod
- Verificar que hackathon existe
- Crear criterio
- Revalidar cache
Tiempo Estimado: 30 minutos
4.2 updateCriterion
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner del hackathon)
- Validar datos con Zod
- Actualizar criterio
- Revalidar cache
Tiempo Estimado: 30 minutos
4.3 deleteCriterion
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner del hackathon)
- Eliminar criterio
- Revalidar cache
Tiempo Estimado: 20 minutos
Criterio de Completitud Fase 4:
- Todas las acciones de criterios funcionando
- Tests pasando
FASE 5: Actions - Participaciones (Prioridad: ALTA)
Objetivo: Implementar registro/desregistro de participantes
5.1 registerForHackathon
Tareas:
- Validar RBAC (PARTICIPANT)
- Verificar estado: REGISTRATION
- Verificar fechas:
now >= registrationOpensAt && now <= registrationClosesAt - Verificar que no está registrado
- Crear HackathonParticipation
- Revalidar cache
Tiempo Estimado: 45 minutos
5.2 unregisterFromHackathon
Tareas:
- Validar RBAC (PARTICIPANT)
- Verificar que está registrado
- Eliminar HackathonParticipation
- Revalidar cache
Tiempo Estimado: 30 minutos
Criterio de Completitud Fase 5:
- Registro funcionando
- Desregistro funcionando
- Validaciones funcionando
- Tests pasando
FASE 6: Action - Publicar Hackathon (Prioridad: ALTA)
Objetivo: Implementar publicación manual de hackathons
6.1 publishHackathon
Tareas:
- Validar RBAC (ORGANIZER/ADMIN owner)
- Verificar que tiene al menos 1 criterio
- Verificar que tiene al menos 1 juez (HackathonJudge - se implementará en módulo futuro, por ahora solo validar criterios)
- Verificar que
now >= registrationOpensAt - Cambiar estado: DRAFT → REGISTRATION
- Revalidar cache
Nota: La validación de jueces se puede hacer más adelante cuando se implemente el módulo de jueces. Por ahora, solo validar criterios.
Tiempo Estimado: 30 minutos
Criterio de Completitud:
- Publicación funcionando
- Validaciones funcionando
- Test pasando
FASE 7: Cron Job (Prioridad: ALTA)
Objetivo: Implementar cambios automáticos de estado
7.1 API Route del Cron
Tareas:
- Crear
src/app/api/cron/update-hackathon-states/route.ts - Validar
CRON_SECRETen headers - Implementar lógica de cambios de estado:
- REGISTRATION → RUNNING (cuando
now >= registrationClosesAt) - RUNNING → JUDGING (cuando
now >= judgingStartsAt) - JUDGING → FINISHED (cuando
now >= judgingEndsAt)
- REGISTRATION → RUNNING (cuando
- Solo procesar hackathons publicados (no DRAFT)
- Retornar estadísticas de actualizaciones
Tiempo Estimado: 45 minutos
7.2 Configuración Vercel
Tareas:
- Crear
vercel.jsoncon configuración de cron - Agregar
CRON_SECRETa.env.local - Documentar configuración
Tiempo Estimado: 15 minutos
Criterio de Completitud:
- Cron funcionando
- Configuración lista
- Test manual funcionando
FASE 8: Testing (Prioridad: CRÍTICA)
Objetivo: Asegurar calidad y cobertura
8.1 Tests de Queries
Tareas:
- Test
getHackathon(existe, no existe) - Test
getHackathonById(existe, no existe) - Test
listHackathons(sin filtros, con filtros) - Test
getOrganizerHackathons
Tiempo Estimado: 1 hora
8.2 Tests de Actions
Tareas:
- Tests de
createHackathon(éxito, RBAC, validación fechas) - Tests de
updateHackathon(éxito, RBAC, extensiones) - Tests de
deleteHackathon(éxito, RBAC) - Tests de
publishHackathon(éxito, validaciones) - Tests de
registerForHackathon(éxito, validaciones) - Tests de
unregisterFromHackathon(éxito, RBAC) - Tests de criterios (add, update, delete)
Tiempo Estimado: 2 horas
8.3 Tests de Validations
Tareas:
- Tests de
createHackathonSchema - Tests de
updateHackathonSchema - Tests de
criterionSchema - Tests de validación de fechas
Tiempo Estimado: 1 hora
Criterio de Completitud:
- Coverage >80%
- Todos los tests pasando
- Tests de RBAC completos
FASE 9: UI - Páginas Públicas (Prioridad: MEDIA)
Objetivo: Implementar vistas públicas de hackathons
9.1 /hackathons - Lista Pública
Tareas:
- Crear Server Component
- Obtener hackathons publicados (REGISTRATION, RUNNING, JUDGING, FINISHED)
- Filtro por status (Client Component mínimo)
- Mostrar lista con información básica
- Links a detalle
Tiempo Estimado: 1 hora
9.2 /hackathons/[slug] - Detalle Público
Tareas:
- Crear Server Component
- Obtener hackathon por slug
- Mostrar información completa
- Botón "Registrarse" (si PARTICIPANT y REGISTRATION)
- Server Action para registro
Tiempo Estimado: 1 hora
Criterio de Completitud:
- Lista funcionando
- Detalle funcionando
- Registro funcionando
FASE 10: UI - Panel de Organizador (Prioridad: ALTA)
Objetivo: Implementar gestión de hackathons para organizadores
10.1 /admin/hackathons/create - Crear Hackathon
Tareas:
- Crear Server Component
- Formulario HTML con campos:
- name, slug, description
- Fechas (7 campos datetime-local)
- maxTeamSize, minTeamSize
- Criterios (array dinámico)
- Server Action
createHackathon - Validación en servidor
- Redirección después de crear
Tiempo Estimado: 2 horas
10.2 /admin/hackathons/[slug] - Editar Hackathon
Tareas:
- Crear Server Component
- Obtener hackathon por slug
- Formulario pre-llenado
- Server Action
updateHackathon - Soporte para extensiones de fechas (si está en curso)
- Validación en servidor
Tiempo Estimado: 1.5 horas
10.3 /admin/hackathons/[slug]/dashboard - Panel Organizador
Tareas:
- Crear Server Component
- Obtener stats:
- Total participantes
- Total equipos (futuro, por ahora 0)
- Total submissions (futuro, por ahora 0)
- Lista de participantes
- Acciones: ver perfil, eliminar participación
Tiempo Estimado: 1.5 horas
Criterio de Completitud:
- Crear funcionando
- Editar funcionando
- Dashboard funcionando
- Validaciones funcionando
📐 Orden de Ejecución Recomendado
Secuencia Lógica:
- FASE 1: Schema y Migración ⚡ (CRÍTICA)
- FASE 2: Module Files Core (Types, Validations, Queries) ⚡ (CRÍTICA)
- FASE 3: Actions CRUD Básico (create, update, delete) ⚡ (ALTA)
- FASE 4: Actions Criterios ⚡ (ALTA)
- FASE 5: Actions Participaciones ⚡ (ALTA)
- FASE 6: Action Publicar ⚡ (ALTA)
- FASE 7: Cron Job ⚡ (ALTA)
- FASE 8: Testing ⚡ (CRÍTICA)
- FASE 9: UI Páginas Públicas (MEDIA)
- FASE 10: UI Panel Organizador (ALTA)
Regla de Oro:
NO avanzar a la siguiente fase hasta que la anterior esté 100% completa y testeada.
✅ Criterios de Completitud por Fase
Fase 1 - Schema
- Schema completo sin errores
- Migración ejecutada
- Relaciones funcionando
Fase 2 - Module Files Core
- Types exportados
- Validations con tests pasando
- Queries con tests pasando (100% coverage)
Fase 3-6 - Actions
- Cada action con RBAC funcionando
- Validaciones funcionando
- Tests pasando
Fase 7 - Cron Job
- Cron funcionando
- Configuración lista
- Test manual exitoso
Fase 8 - Testing
- Coverage >80%
- Todos los tests pasando
- Tests de RBAC completos
Fase 9-10 - UI
- Todas las páginas funcionando
- Validaciones en servidor funcionando
- Navegación funcionando
🎯 Principios de Implementación
1. Modularidad
- Cada archivo con responsabilidad única
- Separación clara: queries, actions, validations, types
- Reutilización de helpers de
core/
2. Profesionalismo
- Código limpio y bien documentado
- Nombres descriptivos
- Manejo de errores consistente
- Patrones consistentes con Módulo 1
3. Seguridad
- RBAC en cada Server Action
- Validación en servidor (nunca confiar en cliente)
- Validación de ownership (ORGANIZER solo puede editar sus hackathons)
4. Testing
- Tests antes de UI (TDD cuando sea posible)
- Coverage >80%
- Tests de RBAC exhaustivos
- Tests de validaciones de fechas
5. UI
- Server Components por defecto
- Client Components solo cuando necesario
- Actualizaciones optimistas donde aplique
- Formularios HTML nativos + Server Actions
📝 Notas Importantes
Validación de Fechas
- SIEMPRE usar
validateHackathonDates()en creación - SIEMPRE usar
validateDateExtension()en actualizaciones de hackathons en curso - El orden es estricto y no negociable
Estados del Hackathon
- DRAFT: No visible públicamente
- REGISTRATION: Visible, abierto a registro
- RUNNING: En curso, no se puede registrar
- JUDGING: En evaluación
- FINISHED: Finalizado
Cron Job
- Solo procesa hackathons publicados (no DRAFT)
- Se ejecuta cada minuto
- Cambios de estado son automáticos e irreversibles (excepto por ADMIN)
Ownership
- ORGANIZER solo puede gestionar hackathons que creó
- ADMIN puede gestionar todos los hackathons
- Validar ownership en cada action
⏱️ Estimación Total
Tiempo Total Estimado: 12-15 horas
Desglose:
- Schema: 30-45 min
- Module Files Core: 2 horas
- Actions: 5 horas
- Cron Job: 1 hora
- Testing: 4 horas
- UI: 5 horas
🚀 Siguiente Paso
Comenzar con FASE 1: Schema y Migración
¿Procedemos con la implementación siguiendo este plan?