localgreenchain/prisma/schema.prisma
Claude b3c2af51bf
Implement marketplace foundation (Agent 9)
Add comprehensive plant trading marketplace with:
- Prisma schema with marketplace models (Listing, Offer, SellerProfile, WishlistItem)
- Service layer for listings, offers, search, and matching
- API endpoints for CRUD operations, search, and recommendations
- Marketplace pages: home, listing detail, create, my-listings, my-offers
- Reusable UI components: ListingCard, ListingGrid, OfferForm, SearchFilters, etc.

Features:
- Browse and search listings by category, price, tags
- Create and manage listings (draft, active, sold, cancelled)
- Make and manage offers on listings
- Seller and buyer views with statistics
- Featured and recommended listings
- In-memory store (ready for database migration via Agent 2)
2025-11-23 03:58:08 +00:00

284 lines
6.9 KiB
Text

// Prisma Schema for LocalGreenChain
// Note: This requires Agent 2 (Database) to set up the database connection
// For now, marketplace uses in-memory storage in lib/marketplace/store.ts
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ===========================================
// User & Authentication Models (Agent 1)
// ===========================================
enum Role {
USER
GROWER
SELLER
ADMIN
}
model User {
id String @id @default(cuid())
email String @unique
emailVerified DateTime?
passwordHash String?
name String?
image String?
role Role @default(USER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
plants Plant[]
farms VerticalFarm[]
listings Listing[]
offers Offer[]
wishlistItems WishlistItem[]
sellerProfile SellerProfile?
auditLogs AuditLog[]
}
// ===========================================
// Plant & Blockchain Models
// ===========================================
model Plant {
id String @id @default(cuid())
name String
species String
variety String?
parentId String?
generation Int @default(1)
registeredAt DateTime @default(now())
ownerId String
locationLat Float?
locationLng Float?
blockHash String?
owner User @relation(fields: [ownerId], references: [id])
parent Plant? @relation("PlantLineage", fields: [parentId], references: [id])
children Plant[] @relation("PlantLineage")
transportEvents TransportEvent[]
environmentRecords EnvironmentRecord[]
listings Listing[]
}
model TransportEvent {
id String @id @default(cuid())
plantId String
eventType String
fromLat Float?
fromLng Float?
toLat Float?
toLng Float?
distance Float?
carbonKg Float?
timestamp DateTime @default(now())
metadata Json?
plant Plant @relation(fields: [plantId], references: [id])
}
model EnvironmentRecord {
id String @id @default(cuid())
plantId String
temperature Float?
humidity Float?
light Float?
soilMoisture Float?
recordedAt DateTime @default(now())
plant Plant @relation(fields: [plantId], references: [id])
}
// ===========================================
// Vertical Farm Models
// ===========================================
model VerticalFarm {
id String @id @default(cuid())
name String
ownerId String
totalArea Float
zones Int
createdAt DateTime @default(now())
owner User @relation(fields: [ownerId], references: [id])
farmZones FarmZone[]
batches CropBatch[]
}
model FarmZone {
id String @id @default(cuid())
farmId String
name String
area Float
lightType String
status String
farm VerticalFarm @relation(fields: [farmId], references: [id])
batches CropBatch[]
}
model CropBatch {
id String @id @default(cuid())
farmId String
zoneId String
cropType String
plantedAt DateTime @default(now())
harvestedAt DateTime?
status String
farm VerticalFarm @relation(fields: [farmId], references: [id])
zone FarmZone @relation(fields: [zoneId], references: [id])
}
// ===========================================
// Marketplace Models (Agent 9)
// ===========================================
enum ListingCategory {
seeds
seedlings
mature_plants
cuttings
produce
supplies
}
enum ListingStatus {
draft
active
sold
expired
cancelled
}
enum OfferStatus {
pending
accepted
rejected
withdrawn
expired
}
model Listing {
id String @id @default(cuid())
sellerId String
plantId String?
title String
description String @db.Text
price Decimal @db.Decimal(10, 2)
currency String @default("USD")
quantity Int
category ListingCategory
status ListingStatus @default(draft)
locationLat Float?
locationLng Float?
locationCity String?
locationRegion String?
tags String[]
viewCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
seller User @relation(fields: [sellerId], references: [id])
plant Plant? @relation(fields: [plantId], references: [id])
offers Offer[]
images ListingImage[]
wishlistItems WishlistItem[]
@@index([sellerId])
@@index([category])
@@index([status])
@@index([createdAt])
}
model ListingImage {
id String @id @default(cuid())
listingId String
url String
alt String?
isPrimary Boolean @default(false)
createdAt DateTime @default(now())
listing Listing @relation(fields: [listingId], references: [id], onDelete: Cascade)
@@index([listingId])
}
model Offer {
id String @id @default(cuid())
listingId String
buyerId String
amount Decimal @db.Decimal(10, 2)
message String? @db.Text
status OfferStatus @default(pending)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
listing Listing @relation(fields: [listingId], references: [id])
buyer User @relation(fields: [buyerId], references: [id])
@@index([listingId])
@@index([buyerId])
@@index([status])
}
model SellerProfile {
id String @id @default(cuid())
userId String @unique
displayName String
bio String? @db.Text
locationCity String?
locationRegion String?
rating Float @default(0)
reviewCount Int @default(0)
totalSales Int @default(0)
verified Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id])
}
model WishlistItem {
id String @id @default(cuid())
userId String
listingId String
addedAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
listing Listing @relation(fields: [listingId], references: [id], onDelete: Cascade)
@@unique([userId, listingId])
@@index([userId])
}
// ===========================================
// Transparency & Audit Models
// ===========================================
model AuditLog {
id String @id @default(cuid())
userId String?
action String
entityType String
entityId String
details Json?
ipAddress String?
userAgent String?
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id])
@@index([entityType, entityId])
@@index([createdAt])
}