generator client { provider = "prisma-client-js" } datasource db { provider = "sqlite" url = env("DATABASE_URL") } /// Категория изделий (игрушки, сувениры и т.д.) model Category { id String @id @default(cuid()) name String slug String @unique sort Int @default(0) products Product[] } model Product { id String @id @default(cuid()) title String slug String @unique shortDescription String? description String? /// Количество на складе (если null — не ведём учёт) quantity Int? /// Материалы (список, например: ["хлопок","дерево"]) materials String @default("[]") /// Цена в копейках (целое число, без дробной части) priceCents Int imageUrl String? published Boolean @default(false) inStock Boolean @default(true) leadTimeDays Int? category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade) categoryId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt images ProductImage[] reviews Review[] orderItems OrderItem[] cartItems CartItem[] } model ProductImage { id String @id @default(cuid()) url String sort Int @default(0) createdAt DateTime @default(now()) product Product @relation(fields: [productId], references: [id], onDelete: Cascade) productId String @@index([productId, sort]) } model User { id String @id @default(cuid()) email String @unique name String? phone String? passwordHash String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt codes AuthCode[] addresses ShippingAddress[] cartItems CartItem[] orders Order[] reviews Review[] } model CartItem { id String @id @default(cuid()) qty Int createdAt DateTime @default(now()) user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String product Product @relation(fields: [productId], references: [id], onDelete: Cascade) productId String @@unique([userId, productId]) @@index([userId]) } model Order { id String @id @default(cuid()) /// Статус заказа (валидация переходов на уровне API) status String @default("DRAFT") totalCents Int @default(0) currency String @default("RUB") addressSnapshotJson String comment String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String items OrderItem[] messages OrderMessage[] @@index([userId, createdAt]) @@index([status, updatedAt]) } model OrderItem { id String @id @default(cuid()) qty Int titleSnapshot String priceCentsSnapshot Int order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) orderId String product Product @relation(fields: [productId], references: [id], onDelete: Restrict) productId String @@index([orderId]) } model OrderMessage { id String @id @default(cuid()) /// 'user' | 'admin' authorType String text String createdAt DateTime @default(now()) order Order @relation(fields: [orderId], references: [id], onDelete: Cascade) orderId String @@index([orderId, createdAt]) } model Review { id String @id @default(cuid()) rating Int text String? /// 'pending' | 'approved' | 'rejected' status String @default("pending") createdAt DateTime @default(now()) moderatedAt DateTime? product Product @relation(fields: [productId], references: [id], onDelete: Cascade) productId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String @@index([productId, status, createdAt]) @@index([status, createdAt]) @@unique([productId, userId]) } model ShippingAddress { id String @id @default(cuid()) label String? recipientName String recipientPhone String addressLine String comment String? lat Float lng Float isDefault Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) userId String @@index([userId, isDefault]) @@index([userId, updatedAt]) } model AuthCode { id String @id @default(cuid()) email String codeHash String purpose String expiresAt DateTime usedAt DateTime? createdAt DateTime @default(now()) user User? @relation(fields: [userId], references: [id], onDelete: Cascade) userId String? @@index([email, purpose]) @@index([expiresAt]) }