Files
telegram-shop/admin-next/prisma/schema.prisma
NW 9ac7afa36e fix(admin): issue #147 — Catalog Tree city edit/delete, sort order, subcategory ops
- handleRename: city rename via /api/locations/rename-city (all rows), district via PUT /api/locations/{id}
- City-level delete: DELETE /api/locations/by-city (blocks on dependencies, 400 with counts)
- Sort order: idempotent ensureSortOrderColumns (ALTER TABLE try/catch) + PATCH /api/{type}s/{id}/sort + up/down arrows on district/category/subcategory
- Tree queries order by sort_order asc, then name
- Subcategory rename/delete verified
- tsc clean
2026-08-10 10:55:12 +01:00

241 lines
8.1 KiB
Plaintext
Executable File

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-arm64-openssl-3.0.x", "linux-arm64-openssl-1.1.x", "linux-arm64-openssl-1.0.x"]
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
// ────────────────────────────────────────────
// Telegram Shop Admin Panel — Full Schema
// ────────────────────────────────────────────
model TgUser {
id Int @id @default(autoincrement())
telegramId String @unique @map("telegram_id")
username String?
country String?
city String?
district String?
status Int @default(0) // 0=active 2=blocked
totalBalance Float @default(0) @map("total_balance")
bonusBalance Float @default(0) @map("bonus_balance")
language String @default("en")
languageSet Int @default(0) @map("language_set")
notes String?
createdAt DateTime @default(now()) @map("created_at")
wallets CryptoWallet[]
transactions Transaction[]
purchases Purchase[]
@@map("users")
}
model CryptoWallet {
id Int @id @default(autoincrement())
userId Int @map("user_id")
walletType String @map("wallet_type") // BTC/LTC/ETH/USDT/USDC
address String
derivationPath String? @map("derivation_path")
mnemonic String? // encrypted
balance Float @default(0)
createdAt DateTime @default(now()) @map("created_at")
user TgUser @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([userId, walletType])
@@map("crypto_wallets")
}
model Transaction {
id Int @id @default(autoincrement())
userId Int @map("user_id")
walletType String @map("wallet_type")
txHash String? @map("tx_hash")
amount Float
createdAt DateTime @default(now()) @map("created_at")
user TgUser @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("transactions")
}
model Location {
id Int @id @default(autoincrement())
country String
city String
district String @default("")
sortOrder Int @default(0) @map("sort_order")
isActive Int @default(1) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
categories Category[]
products Product[]
@@unique([country, city, district])
@@map("locations")
}
model Category {
id Int @id @default(autoincrement())
locationId Int @map("location_id")
name String
sortOrder Int @default(0) @map("sort_order")
isActive Int @default(1) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
subcategories Subcategory[]
products Product[]
@@unique([locationId, name])
@@map("categories")
}
model Subcategory {
id Int @id @default(autoincrement())
categoryId Int @map("category_id")
name String
sortOrder Int @default(0) @map("sort_order")
isActive Int @default(1) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
products Product[]
@@unique([categoryId, name])
@@map("subcategories")
}
model Product {
id Int @id @default(autoincrement())
locationId Int @map("location_id")
categoryId Int @map("category_id")
subcategoryId Int? @map("subcategory_id")
name String
description String?
privateData String? @map("private_data")
price Float
quantityInStock Int @default(0) @map("quantity_in_stock")
photoUrl String? @map("photo_url")
hiddenPhotoUrl String? @map("hidden_photo_url")
hiddenCoordinates String? @map("hidden_coordinates")
hiddenDescription String? @map("hidden_description")
isMono Int @default(0) @map("is_mono")
createdAt DateTime @default(now()) @map("created_at")
location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
subcategory Subcategory? @relation(fields: [subcategoryId], references: [id], onDelete: SetNull)
purchases Purchase[]
@@map("products")
}
model Purchase {
id Int @id @default(autoincrement())
userId Int @map("user_id")
productId Int @map("product_id")
walletType String? @map("wallet_type")
txHash String? @map("tx_hash")
quantity Int
totalPrice Float @map("total_price")
purchaseDate DateTime @default(now()) @map("purchase_date")
status String @default("pending") // pending/completed/cancelled
user TgUser @relation(fields: [userId], references: [id], onDelete: Cascade)
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
@@map("purchases")
}
model CommissionPayment {
id Int @id @default(autoincrement())
totalBalanceUsd Float @map("total_balance_usd")
commissionRate Float @map("commission_rate")
commissionAmountUsd Float @map("commission_amount_usd")
paidAmountUsd Float @map("paid_amount_usd")
walletCount Int @map("wallet_count")
note String?
createdAt DateTime @default(now()) @map("created_at")
@@map("commission_payments")
}
model AuditLog {
id Int @id @default(autoincrement())
action String
adminId String @map("admin_id")
details String? // JSON string
createdAt DateTime @default(now()) @map("created_at")
@@map("audit_log")
}
// ─── Chatbot & Leads Module ─────────────────────────────────
model ChatSession {
id Int @id @default(autoincrement())
sessionId String @unique @map("session_id")
telegramId String? @map("telegram_id")
leadId Int? @map("lead_id")
messages String // JSON array of {role, content, timestamp}
language String @default("en")
device String?
ip String?
country String?
customerProfile String? @map("customer_profile") // AI-generated profile JSON
isActive Boolean @default(true) @map("is_active")
operatorName String? @map("operator_name")
autoReplyDisabled Boolean @default(false) @map("auto_reply_disabled")
operatorConnectedAt DateTime? @map("operator_connected_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
lead Lead? @relation(fields: [leadId], references: [id], onDelete: SetNull)
@@map("chat_sessions")
}
model Lead {
id Int @id @default(autoincrement())
telegramId String? @unique @map("telegram_id")
name String?
phone String?
email String?
telegram String?
status String @default("new") // new/contacted/qualified/lost/spam
verification String @default("pending")
notes String?
customFields String @default("{}") @map("custom_fields")
geoAddress String? @map("geo_address")
aiLeadScore Float? @map("ai_lead_score")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
chatSessions ChatSession[]
@@map("leads")
}
model SiteSetting {
id Int @id @default(autoincrement())
key String @unique
value String
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @default(now()) @map("updated_at")
@@map("site_settings")
}
model UserState {
chatId String @id @map("chat_id")
stateData String? @map("state_data")
updatedAt Int @map("updated_at")
@@map("user_states")
}