Files
SkyArtShop/backend/prisma/schema-updated.prisma
Local Server c1da8eff42 webupdatev1
2026-01-04 17:52:37 -06:00

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")
}