// Domain models model Group { id String @id @default(cuid()) name String description String? days WeekDay[] time String? capacity Int? price Decimal? @db.Decimal(10, 2) billingType BillingType? dueDay Int? inviteToken String? @unique createdById String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt owner User @relation("OwnerGroups", fields: [createdById], references: [id], onDelete: Cascade) members GroupMember[] attendees Attendee[] payments Payment[] waitlist GroupWaitlistEntry[] classSessions ClassSession[] @@map("groups") } enum WeekDay { MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY SUNDAY } enum BillingType { MONTHLY PER_CLASS } model GroupMember { id String @id @default(cuid()) groupId String userId String role Role @default(MEMBER) // OWNER, ADMIN, MEMBER joinedAt DateTime @default(now()) group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([groupId, userId]) @@map("group_members") } enum Role { OWNER ADMIN MEMBER } enum AttendeeStatus { ACTIVE PAUSED DROPPED } model Attendee { id String @id @default(cuid()) groupId String fullName String email String? phone String? guardianName String? guardianPhone String? notes String? notifyToken String? @unique @default(cuid()) status AttendeeStatus @default(ACTIVE) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) payments Payment[] attendances Attendance[] slotReleases SlotRelease[] @@index([groupId]) @@map("attendees") } model Payment { id String @id @default(cuid()) groupId String attendeeId String amount Decimal @db.Decimal(10, 2) currency String @default("MXN") status PaymentStatus @default(PENDING) // PENDING, PAID, OVERDUE, CANCELLED dueDate DateTime paidAt DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) attendee Attendee @relation(fields: [attendeeId], references: [id], onDelete: Cascade) @@index([groupId]) @@index([attendeeId]) @@map("payments") } enum PaymentStatus { PENDING PAID OVERDUE CANCELLED } model WaitlistEntry { id String @id @default(cuid()) email String name String? status WaitlistStatus @default(PENDING) // PENDING, INVITED, JOINED, DECLINED createdAt DateTime @default(now()) updatedAt DateTime @updatedAt userId String? @unique user User? @relation(fields: [userId], references: [id], onDelete: SetNull) @@unique([email]) @@map("waitlist_entries") } model GroupWaitlistEntry { id String @id @default(cuid()) groupId String fullName String phone String email String? notes String? status WaitlistStatus @default(PENDING) // PENDING, INVITED, JOINED, DECLINED createdAt DateTime @default(now()) updatedAt DateTime @updatedAt group Group @relation(fields: [groupId], references: [id], onDelete: Cascade) @@unique([groupId, phone]) @@index([groupId]) @@map("group_waitlist_entries") } enum WaitlistStatus { PENDING INVITED JOINED DECLINED } enum PaymentProvider { MERCADO_PAGO STRIPE } model MerchantAccount { id String @id @default(cuid()) userId String @unique provider PaymentProvider accessToken String? sandbox Boolean @default(true) connectedAt DateTime @default(now()) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@map("merchant_accounts") }