263 lines
8.4 KiB
Plaintext
263 lines
8.4 KiB
Plaintext
|
|
// Prisma Schema - Complete and Aligned with PostgreSQL
|
||
|
|
// Database schema definition and ORM configuration
|
||
|
|
// Last updated: January 3, 2026
|
||
|
|
|
||
|
|
generator client {
|
||
|
|
provider = "prisma-client-js"
|
||
|
|
}
|
||
|
|
|
||
|
|
datasource db {
|
||
|
|
provider = "postgresql"
|
||
|
|
url = "postgresql://skyartapp:SkyArt2025Pass@localhost:5432/skyartshop?schema=public"
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// ADMIN & AUTH MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model AdminUser {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
username String @unique
|
||
|
|
email String @unique
|
||
|
|
password String
|
||
|
|
name String?
|
||
|
|
role String @default("admin")
|
||
|
|
isActive Boolean @default(true) @map("isactive")
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
@@map("adminusers")
|
||
|
|
}
|
||
|
|
|
||
|
|
model Role {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
name String @unique
|
||
|
|
description String?
|
||
|
|
permissions String[]
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
|
||
|
|
@@map("roles")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// PRODUCT MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model Product {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
name String
|
||
|
|
slug String? @unique
|
||
|
|
shortDescription String? @map("shortdescription") @db.Text
|
||
|
|
description String? @db.Text
|
||
|
|
price Decimal @db.Decimal(10, 2)
|
||
|
|
stockQuantity Int @default(0) @map("stockquantity")
|
||
|
|
category String?
|
||
|
|
sku String?
|
||
|
|
weight Decimal? @db.Decimal(10, 2)
|
||
|
|
dimensions String?
|
||
|
|
material String?
|
||
|
|
isActive Boolean @default(true) @map("isactive")
|
||
|
|
isFeatured Boolean @default(false) @map("isfeatured")
|
||
|
|
isBestseller Boolean @default(false) @map("isbestseller")
|
||
|
|
metaKeywords String? @map("metakeywords") @db.Text
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
images ProductImage[]
|
||
|
|
|
||
|
|
@@index([isActive])
|
||
|
|
@@index([isFeatured, isActive])
|
||
|
|
@@index([slug])
|
||
|
|
@@index([category])
|
||
|
|
@@index([createdAt(sort: Desc)])
|
||
|
|
@@map("products")
|
||
|
|
}
|
||
|
|
|
||
|
|
model ProductImage {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
productId String @map("product_id")
|
||
|
|
imageUrl String @map("image_url")
|
||
|
|
colorVariant String? @map("color_variant")
|
||
|
|
colorCode String? @map("color_code")
|
||
|
|
altText String? @map("alt_text")
|
||
|
|
displayOrder Int @default(0) @map("display_order")
|
||
|
|
isPrimary Boolean @default(false) @map("is_primary")
|
||
|
|
variantPrice Decimal? @map("variant_price") @db.Decimal(10, 2)
|
||
|
|
variantStock Int @default(0) @map("variant_stock")
|
||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
||
|
|
|
||
|
|
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
||
|
|
|
||
|
|
@@index([productId])
|
||
|
|
@@index([productId, isPrimary])
|
||
|
|
@@index([productId, displayOrder, createdAt])
|
||
|
|
@@index([colorVariant])
|
||
|
|
@@map("product_images")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// PORTFOLIO MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model PortfolioProject {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
title String
|
||
|
|
description String? @db.Text
|
||
|
|
featuredImage String? @map("featuredimage")
|
||
|
|
imageUrl String? @map("imageurl")
|
||
|
|
images Json? @db.JsonB
|
||
|
|
category String?
|
||
|
|
categoryId Int? @map("categoryid")
|
||
|
|
isActive Boolean @default(true) @map("isactive")
|
||
|
|
displayOrder Int @default(0) @map("displayorder")
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
@@index([isActive])
|
||
|
|
@@index([displayOrder, createdAt(sort: Desc)])
|
||
|
|
@@map("portfolioprojects")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// BLOG MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model BlogPost {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
title String
|
||
|
|
slug String @unique
|
||
|
|
excerpt String? @db.Text
|
||
|
|
content String @db.Text
|
||
|
|
imageUrl String? @map("imageurl")
|
||
|
|
isPublished Boolean @default(true) @map("ispublished")
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
@@index([isPublished])
|
||
|
|
@@index([slug])
|
||
|
|
@@index([createdAt(sort: Desc)])
|
||
|
|
@@map("blogposts")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// PAGE MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model Page {
|
||
|
|
id String @id @default(uuid())
|
||
|
|
title String
|
||
|
|
slug String @unique
|
||
|
|
pageContent String? @map("pagecontent") @db.Text
|
||
|
|
metaTitle String? @map("metatitle")
|
||
|
|
metaDescription String? @map("metadescription") @db.Text
|
||
|
|
isActive Boolean @default(true) @map("isactive")
|
||
|
|
isPublished Boolean @default(true) @map("ispublished")
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
@@index([isActive])
|
||
|
|
@@index([slug])
|
||
|
|
@@map("pages")
|
||
|
|
}
|
||
|
|
|
||
|
|
model HomepageSection {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
sectionType String @map("sectiontype")
|
||
|
|
title String?
|
||
|
|
content Json? @db.JsonB
|
||
|
|
displayOrder Int @default(0) @map("displayorder")
|
||
|
|
isActive Boolean @default(true) @map("isactive")
|
||
|
|
createdAt DateTime @default(now()) @map("createdat")
|
||
|
|
updatedAt DateTime @updatedAt @map("updatedat")
|
||
|
|
|
||
|
|
@@index([displayOrder])
|
||
|
|
@@map("homepagesections")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// MEDIA LIBRARY MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model Upload {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
filename String @unique
|
||
|
|
originalName String @map("original_name")
|
||
|
|
filePath String @map("file_path")
|
||
|
|
fileSize Int @map("file_size")
|
||
|
|
mimeType String @map("mime_type")
|
||
|
|
uploadedBy String? @map("uploaded_by")
|
||
|
|
folderId Int? @map("folder_id")
|
||
|
|
usedInType String? @map("used_in_type")
|
||
|
|
usedInId String? @map("used_in_id")
|
||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
|
|
||
|
|
folder MediaFolder? @relation(fields: [folderId], references: [id], onDelete: SetNull)
|
||
|
|
|
||
|
|
@@index([filename])
|
||
|
|
@@index([createdAt(sort: Desc)])
|
||
|
|
@@index([folderId])
|
||
|
|
@@index([usedInType, usedInId])
|
||
|
|
@@map("uploads")
|
||
|
|
}
|
||
|
|
|
||
|
|
model MediaFolder {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
name String
|
||
|
|
parentId Int? @map("parent_id")
|
||
|
|
path String
|
||
|
|
createdBy String? @map("created_by")
|
||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
|
|
||
|
|
parent MediaFolder? @relation("FolderHierarchy", fields: [parentId], references: [id], onDelete: Cascade)
|
||
|
|
children MediaFolder[] @relation("FolderHierarchy")
|
||
|
|
uploads Upload[]
|
||
|
|
|
||
|
|
@@unique([parentId, name])
|
||
|
|
@@index([parentId])
|
||
|
|
@@index([path])
|
||
|
|
@@map("media_folders")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// SITE SETTINGS MODELS
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model SiteSetting {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
key String @unique
|
||
|
|
settings Json @default("{}") @db.JsonB
|
||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
|
|
||
|
|
@@map("site_settings")
|
||
|
|
}
|
||
|
|
|
||
|
|
model TeamMember {
|
||
|
|
id Int @id @default(autoincrement())
|
||
|
|
name String
|
||
|
|
position String
|
||
|
|
bio String? @db.Text
|
||
|
|
imageUrl String? @map("image_url")
|
||
|
|
displayOrder Int @default(0) @map("display_order")
|
||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
|
|
||
|
|
@@index([displayOrder, createdAt(sort: Desc)])
|
||
|
|
@@map("team_members")
|
||
|
|
}
|
||
|
|
|
||
|
|
// =====================================================
|
||
|
|
// SESSION MODEL (for express-session)
|
||
|
|
// =====================================================
|
||
|
|
|
||
|
|
model Session {
|
||
|
|
sid String @id
|
||
|
|
sess Json @db.JsonB
|
||
|
|
expire DateTime
|
||
|
|
|
||
|
|
@@index([expire])
|
||
|
|
@@map("session")
|
||
|
|
}
|