From 792a951e02c132e7848a5b9a5de85c507bab4814 Mon Sep 17 00:00:00 2001 From: streaper2 Date: Sun, 26 Apr 2026 23:10:05 +0200 Subject: [PATCH] feat: initialize Prisma schema with core business, user, and communication models and configure docker-compose for database deployment --- docker-compose.yml | 4 +- prisma/schema.prisma | 330 +++++++++++++++++++++---------------------- 2 files changed, 167 insertions(+), 167 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7fe27fd..d1e0818 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,7 +29,7 @@ services: ports: - "3000:3000" environment: - - DATABASE_URL=postgresql://admin:adminpassword@db:5432/afropreunariat_dev?schema=public + - DATABASE_URL=postgresql://admin:adminpassword@db:5432/afrohub_dev?schema=public - NEXT_PUBLIC_SITE_URL=http://localhost:3000 depends_on: db: @@ -45,7 +45,7 @@ services: ports: - "3001:3001" environment: - - DATABASE_URL=postgresql://admin:adminpassword@db:5432/afropreunariat_dev?schema=public + - DATABASE_URL=postgresql://admin:adminpassword@db:5432/afrohub_dev?schema=public - NEXT_PUBLIC_SITE_URL=http://localhost:3000 - NEXT_PUBLIC_ADMIN_URL=http://localhost:3001 depends_on: diff --git a/prisma/schema.prisma b/prisma/schema.prisma index d63fff3..e55ccb2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -9,119 +9,119 @@ datasource db { } model User { - id String @id @default(uuid()) - name String - email String @unique - password String - role UserRole @default(VISITOR) - avatar String? - emailVerified Boolean @default(false) - verificationToken String? @unique - resetToken String? @unique - resetTokenExpiry DateTime? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - bio String? - location String? - countryId String? - phone String? - isSuspended Boolean @default(false) - suspensionReason String? - businesses Business? - comments Comment[] - conversations ConversationParticipant[] - sentMessages Message[] - reports MessageReport[] - ratings Rating[] - country Country? @relation(fields: [countryId], references: [id]) + id String @id @default(uuid()) + name String + email String @unique + password String + role UserRole @default(VISITOR) + avatar String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + bio String? + location String? + phone String? + isSuspended Boolean @default(false) + suspensionReason String? + countryId String? + resetToken String? @unique + resetTokenExpiry DateTime? + emailVerified Boolean @default(false) + verificationToken String? @unique + businesses Business? + comments Comment[] + conversations ConversationParticipant[] + sentMessages Message[] + reports MessageReport[] + ratings Rating[] + country Country? @relation(fields: [countryId], references: [id]) } model Business { - id String @id @default(uuid()) - name String - category String + id String @id @default(uuid()) + name String + category String + location String + description String + logoUrl String + videoUrl String? + contactEmail String + contactPhone String? + socialLinks Json? + verified Boolean @default(false) + viewCount Int @default(0) + rating Float @default(0.0) + ratingCount Int @default(0) + tags String[] + isFeatured Boolean @default(false) + founderName String? + founderImageUrl String? + keyMetric String? + ownerId String @unique + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + slug String? @unique + isActive Boolean @default(false) + showEmail Boolean @default(true) + showPhone Boolean @default(true) + showSocials Boolean @default(true) + websiteUrl String? + isSuspended Boolean @default(false) + suspensionReason String? + plan Plan @default(STARTER) + city String? + countryId String? + coverUrl String? + coverPosition String? @default("50% 50%") + coverZoom Float? @default(1.0) suggestedCategory String? - location String - countryId String? - city String? - description String - logoUrl String - coverUrl String? - coverPosition String? @default("50% 50%") - coverZoom Float? @default(1.0) - videoUrl String? - contactEmail String - contactPhone String? - socialLinks Json? - verified Boolean @default(false) - viewCount Int @default(0) - rating Float @default(0.0) - ratingCount Int @default(0) - tags String[] - isFeatured Boolean @default(false) - founderName String? - founderImageUrl String? - keyMetric String? - ownerId String @unique - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - slug String? @unique - isActive Boolean @default(false) - showEmail Boolean @default(true) - showPhone Boolean @default(true) - showSocials Boolean @default(true) - websiteUrl String? - isSuspended Boolean @default(false) - suspensionReason String? - plan Plan @default(STARTER) - owner User @relation(fields: [ownerId], references: [id]) - comments Comment[] - conversations Conversation[] - offers Offer[] - ratings Rating[] - country Country? @relation(fields: [countryId], references: [id]) - categoryRef BusinessCategory? @relation(fields: [categoryId], references: [id]) - categoryId String? + categoryId String? + categoryRef BusinessCategory? @relation(fields: [categoryId], references: [id]) + country Country? @relation(fields: [countryId], references: [id]) + owner User @relation(fields: [ownerId], references: [id]) + comments Comment[] + conversations Conversation[] + offers Offer[] + ratings Rating[] } model BusinessCategory { id String @id @default(uuid()) name String @unique slug String @unique - icon String? // Lucide icon name + icon String? isActive Boolean @default(true) - businesses Business[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + businesses Business[] } model Country { id String @id @default(uuid()) name String @unique - code String @unique // ISO alpha-2 - flag String? // Emoji or URL + code String @unique + flag String? isActive Boolean @default(true) - description String? @db.Text - businesses Business[] - users User[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + description String? + businesses Business[] + users User[] } model PricingPlan { - id String @id @default(uuid()) - tier Plan @unique - name String - priceXOF String - yearlyPriceXOF String? - priceEUR String + id String @id @default(uuid()) + tier Plan @unique + name String + priceXOF String + priceEUR String + description String + features String[] + offerLimit Int @default(1) + recommended Boolean @default(false) + color String @default("gray") + updatedAt DateTime @updatedAt yearlyPriceEUR String? - description String - features String[] - offerLimit Int @default(1) - recommended Boolean @default(false) - color String @default("gray") - updatedAt DateTime @updatedAt + yearlyPriceXOF String? } model Offer { @@ -142,23 +142,22 @@ model Offer { model BlogPost { id String @id @default(uuid()) title String - slug String? @unique excerpt String content String author String date DateTime @default(now()) imageUrl String - tags String[] @default([]) - metaTitle String? - metaDescription String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + metaDescription String? + metaTitle String? + slug String? @unique + tags String[] @default([]) } model Interview { id String @id @default(uuid()) title String - slug String? @unique guestName String companyName String role String @@ -169,11 +168,12 @@ model Interview { excerpt String date DateTime @default(now()) duration String? - tags String[] @default([]) - metaTitle String? - metaDescription String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt + metaDescription String? + metaTitle String? + slug String? @unique + tags String[] @default([]) } model Comment { @@ -194,40 +194,34 @@ model AnalyticsEvent { label String? value Float? metadata Json? - ip String? - country String? - city String? + createdAt DateTime @default(now()) browser String? - os String? + city String? + country String? device String? + ip String? + os String? referrer String? userId String? - createdAt DateTime @default(now()) } model Rating { - id String @id @default(uuid()) + id String @id @default(uuid()) value Int + userId String + businessId String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt comment String? reply String? replyAt DateTime? status RatingStatus @default(PENDING) - userId String - businessId String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - business Business @relation(fields: [businessId], references: [id], onDelete: Cascade) + business Business @relation(fields: [businessId], references: [id], onDelete: Cascade) + user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@unique([userId, businessId]) } -enum RatingStatus { - PENDING - APPROVED - REJECTED -} - model Conversation { id String @id @default(uuid()) businessId String @@ -272,6 +266,63 @@ model MessageReport { reporter User @relation(fields: [reporterId], references: [id], onDelete: Cascade) } +model SiteSetting { + id String @id @default("singleton") + siteName String @default("Afrohub") + siteSlogan String @default("La plateforme de référence pour l'entrepreneuriat africain.") + contactEmail String @default("support@afrohub.com") + contactPhone String? @default("+225 00 00 00 00 00") + address String? @default("Abidjan, Côte d'Ivoire") + facebookUrl String? + twitterUrl String? + instagramUrl String? + linkedinUrl String? + footerText String? @default("© 2025 Afrohub. Tous droits réservés.") + updatedAt DateTime @updatedAt + homeBlogCount Int @default(3) + homeBlogShow Boolean @default(true) + homeBlogSubtitle String @default("Toutes les actualités de l'entrepreneuriat africain.") + homeBlogTitle String @default("Derniers Articles") + homeBlogCategories String[] @default([]) + homeBlogIds String[] @default([]) + homeBlogSelection String @default("latest") + homeCategories String[] @default(["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"]) + resetPasswordSubject String @default("Réinitialisation de votre mot de passe - Afrohub") + resetPasswordTemplate String @default("

{siteName}

Bonjour {name},

Vous avez demandé la réinitialisation de votre mot de passe. Cliquez sur le bouton ci-dessous pour choisir un nouveau mot de passe :

Réinitialiser mon mot de passe

Ce lien expirera dans 1 heure. Si vous n'avez pas demandé cette réinitialisation, vous pouvez ignorer cet email.


© 2025 {siteName}. Tous droits réservés.

") + verifyEmailSubject String @default("Vérification de votre compte - Afrohub") + verifyEmailTemplate String @default("

{siteName}

Bonjour {name},

Merci de vous être inscrit sur {siteName}. Pour finaliser la création de votre compte, merci de vérifier votre adresse email en cliquant sur le bouton ci-dessous :

Vérifier mon compte

Si vous n'avez pas créé de compte sur notre plateforme, vous pouvez ignorer cet email.


© 2025 {siteName}. Tous droits réservés.

") +} + +model LegalDocument { + id String @id @default(uuid()) + type String @unique + title String + content String + updatedAt DateTime @updatedAt +} + +model Event { + id String @id @default(uuid()) + title String + description String + date DateTime + location String + thumbnailUrl String + link String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + metaDescription String? + metaTitle String? + slug String? @unique + tags String[] @default([]) +} + +enum RatingStatus { + PENDING + APPROVED + REJECTED +} + enum ReportStatus { PENDING RESOLVED @@ -299,54 +350,3 @@ enum InterviewType { VIDEO ARTICLE } - -model SiteSetting { - id String @id @default("singleton") - siteName String @default("Afrohub") - siteSlogan String @default("La plateforme de référence pour l'entrepreneuriat africain.") - contactEmail String @default("support@afrohub.com") - contactPhone String? @default("+225 00 00 00 00 00") - address String? @default("Abidjan, Côte d'Ivoire") - facebookUrl String? - twitterUrl String? - instagramUrl String? - linkedinUrl String? - footerText String? @default("© 2025 Afrohub. Tous droits réservés.") - homeBlogShow Boolean @default(true) - homeBlogTitle String @default("Derniers Articles") - homeBlogSubtitle String @default("Toutes les actualités de l'entrepreneuriat africain.") - homeBlogCount Int @default(3) - homeBlogSelection String @default("latest") - homeBlogIds String[] @default([]) - homeBlogCategories String[] @default([]) - homeCategories String[] @default(["Technologie & IT", "Agriculture & Agrobusiness", "Mode & Textile", "Cosmétique & Beauté"]) - resetPasswordSubject String @default("Réinitialisation de votre mot de passe - Afrohub") - resetPasswordTemplate String @default("

{siteName}

Bonjour {name},

Vous avez demandé la réinitialisation de votre mot de passe. Cliquez sur le bouton ci-dessous pour choisir un nouveau mot de passe :

Réinitialiser mon mot de passe

Ce lien expirera dans 1 heure. Si vous n'avez pas demandé cette réinitialisation, vous pouvez ignorer cet email.


© 2025 {siteName}. Tous droits réservés.

") @db.Text - verifyEmailSubject String @default("Vérification de votre compte - Afrohub") - verifyEmailTemplate String @default("

{siteName}

Bonjour {name},

Merci de vous être inscrit sur {siteName}. Pour finaliser la création de votre compte, merci de vérifier votre adresse email en cliquant sur le bouton ci-dessous :

Vérifier mon compte

Si vous n'avez pas créé de compte sur notre plateforme, vous pouvez ignorer cet email.


© 2025 {siteName}. Tous droits réservés.

") @db.Text - updatedAt DateTime @updatedAt -} - -model LegalDocument { - id String @id @default(uuid()) - type String @unique // 'CGU' or 'CGV' - title String - content String @db.Text - updatedAt DateTime @updatedAt -} - -model Event { - id String @id @default(uuid()) - title String - slug String? @unique - description String @db.Text - date DateTime - location String - thumbnailUrl String - link String? - tags String[] @default([]) - metaTitle String? - metaDescription String? - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt -}