Initial commit: JuanitoSport - Muay Thai & Yog4Fight PWA
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
enum Role {
|
||||
ADMIN
|
||||
MEMBER
|
||||
}
|
||||
|
||||
enum MediaType {
|
||||
PHOTO
|
||||
VIDEO
|
||||
}
|
||||
|
||||
enum MediaVisibility {
|
||||
PUBLIC
|
||||
MEMBERS_ONLY
|
||||
MUAY_THAI_ONLY
|
||||
YOGA_ONLY
|
||||
}
|
||||
|
||||
enum CertificateStatus {
|
||||
PENDING
|
||||
VALIDATED
|
||||
REJECTED
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
name String
|
||||
password String
|
||||
role Role @default(MEMBER)
|
||||
avatar String?
|
||||
phone String?
|
||||
isMuayThai Boolean @default(false)
|
||||
isYoga Boolean @default(false)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
muayThai MuayThaiProfile?
|
||||
yoga YogaProfile?
|
||||
media Media[]
|
||||
messagesRead MessageRead[]
|
||||
certificates Certificate[]
|
||||
absences Absence[]
|
||||
homework Homework[]
|
||||
yogaAttend YogaAttendance[]
|
||||
}
|
||||
|
||||
model MuayThaiProfile {
|
||||
id String @id @default(cuid())
|
||||
userId String @unique
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
jumpRopeBestTime Int? // en secondes
|
||||
burpee100BestTime Int? // en secondes
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
sessions TrainingSession[]
|
||||
}
|
||||
|
||||
model TrainingSession {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile MuayThaiProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
date DateTime @default(now())
|
||||
jumpRopeTime Int? // en secondes
|
||||
burpee100Time Int? // en secondes
|
||||
notes String?
|
||||
}
|
||||
|
||||
model YogaProfile {
|
||||
id String @id @default(cuid())
|
||||
userId String @unique
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
sessionsRemaining Int @default(1)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
attendances YogaAttendance[]
|
||||
}
|
||||
|
||||
model YogaAttendance {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
profile YogaProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
date DateTime @default(now())
|
||||
pricePaid Float?
|
||||
notes String?
|
||||
}
|
||||
|
||||
model YogaTier {
|
||||
id String @id @default(cuid())
|
||||
name String // ex: "Séance unique", "Pack 5", "Pack 10"
|
||||
numberOfSessions Int
|
||||
priceTotal Float
|
||||
isActive Boolean @default(true)
|
||||
}
|
||||
|
||||
model Media {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String?
|
||||
type MediaType @default(PHOTO)
|
||||
url String
|
||||
thumbnail String?
|
||||
visibility MediaVisibility @default(MEMBERS_ONLY)
|
||||
uploadedById String?
|
||||
uploadedBy User? @relation(fields: [uploadedById], references: [id], onDelete: SetNull)
|
||||
createdAt DateTime @default(now())
|
||||
}
|
||||
|
||||
model Message {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
content String
|
||||
category String? // muay-thai | yoga | general
|
||||
createdAt DateTime @default(now())
|
||||
readBy MessageRead[]
|
||||
}
|
||||
|
||||
model MessageRead {
|
||||
id String @id @default(cuid())
|
||||
messageId String
|
||||
message Message @relation(fields: [messageId], references: [id], onDelete: Cascade)
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
readAt DateTime @default(now())
|
||||
|
||||
@@unique([messageId, userId])
|
||||
}
|
||||
|
||||
model Homework {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
description String
|
||||
videoUrl String?
|
||||
createdAt DateTime @default(now())
|
||||
userId String?
|
||||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||||
}
|
||||
|
||||
model Certificate {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
fileUrl String
|
||||
status CertificateStatus @default(PENDING)
|
||||
createdAt DateTime @default(now())
|
||||
reviewedAt DateTime?
|
||||
}
|
||||
|
||||
model Absence {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
date DateTime
|
||||
reason String?
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
const adminEmail = process.env.ADMIN_EMAIL || "pierre@secourit.fr";
|
||||
const adminPassword = process.env.ADMIN_PASSWORD || "JuanitoAdmin2026!";
|
||||
|
||||
const existing = await prisma.user.findUnique({
|
||||
where: { email: adminEmail },
|
||||
});
|
||||
|
||||
if (!existing) {
|
||||
const hashed = await bcrypt.hash(adminPassword, 10);
|
||||
await prisma.user.create({
|
||||
data: {
|
||||
email: adminEmail,
|
||||
name: "Juanito",
|
||||
password: hashed,
|
||||
role: "ADMIN",
|
||||
muayThai: { create: {} },
|
||||
},
|
||||
});
|
||||
console.log(`✅ Admin créé: ${adminEmail}`);
|
||||
} else {
|
||||
console.log(`Admin existe déjà: ${adminEmail}`);
|
||||
}
|
||||
|
||||
// Créer les tiers Yoga par défaut
|
||||
const tiers = [
|
||||
{ name: "Séance unique", numberOfSessions: 1, priceTotal: 9 },
|
||||
{ name: "Pack 5 séances", numberOfSessions: 5, priceTotal: 40 },
|
||||
{ name: "Pack 10 séances", numberOfSessions: 10, priceTotal: 70 },
|
||||
];
|
||||
for (const t of tiers) {
|
||||
const exists = await prisma.yogaTier.findFirst({
|
||||
where: { name: t.name },
|
||||
});
|
||||
if (!exists) {
|
||||
await prisma.yogaTier.create({ data: t });
|
||||
console.log(`✅ Tier yoga créé: ${t.name}`);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Seed terminé ✅");
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user