📖 Historias Técnicas Detalladas (MVP estricto)
Narradas paso a paso, con validaciones server-side y reglas del MVP actualizado. Notificaciones solo por email (Clerk); no hay notificaciones in-app.
🔗 Reglas transversales que aplican en todas las historias
- Publicación manual: un hackathon solo se puede publicar si
now >= registrationOpensAt; el cron no pasa deDRAFTaREGISTRATION, solo mueve estados ya publicados (REGISTRATION→RUNNING→JUDGING→FINISHED). - Roles exclusivos: un mismo usuario no puede ser
JUDGEy participante del mismo hackathon. Organizer no asigna jueces que sean participantes activos ahí. - Equipos: crear/unirse/salir permitido solo si
hackathon.status IN (REGISTRATION, RUNNING)ynow < submissionDeadline. EnJUDGINGyFINISHEDla membresía está congelada (solo lectura). Si el equipo no tiene submission y queda vacío, se borra inmediato; si tiene submission, no se permite que el último miembro salga. - Submissions: una por equipo (
@@unique(teamId)); editable hastasubmissionDeadline; después queda solo lectura. Segundo intento debe redirigir/avisar que ya existe submission del equipo. - Scores: un juez solo ve sus propios scores hasta
FINISHED; después puede ver el detalle completo. Si un juez es removido, sus scores permanecen en DB pero se excluyen del cálculo (se cuentan solo jueces conHackathonJudgevigente; remover juez = hard delete deHackathonJudgeen MVP). - Contacto sponsor: no se exponen emails; se envía correo vía proxy a los miembros del equipo cuando un sponsor contacta.
🎭 Historia 1: María (PARTICIPANT) vive todo el ciclo
Contexto: Primera vez en un hackathon; quiere formar equipo y competir.
Vistas y rutas clave: landing /, onboarding /onboarding, panel /dashboard, página pública del hackathon /hackathons/[slug], equipos /hackathons/[slug]/teams, mi equipo /hackathons/[slug]/my-team, submit /hackathons/[slug]/submit, leaderboard /hackathons/[slug]/leaderboard.
- Día 1 (registro abierto): Llega a landing
/, clic en “Registrarse” → Clerk →/onboarding. Completa perfil (nombre, bio, stack, avatar) →Profilecreado con rolPARTICIPANT. - Ver hackathon:
/hackathons/hackucentral-2025muestra estadoREGISTRATIONy timeline. Botón “Registrarse”. - Registro: Clic en “Registrarse” → Server Action valida
requireRole(['PARTICIPANT']),status=REGISTRATION,nowdentro de ventana. CreaHackathonParticipation. Mensaje: “Registrado”. Redirige a/hackathons/hackucentral-2025/teams. - Equipo (crear): Tab “Crear equipo” en
/hackathons/[slug]/teams: valida que no tenga equipo en ese hackathon, generacodeúnico, creaTeamyTeamMember. Muestra código para invitar. Tab “Unirse a equipo” acepta código y valida cupo, no pertenecer ya a otro equipo, y que el código exista. Crear/unirse permitido solo sihackathon.status IN (REGISTRATION, RUNNING)ynow < submissionDeadline. - Invitar/Unirse: Sus compañeras usan el código; cada join valida participante registrado, cupo, unicidad de equipo. Listado muestra miembros actuales en
/hackathons/[slug]/my-team. - Edición de equipo: Mientras
hackathon.status IN (REGISTRATION, RUNNING)ynow < submissionDeadline, botón “Salir del equipo” en/hackathons/[slug]/my-team. Si sale y el team no tiene submission, se borra suTeamMember; si queda vacío y no hay submission, se borra el equipo. Si el team tiene submission, no se permite que el último miembro salga. - Envío de proyecto (
RUNNING):/hackathons/hackucentral-2025/submitmuestra countdown. Server Action valida: miembro de equipo,status=RUNNING,now < submissionDeadline, tamaño de equipo>= minTeamSize, equipo sin submission previa, URLs válidas. CreaSubmission(opcionalchallengeId). Si intenta un segundo envío, se redirige al detalle existente con mensaje “Tu equipo ya envió un proyecto”. - Edición de submission: Mientras
now < submissionDeadline, botón “Editar” en/hackathons/[slug]/submithabilitado. Cambios en título/description/links/challenge. Al llegar la fecha límite, se bloquea y se muestra mensaje “Submission bloqueada (fecha límite superada)”. - Post-submission: Ve estado “En espera de evaluación”. Si intenta editar en
JUDGING, recibe error de bloqueo. - Resultados (
FINISHED): Recibe email “Resultados disponibles”. En/hackathons/[slug]/leaderboardve ranking, puntaje ponderado, desglose por criterio y comentarios. Si ganó un challenge, lo ve destacado.
🎭 Historia 2: Carlos (JUDGE) evalúa sin sesgo
Contexto: Juez invitado; no puede participar en el mismo hackathon.
Vistas y rutas clave: panel de juez /judge, detalle del hackathon asignado /judge/hackathons/[slug], evaluación /judge/hackathons/[slug]/evaluate, vista de restricciones de scores /judge/hackathons/[slug]/all-scores, resultados post-evento /judge/hackathons/[slug]/results.
- Rol y asignación: Admin cambia rol a
JUDGE(email). Organizer asigna a Carlos en/admin/hackathons/[slug]/judges; validación bloquea si Carlos ya es participante. Se creaHackathonJudge; email de invitación. Un juez solo puede tener 1 hackathon activo (REGISTRATION/RUNNING/JUDGING) asignado. - Previo a judging: Panel de juez
/judgey/judge/hackathons/[slug]muestra criterios (nombre, peso, maxScore) y la fecha de inicio deJUDGINGcon contador. No ve submissions antes deJUDGING. - Durante
JUDGING:/judge/hackathons/[slug]/evaluatelista submissions del hackathon asignado, solo “Not evaluated” y “Evaluated por ti”. Al evaluar una submission, Server Action valida: rolJUDGE, asignación existe, hackathonJUDGING, submission pertenece al hackathon, scores dentro de rango. CreaScorepor criterio con constraint (submission, judge, criterion) único. - Aislamiento:
/judge/hackathons/[slug]/all-scoresmuestra mensaje de restricción; solo sus propias evaluaciones hastaFINISHED. - Progreso: Barra “Evaluated X/Y”, persistente. Puede salir y volver sin perder estado.
- Después (
FINISHED): En/judge/hackathons/[slug]/resultsve leaderboard completo y comparativa de jueces. Si necesita corregir un score, solo ADMIN puede hacerlo (no hay edición de score por juez en MVP). Si se remueve al juez del hackathon, sus scores permanecen pero no se consideran en el cálculo (solo cuentan jueces conHackathonJudgevigente).
🎭 Historia 3: Patricia (ORGANIZER) publica y conduce el evento
Contexto: Organiza su primer hackathon.
Vistas y rutas clave: panel de organizador /admin/hackathons, creación /admin/hackathons/create, detalle y edición /admin/hackathons/[slug], criterios /admin/hackathons/[slug]/criteria, jueces /admin/hackathons/[slug]/judges, panel operativo /admin/hackathons/[slug]/dashboard.
- Creación en borrador: Rol
ORGANIZER. Formulario/admin/hackathons/createcon validación de orden estricto: registrationOpensAt < registrationClosesAt < startsAt < submissionDeadline < judgingStartsAt < judgingEndsAt. Si el orden falla, se rechaza. - Criterios y jueces: Configura criterios (peso 1-10, maxScore) en
/admin/hackathons/[slug]/criteriay asigna jueces en/admin/hackathons/[slug]/judges. No puede asignar jueces que sean participantes del mismo hackathon. - Publicación manual: Botón “Publicar” en
/admin/hackathons/[slug]solo habilita si checklist completo ynow >= registrationOpensAt. Al publicar pasa aREGISTRATION; cron seguirá moviendo estados en fechas programadas. - Gestión en marcha:
/admin/hackathons/[slug]/dashboardmuestra métricas (participantes, equipos, submissions). Puede remover participaciones o miembros de equipo problemáticos. Puede extender solo la fase siguiente, máximo +7 días, nunca acortar, y siempre preservando el orden de fechas. Si ajusta fechas, el cron usa los nuevos valores. - Visibilidad: No ve scores ni leaderboard durante
JUDGING; solo progreso de evaluación (evaluadas X/Y). EnFINISHEDve leaderboard completo. - Cierre: En
FINISHED, exporta resultados y ganadores de challenges desde/admin/hackathons/[slug]/dashboard.
🎭 Historia 4: Roberto (SPONSOR) crea challenge y hace shortlist
Contexto: Sponsor de Google quiere promover Gemini API.
Vistas y rutas clave: panel sponsor /sponsor, creación de organización /sponsor/organizations/create, creación de sponsorship /sponsor/sponsorships/create, creación de challenge /sponsor/challenges/create, listado de submissions de su challenge /sponsor/challenges/[id]/submissions, shortlist /sponsor/shortlist.
- Rol y organización: Rol
SPONSOR. CreaOrganization(logo, sitio, descripción) y queda como owner (OrganizationMember) en/sponsor/organizations/create. - Sponsorship y challenge: Crea
Sponsorshipligado a un hackathon (tier, benefits JSON) en/sponsor/sponsorships/create. Luego creaChallengeasociado a esa sponsorship en/sponsor/challenges/create(título, descripción, tags, premios). - Durante el evento: Panel sponsor
/sponsory/sponsor/challenges/[id]/submissionslista submissions que eligieron su challenge (filtrochallengeId). No ve scores ni feedback mientrasstatus != FINISHED. - Shortlist: Puede marcar “Agregar a shortlist” en
/sponsor/challenges/[id]/submissions; Server Action valida rol, membresía en la org, que la submission eligió su challenge, y unicidad submission+org. Guarda notas privadas. Consulta shortlist en/sponsor/shortlist. - Contacto: Botón “Contactar equipo” desde shortlist envía email vía proxy (Clerk) a los miembros; la UI no revela direcciones de correo.
- Después (
FINISHED): Ve leaderboard completo y ganador de su challenge (mejor score entre quienes eligieron su challenge) en/sponsor/challenges/[id]/submissionso/sponsor. Accede a perfiles detallados de shortlist para scouting.
🎭 Historia 5: Laura (ADMIN) “modo Dios” con override
Contexto: Admin de plataforma con poderes completos.
Vistas y rutas clave: panel admin /admin, gestión de usuarios /admin/users, listado de hackathons /admin/hackathons, edición forzada /admin/hackathons/[slug]/edit, ajustes de organizations /admin/organizations, sponsorships /admin/sponsorships, challenges /admin/challenges, resultados globales /admin/dashboard.
- Usuarios: CRUD de usuarios en
/admin/users, cambio de roles (incluido ADMIN). Puede borrar usuarios con cascade (participaciones, equipos, submissions, scores). - Hackathons: Edita cualquier campo en
/admin/hackathons/[slug]/edit, incluso fuera de ventanas o rompiendo orden (override). Puede publicar sin restricciones de fecha (solo ADMIN), forzar estados y borrar hackathons completos. - Organizaciones y challenges: CRUD total sobre organizations, sponsorships, challenges en sus rutas
/admin/organizations,/admin/sponsorships,/admin/challenges. Puede reasignar ownership. - Scores y submissions: Visibilidad total; puede corregir scores y submissions, y forzar estados/fechas si hay incidentes.
- Auditoría futura: No hay audit log en el MVP; se asume confianza en ADMIN.
✅ Respuestas rápidas a las preguntas de coherencia
- Edición de submission: Sí, hasta
submissionDeadline; después queda locked (aunque aún no inicieJUDGING). - Conflicto de interés juez: MVP no incluye recusación por proyecto; la mitigación es preventiva (no asignar jueces que sean participantes). Si hay conflicto, Organizer/ADMIN puede remover al juez manualmente.
- Pausar/cancelar hackathon: No hay pausa/cancel en MVP. Organizer puede ajustar fechas futuras o ADMIN puede forzar estado/borrar el evento.
- Sponsor y resultados: Sponsor ve leaderboard final y ganador de su challenge cuando
FINISHED; no ve scores ni emails antes. - Notificaciones: Solo email (Clerk); no hay in-app notifications.
🔍 Checklist de coherencia
- PARTICIPANT: Registro en ventana, equipo único por hackathon, leave hasta
submissionDeadline, una submission por equipo, editable hasta el deadline, ve resultados enFINISHED. - JUDGE: Asignado solo si no es participante, evalúa con constraints por criterio, no ve scores ajenos hasta
FINISHED. - ORGANIZER: Publica manualmente si
now >= registrationOpensAt, mantiene orden de fechas, no ve scores hastaFINISHED, puede gestionar participantes/equipos. - SPONSOR: Ve solo submissions de su challenge, shortlist con notas, contacta vía proxy, ve ganador de su challenge en
FINISHED. - ADMIN: Sin restricciones; puede override fechas, roles, scores y estados.