generator client { provider = "prisma-client-js" binaryTargets = ["native", "linux-musl", "debian-openssl-3.0.x", "linux-musl-openssl-3.0.x"] } datasource db { provider = "sqlite" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique name String passwordHash String? provider String @default("email") providerId String? avatar String? flhBalance Int @default(5000) isPro Boolean @default(false) isPremium Boolean @default(false) experienceLevel String? madhab String? coachPersona String? preferredName String? coachingGoals String? lastCoachedAt DateTime? dailyMsgCount Int @default(0) dailyMsgResetAt DateTime? stripeCustomerId String? stripeSubscriptionId String? trialEndsAt DateTime? createdAt DateTime @default(now()) @@index([provider, providerId]) listings Listing[] purchases Purchase[] @relation("BuyerPurchases") sales Purchase[] @relation("SellerPurchases") cashouts CashoutRequest[] halalBookmarks HalalBookmark[] halalUsage HalalUsage? userPlaces UserPlace[] ownedGroups Group[] @relation("GroupOwner") groupMemberships GroupMember[] forumThreads ForumThread[] forumPosts ForumPost[] chatHistory ChatHistory[] notifications Notification[] referredReferrals Referral[] @relation("Referrer") referrerReferral Referral? @relation("Referred") dailyStreak DailyStreak? xpTransactions XpTransaction[] achievements Achievement[] userLevel UserLevel? dhikrSessions DhikrSession[] dhikrDays DhikrDay[] } model DailyStreak { userId String @id user User @relation(fields: [userId], references: [id]) currentStreak Int @default(0) longestStreak Int @default(0) lastClaimDate DateTime? streakFreeze Int @default(0) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model XpTransaction { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) amount Int reason String // 'daily_login' | 'chat_message' | 'forum_post' | 'purchase' | 'referral' | 'achievement' createdAt DateTime @default(now()) @@index([userId]) } model Achievement { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) type String // 'first_chat' | 'streak_7' | 'streak_30' | 'level_5' | 'first_purchase' | 'first_post' title String description String? icon String? unlockedAt DateTime @default(now()) @@index([userId]) @@unique([userId, type]) } model UserLevel { userId String @id user User @relation(fields: [userId], references: [id]) level Int @default(1) xp Int @default(0) xpToNext Int @default(100) updatedAt DateTime @updatedAt } model Listing { id String @id @default(cuid()) title String description String category String priceFlh Int sellerId String seller User @relation(fields: [sellerId], references: [id]) status String @default("active") featured Boolean @default(false) featuredUntil DateTime? fileType String? createdAt DateTime @default(now()) purchases Purchase[] } model Purchase { id String @id @default(cuid()) listingId String listing Listing @relation(fields: [listingId], references: [id]) buyerId String buyer User @relation("BuyerPurchases", fields: [buyerId], references: [id]) sellerId String seller User @relation("SellerPurchases", fields: [sellerId], references: [id]) amountFlh Int platformFee Int sellerPayout Int autoConfirmAt DateTime createdAt DateTime @default(now()) } model CashoutRequest { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) amountFlh Int fiatAmount Float status String @default("pending") createdAt DateTime @default(now()) } model ForumCategory { id String @id @default(cuid()) name String @unique description String? icon String? order Int? createdAt DateTime @default(now()) threads ForumThread[] } model ForumThread { id String @id @default(cuid()) title String content String categoryId String category ForumCategory @relation(fields: [categoryId], references: [id]) authorId String author User @relation(fields: [authorId], references: [id]) pinned Boolean @default(false) shariahStatus String @default("pending") shariahFlags String? createdAt DateTime @default(now()) posts ForumPost[] group Group? @relation(fields: [groupId], references: [id]) groupId String? } model Group { id String @id @default(cuid()) name String description String? ownerId String owner User @relation("GroupOwner", fields: [ownerId], references: [id]) inviteCode String @unique createdAt DateTime @default(now()) members GroupMember[] threads ForumThread[] } model GroupMember { id String @id @default(cuid()) groupId String group Group @relation(fields: [groupId], references: [id]) userId String user User @relation(fields: [userId], references: [id]) role String @default("member") joinedAt DateTime @default(now()) @@unique([groupId, userId]) } model ForumPost { id String @id @default(cuid()) content String threadId String thread ForumThread @relation(fields: [threadId], references: [id]) authorId String author User @relation(fields: [authorId], references: [id]) shariahStatus String @default("pending") shariahFlags String? createdAt DateTime @default(now()) } model ChatHistory { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) role String content String metadata String? createdAt DateTime @default(now()) @@index([userId]) } model HalalBookmark { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) itemId String itemType String label String? createdAt DateTime @default(now()) @@index([userId]) } model HalalUsage { userId String @id user User @relation(fields: [userId], references: [id]) queriesUsed Int @default(0) queriesLimit Int @default(100) periodEnd DateTime? } model UserPlace { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) name String address String lat Float lng Float type String // "mosque" | "restaurant" | "cafe" notes String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) @@index([lat, lng]) } model Notification { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) type String // 'streak_reminder' | 'daily_verse' | 'premium_expiring' | 'new_listing' | 'forum_reply' | 'achievement' | 'referral_bonus' title String body String? data String? // JSON string with extra payload read Boolean @default(false) createdAt DateTime @default(now()) @@index([userId, read]) } model Referral { id String @id @default(cuid()) referrerId String referrer User @relation("Referrer", fields: [referrerId], references: [id]) referredId String @unique referred User @relation("Referred", fields: [referredId], references: [id]) status String @default("pending") // pending | joined | upgraded rewardFlh Int @default(0) createdAt DateTime @default(now()) upgradedAt DateTime? @@index([referrerId]) } model PremiumBenefit { id String @id @default(cuid()) tier String // 'premium' | 'pro' name String description String? icon String? active Boolean @default(true) createdAt DateTime @default(now()) } model HalalPlaceCache { id String @id @default(cuid()) cacheKey String @unique data String expiresAt DateTime } model DhikrSession { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id]) type String // 'subhanallah' | 'alhamdulillah' | 'allahuakbar' | 'custom' count Int @default(0) target Int @default(33) completed Boolean @default(true) createdAt DateTime @default(now()) @@index([userId, createdAt]) } model DhikrDay { userId String user User @relation(fields: [userId], references: [id]) date String // YYYY-MM-DD subhanallah Int @default(0) alhamdulillah Int @default(0) allahuakbar Int @default(0) custom Int @default(0) totalCount Int @default(0) sessionCount Int @default(0) updatedAt DateTime @updatedAt @@id([userId, date]) @@index([userId]) } // Add Relations to User model /// NOTE: The Notification and Referral relations are declared on the models above. /// User now implicitly has: notifications Notification[], referredReferrals Referral[] (via "Referrer"), referrerReferral Referral? (via "Referred")