feat: initial commit - EZBio Next.js 16 fullstack URL shortener & bio link

This commit is contained in:
Tien Tran committed 2026-09-28 00:28:09 -07:00
commit 569c10342f
64 files changed
+15670

No files matched your search

+127
View File
@@ -0,0 +1,127 @@
// 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")
}