feat: add competition heats system backend
- Add 3 new database tables: divisions, competition_types, event_user_heats - Add seed data for 6 divisions (NEW, NOV, INT, ADV, ALL, CHA) and 2 competition types (J&J, STR) - Add API endpoints for divisions and competition types - Add heats management endpoints in events route (POST/GET/DELETE) - Implement unique constraint: cannot have same role in same division+competition type - Add participant verification before allowing heats management - Support heat numbers 1-9 with optional Leader/Follower role
This commit is contained in:
@@ -54,6 +54,7 @@ model User {
|
||||
ratingsGiven Rating[] @relation("RaterRatings")
|
||||
ratingsReceived Rating[] @relation("RatedRatings")
|
||||
eventParticipants EventParticipant[]
|
||||
heats EventUserHeat[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
@@ -76,6 +77,7 @@ model Event {
|
||||
matches Match[]
|
||||
participants EventParticipant[]
|
||||
checkinToken EventCheckinToken?
|
||||
userHeats EventUserHeat[]
|
||||
|
||||
@@map("events")
|
||||
}
|
||||
@@ -187,3 +189,53 @@ model EventParticipant {
|
||||
@@index([eventId])
|
||||
@@map("event_participants")
|
||||
}
|
||||
|
||||
// Competition divisions (Newcomer, Novice, Intermediate, etc.)
|
||||
model Division {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique @db.VarChar(50)
|
||||
abbreviation String @unique @db.VarChar(3)
|
||||
displayOrder Int @map("display_order")
|
||||
|
||||
// Relations
|
||||
userHeats EventUserHeat[]
|
||||
|
||||
@@map("divisions")
|
||||
}
|
||||
|
||||
// Competition types (Jack & Jill, Strictly, etc.)
|
||||
model CompetitionType {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @unique @db.VarChar(50)
|
||||
abbreviation String @unique @db.VarChar(3)
|
||||
|
||||
// Relations
|
||||
userHeats EventUserHeat[]
|
||||
|
||||
@@map("competition_types")
|
||||
}
|
||||
|
||||
// User's declared heats for matchmaking
|
||||
model EventUserHeat {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int @map("user_id")
|
||||
eventId Int @map("event_id")
|
||||
divisionId Int @map("division_id")
|
||||
competitionTypeId Int @map("competition_type_id")
|
||||
heatNumber Int @map("heat_number") // 1-9
|
||||
role String? @db.VarChar(10) // 'Leader', 'Follower', or NULL
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
// Relations
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
event Event @relation(fields: [eventId], references: [id], onDelete: Cascade)
|
||||
division Division @relation(fields: [divisionId], references: [id])
|
||||
competitionType CompetitionType @relation(fields: [competitionTypeId], references: [id])
|
||||
|
||||
// Constraint: Cannot have same role in same division+competition type
|
||||
@@unique([userId, eventId, divisionId, competitionTypeId, role])
|
||||
@@index([userId, eventId])
|
||||
@@index([eventId])
|
||||
@@map("event_user_heats")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user