// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } // Modelo de Usuario model User { id String @id @default(uuid()) email String @unique password String // Datos personales firstName String lastName String phone String? avatarUrl String? city String? birthDate DateTime? // Datos de juego (usamos String para simular enums en SQLite) role String @default("PLAYER") // PLAYER, ADMIN, SUPERADMIN playerLevel String @default("BEGINNER") // BEGINNER, ELEMENTARY, INTERMEDIATE, ADVANCED, COMPETITION, PROFESSIONAL handPreference String @default("RIGHT") // RIGHT, LEFT, BOTH positionPreference String @default("BOTH") // DRIVE, BACKHAND, BOTH bio String? yearsPlaying Int? // Estadísticas globales matchesPlayed Int @default(0) matchesWon Int @default(0) matchesLost Int @default(0) totalPoints Int @default(0) // Estado isActive Boolean @default(true) isVerified Boolean @default(false) lastLogin DateTime? // Relaciones bookings Booking[] levelHistory LevelHistory[] // Relaciones con MatchResult team1Player1Matches MatchResult[] @relation("Team1Player1") team1Player2Matches MatchResult[] @relation("Team1Player2") team2Player1Matches MatchResult[] @relation("Team2Player1") team2Player2Matches MatchResult[] @relation("Team2Player2") // Relación con UserStats userStats UserStats[] // Amistades friendsSent Friend[] @relation("FriendRequestsSent") friendsReceived Friend[] @relation("FriendRequestsReceived") // Grupos groupsCreated Group[] @relation("GroupsCreated") groupMembers GroupMember[] @relation("GroupMemberships") // Reservas recurrentes recurringBookings RecurringBooking[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("users") } // Modelo de Historial de Niveles model LevelHistory { id String @id @default(uuid()) // Niveles oldLevel String newLevel String // Referencias user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String // Quién realizó el cambio (admin) changedBy String // Metadata reason String? createdAt DateTime @default(now()) @@index([userId]) @@map("level_history") } // Modelo de Cancha model Court { id String @id @default(uuid()) name String @unique description String? // Características type String @default("PANORAMIC") // PANORAMIC, OUTDOOR, INDOOR, SINGLE isIndoor Boolean @default(false) hasLighting Boolean @default(true) hasParking Boolean @default(false) // Precio por hora (en centavos para evitar decimales) pricePerHour Int @default(2000) // Imagen imageUrl String? // Estado isActive Boolean @default(true) // Relaciones bookings Booking[] schedules CourtSchedule[] recurringBookings RecurringBooking[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("courts") } // Modelo de Horarios de Cancha (días y horas de operación) model CourtSchedule { id String @id @default(uuid()) // Día de la semana (0=Domingo, 1=Lunes, ..., 6=Sábado) dayOfWeek Int // Horario openTime String closeTime String // Precio especial para esta franja (opcional) priceOverride Int? // Relación court Court @relation(fields: [courtId], references: [id], onDelete: Cascade) courtId String @@unique([courtId, dayOfWeek]) @@map("court_schedules") } // Modelo de Reserva model Booking { id String @id @default(uuid()) // Fecha y hora date DateTime startTime String endTime String // Estado (PENDING, CONFIRMED, CANCELLED, COMPLETED, NO_SHOW) status String @default("PENDING") // Precio totalPrice Int // Notas notes String? // Relaciones user User @relation(fields: [userId], references: [id]) userId String court Court @relation(fields: [courtId], references: [id]) courtId String // Relación con MatchResult matchResult MatchResult? // Referencia a reserva recurrente (si aplica) recurringBooking RecurringBooking? @relation(fields: [recurringBookingId], references: [id]) recurringBookingId String? // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([courtId]) @@index([date]) @@index([recurringBookingId]) @@map("bookings") } // Modelo de Amistad model Friend { id String @id @default(uuid()) // Quien envía la solicitud requester User @relation("FriendRequestsSent", fields: [requesterId], references: [id]) requesterId String // Quien recibe la solicitud addressee User @relation("FriendRequestsReceived", fields: [addresseeId], references: [id]) addresseeId String // Estado (PENDING, ACCEPTED, REJECTED, BLOCKED) status String @default("PENDING") // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([requesterId, addresseeId]) @@index([requesterId]) @@index([addresseeId]) @@index([status]) @@map("friends") } // Modelo de Grupo model Group { id String @id @default(uuid()) name String description String? // Creador del grupo createdBy User @relation("GroupsCreated", fields: [createdById], references: [id]) createdById String // Relaciones members GroupMember[] // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([createdById]) @@map("groups") } // Modelo de Miembro de Grupo model GroupMember { id String @id @default(uuid()) // Grupo group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) groupId String // Usuario user User @relation("GroupMemberships", fields: [userId], references: [id]) userId String // Rol (ADMIN, MEMBER) role String @default("MEMBER") // Fecha de unión joinedAt DateTime @default(now()) @@unique([groupId, userId]) @@index([groupId]) @@index([userId]) @@map("group_members") } // Modelo de Reserva Recurrente model RecurringBooking { id String @id @default(uuid()) // Usuario que crea la reserva recurrente user User @relation(fields: [userId], references: [id]) userId String // Cancha court Court @relation(fields: [courtId], references: [id]) courtId String // Día de la semana (0=Domingo, 1=Lunes, ..., 6=Sábado) dayOfWeek Int // Horario startTime String endTime String // Rango de fechas startDate DateTime endDate DateTime? // Estado isActive Boolean @default(true) // Relaciones bookings Booking[] // Timestamps createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([courtId]) @@index([dayOfWeek]) @@index([isActive]) @@map("recurring_bookings") } // Modelo de Resultado de Partido model MatchResult { id String @id @default(uuid()) // Relación opcional con reserva booking Booking? @relation(fields: [bookingId], references: [id], onDelete: SetNull) bookingId String? @unique // Jugadores del Equipo 1 team1Player1 User @relation("Team1Player1", fields: [team1Player1Id], references: [id]) team1Player1Id String team1Player2 User @relation("Team1Player2", fields: [team1Player2Id], references: [id]) team1Player2Id String // Jugadores del Equipo 2 team2Player1 User @relation("Team2Player1", fields: [team2Player1Id], references: [id]) team2Player1Id String team2Player2 User @relation("Team2Player2", fields: [team2Player2Id], references: [id]) team2Player2Id String // Resultado team1Score Int team2Score Int winner String // TEAM1, TEAM2, DRAW // Fecha en que se jugó el partido playedAt DateTime // Confirmaciones (JSON array de userIds) confirmedBy String @default("[]") // Timestamps createdAt DateTime @default(now()) @@index([team1Player1Id]) @@index([team1Player2Id]) @@index([team2Player1Id]) @@index([team2Player2Id]) @@index([playedAt]) @@map("match_results") } // Modelo de Estadísticas de Usuario por Período model UserStats { id String @id @default(uuid()) // Usuario user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String // Período (MONTH, YEAR, ALL_TIME) period String // Valor del período (ej: "2024-01" para mes, "2024" para año) periodValue String // Estadísticas de partidos matchesPlayed Int @default(0) matchesWon Int @default(0) matchesLost Int @default(0) // Estadísticas de torneos tournamentsPlayed Int @default(0) tournamentsWon Int @default(0) // Puntos para ranking points Int @default(0) // Timestamps updatedAt DateTime @updatedAt @@unique([userId, period, periodValue]) @@index([userId]) @@index([period, periodValue]) @@index([points]) @@map("user_stats") }