first commit

This commit is contained in:
2026-01-17 14:17:42 +05:30
commit 0f194eb9e7
328 changed files with 73544 additions and 0 deletions

434
prisma/schema.prisma Normal file
View File

@@ -0,0 +1,434 @@
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Account {
id String @id @default(cuid())
userId String
type String
provider String
providerAccountId String
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
}
model Session {
id String @id @default(cuid())
sessionToken String @unique
userId String
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model User {
id String @id @default(cuid())
name String?
email String @unique
emailVerified DateTime?
image String?
password String?
role Role @default(CUSTOMER)
referralCode String @unique @default(cuid())
referrerId String?
phone String?
address String?
joinedAt DateTime @default(now())
isActive Boolean @default(true)
currentRankId String?
// Partner-specific fields
partnerTier String? // 'Diamond', 'Gold', 'Silver'
minReferrals Int @default(3) // Minimum members a partner needs to add
accounts Account[]
sessions Session[]
// Referral relationships
referrer User? @relation("UserReferrals", fields: [referrerId], references: [id])
referrals User[] @relation("UserReferrals")
// Orders and transactions
orders Order[]
commissions Commission[] @relation("UserCommissions")
commissionsFrom Commission[] @relation("UserCommissionsFrom")
payouts Payout[]
wallet Wallet?
// Address management
addresses Address[]
// Rank system
currentRank Rank? @relation(fields: [currentRankId], references: [id])
rankAchievements RankAchievement[]
// Form responses
formResponses FormResponse[]
// Reviews and feedback
reviews Review[]
reviewHelpfulVotes ReviewHelpfulVote[]
reviewReports ReviewReport[]
@@map("users")
}
model VerificationToken {
identifier String
token String @unique
expires DateTime
@@unique([identifier, token])
}
model Category {
id String @id @default(cuid())
name String @unique
description String?
image String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
products Product[]
@@index([isActive])
@@index([name])
@@map("categories")
}
model Product {
id String @id @default(cuid())
name String
description String?
price Float
discount Float @default(0)
images String[]
stock Int @default(0)
manageStock Boolean @default(true)
sku String @unique
slug String @unique
isActive Boolean @default(true)
categoryId String
brand String?
origin String?
weight String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
category Category @relation(fields: [categoryId], references: [id])
orderItems OrderItem[]
reviews Review[]
@@index([isActive])
@@index([categoryId])
@@index([createdAt])
@@index([isActive, stock])
@@index([categoryId, isActive])
@@index([createdAt, isActive])
@@index([isActive, createdAt(sort: Desc)])
@@index([isActive, createdAt(sort: Desc), categoryId])
@@map("products")
}
model Order {
id String @id @default(cuid())
userId String
total Float
status OrderStatus @default(PENDING)
razorpayOrderId String?
razorpayPaymentId String?
shippingAddressId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
orderItems OrderItem[]
shippingAddress Address? @relation(fields: [shippingAddressId], references: [id])
@@map("orders")
}
model OrderItem {
id String @id @default(cuid())
orderId String
productId String
quantity Int
price Float
order Order @relation(fields: [orderId], references: [id])
product Product @relation(fields: [productId], references: [id])
@@map("order_items")
}
model Commission {
id String @id @default(cuid())
userId String
fromUserId String
orderId String
amount Float
level Int
type CommissionType @default(REFERRAL)
status CommissionStatus @default(PENDING)
createdAt DateTime @default(now())
user User @relation("UserCommissions", fields: [userId], references: [id])
fromUser User @relation("UserCommissionsFrom", fields: [fromUserId], references: [id])
@@map("commissions")
}
model Wallet {
id String @id @default(cuid())
userId String @unique
balance Float @default(0)
totalEarnings Float @default(0)
totalWithdrawn Float @default(0)
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@map("wallets")
}
model Payout {
id String @id @default(cuid())
userId String
amount Float
status PayoutStatus @default(PENDING)
bankDetails String?
adminNotes String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
@@map("payouts")
}
model CommissionSettings {
id String @id @default(cuid())
level Int @unique
percentage Float
isActive Boolean @default(true)
@@map("commission_settings")
}
model Address {
id String @id @default(cuid())
userId String
firstName String
lastName String
company String?
address1 String
address2 String?
city String
state String
zipCode String
country String @default("India")
phone String?
isDefault Boolean @default(false)
type AddressType @default(HOME)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
orders Order[]
@@map("addresses")
}
model SystemSettings {
id String @id @default(cuid())
siteName String @default("Padmaaja Rasooi")
siteDescription String @default("Premium quality rice products and grains. Experience the finest rice sourced directly from local farmers.")
supportEmail String @default("info@padmajarice.com")
minimumPayout Float @default(1000)
enableReferrals Boolean @default(true)
enableCommissions Boolean @default(true)
maintenanceMode Boolean @default(false)
allowRegistration Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("system_settings")
}
model Rank {
id String @id @default(cuid())
name String @unique
description String?
minReferrals Int @default(0)
minSalesVolume Float @default(0)
minTeamVolume Float @default(0)
commissionMultiplier Float @default(1.0)
benefits String[]
color String @default("#3B82F6")
icon String @default("🏆")
order Int @unique
isActive Boolean @default(true)
createdAt DateTime @default(now())
users User[]
achievements RankAchievement[]
@@map("ranks")
}
model RankAchievement {
id String @id @default(cuid())
userId String
rankId String
achievedAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
rank Rank @relation(fields: [rankId], references: [id])
@@unique([userId, rankId])
@@map("rank_achievements")
}
enum Role {
ADMIN
MEMBER // For Partners
WHOLESALER // For Wholesale customers
PART_TIME // For those who want part-time job opportunities
CUSTOMER // Regular customers
}
enum OrderStatus {
PENDING
PAID
SHIPPED
DELIVERED
CANCELLED
}
enum CommissionType {
REFERRAL
LEVEL
BONUS
}
enum CommissionStatus {
PENDING
APPROVED
PAID
CANCELLED
}
enum PayoutStatus {
PENDING
APPROVED
REJECTED
PAID
}
enum AddressType {
HOME
WORK
OTHER
}
model FormResponse {
id String @id @default(cuid())
formId String // e.g., "contact", "partnership", "bulk_inquiry"
data Json @db.JsonB // Actual form submission data
status String @default("new")
metadata Json? @db.JsonB // Additional metadata like IP, user agent
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId String? // Optional relation to user if logged in
user User? @relation(fields: [userId], references: [id])
@@index([status])
@@index([userId])
@@index([formId])
@@map("form_responses")
}
model Review {
id String @id @default(cuid())
productId String
userId String
rating Int @default(5) // 1-5 stars
title String?
comment String?
images String[] @default([])
isVerified Boolean @default(false) // Verified purchase
isApproved Boolean @default(false) // Admin approval
helpfulVotes Int @default(0)
reportCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
// Relations for helpful votes and reports
helpfulVotedBy ReviewHelpfulVote[]
reportedBy ReviewReport[]
@@unique([productId, userId]) // One review per user per product
@@index([productId])
@@index([userId])
@@index([rating])
@@index([isApproved])
@@index([createdAt])
@@index([productId, isApproved])
@@index([createdAt, isApproved])
@@index([isApproved, createdAt(sort: Desc)])
@@index([isApproved, createdAt(sort: Desc), productId])
@@map("reviews")
}
model ReviewHelpfulVote {
id String @id @default(cuid())
reviewId String
userId String
review Review @relation(fields: [reviewId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([reviewId, userId])
@@map("review_helpful_votes")
}
model ReviewReport {
id String @id @default(cuid())
reviewId String
userId String
reason ReportReason
comment String?
createdAt DateTime @default(now())
review Review @relation(fields: [reviewId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([reviewId, userId])
@@map("review_reports")
}
enum ReportReason {
SPAM
INAPPROPRIATE
FAKE
OFFENSIVE
OTHER
}

410
prisma/seed-padmaaja.ts Normal file
View File

@@ -0,0 +1,410 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function seedPadmaajaRasooi() {
console.log('🌾 Seeding Padmaaja Rasooi database...')
// Create Categories for Food Products
const flourCategory = await prisma.category.upsert({
where: { name: 'Flour & Grains' },
update: {},
create: {
name: 'Flour & Grains',
description: 'Premium quality flours and grain products for healthy cooking',
image: '/images/categories/flour.jpg',
isActive: true
}
})
const riceCategory = await prisma.category.upsert({
where: { name: 'Rice & Cereals' },
update: {},
create: {
name: 'Rice & Cereals',
description: 'Authentic basmati and non-basmati rice varieties',
image: '/images/categories/rice.jpg',
isActive: true
}
})
const spicesCategory = await prisma.category.upsert({
where: { name: 'Spices & Seasonings' },
update: {},
create: {
name: 'Spices & Seasonings',
description: 'Traditional spice blends and pure spices',
image: '/images/categories/spices.jpg',
isActive: true
}
})
const pulsesCategory = await prisma.category.upsert({
where: { name: 'Pulses & Legumes' },
update: {},
create: {
name: 'Pulses & Legumes',
description: 'Organic dals and pulses rich in protein',
image: '/images/categories/pulses.jpg',
isActive: true
}
})
console.log('📂 Categories created successfully')
// Create Food Products
// Flour Products
await prisma.product.upsert({
where: { sku: 'PD-FLOUR-001' },
update: {},
create: {
name: 'SHREE AAHAR Multigrain Flour',
description: 'Premium multigrain flour made from wheat, jowar, bajra, ragi, and other nutritious grains. Perfect for making healthy rotis, parathas, and other Indian breads. Rich in fiber, protein, and essential nutrients for wholesome family nutrition.',
price: 150.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1574323347407-f5e1ad6d020b?w=600&h=400&fit=crop&crop=center',
'https://images.unsplash.com/photo-1509440159596-0249088772ff?w=600&h=400&fit=crop&crop=center'
],
stock: 500,
sku: 'PD-FLOUR-001',
slug: 'shree-aahar-multigrain-flour',
isActive: true,
categoryId: flourCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-FLOUR-002' },
update: {},
create: {
name: 'Premium Whole Wheat Flour',
description: 'Pure whole wheat flour ground from carefully selected wheat grains. Stone-ground to preserve natural nutrients and fiber. Ideal for daily cooking and baking needs.',
price: 80.00,
discount: 5,
images: [
'https://images.unsplash.com/photo-1594736797933-d0d6483cae4d?w=600&h=400&fit=crop&crop=center'
],
stock: 750,
sku: 'PD-FLOUR-002',
slug: 'premium-whole-wheat-flour',
isActive: true,
categoryId: flourCategory.id
}
})
// Rice Products - Based on Rate List Rice 1121
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-001' },
update: {},
create: {
name: 'Premium Basmati Rice 1121 - Extra Long Grain',
description: 'Finest quality aged basmati rice 1121 variety with extra-long grains and distinctive aroma. Naturally aged for 12+ months for superior taste and texture. Perfect for biryanis, pulavs, and special occasions.',
price: 250.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1586201375761-83865001e31c?w=600&h=400&fit=crop&crop=center',
'https://images.unsplash.com/photo-1536304993881-ff6e9eefa2a6?w=600&h=400&fit=crop&crop=center'
],
stock: 300,
sku: 'PD-RICE-1121-001',
slug: 'premium-basmati-rice-1121-extra-long',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-002' },
update: {},
create: {
name: 'Basmati Rice 1121 - Steam Processed',
description: 'Steam processed basmati rice 1121 with enhanced shelf life and consistent quality. Perfect for daily cooking and commercial use. Maintains the authentic basmati aroma and taste.',
price: 220.00,
discount: 5,
images: [
'https://images.unsplash.com/photo-1586201375761-83865001e31c?w=600&h=400&fit=crop&crop=center'
],
stock: 500,
sku: 'PD-RICE-1121-002',
slug: 'basmati-rice-1121-steam-processed',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-003' },
update: {},
create: {
name: 'Basmati Rice 1121 - Sella (Parboiled)',
description: 'Parboiled basmati rice 1121 with golden color and enhanced nutritional value. Partially boiled in the husk to retain nutrients. Excellent for biryanis and festive cooking.',
price: 240.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1536304993881-ff6e9eefa2a6?w=600&h=400&fit=crop&crop=center'
],
stock: 400,
sku: 'PD-RICE-1121-003',
slug: 'basmati-rice-1121-sella-parboiled',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-004' },
update: {},
create: {
name: 'Basmati Rice 1121 - White Sella',
description: 'White sella basmati rice 1121 with creamy white appearance and excellent cooking properties. Ideal for premium restaurants and households seeking restaurant-quality rice.',
price: 260.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1516684669134-de6f7c473a2a?w=600&h=400&fit=crop&crop=center'
],
stock: 350,
sku: 'PD-RICE-1121-004',
slug: 'basmati-rice-1121-white-sella',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-005' },
update: {},
create: {
name: 'Basmati Rice 1121 - Golden Sella',
description: 'Golden sella basmati rice 1121 with rich golden color and enhanced taste. Steam processing retains natural nutrients while ensuring longer shelf life.',
price: 270.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1586201375761-83865001e31c?w=600&h=400&fit=crop&crop=center'
],
stock: 300,
sku: 'PD-RICE-1121-005',
slug: 'basmati-rice-1121-golden-sella',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-1121-006' },
update: {},
create: {
name: 'Basmati Rice 1121 - Broken (25% Broken)',
description: 'Premium quality broken basmati rice 1121 (25% broken) ideal for daily consumption at economical rates. Maintains the basmati flavor at affordable pricing.',
price: 180.00,
discount: 10,
images: [
'https://images.unsplash.com/photo-1516684669134-de6f7c473a2a?w=600&h=400&fit=crop&crop=center'
],
stock: 600,
sku: 'PD-RICE-1121-006',
slug: 'basmati-rice-1121-broken-25-percent',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-NON-BASMATI-001' },
update: {},
create: {
name: 'Non-Basmati Rice - IR64 Variety',
description: 'High-quality IR64 non-basmati rice variety suitable for daily consumption. Good texture, taste, and cooking properties. Ideal for households and commercial use.',
price: 85.00,
discount: 10,
images: [
'https://images.unsplash.com/photo-1516684669134-de6f7c473a2a?w=600&h=400&fit=crop&crop=center'
],
stock: 800,
sku: 'PD-RICE-NON-BASMATI-001',
slug: 'non-basmati-rice-ir64-variety',
isActive: true,
categoryId: riceCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-RICE-NON-BASMATI-002' },
update: {},
create: {
name: 'Non-Basmati Rice - Swarna Variety',
description: 'Premium Swarna variety non-basmati rice with excellent cooking properties and nutritional value. Popular choice for daily meals across Indian households.',
price: 90.00,
discount: 5,
images: [
'https://images.unsplash.com/photo-1516684669134-de6f7c473a2a?w=600&h=400&fit=crop&crop=center'
],
stock: 700,
sku: 'PD-RICE-NON-BASMATI-002',
slug: 'non-basmati-rice-swarna-variety',
isActive: true,
categoryId: riceCategory.id
}
})
// Spice Products
await prisma.product.upsert({
where: { sku: 'PD-SPICE-001' },
update: {},
create: {
name: 'Traditional Garam Masala',
description: 'Authentic garam masala blend prepared using traditional family recipes. Made from carefully selected and ground spices including cardamom, cinnamon, cloves, and black pepper for perfect aroma and taste.',
price: 120.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1596040033229-a9821ebd058d?w=600&h=400&fit=crop&crop=center'
],
stock: 200,
sku: 'PD-SPICE-001',
slug: 'traditional-garam-masala',
isActive: true,
categoryId: spicesCategory.id
}
})
await prisma.product.upsert({
where: { sku: 'PD-SPICE-002' },
update: {},
create: {
name: 'Pure Turmeric Powder',
description: 'Premium quality turmeric powder made from fresh turmeric roots. Rich in curcumin and natural antioxidants. Essential for Indian cooking and known for its health benefits.',
price: 90.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1615485290382-441e4d049cb5?w=600&h=400&fit=crop&crop=center'
],
stock: 350,
sku: 'PD-SPICE-002',
slug: 'pure-turmeric-powder',
isActive: true,
categoryId: spicesCategory.id
}
})
// Pulses Products
await prisma.product.upsert({
where: { sku: 'PD-PULSE-001' },
update: {},
create: {
name: 'Organic Toor Dal',
description: 'Premium quality organic toor dal (pigeon peas) sourced directly from certified organic farms. Rich in protein and dietary fiber. Chemical-free and naturally grown without pesticides.',
price: 140.00,
discount: 0,
images: [
'https://images.unsplash.com/photo-1559181567-c3190ca9959b?w=600&h=400&fit=crop&crop=center'
],
stock: 250,
sku: 'PD-PULSE-001',
slug: 'organic-toor-dal',
isActive: true,
categoryId: pulsesCategory.id
}
})
console.log('🍚 Food products created successfully')
// Update System Settings for Padmaaja Rasooi
await prisma.systemSettings.upsert({
where: { id: 'padmaaja-system' },
update: {},
create: {
id: 'padmaaja-system',
siteName: 'Padmaaja Rasooi',
siteDescription: 'Authentic Indian Food Products - Preserving Traditional Flavors with Modern Quality Standards',
supportEmail: 'info@padmajarice.com',
minimumPayout: 1000,
enableReferrals: true,
enableCommissions: true,
maintenanceMode: false,
allowRegistration: true
}
})
// Create Marketing Partnership Commission Settings
const commissionLevels = [
{ level: 1, percentage: 8.0 }, // Direct referral
{ level: 2, percentage: 4.0 }, // Second level
{ level: 3, percentage: 2.0 }, // Third level
{ level: 4, percentage: 1.0 }, // Fourth level
{ level: 5, percentage: 0.5 } // Fifth level
]
for (const commission of commissionLevels) {
await prisma.commissionSettings.upsert({
where: { level: commission.level },
update: {},
create: {
level: commission.level,
percentage: commission.percentage,
isActive: true
}
})
}
// Create Marketing Partnership Ranks
const partnershipRanks = [
{
name: 'Silver Partner',
description: 'Entry level marketing partnership with basic benefits',
minReferrals: 0,
minSalesVolume: 5000,
minTeamVolume: 15000,
commissionMultiplier: 1.0,
benefits: ['Standard commission rates', 'Basic marketing materials', 'Email support'],
color: '#C0C0C0',
icon: '🥈',
order: 1
},
{
name: 'Gold Partner',
description: 'Intermediate partnership level with enhanced benefits',
minReferrals: 5,
minSalesVolume: 15000,
minTeamVolume: 50000,
commissionMultiplier: 1.2,
benefits: ['Enhanced commissions', 'Premium marketing materials', 'Priority support', 'Training access'],
color: '#FFD700',
icon: '🥇',
order: 2
},
{
name: 'Diamond Partner',
description: 'Premium partnership level with maximum benefits',
minReferrals: 15,
minSalesVolume: 50000,
minTeamVolume: 150000,
commissionMultiplier: 1.5,
benefits: ['Maximum commissions', 'Exclusive products', 'Dedicated support', 'Leadership bonuses', 'Custom branding'],
color: '#B9F2FF',
icon: '💎',
order: 3
}
]
for (const rank of partnershipRanks) {
await prisma.rank.upsert({
where: { name: rank.name },
update: {},
create: rank
})
}
console.log('🏆 Marketing partnership ranks created successfully')
console.log('✅ Padmaaja Rasooi database seeded successfully!')
}
// Run the seed function
seedPadmaajaRasooi()
.catch((e) => {
console.error('❌ Error seeding database:', e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})

202
prisma/seed-products.ts Normal file
View File

@@ -0,0 +1,202 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function seedProducts() {
console.log('🌾 Seeding Kashmina products...')
try {
// First, delete all existing products
console.log('🗑️ Deleting existing products...')
await prisma.orderItem.deleteMany({})
await prisma.product.deleteMany({})
// Ensure rice category exists
const riceCategory = await prisma.category.upsert({
where: { name: 'Rice & Cereals' },
update: {},
create: {
name: 'Rice & Cereals',
description: 'Premium Basmati and specialty rice varieties sourced directly from Haryanai farmers',
image: '/images/categories/rice.jpg',
isActive: true
}
})
console.log('📦 Creating rice products with weight variations...')
// Product data based on the attached price sheet with proper per-kg calculations
const riceProducts = [
// KASHMINA STEAM
{
baseName: 'Kashmina Steam Grade-1',
description: 'Superior Grade-1 Kashmina Steam rice with perfect steam processing for enhanced aroma and taste.',
marketRatePerKg: 116, // Updated rate
companyRatePerKg: 116, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Steam Dubar',
description: 'High-quality Dubar grade Kashmina Steam rice perfect for everyday cooking needs.',
marketRatePerKg: 68, // Updated rate
companyRatePerKg: 68, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Steam Tibar',
description: 'Premium Tibar grade Kashmina Steam rice with excellent texture and cooking properties.',
marketRatePerKg: 78, // Updated rate
companyRatePerKg: 78, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
// KASHMINA SELLA
{
baseName: 'Kashmina Sella Grade-1',
description: 'Premium Grade-1 Kashmina Sella rice with perfect texture and aroma. Ideal for biryani and special occasions.',
marketRatePerKg: 104, // Updated rate
companyRatePerKg: 104, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Sella Tibar',
description: 'High-quality Tibar grade Kashmina Sella rice with excellent cooking properties and authentic taste.',
marketRatePerKg: 72, // Updated rate
companyRatePerKg: 72, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Sella Dubar',
description: 'Premium Dubar grade Kashmina Sella rice perfect for everyday cooking and special meals.',
marketRatePerKg: 65, // Updated rate
companyRatePerKg: 65, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
// KASHMINA GOLDEN
{
baseName: 'Kashmina Golden Grade-1',
description: 'Exquisite Grade-1 Kashmina Golden rice with rich golden color and superior quality. Perfect for special occasions.',
marketRatePerKg: 109, // Updated rate
companyRatePerKg: 109, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Golden Tibar',
description: 'Premium Tibar grade Kashmina Golden rice with authentic golden hue and exceptional flavor.',
marketRatePerKg: 74, // Updated rate
companyRatePerKg: 74, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
},
{
baseName: 'Kashmina Golden Dubar',
description: 'High-quality Dubar grade Kashmina Golden rice ideal for daily cooking and family meals.',
marketRatePerKg: 66, // Updated rate
companyRatePerKg: 66, // Company rate same as market rate
origin: 'Haryana, India',
brand: 'Kashmina'
}
]
// Images for different weight variations
const image5kg = 'https://4m5m4tx28rtva30c.public.blob.vercel-storage.com/media/2025-09-07/Kashmina%20Rice%205KG.png-1757220648279'
const image30kg = 'https://4m5m4tx28rtva30c.public.blob.vercel-storage.com/media/2025-09-07/Kashmina%20Rice%2030KG.png-1757220559950'
// Create products with only 5kg and 30kg variations
for (const product of riceProducts) {
// Calculate prices for different weights
const price5kg = product.companyRatePerKg * 5
const price30kg = product.companyRatePerKg * 30
// Create 5kg variant
const product5kg = await prisma.product.create({
data: {
name: `${product.baseName} - 5kg`,
description: `${product.description} Available in convenient 5kg packaging for household use.`,
price: price5kg,
discount: 0, // No discount
images: [image5kg],
stock: 100,
manageStock: false,
sku: `${product.baseName.toLowerCase().replace(/[^a-z0-9]/g, '')}-5kg`,
slug: `${product.baseName.toLowerCase().replace(/[^a-z0-9]/g, '-')}-5kg`,
isActive: true,
categoryId: riceCategory.id,
brand: product.brand,
origin: product.origin,
weight: '5kg'
}
})
// Create 30kg variant
const product30kg = await prisma.product.create({
data: {
name: `${product.baseName} - 30kg`,
description: `${product.description} Available in bulk 30kg packaging for restaurants, hotels, and wholesale buyers.`,
price: price30kg,
discount: 0, // No discount
images: [image30kg],
stock: 50,
manageStock: false,
sku: `${product.baseName.toLowerCase().replace(/[^a-z0-9]/g, '')}-30kg`,
slug: `${product.baseName.toLowerCase().replace(/[^a-z0-9]/g, '-')}-30kg`,
isActive: true,
categoryId: riceCategory.id,
brand: product.brand,
origin: product.origin,
weight: '30kg'
}
})
console.log(`✅ Created: ${product5kg.name} (₹${product5kg.price}) - Per kg: ₹${product.companyRatePerKg}`)
console.log(`✅ Created: ${product30kg.name} (₹${product30kg.price}) - Per kg: ₹${product.companyRatePerKg}`)
}
const productCount = await prisma.product.count()
console.log(`🎉 Successfully created ${productCount} products!`)
// Display summary
console.log('\n📊 Product Summary:')
console.log('==================')
const productsByWeight = await prisma.product.groupBy({
by: ['weight'],
_count: {
id: true
}
})
for (const group of productsByWeight) {
console.log(`${group.weight}: ${group._count.id} products`)
}
console.log('\n✨ Products seeding completed successfully!')
} catch (error) {
console.error('❌ Error seeding products:', error)
throw error
}
}
async function main() {
await seedProducts()
}
main()
.catch((e) => {
console.error(e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})
export default seedProducts

223
prisma/seed.ts Normal file
View File

@@ -0,0 +1,223 @@
import { PrismaClient } from '@prisma/client'
import { faker } from '@faker-js/faker'
import { rankSystem } from '@/lib/ranks'
const prisma = new PrismaClient()
const categories = [
{
name: 'Health & Wellness',
description: 'Premium health and wellness products for optimal living'
},
{
name: 'Beauty & Skincare',
description: 'Natural and organic beauty products for radiant skin'
},
{
name: 'Nutrition & Supplements',
description: 'High-quality nutritional supplements and vitamins'
},
{
name: 'Fitness & Sports',
description: 'Performance products for active lifestyles'
},
{
name: 'Personal Care',
description: 'Daily essentials for personal hygiene and care'
},
{
name: 'Home & Lifestyle',
description: 'Premium products for modern living'
}
]
const productTemplates = [
// Health & Wellness
{ namePrefix: 'Organic', nameSuffix: ['Detox Tea', 'Green Tea', 'Herbal Blend', 'Immune Booster'] },
{ namePrefix: 'Natural', nameSuffix: ['Energy Drink', 'Wellness Tonic', 'Health Elixir', 'Vitality Boost'] },
{ namePrefix: 'Premium', nameSuffix: ['Superfood Powder', 'Antioxidant Complex', 'Immunity Support', 'Daily Greens'] },
// Beauty & Skincare
{ namePrefix: 'Radiant', nameSuffix: ['Face Serum', 'Night Cream', 'Eye Cream', 'Moisturizer'] },
{ namePrefix: 'Glow', nameSuffix: ['Facial Cleanser', 'Toner', 'Face Mask', 'Exfoliator'] },
{ namePrefix: 'Youth', nameSuffix: ['Anti-Aging Cream', 'Collagen Serum', 'Wrinkle Reducer', 'Firming Lotion'] },
// Nutrition & Supplements
{ namePrefix: 'Power', nameSuffix: ['Protein Powder', 'Multivitamin', 'Omega-3', 'Probiotics'] },
{ namePrefix: 'Elite', nameSuffix: ['Pre-Workout', 'BCAA Complex', 'Creatine Formula', 'Recovery Blend'] },
{ namePrefix: 'Pure', nameSuffix: ['Vitamin D3', 'Magnesium', 'Zinc Complex', 'B-Complex'] },
// Fitness & Sports
{ namePrefix: 'Athletic', nameSuffix: ['Performance Drink', 'Energy Bar', 'Recovery Shake', 'Endurance Formula'] },
{ namePrefix: 'Sport', nameSuffix: ['Electrolyte Mix', 'Protein Bar', 'Hydration Pack', 'Energy Gel'] },
// Personal Care
{ namePrefix: 'Fresh', nameSuffix: ['Body Wash', 'Shampoo', 'Conditioner', 'Deodorant'] },
{ namePrefix: 'Pure', nameSuffix: ['Toothpaste', 'Mouthwash', 'Hand Sanitizer', 'Body Lotion'] },
// Home & Lifestyle
{ namePrefix: 'Eco', nameSuffix: ['Cleaning Spray', 'Laundry Detergent', 'Dish Soap', 'Air Freshener'] },
{ namePrefix: 'Smart', nameSuffix: ['Essential Oil', 'Diffuser Blend', 'Room Spray', 'Candle'] }
]
const healthDescriptions = [
'Boost your immune system naturally with this powerful blend of organic ingredients.',
'Experience enhanced vitality and energy with our premium formulation.',
'Support your wellness journey with this scientifically-backed supplement.',
'Detoxify and rejuvenate your body with natural, plant-based ingredients.',
'Maintain optimal health with this carefully crafted nutritional supplement.'
]
const beautyDescriptions = [
'Transform your skin with this luxurious, age-defying formula.',
'Achieve radiant, youthful-looking skin with natural ingredients.',
'Nourish and protect your skin with this premium skincare solution.',
'Experience the power of nature in this scientifically-formulated product.',
'Reveal your natural beauty with this gentle yet effective treatment.'
]
const fitnessDescriptions = [
'Fuel your workouts and achieve peak performance with this advanced formula.',
'Support muscle recovery and growth with premium quality ingredients.',
'Enhance your athletic performance and endurance naturally.',
'Optimize your fitness journey with this scientifically-designed supplement.',
'Power through your workouts with sustained energy and focus.'
]
const getRandomDescription = (categoryName: string): string => {
switch (categoryName.toLowerCase()) {
case 'health & wellness':
case 'nutrition & supplements':
return faker.helpers.arrayElement(healthDescriptions)
case 'beauty & skincare':
case 'personal care':
return faker.helpers.arrayElement(beautyDescriptions)
case 'fitness & sports':
return faker.helpers.arrayElement(fitnessDescriptions)
default:
return faker.commerce.productDescription()
}
}
const generateProductImages = (): string[] => {
const imageCount = faker.number.int({ min: 1, max: 4 })
const images: string[] = []
for (let i = 0; i < imageCount; i++) {
images.push(`https://images.unsplash.com/photo-${faker.number.int({ min: 1500000000000, max: 1700000000000 })}?w=800&h=600&fit=crop`)
}
return images
}
const generateProductSlug = (name: string): string => {
return name
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, '') // Remove special characters
.replace(/\s+/g, '-') // Replace spaces with hyphens
.replace(/-+/g, '-') // Replace multiple hyphens with single
.trim()
}
async function main() {
console.log('🌱 Starting database seeding...')
// Clear existing data
console.log('🧹 Clearing existing data...')
await prisma.product.deleteMany()
await prisma.category.deleteMany()
await prisma.commissionSettings.deleteMany()
// Create commission settings
console.log('💰 Creating commission settings...')
await prisma.commissionSettings.createMany({
data: [
{ level: 1, percentage: 10, isActive: true },
{ level: 2, percentage: 5, isActive: true },
{ level: 3, percentage: 3, isActive: true },
{ level: 4, percentage: 2, isActive: true },
{ level: 5, percentage: 1, isActive: true }
]
})
// Create categories
console.log('📂 Creating categories...')
const createdCategories = []
for (const category of categories) {
const createdCategory = await prisma.category.create({
data: {
name: category.name,
description: category.description
}
})
createdCategories.push(createdCategory)
}
// Create products
console.log('📦 Creating products...')
const productsToCreate = 120 // 20 products per category
for (let i = 0; i < productsToCreate; i++) {
const category = faker.helpers.arrayElement(createdCategories)
const template = faker.helpers.arrayElement(productTemplates)
const productName = `${template.namePrefix} ${faker.helpers.arrayElement(template.nameSuffix)}`
const basePrice = faker.number.float({ min: 19.99, max: 299.99, multipleOf: 0.01 })
const discount = faker.number.int({ min: 0, max: 40 })
await prisma.product.create({
data: {
name: productName,
description: getRandomDescription(category.name),
price: basePrice,
discount: discount,
images: generateProductImages(),
stock: faker.number.int({ min: 0, max: 500 }),
sku: faker.string.alphanumeric({ length: 8, casing: 'upper' }),
slug: generateProductSlug(productName) + '-' + faker.string.alphanumeric({ length: 4, casing: 'lower' }),
categoryId: category.id,
isActive: faker.datatype.boolean({ probability: 0.9 }), // 90% active products
createdAt: faker.date.between({
from: new Date('2023-01-01'),
to: new Date()
})
}
})
if ((i + 1) % 20 === 0) {
console.log(`✅ Created ${i + 1} products...`)
}
}
// Initialize rank system
console.log('🏆 Initializing rank system...')
await rankSystem.initializeDefaultRanks()
// Get final counts
const categoryCount = await prisma.category.count()
const productCount = await prisma.product.count()
const commissionCount = await prisma.commissionSettings.count()
console.log('\n🎉 Seeding completed successfully!')
console.log(`📂 Categories created: ${categoryCount}`)
console.log(`📦 Products created: ${productCount}`)
console.log(`💰 Commission levels created: ${commissionCount}`)
console.log('\n📊 Products per category:')
for (const category of createdCategories) {
const count = await prisma.product.count({
where: { categoryId: category.id }
})
console.log(` ${category.name}: ${count} products`)
}
}
main()
.catch((e) => {
console.error('❌ Error during seeding:', e)
process.exit(1)
})
.finally(async () => {
await prisma.$disconnect()
})