Saltar al contenido principal

📋 Plan de Ejecución - Módulo 4: Sponsors Module

Fecha de Creación: 1 de enero, 2025
Estado: 📝 Planificado
Dependencias: ✅ Core Layer, ✅ Users Module, ✅ Hackathons Module, ✅ Teams Module, ✅ Submissions Module


🎯 Objetivo del Módulo

Implementar el sistema completo de sponsors con:

  • Gestión de organizaciones (organizations)
  • Sistema de sponsorships con tiers
  • Challenges de sponsors
  • Shortlist de proyectos favoritos
  • Panel de sponsor para gestión

📊 Análisis de Requerimientos

1. Schema Prisma (5 modelos nuevos)

Model Organization

model Organization {
id String @id @default(cuid())
name String
description String? @db.Text
logoUrl String?
website String?

members OrganizationMember[]
sponsorships Sponsorship[]

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@index([name])
}

Model OrganizationMember

model OrganizationMember {
id String @id @default(cuid())
organizationId String
profileId String
role OrgMemberRole @default(MEMBER)

organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)

createdAt DateTime @default(now())

@@unique([organizationId, profileId])
@@index([organizationId])
@@index([profileId])
}

Enum OrgMemberRole

enum OrgMemberRole {
OWNER
ADMIN
MEMBER
}

Model Sponsorship

model Sponsorship {
id String @id @default(cuid())
organizationId String
hackathonId String
tier SponsorshipTier
benefits Json? // Estructura flexible para beneficios del tier

organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
hackathon Hackathon @relation(fields: [hackathonId], references: [id], onDelete: Cascade)
challenges Challenge[]

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@unique([organizationId, hackathonId]) // Una org solo puede patrocinar un hackathon una vez
@@index([hackathonId])
@@index([organizationId])
@@index([tier])
}

Enum SponsorshipTier

enum SponsorshipTier {
DIAMOND
PLATINUM
GOLD
SILVER
BRONZE
PARTNER
}

Model Challenge

model Challenge {
id String @id @default(cuid())
hackathonId String
sponsorshipId String
title String
description String @db.Text
tags String[] // Tags para categorización (ej: "AI", "Blockchain", "Web3")
prizeDetails String? @db.Text // Detalles del premio (opcional)

hackathon Hackathon @relation(fields: [hackathonId], references: [id], onDelete: Cascade)
sponsorship Sponsorship @relation(fields: [sponsorshipId], references: [id], onDelete: Cascade)
shortlistItems ShortlistItem[]

createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

@@index([hackathonId])
@@index([sponsorshipId])
}

Nota: La relación con Submission se maneja a través de ShortlistItem, no directamente.

Model ShortlistItem

model ShortlistItem {
id String @id @default(cuid())
submissionId String
organizationId String
challengeId String
notes String? @db.Text // Notas internas del sponsor sobre el proyecto

submission Submission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
challenge Challenge @relation(fields: [challengeId], references: [id], onDelete: Cascade)

createdAt DateTime @default(now())

@@unique([submissionId, organizationId]) // Un proyecto solo puede estar en el shortlist de una org una vez
@@index([submissionId])
@@index([organizationId])
@@index([challengeId])
}

2. Actualización del Schema Existente

Actualizar Profile model

model Profile {
// ... campos existentes ...

// Agregar relaciones
organizationMemberships OrganizationMember[]
}

Actualizar Hackathon model

model Hackathon {
// ... campos existentes ...

// Agregar relaciones
sponsorships Sponsorship[]
}

Actualizar Submission model

model Submission {
// ... campos existentes ...

// Agregar relaciones
shortlistItems ShortlistItem[]
}

🗂️ Estructura del Módulo

Archivos a Crear

src/modules/sponsors/
├── types.ts # TypeScript types
├── validations.ts # Zod schemas
├── queries.ts # Read operations
└── actions.ts # Write operations (Server Actions)

📐 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:

  1. Actualizar prisma/schema.prisma

    • Agregar model Organization
    • Agregar model OrganizationMember
    • Agregar model Sponsorship
    • Agregar model Challenge
    • Agregar model ShortlistItem
    • Agregar enums OrgMemberRole y SponsorshipTier
    • Actualizar relaciones en Profile, Hackathon, Submission
    • Definir índices y constraints
  2. Ejecutar migración

    pnpm prisma migrate dev --name add_sponsors_module
  3. Verificar schema en Prisma Studio

Criterio de Completitud:

  • Schema completo sin errores
  • Migración ejecada exitosamente
  • Relaciones funcionando correctamente
  • Índices y constraints correctos

Tiempo Estimado: 45-60 minutos


FASE 2: Sponsors Module Core - Types y Validations (Prioridad: CRÍTICA)

Objetivo: Definir tipos TypeScript y schemas de validación

2.1 Types (src/modules/sponsors/types.ts)

Tareas:

  1. Definir tipos TypeScript:
    • OrganizationWithRelations (con miembros, sponsorships)
    • OrganizationMemberWithProfile
    • SponsorshipWithRelations (con organization, hackathon, challenges)
    • ChallengeWithRelations (con sponsorship, shortlistItems)
    • ShortlistItemWithRelations (con submission, organization, challenge)
    • CreateOrganizationInput
    • UpdateOrganizationInput
    • CreateSponsorshipInput
    • UpdateSponsorshipInput
    • CreateChallengeInput
    • UpdateChallengeInput
    • ShortlistSubmissionInput

Criterio de Completitud:

  • Todos los tipos exportados
  • Tipos usados en queries/actions

Tiempo Estimado: 20 minutos

2.2 Validations (src/modules/sponsors/validations.ts)

Tareas:

  1. Crear createOrganizationSchema (Zod)

    • name (min 3, max 100)
    • description (opcional, max 1000)
    • logoUrl (opcional, URL válida)
    • website (opcional, URL válida)
  2. Crear updateOrganizationSchema (Zod)

    • Todos los campos opcionales
  3. Crear createSponsorshipSchema (Zod)

    • organizationId (CUID)
    • hackathonId (CUID)
    • tier (enum SponsorshipTier)
    • benefits (opcional, JSON)
  4. Crear updateSponsorshipSchema (Zod)

    • tier (opcional)
    • benefits (opcional)
  5. Crear createChallengeSchema (Zod)

    • hackathonId (CUID)
    • sponsorshipId (CUID)
    • title (min 3, max 200)
    • description (min 10, max 5000)
    • tags (array de strings, max 10 tags)
    • prizeDetails (opcional, max 2000)
  6. Crear updateChallengeSchema (Zod)

    • Todos los campos opcionales
  7. Crear shortlistSubmissionSchema (Zod)

    • submissionId (CUID)
    • organizationId (CUID)
    • challengeId (CUID)
    • notes (opcional, max 2000)

Criterio de Completitud:

  • Todos los schemas creados
  • Tests de validaciones pasando

Tiempo Estimado: 45 minutos


FASE 3: Sponsors Module Core - Queries (Prioridad: CRÍTICA)

Objetivo: Implementar todas las queries de lectura

3.1 Queries (src/modules/sponsors/queries.ts)

Tareas:

  1. Implementar getOrganizationById(id: string)

    • Incluir miembros y sponsorships
  2. Implementar getOrganizationByProfileId(profileId: string)

    • Obtener organizaciones donde el perfil es miembro
  3. Implementar getOrganizationsByMember(profileId: string)

    • Lista de organizaciones del usuario
  4. Implementar getSponsorshipById(id: string)

    • Incluir organization, hackathon, challenges
  5. Implementar getSponsorshipsByHackathon(hackathonId: string)

    • Lista de sponsorships de un hackathon
    • Ordenar por tier (DIAMOND primero)
  6. Implementar getSponsorshipsByOrganization(organizationId: string)

    • Lista de sponsorships de una organización
  7. Implementar getChallengeById(id: string)

    • Incluir sponsorship, shortlistItems
  8. Implementar getChallengesBySponsorship(sponsorshipId: string)

    • Lista de challenges de un sponsorship
  9. Implementar getChallengesByHackathon(hackathonId: string)

    • Lista de todos los challenges de un hackathon
  10. Implementar getShortlistByOrganization(organizationId: string)

    • Lista de proyectos en shortlist
    • Incluir submission, challenge, team
  11. Implementar getShortlistByChallenge(challengeId: string)

    • Lista de proyectos en shortlist de un challenge específico
  12. Implementar isShortlisted(submissionId: string, organizationId: string)

    • Verificar si un proyecto está en el shortlist

Criterio de Completitud:

  • Todas las queries implementadas
  • Tests de queries pasando (100% coverage)

Tiempo Estimado: 2 horas


FASE 4: Sponsors Module Core - Actions (Prioridad: CRÍTICA)

Objetivo: Implementar todas las Server Actions

4.1 Actions (src/modules/sponsors/actions.ts)

Tareas:

  1. Implementar createOrganization(data: CreateOrganizationInput, currentUserId: string)

    • RBAC: solo SPONSOR/ADMIN
    • Validar con Zod
    • Crear Organization
    • Crear OrganizationMember con role OWNER
    • Revalidar paths
  2. Implementar updateOrganization(organizationId: string, data: UpdateOrganizationInput, currentUserId: string)

    • RBAC: solo SPONSOR/ADMIN (miembro de la org con role OWNER/ADMIN)
    • Validar ownership
    • Validar con Zod
    • Actualizar Organization
    • Revalidar paths
  3. Implementar addOrganizationMember(organizationId: string, profileId: string, role: OrgMemberRole, currentUserId: string)

    • RBAC: solo SPONSOR/ADMIN (miembro de la org con role OWNER/ADMIN)
    • Validar ownership
    • Validar que profileId no es ya miembro
    • Crear OrganizationMember
    • Revalidar paths
  4. Implementar removeOrganizationMember(organizationId: string, profileId: string, currentUserId: string)

    • RBAC: solo SPONSOR/ADMIN (miembro de la org con role OWNER/ADMIN)
    • Validar ownership
    • Validar que no se elimina el último OWNER
    • Eliminar OrganizationMember
    • Revalidar paths
  5. Implementar createSponsorship(data: CreateSponsorshipInput, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization)
    • Validar que organization existe
    • Validar que hackathon existe
    • Validar que no existe sponsorship previa (unique constraint)
    • Validar con Zod
    • Crear Sponsorship
    • Revalidar paths
  6. Implementar updateSponsorship(sponsorshipId: string, data: UpdateSponsorshipInput, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization)
    • Validar ownership
    • Validar con Zod
    • Actualizar Sponsorship
    • Revalidar paths
  7. Implementar createChallenge(data: CreateChallengeInput, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization del sponsorship)
    • Validar que sponsorship existe
    • Validar que hackathon del sponsorship existe
    • Validar con Zod
    • Crear Challenge
    • Revalidar paths
  8. Implementar updateChallenge(challengeId: string, data: UpdateChallengeInput, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization del sponsorship)
    • Validar ownership
    • Validar con Zod
    • Actualizar Challenge
    • Revalidar paths
  9. Implementar deleteChallenge(challengeId: string, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization del sponsorship)
    • Validar ownership
    • Eliminar Challenge (cascade elimina shortlistItems)
    • Revalidar paths
  10. Implementar shortlistSubmission(data: ShortlistSubmissionInput, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization)
    • Validar que submission existe
    • Validar que challenge existe y pertenece a la organization
    • Validar que submission pertenece al hackathon del challenge
    • Validar que no está ya en shortlist (unique constraint)
    • Validar con Zod
    • Crear ShortlistItem
    • Revalidar paths
  11. Implementar removeFromShortlist(submissionId: string, organizationId: string, currentUserId: string)

    • RBAC: solo SPONSOR (miembro de la organization)
    • Validar ownership
    • Eliminar ShortlistItem
    • Revalidar paths

Criterio de Completitud:

  • Todas las actions implementadas
  • RBAC funcionando
  • Validaciones funcionando
  • Tests pasando

Tiempo Estimado: 3-4 horas


FASE 5: Testing (Prioridad: CRÍTICA)

Objetivo: Tests completos con >80% coverage

Tareas:

  1. Crear tests/modules/sponsors/validations.test.ts

    • Tests de todos los schemas Zod
    • Tests de edge cases
  2. Crear tests/modules/sponsors/queries.test.ts

    • Tests de todas las queries
    • Tests de relaciones cargadas
    • Tests de filtros
  3. Crear tests/modules/sponsors/actions.test.ts

    • Tests de todas las actions
    • Tests de RBAC
    • Tests de validaciones de negocio
    • Tests de constraints (unique, cascade)

Criterio de Completitud:

  • Coverage >80%
  • Todos los tests pasando
  • Tests de RBAC completos

Tiempo Estimado: 3-4 horas


FASE 6: UI - Organizations (Prioridad: ALTA)

Objetivo: UI para gestión de organizaciones

Tareas:

  1. Crear /sponsor/organizations/create/page.tsx

    • Formulario crear organización
    • Campos: name, description, logoUrl, website
    • Server Action: createOrganization
    • Redirige a /sponsor/organizations/[id] después de crear
  2. Crear /sponsor/organizations/[id]/page.tsx

    • Detalle de organización
    • Lista de miembros con roles
    • Lista de sponsorships
    • Botón "Editar" (solo OWNER/ADMIN)
    • Botón "Agregar Miembro" (solo OWNER/ADMIN)
  3. Crear /sponsor/organizations/[id]/edit/page.tsx

    • Formulario editar organización
    • Server Action: updateOrganization
  4. Crear /sponsor/organizations/page.tsx

    • Lista de organizaciones del usuario actual
    • Link a crear nueva organización

Tiempo Estimado: 2 horas


FASE 7: UI - Sponsorships (Prioridad: ALTA)

Objetivo: UI para gestión de sponsorships

Tareas:

  1. Crear /sponsor/sponsorships/create/page.tsx

    • Formulario crear sponsorship
    • Select de organización (solo organizaciones del usuario)
    • Select de hackathon (solo hackathons publicados)
    • Select de tier (DIAMOND, PLATINUM, GOLD, SILVER, BRONZE, PARTNER)
    • Textarea para benefits (JSON opcional)
    • Server Action: createSponsorship
  2. Crear /sponsor/sponsorships/[id]/page.tsx

    • Detalle de sponsorship
    • Información del tier
    • Lista de challenges
    • Botón "Crear Challenge"
    • Botón "Editar" (solo miembros de la org)
  3. Crear /sponsor/sponsorships/[id]/edit/page.tsx

    • Formulario editar sponsorship
    • Server Action: updateSponsorship

Tiempo Estimado: 2 horas


FASE 8: UI - Challenges (Prioridad: ALTA)

Objetivo: UI para gestión de challenges

Tareas:

  1. Crear /sponsor/challenges/create/page.tsx

    • Formulario crear challenge
    • Select de sponsorship (solo sponsorships de organizaciones del usuario)
    • Campos: title, description, tags (input múltiple), prizeDetails
    • Server Action: createChallenge
  2. Crear /sponsor/challenges/[id]/page.tsx

    • Detalle de challenge
    • Información del challenge
    • Lista de submissions en shortlist
    • Botón "Agregar a Shortlist"
    • Botón "Editar" (solo miembros de la org)
    • Botón "Eliminar" (solo miembros de la org)
  3. Crear /sponsor/challenges/[id]/edit/page.tsx

    • Formulario editar challenge
    • Server Action: updateChallenge
  4. Crear /sponsor/challenges/[id]/submissions/page.tsx

    • Lista de submissions del hackathon
    • Filtro por challenge (opcional)
    • Botón "Agregar a Shortlist" por cada submission
    • Mostrar si ya está en shortlist

Tiempo Estimado: 2.5 horas


FASE 9: UI - Shortlist (Prioridad: ALTA)

Objetivo: UI para gestión de shortlist

Tareas:

  1. Crear /sponsor/shortlist/page.tsx

    • Lista de proyectos en shortlist
    • Filtro por organización
    • Filtro por challenge
    • Información de cada submission
    • Botón "Ver Detalle"
    • Botón "Remover de Shortlist"
  2. Crear /sponsor/shortlist/[submissionId]/page.tsx

    • Detalle de submission en shortlist
    • Información del equipo
    • Información del challenge
    • Notas del sponsor
    • Botón "Editar Notas"
    • Botón "Contactar Equipo" (email vía Clerk)

Tiempo Estimado: 1.5 horas


FASE 10: UI - Panel de Sponsor (Prioridad: ALTA)

Objetivo: Dashboard principal para sponsors

Tareas:

  1. Crear /sponsor/page.tsx

    • Dashboard principal
    • Estadísticas:
      • Total de organizaciones
      • Total de sponsorships activas
      • Total de challenges
      • Total de proyectos en shortlist
    • Lista de hackathons patrocinados
    • Acciones rápidas:
      • Crear organización
      • Crear sponsorship
      • Ver shortlist
  2. Crear /sponsor/hackathons/[slug]/page.tsx

    • Vista de hackathon patrocinado
    • Lista de challenges del hackathon
    • Lista de submissions
    • Estadísticas del hackathon

Tiempo Estimado: 2 horas


FASE 11: Integración con Módulos Existentes (Prioridad: MEDIA)

Objetivo: Integrar sponsors con módulos existentes

Tareas:

  1. Actualizar /hackathons/[slug]/page.tsx

    • Mostrar lista de sponsors (con logos)
    • Mostrar lista de challenges disponibles
    • Link a challenges en submissions
  2. Actualizar /hackathons/[slug]/submissions/[submissionId]/page.tsx

    • Mostrar challenges disponibles
    • Botón "Aplicar a Challenge" (si es PARTICIPANT y tiene submission)
  3. Actualizar /hackathons/[slug]/teams/[teamId]/submit/page.tsx

    • Mostrar challenges disponibles al crear/editar submission
    • Campo opcional para seleccionar challenge

Nota: La relación entre Submission y Challenge se maneja a través de ShortlistItem, no directamente. Los participantes pueden "aplicar" a un challenge, lo que crea un ShortlistItem.

Tiempo Estimado: 2 horas


📐 Orden de Ejecución Recomendado

Secuencia Lógica:

  1. FASE 1: Schema y Migración ⚡ (CRÍTICA)
  2. FASE 2: Types y Validations ⚡ (CRÍTICA)
  3. FASE 3: Queries ⚡ (CRÍTICA)
  4. FASE 4: Actions ⚡ (CRÍTICA)
  5. FASE 5: Testing ⚡ (CRÍTICA)
  6. FASE 6: UI Organizations (ALTA)
  7. FASE 7: UI Sponsorships (ALTA)
  8. FASE 8: UI Challenges (ALTA)
  9. FASE 9: UI Shortlist (ALTA)
  10. FASE 10: UI Panel Sponsor (ALTA)
  11. FASE 11: Integración (MEDIA)

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
  • Índices y constraints correctos

Fase 2 - Types y Validations

  • Types exportados
  • Validations con tests pasando

Fase 3 - Queries

  • Todas las queries implementadas
  • Tests pasando (100% coverage)

Fase 4 - Actions

  • Todas las actions implementadas
  • RBAC funcionando
  • Validaciones funcionando
  • Tests pasando

Fase 5 - Testing

  • Coverage >80%
  • Todos los tests pasando
  • Tests de RBAC completos

Fase 6-11 - UI

  • Todas las páginas funcionando
  • Validaciones en servidor funcionando
  • Navegación funcionando
  • Integración con módulos existentes

🎯 Principios de Implementación

RBAC (Role-Based Access Control)

  • SPONSOR: Puede crear organizaciones, sponsorships, challenges, shortlist
  • ADMIN: Puede hacer todo lo que SPONSOR puede hacer
  • ORGANIZER: No tiene acceso al módulo de sponsors (solo puede ver sponsors en hackathons)
  • PARTICIPANT: Puede ver challenges y aplicar a ellos (crear ShortlistItem)
  • JUDGE: No tiene acceso al módulo de sponsors

Validaciones de Negocio

  1. Organizations:

    • Un usuario solo puede crear organizaciones si tiene role SPONSOR o ADMIN
    • Solo OWNER/ADMIN pueden editar organización
    • No se puede eliminar el último OWNER
  2. Sponsorships:

    • Una organización solo puede patrocinar un hackathon una vez (unique constraint)
    • Solo miembros de la organización pueden crear sponsorships
  3. Challenges:

    • Solo se pueden crear challenges para sponsorships de la organización del usuario
    • Challenges pertenecen a un hackathon específico
  4. Shortlist:

    • Un proyecto solo puede estar en el shortlist de una organización una vez (unique constraint)
    • Solo miembros de la organización pueden agregar a shortlist
    • El proyecto debe pertenecer al hackathon del challenge

Relaciones y Constraints

  • Organization → OrganizationMember: Cascade delete
  • Organization → Sponsorship: Cascade delete
  • Sponsorship → Challenge: Cascade delete
  • Challenge → ShortlistItem: Cascade delete
  • Submission → ShortlistItem: Cascade delete
  • Unique constraints:
    • [organizationId, profileId] en OrganizationMember
    • [organizationId, hackathonId] en Sponsorship
    • [submissionId, organizationId] en ShortlistItem

📊 Estimación de Tiempo Total

FaseTiempo Estimado
FASE 1: Schema45-60 min
FASE 2: Types y Validations1 hora
FASE 3: Queries2 horas
FASE 4: Actions3-4 horas
FASE 5: Testing3-4 horas
FASE 6: UI Organizations2 horas
FASE 7: UI Sponsorships2 horas
FASE 8: UI Challenges2.5 horas
FASE 9: UI Shortlist1.5 horas
FASE 10: UI Panel Sponsor2 horas
FASE 11: Integración2 horas
TOTAL22-24 horas (~3 días de trabajo)

🚨 Consideraciones Importantes

1. Relación Submission-Challenge

Importante: La relación entre Submission y Challenge NO es directa. Se maneja a través de ShortlistItem:

  • Un participante puede "aplicar" a un challenge, lo que crea un ShortlistItem
  • Un sponsor puede agregar un proyecto a su shortlist, lo que también crea un ShortlistItem
  • Esto permite flexibilidad: un proyecto puede estar en múltiples shortlists de diferentes organizaciones

2. Benefits en Sponsorship

El campo benefits es de tipo Json?, lo que permite flexibilidad:

  • Puede contener información estructurada sobre beneficios del tier
  • Ejemplo: { "logo": true, "booth": true, "speaking": false, "prize": 5000 }
  • La UI puede renderizar esto dinámicamente

3. Tags en Challenge

Los tags son un array de strings, útil para:

  • Categorización (ej: ["AI", "Blockchain", "Web3"])
  • Búsqueda y filtrado
  • Matching automático con submissions

4. Notas en ShortlistItem

Las notes son opcionales y permiten a los sponsors:

  • Anotar observaciones sobre proyectos
  • Marcar proyectos favoritos
  • Comunicarse internamente sobre proyectos

🎯 Objetivos Finales

Al completar este módulo, se debe poder:

  1. ✅ Sponsors pueden crear y gestionar organizaciones
  2. ✅ Sponsors pueden crear sponsorships para hackathons
  3. ✅ Sponsors pueden crear challenges para sus sponsorships
  4. ✅ Sponsors pueden agregar proyectos a su shortlist
  5. ✅ Participantes pueden ver challenges y aplicar a ellos
  6. ✅ Organizadores pueden ver sponsors de sus hackathons
  7. ✅ Panel de sponsor muestra estadísticas y gestión completa
  8. ✅ Tests tienen >80% coverage
  9. ✅ RBAC funciona correctamente en todas las acciones
  10. ✅ UI es funcional y profesional

📝 Notas Finales

Dependencias Verificadas

  • ✅ Core Layer: rbac.ts, errors.ts, db.ts, auth.ts
  • ✅ Users Module: Profile model, Role enum
  • ✅ Hackathons Module: Hackathon model, HackathonStatus enum
  • ✅ Teams Module: Team model, TeamMember model
  • ✅ Submissions Module: Submission model

Patrones a Seguir

  • Usar Server Actions para todas las operaciones de escritura
  • Usar Server Components por defecto
  • Validar con Zod en todas las entradas
  • Implementar RBAC en todas las actions
  • Escribir tests desde el inicio
  • Seguir la estructura de módulos existente

Última Actualización: 1 de enero, 2025
Estado: 📝 Planificado
Próximo Paso: Iniciar FASE 1 - Schema y Migración