// Prisma Schema for EZBio - Modern URL Shortener & Link in Bio generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) name String email String @unique password String role String @default("user") // "admin" | "user" username String @unique isActive Boolean @default(true) emailVerified DateTime? avatar String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt shortUrls ShortUrl[] portal Portal? uploadedFiles UploadedFile[] @@map("users") } model ShortUrl { id String @id @default(cuid()) originalUrl String shortCode String @unique title String? password String? // bcrypt hash if password protected expiresAt DateTime? displayOnPortal Boolean @default(false) clicksCount Int @default(0) userId String? user User? @relation(fields: [userId], references: [id], onDelete: Cascade) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt tags Tag[] @relation("ShortUrlTags") clicks UrlClick[] @@index([userId]) @@index([shortCode]) @@map("short_urls") } model Tag { id String @id @default(cuid()) name String @unique shortUrls ShortUrl[] @relation("ShortUrlTags") createdAt DateTime @default(now()) @@map("tags") } model UrlClick { id String @id @default(cuid()) shortUrlId String shortUrl ShortUrl @relation(fields: [shortUrlId], references: [id], onDelete: Cascade) ipAddress String? userAgent String? deviceType String? // "desktop" | "mobile" | "tablet" operatingSystem String? browser String? countryName String? countryCode String? city String? referrer String? createdAt DateTime @default(now()) @@index([shortUrlId]) @@index([createdAt]) @@map("url_clicks") } model Portal { id String @id @default(cuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) title String? description String? avatar String? backgroundImage String? headerColor String? @default("#000000") titleColorStyle String? @default("gradient-1") backgroundStyle String? @default("gradient-1") vcard Json? // { fullName, phone, email, company, website } socialLinks Json? // { facebook, twitter, instagram, threads, tiktok, youtube, telegram } createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("portals") } model Setting { id String @id @default(cuid()) key String @unique value String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("settings") } model UploadedFile { id String @id @default(cuid()) key String @unique // Storage key or local filename url String // Public URL or relative path originalName String mimeType String sizeBytes BigInt // File size in bytes category String // "avatar", "background", "logo", "favicon", "og_image" storageType String @default("cloudflare_r2") // "cloudflare_r2" | "local" userId String? user User? @relation(fields: [userId], references: [id], onDelete: SetNull) createdAt DateTime @default(now()) @@index([category]) @@map("uploaded_files") }