2229 lines
58 KiB
Plaintext
2229 lines
58 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
phone String?
|
|
name String
|
|
role UserRole
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer?
|
|
buyer Buyer?
|
|
administrator Administrator?
|
|
notifications NotificationRecipient[]
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
model Farmer {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
farmerCode String @unique
|
|
name String
|
|
phone String?
|
|
email String?
|
|
dateOfBirth DateTime?
|
|
gender Gender?
|
|
maritalStatus MaritalStatus?
|
|
spouseName String?
|
|
numberOfChildren Int? @default(0)
|
|
religionId String?
|
|
religion Religion? @relation(fields: [religionId], references: [id])
|
|
nationalityId String? @default("indonesia")
|
|
nationality Country? @relation("FarmerNationality", fields: [nationalityId], references: [id])
|
|
address String?
|
|
village String?
|
|
district String?
|
|
province String?
|
|
postalCode String?
|
|
countryId String? @default("indonesia")
|
|
country Country? @relation("FarmerCountry", fields: [countryId], references: [id])
|
|
|
|
// Location data
|
|
latitude Float?
|
|
longitude Float?
|
|
addressGeoJson Json? // GeoJSON point for precise location
|
|
|
|
// Identity information
|
|
identityType IdentityType?
|
|
identityNumber String?
|
|
identityExpiry DateTime?
|
|
|
|
// Banking information
|
|
bankAccount String?
|
|
bankName String?
|
|
accountHolderName String?
|
|
|
|
// Photos and attachments
|
|
profilePhotoUrl String?
|
|
idCardFrontUrl String?
|
|
idCardBackUrl String?
|
|
|
|
// Verification status
|
|
isVerified Boolean @default(false)
|
|
verificationDate DateTime?
|
|
verifiedBy String? // admin ID who verified
|
|
verificationNotes String?
|
|
|
|
// Farming experience
|
|
farmingExperience Int? // years of experience
|
|
educationLevelId String?
|
|
educationLevel EducationLevel? @relation(fields: [educationLevelId], references: [id])
|
|
occupation String? // primary occupation if not full-time farmer
|
|
monthlyIncome Decimal? // estimated monthly income
|
|
landOwnership LandOwnership?
|
|
primaryCrop String?
|
|
farmingMethods String[] // organic, conventional, etc.
|
|
hasVehicle Boolean? // for transportation
|
|
vehicleType String? // motorcycle, car, truck, etc.
|
|
hasSmartphone Boolean? @default(true)
|
|
internetAccess Boolean? @default(true)
|
|
|
|
// Emergency contact
|
|
emergencyContactName String?
|
|
emergencyContactPhone String?
|
|
emergencyContactRelation String?
|
|
|
|
// Status and metadata
|
|
status FarmerStatus @default(ACTIVE)
|
|
notes String?
|
|
joinedAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
farms Farm[]
|
|
trainings FarmerTraining[]
|
|
certifications FarmerCertification[]
|
|
procurements Procurement[]
|
|
harvests Harvest[]
|
|
attachments FarmerAttachment[]
|
|
workers FarmWorker[]
|
|
laborRecords LaborRecord[]
|
|
laborSchedules LaborSchedule[]
|
|
equipment Equipment[]
|
|
assets Asset[]
|
|
financialRecords FinancialRecord[]
|
|
reviews BuyerReview[]
|
|
contracts Contract[]
|
|
seasonHarvests SeasonHarvest[]
|
|
|
|
@@map("farmers")
|
|
}
|
|
|
|
model Buyer {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
buyerCode String @unique
|
|
name String
|
|
company String?
|
|
phone String?
|
|
email String?
|
|
address String?
|
|
|
|
// Enhanced buyer details
|
|
buyerType BuyerType?
|
|
businessLicense String?
|
|
taxNumber String?
|
|
contactPerson String?
|
|
contactPersonPhone String?
|
|
paymentTerms Int? // days
|
|
creditLimit Decimal?
|
|
preferredProducts String[]
|
|
qualityRequirements String?
|
|
|
|
// Location and logistics
|
|
warehouseAddress String?
|
|
deliveryPreference String?
|
|
operatingRadius Decimal? // km
|
|
|
|
// Business details
|
|
businessSize BusinessSize?
|
|
yearEstablished Int?
|
|
annualVolume Decimal? // estimated annual purchase volume
|
|
employeeCount Int?
|
|
website String?
|
|
|
|
// Financial information
|
|
bankAccount String?
|
|
bankName String?
|
|
accountHolderName String?
|
|
|
|
// Verification and status
|
|
isVerified Boolean @default(false)
|
|
verificationDate DateTime?
|
|
verifiedBy String? // admin ID who verified
|
|
verificationNotes String?
|
|
status BuyerStatus @default(ACTIVE)
|
|
|
|
// Photos and documents
|
|
profilePhotoUrl String?
|
|
businessLicenseUrl String?
|
|
taxCertificateUrl String?
|
|
|
|
// Preferences
|
|
preferredPickupDays String[] // Mon, Tue, Wed, etc.
|
|
preferredPickupTime String?
|
|
minimumOrderQuantity Decimal?
|
|
maximumOrderQuantity Decimal?
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
procurements Procurement[]
|
|
reviews BuyerReview[]
|
|
contracts Contract[]
|
|
|
|
@@map("buyers")
|
|
}
|
|
|
|
model Administrator {
|
|
id String @id @default(cuid())
|
|
userId String @unique
|
|
adminCode String @unique
|
|
name String
|
|
phone String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("administrators")
|
|
}
|
|
|
|
model Farm {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
farmCode String @unique
|
|
name String
|
|
address String?
|
|
village String?
|
|
district String?
|
|
province String?
|
|
postalCode String?
|
|
area Decimal? // in hectares
|
|
|
|
// Location data
|
|
latitude Float?
|
|
longitude Float?
|
|
boundaries Json? // GeoJSON polygon for farm boundaries
|
|
elevation Float? // meters above sea level
|
|
|
|
// Farm characteristics
|
|
soilType String?
|
|
soilPH Float?
|
|
waterSource WaterSource?
|
|
irrigationType IrrigationType?
|
|
slope SlopeType?
|
|
climate ClimateType?
|
|
|
|
// Infrastructure
|
|
hasElectricity Boolean? @default(false)
|
|
hasWaterAccess Boolean? @default(false)
|
|
hasStorageFacility Boolean? @default(false)
|
|
hasProcessingUnit Boolean? @default(false)
|
|
accessRoadType RoadType?
|
|
|
|
// Photos and documentation
|
|
mainPhotoUrl String?
|
|
aerialPhotoUrl String?
|
|
soilPhotoUrl String?
|
|
|
|
// Ownership and legal
|
|
ownershipType FarmOwnership?
|
|
landCertificateNumber String?
|
|
landCertificateUrl String?
|
|
|
|
// Agricultural details
|
|
establishedYear Int?
|
|
totalInvestment Decimal?
|
|
annualProduction Decimal? // estimated kg per year
|
|
mainCrops String[] // primary crops grown
|
|
farmingSystem FarmingSystem?
|
|
organicCertified Boolean? @default(false)
|
|
|
|
description String?
|
|
notes String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade)
|
|
plots Plot[]
|
|
harvests Harvest[]
|
|
attachments FarmAttachment[]
|
|
weatherData WeatherData[]
|
|
weatherForecasts WeatherForecast[]
|
|
inputs FarmInput[]
|
|
inputSchedules InputSchedule[]
|
|
laborRecords LaborRecord[]
|
|
laborSchedules LaborSchedule[]
|
|
equipmentUsage EquipmentUsage[]
|
|
pestDiseaseRecords PestDiseaseRecord[]
|
|
financialRecords FinancialRecord[]
|
|
soilTests SoilTest[]
|
|
|
|
@@map("farms")
|
|
}
|
|
|
|
model Plot {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
name String
|
|
area Decimal? // in hectares
|
|
productId String?
|
|
variantId String?
|
|
plantedDate DateTime?
|
|
boundaries Json? // GeoJSON polygon for plot boundaries
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id], onDelete: Cascade)
|
|
product Product? @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
harvests Harvest[]
|
|
weatherData WeatherData[]
|
|
weatherForecasts WeatherForecast[]
|
|
inputs FarmInput[]
|
|
inputSchedules InputSchedule[]
|
|
laborRecords LaborRecord[]
|
|
laborSchedules LaborSchedule[]
|
|
equipmentUsage EquipmentUsage[]
|
|
pestDiseaseRecords PestDiseaseRecord[]
|
|
financialRecords FinancialRecord[]
|
|
soilTests SoilTest[]
|
|
seasons PlotSeason[]
|
|
|
|
@@map("plots")
|
|
}
|
|
|
|
model Harvest {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
farmId String
|
|
plotId String?
|
|
variantId String
|
|
quantity Decimal // in kg
|
|
harvestDate DateTime
|
|
qualityGrade QualityGrade
|
|
waterContent Decimal? // percentage
|
|
density Decimal? // kg/m3
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
variant ProductVariant @relation(fields: [variantId], references: [id])
|
|
procurement Procurement?
|
|
modifiers HarvestModifier[]
|
|
|
|
@@map("harvests")
|
|
}
|
|
|
|
model Procurement {
|
|
id String @id @default(cuid())
|
|
procurementCode String @unique
|
|
farmerId String
|
|
buyerId String?
|
|
harvestId String @unique
|
|
variantId String
|
|
|
|
// Quantity and quality details
|
|
quantity Decimal // in kg
|
|
qualityGrade QualityGrade
|
|
waterContent Decimal? // percentage
|
|
density Decimal? // kg/m3
|
|
|
|
// Pricing details
|
|
basePrice Decimal // price per kg
|
|
premiumRate Decimal @default(0) // percentage
|
|
totalPrice Decimal
|
|
transportCost Decimal? @default(0)
|
|
processingCost Decimal? @default(0)
|
|
finalAmount Decimal // total amount to be paid
|
|
|
|
// Location and logistics
|
|
pickupLocation String?
|
|
deliveryLocation String?
|
|
pickupDate DateTime?
|
|
deliveryDate DateTime?
|
|
transportMethod String? // truck, motorcycle, etc.
|
|
|
|
// Quality assessment
|
|
assessedBy String? // quality assessor ID
|
|
assessmentDate DateTime?
|
|
assessmentNotes String?
|
|
rejectedQuantity Decimal? @default(0)
|
|
rejectionReason String?
|
|
|
|
// Payment details
|
|
paymentMethod PaymentMethod?
|
|
paymentReference String?
|
|
bankAccount String?
|
|
|
|
// Status and tracking
|
|
status ProcurementStatus @default(PENDING)
|
|
procurementDate DateTime @default(now())
|
|
approvedDate DateTime?
|
|
approvedBy String? // admin ID who approved
|
|
paymentDate DateTime?
|
|
completedDate DateTime?
|
|
|
|
// Documentation
|
|
contractId String? // link to formal contract
|
|
contractNumber String?
|
|
invoiceNumber String?
|
|
receiptNumber String?
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
buyer Buyer? @relation(fields: [buyerId], references: [id])
|
|
harvest Harvest @relation(fields: [harvestId], references: [id])
|
|
variant ProductVariant @relation(fields: [variantId], references: [id])
|
|
contract Contract? @relation(fields: [contractId], references: [id])
|
|
attachments ProcurementAttachment[]
|
|
|
|
@@map("procurements")
|
|
}
|
|
|
|
model HarvestModifier {
|
|
id String @id @default(cuid())
|
|
harvestId String
|
|
modifierId String
|
|
value String // actual value applied
|
|
adjustment Decimal? // calculated price adjustment
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
harvest Harvest @relation(fields: [harvestId], references: [id], onDelete: Cascade)
|
|
modifier ProductModifier @relation(fields: [modifierId], references: [id])
|
|
|
|
@@unique([harvestId, modifierId])
|
|
@@map("harvest_modifiers")
|
|
}
|
|
|
|
model FarmerAttachment {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
type AttachmentType
|
|
title String
|
|
description String?
|
|
fileUrl String
|
|
fileName String
|
|
fileSize Int? // in bytes
|
|
mimeType String?
|
|
uploadedBy String? // user ID who uploaded
|
|
isVerified Boolean @default(false)
|
|
verifiedBy String? // admin ID who verified
|
|
verifiedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("farmer_attachments")
|
|
}
|
|
|
|
model FarmAttachment {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
type FarmAttachmentType
|
|
title String
|
|
description String?
|
|
fileUrl String
|
|
fileName String
|
|
fileSize Int? // in bytes
|
|
mimeType String?
|
|
uploadedBy String? // user ID who uploaded
|
|
takenDate DateTime? // when photo was taken
|
|
gpsLocation Json? // GeoJSON point where photo was taken
|
|
isVerified Boolean @default(false)
|
|
verifiedBy String? // admin ID who verified
|
|
verifiedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("farm_attachments")
|
|
}
|
|
|
|
model ProcurementAttachment {
|
|
id String @id @default(cuid())
|
|
procurementId String
|
|
type ProcurementAttachmentType
|
|
title String
|
|
description String?
|
|
fileUrl String
|
|
fileName String
|
|
fileSize Int? // in bytes
|
|
mimeType String?
|
|
uploadedBy String? // user ID who uploaded
|
|
takenDate DateTime? // when photo was taken
|
|
gpsLocation Json? // GeoJSON point where photo was taken
|
|
isVerified Boolean @default(false)
|
|
verifiedBy String? // admin ID who verified
|
|
verifiedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
procurement Procurement @relation(fields: [procurementId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("procurement_attachments")
|
|
}
|
|
|
|
model Training {
|
|
id String @id @default(cuid())
|
|
title String
|
|
description String?
|
|
content String?
|
|
category String
|
|
duration Int? // in minutes
|
|
level String? // beginner, intermediate, advanced
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmerTrainings FarmerTraining[]
|
|
|
|
@@map("trainings")
|
|
}
|
|
|
|
model FarmerTraining {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
trainingId String
|
|
status TrainingStatus @default(ENROLLED)
|
|
progress Int @default(0) // percentage
|
|
score Float?
|
|
completedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade)
|
|
training Training @relation(fields: [trainingId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([farmerId, trainingId])
|
|
@@map("farmer_trainings")
|
|
}
|
|
|
|
model Certification {
|
|
id String @id @default(cuid())
|
|
name String
|
|
description String?
|
|
validityPeriod Int? // in months
|
|
requirements String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmerCertifications FarmerCertification[]
|
|
|
|
@@map("certifications")
|
|
}
|
|
|
|
model FarmerCertification {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
certificationId String
|
|
status CertificationStatus @default(PENDING)
|
|
issuedDate DateTime?
|
|
expiryDate DateTime?
|
|
certificateNumber String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade)
|
|
certification Certification @relation(fields: [certificationId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([farmerId, certificationId])
|
|
@@map("farmer_certifications")
|
|
}
|
|
|
|
model Article {
|
|
id String @id @default(cuid())
|
|
title String
|
|
content String
|
|
excerpt String?
|
|
category String
|
|
tags String[]
|
|
author String?
|
|
status ArticleStatus @default(DRAFT)
|
|
views BigInt @default(0)
|
|
publishedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("articles")
|
|
}
|
|
|
|
model Product {
|
|
id String @id @default(cuid())
|
|
name String // e.g., "Pepper"
|
|
code String @unique
|
|
description String?
|
|
category String
|
|
unit String @default("kg") // kg, ton, etc
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
plots Plot[]
|
|
variants ProductVariant[]
|
|
modifiers ProductModifier[]
|
|
contracts Contract[]
|
|
priceHistory PriceHistory[]
|
|
marketPrices MarketPrice[]
|
|
marketDemand MarketDemand[]
|
|
plotSeasons PlotSeason[]
|
|
seasonHarvests SeasonHarvest[]
|
|
|
|
@@map("products")
|
|
}
|
|
|
|
model ProductVariant {
|
|
id String @id @default(cuid())
|
|
productId String
|
|
name String // e.g., "Black Pepper", "White Pepper"
|
|
code String @unique
|
|
description String?
|
|
basePrice Decimal? // default base price
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
|
plots Plot[]
|
|
harvests Harvest[]
|
|
procurements Procurement[]
|
|
contracts Contract[]
|
|
priceHistory PriceHistory[]
|
|
marketPrices MarketPrice[]
|
|
marketDemand MarketDemand[]
|
|
plotSeasons PlotSeason[]
|
|
seasonHarvests SeasonHarvest[]
|
|
|
|
@@map("product_variants")
|
|
}
|
|
|
|
model ProductModifier {
|
|
id String @id @default(cuid())
|
|
productId String
|
|
name String // e.g., "Water Content", "Density"
|
|
code String
|
|
description String?
|
|
selectionType ModifierSelectionType @default(INPUT)
|
|
nominalType NominalType @default(NOMINAL)
|
|
options String[] // For dropdown selections
|
|
minimum Decimal?
|
|
maximum Decimal?
|
|
unit String? // %, kg/m3, etc
|
|
isRequired Boolean @default(false)
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
|
rules ProductModifierRule[]
|
|
harvestModifiers HarvestModifier[]
|
|
|
|
@@unique([productId, code])
|
|
@@map("product_modifiers")
|
|
}
|
|
|
|
model ProductModifierRule {
|
|
id String @id @default(cuid())
|
|
modifierId String
|
|
condition RuleCondition
|
|
priceAdjustment Decimal // amount to adjust price
|
|
value String? // For equals condition
|
|
minValue Decimal? // For lessThan or between conditions
|
|
maxValue Decimal? // For greaterThan or between conditions
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
modifier ProductModifier @relation(fields: [modifierId], references: [id], onDelete: Cascade)
|
|
|
|
@@map("product_modifier_rules")
|
|
}
|
|
|
|
model PriceHistory {
|
|
id String @id @default(cuid())
|
|
productId String?
|
|
variantId String?
|
|
qualityGrade QualityGrade
|
|
basePrice Decimal
|
|
marketPrice Decimal?
|
|
premiumRate Decimal @default(0)
|
|
effectiveDate DateTime
|
|
region String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
product Product? @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
|
|
@@map("price_history")
|
|
}
|
|
|
|
model WeatherData {
|
|
id String @id @default(cuid())
|
|
farmId String?
|
|
plotId String?
|
|
latitude Float
|
|
longitude Float
|
|
date DateTime
|
|
temperature Float? // celsius
|
|
humidity Float? // percentage
|
|
rainfall Float? // mm
|
|
windSpeed Float? // km/h
|
|
windDirection String? // N, NE, E, SE, S, SW, W, NW
|
|
pressure Float? // hPa
|
|
uvIndex Float?
|
|
visibility Float? // km
|
|
weatherCondition String? // sunny, cloudy, rainy, etc.
|
|
dataSource String? // manual, weather_station, api
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm? @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("weather_data")
|
|
}
|
|
|
|
model WeatherForecast {
|
|
id String @id @default(cuid())
|
|
farmId String?
|
|
plotId String?
|
|
latitude Float
|
|
longitude Float
|
|
forecastDate DateTime
|
|
minTemperature Float?
|
|
maxTemperature Float?
|
|
humidity Float?
|
|
rainfall Float?
|
|
windSpeed Float?
|
|
weatherCondition String?
|
|
confidence Float? // percentage
|
|
source String
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
farm Farm? @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("weather_forecasts")
|
|
}
|
|
|
|
model FarmInput {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
plotId String?
|
|
inputType InputType
|
|
productName String
|
|
brand String?
|
|
quantity Decimal
|
|
unit String
|
|
cost Decimal
|
|
supplier String?
|
|
supplierContact String?
|
|
batchNumber String?
|
|
expiryDate DateTime?
|
|
applicationDate DateTime?
|
|
applicationMethod String?
|
|
applicationRate String? // per hectare or per plant
|
|
activeIngredient String? // for pesticides/fertilizers
|
|
concentration Decimal? // percentage
|
|
notes String?
|
|
invoiceNumber String?
|
|
receiptUrl String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("farm_inputs")
|
|
}
|
|
|
|
model InputSchedule {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
plotId String?
|
|
inputType InputType
|
|
productName String
|
|
scheduledDate DateTime
|
|
quantity Decimal
|
|
unit String
|
|
method String?
|
|
status ScheduleStatus @default(PENDING)
|
|
appliedDate DateTime?
|
|
appliedBy String?
|
|
actualQuantity Decimal?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("input_schedules")
|
|
}
|
|
|
|
model Supplier {
|
|
id String @id @default(cuid())
|
|
name String
|
|
contactPerson String?
|
|
phone String?
|
|
email String?
|
|
address String?
|
|
supplierType SupplierType
|
|
paymentTerms String?
|
|
deliveryTerms String?
|
|
qualityCertifications String[]
|
|
isActive Boolean @default(true)
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("suppliers")
|
|
}
|
|
|
|
model FarmWorker {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
workerCode String @unique
|
|
name String
|
|
phone String?
|
|
email String?
|
|
address String?
|
|
identityNumber String?
|
|
role WorkerRole
|
|
skillLevel SkillLevel?
|
|
dailyWage Decimal?
|
|
monthlyWage Decimal?
|
|
paymentMethod PaymentMethod?
|
|
bankAccount String?
|
|
emergencyContact String?
|
|
emergencyPhone String?
|
|
hireDate DateTime?
|
|
contractType ContractType?
|
|
contractEnd DateTime?
|
|
isActive Boolean @default(true)
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
laborRecords LaborRecord[]
|
|
laborSchedules LaborSchedule[]
|
|
|
|
@@map("farm_workers")
|
|
}
|
|
|
|
model LaborRecord {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
farmId String
|
|
workerId String?
|
|
plotId String?
|
|
workType WorkType
|
|
hoursWorked Decimal
|
|
wages Decimal
|
|
workDate DateTime
|
|
startTime DateTime?
|
|
endTime DateTime?
|
|
description String?
|
|
supervisor String? // supervisor name or ID
|
|
qualityRating Decimal? // 1-5 rating
|
|
weather String?
|
|
notes String?
|
|
approved Boolean @default(false)
|
|
approvedBy String?
|
|
approvedDate DateTime?
|
|
paymentStatus PaymentStatus @default(PENDING)
|
|
paidDate DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
worker FarmWorker? @relation(fields: [workerId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("labor_records")
|
|
}
|
|
|
|
model LaborSchedule {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
farmId String
|
|
workerId String?
|
|
plotId String?
|
|
workType WorkType
|
|
scheduledDate DateTime
|
|
estimatedHours Decimal
|
|
estimatedWage Decimal?
|
|
status ScheduleStatus @default(PENDING)
|
|
assignedBy String?
|
|
notes String?
|
|
actualRecord String? // reference to LaborRecord ID
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
worker FarmWorker? @relation(fields: [workerId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("labor_schedules")
|
|
}
|
|
|
|
model Equipment {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
equipmentCode String @unique
|
|
name String
|
|
type EquipmentType
|
|
brand String?
|
|
model String?
|
|
serialNumber String?
|
|
purchaseDate DateTime?
|
|
purchasePrice Decimal?
|
|
currentValue Decimal?
|
|
condition EquipmentCondition
|
|
status EquipmentStatus @default(ACTIVE)
|
|
location String? // where equipment is stored
|
|
fuelType String? // diesel, petrol, electric, manual
|
|
capacity String? // engine capacity, load capacity
|
|
powerRating String? // horsepower, wattage
|
|
yearManufactured Int?
|
|
warranty String?
|
|
insurancePolicy String?
|
|
insuranceExpiry DateTime?
|
|
lastMaintenance DateTime?
|
|
nextMaintenance DateTime?
|
|
maintenanceCost Decimal?
|
|
operatingHours Decimal? // total operating hours
|
|
isActive Boolean @default(true)
|
|
notes String?
|
|
photoUrl String?
|
|
manualUrl String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
maintenanceRecords MaintenanceRecord[]
|
|
usageRecords EquipmentUsage[]
|
|
|
|
@@map("equipment")
|
|
}
|
|
|
|
model MaintenanceRecord {
|
|
id String @id @default(cuid())
|
|
equipmentId String
|
|
maintenanceType MaintenanceType
|
|
description String
|
|
cost Decimal
|
|
serviceProvider String?
|
|
serviceDate DateTime
|
|
nextServiceDue DateTime?
|
|
partsReplaced String[]
|
|
laborHours Decimal?
|
|
invoiceNumber String?
|
|
receiptUrl String?
|
|
performedBy String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
equipment Equipment @relation(fields: [equipmentId], references: [id])
|
|
|
|
@@map("maintenance_records")
|
|
}
|
|
|
|
model EquipmentUsage {
|
|
id String @id @default(cuid())
|
|
equipmentId String
|
|
farmId String?
|
|
plotId String?
|
|
operatorName String?
|
|
usageDate DateTime
|
|
startTime DateTime?
|
|
endTime DateTime?
|
|
hoursUsed Decimal
|
|
fuelConsumed Decimal?
|
|
workType WorkType?
|
|
description String?
|
|
meterReading Decimal? // odometer, hour meter reading
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
equipment Equipment @relation(fields: [equipmentId], references: [id])
|
|
farm Farm? @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("equipment_usage")
|
|
}
|
|
|
|
model Asset {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
assetCode String @unique
|
|
name String
|
|
type AssetType
|
|
category String? // building, land improvement, infrastructure
|
|
description String?
|
|
purchaseDate DateTime?
|
|
purchasePrice Decimal?
|
|
currentValue Decimal?
|
|
depreciation Decimal? // annual depreciation rate
|
|
condition AssetCondition
|
|
location String?
|
|
size String? // dimensions, area
|
|
material String? // construction material
|
|
lifespan Int? // expected lifespan in years
|
|
warrantyExpiry DateTime?
|
|
insurancePolicy String?
|
|
insuranceExpiry DateTime?
|
|
photoUrls String[]
|
|
documentUrls String[]
|
|
isActive Boolean @default(true)
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
|
|
@@map("assets")
|
|
}
|
|
|
|
model BuyerReview {
|
|
id String @id @default(cuid())
|
|
buyerId String
|
|
farmerId String
|
|
rating Decimal // 1-5 rating
|
|
comment String?
|
|
reviewType ReviewType
|
|
procurementId String? // reference to procurement if applicable
|
|
isAnonymous Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
buyer Buyer @relation(fields: [buyerId], references: [id])
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
|
|
@@map("buyer_reviews")
|
|
}
|
|
|
|
model PestDiseaseRecord {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
plotId String?
|
|
type PestDiseaseType
|
|
name String
|
|
scientificName String?
|
|
severity SeverityLevel
|
|
affectedArea Decimal? // percentage or hectares
|
|
identifiedDate DateTime
|
|
identifiedBy String? // farmer, expert, etc.
|
|
symptoms String?
|
|
treatmentApplied String?
|
|
treatmentDate DateTime?
|
|
treatmentCost Decimal?
|
|
treatmentMethod String?
|
|
preventionTaken String?
|
|
resolved Boolean @default(false)
|
|
resolvedDate DateTime?
|
|
recurrence Boolean @default(false)
|
|
photos String[] // photo URLs
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("pest_disease_records")
|
|
}
|
|
|
|
model FinancialRecord {
|
|
id String @id @default(cuid())
|
|
farmerId String
|
|
farmId String?
|
|
plotId String?
|
|
type TransactionType
|
|
category String
|
|
subcategory String?
|
|
amount Decimal
|
|
currencyId String @default("idr")
|
|
currency Currency @relation(fields: [currencyId], references: [id])
|
|
description String
|
|
transactionDate DateTime
|
|
paymentMethod PaymentMethod?
|
|
receiptNumber String?
|
|
invoiceNumber String?
|
|
referenceNumber String?
|
|
taxAmount Decimal? @default(0)
|
|
bankAccount String?
|
|
payee String? // who received payment
|
|
approvedBy String? // admin who approved
|
|
status TransactionStatus @default(PENDING)
|
|
notes String?
|
|
attachmentUrls String[]
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
farm Farm? @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("financial_records")
|
|
}
|
|
|
|
model SoilTest {
|
|
id String @id @default(cuid())
|
|
farmId String
|
|
plotId String?
|
|
testCode String @unique
|
|
testDate DateTime
|
|
sampleDepth Decimal? // cm
|
|
sampleLocation String?
|
|
gpsCoordinates Json? // GeoJSON point
|
|
|
|
// Basic soil properties
|
|
pH Decimal?
|
|
organicMatter Decimal? // percentage
|
|
soilTexture String? // clay, sand, loam, etc.
|
|
bulkDensity Decimal? // g/cm³
|
|
porosity Decimal? // percentage
|
|
|
|
// Nutrients (ppm)
|
|
nitrogen Decimal?
|
|
phosphorus Decimal?
|
|
potassium Decimal?
|
|
calcium Decimal?
|
|
magnesium Decimal?
|
|
sulfur Decimal?
|
|
|
|
// Micronutrients (ppm)
|
|
zinc Decimal?
|
|
iron Decimal?
|
|
manganese Decimal?
|
|
copper Decimal?
|
|
boron Decimal?
|
|
|
|
// Other properties
|
|
conductivity Decimal? // dS/m
|
|
cationExchangeCapacity Decimal? // cmol/kg
|
|
baseStaturation Decimal? // percentage
|
|
carbonNitrogenRatio Decimal?
|
|
|
|
// Analysis details
|
|
recommendations String?
|
|
testLaboratory String?
|
|
technicianName String?
|
|
testCost Decimal?
|
|
reportUrl String?
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farm Farm @relation(fields: [farmId], references: [id])
|
|
plot Plot? @relation(fields: [plotId], references: [id])
|
|
|
|
@@map("soil_tests")
|
|
}
|
|
|
|
model EducationLevel {
|
|
id String @id @default(cuid())
|
|
name String @unique
|
|
level Int // 0=No formal, 1=Elementary, etc.
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmers Farmer[]
|
|
|
|
@@map("education_levels")
|
|
}
|
|
|
|
model Currency {
|
|
id String @id // ISO currency code like "idr", "usd"
|
|
name String @unique
|
|
code String @unique // ISO 4217 currency code
|
|
symbol String // €, $, Rp, etc.
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
financialRecords FinancialRecord[]
|
|
|
|
@@map("currencies")
|
|
}
|
|
|
|
model Country {
|
|
id String @id // ISO country code like "indonesia", "malaysia"
|
|
name String @unique
|
|
code String @unique // ISO 3166-1 alpha-2 code
|
|
region String?
|
|
continent String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmerNationalities Farmer[] @relation("FarmerNationality")
|
|
farmerCountries Farmer[] @relation("FarmerCountry")
|
|
|
|
@@map("countries")
|
|
}
|
|
|
|
model Religion {
|
|
id String @id @default(cuid())
|
|
name String @unique
|
|
description String?
|
|
isActive Boolean @default(true)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmers Farmer[]
|
|
|
|
@@map("religions")
|
|
}
|
|
|
|
model Message {
|
|
id String @id @default(cuid())
|
|
senderId String
|
|
receiverId String?
|
|
groupId String?
|
|
subject String?
|
|
content String
|
|
messageType MessageType
|
|
priority Priority @default(NORMAL)
|
|
isRead Boolean @default(false)
|
|
readAt DateTime?
|
|
attachments String[] // file URLs
|
|
deliveryStatus MessageStatus @default(SENT)
|
|
sentAt DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@map("messages")
|
|
}
|
|
|
|
model MarketPrice {
|
|
id String @id @default(cuid())
|
|
productId String
|
|
variantId String?
|
|
market String
|
|
region String
|
|
price Decimal
|
|
unit String @default("kg")
|
|
qualityGrade QualityGrade
|
|
priceDate DateTime
|
|
source String? // where price data came from
|
|
volume Decimal? // trading volume
|
|
trend PriceTrend?
|
|
verified Boolean @default(false)
|
|
verifiedBy String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
product Product @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
|
|
@@map("market_prices")
|
|
}
|
|
|
|
model Contract {
|
|
id String @id @default(cuid())
|
|
contractNumber String @unique
|
|
farmerId String
|
|
buyerId String
|
|
productId String?
|
|
variantId String?
|
|
|
|
// Contract terms
|
|
title String
|
|
description String?
|
|
contractType AgreementType @default(PURCHASE_AGREEMENT)
|
|
|
|
// Pricing and quantity
|
|
agreedPrice Decimal // price per unit
|
|
minimumQuantity Decimal?
|
|
maximumQuantity Decimal?
|
|
totalValue Decimal?
|
|
unit String @default("kg")
|
|
|
|
// Quality specifications
|
|
qualityGrade QualityGrade?
|
|
qualityRequirements String?
|
|
|
|
// Timeline
|
|
startDate DateTime
|
|
endDate DateTime
|
|
deliverySchedule String? // delivery frequency/schedule
|
|
|
|
// Payment terms
|
|
paymentTerms String? // payment conditions
|
|
paymentMethod PaymentMethod?
|
|
advancePayment Decimal? @default(0)
|
|
advancePercentage Decimal? @default(0)
|
|
|
|
// Legal and compliance
|
|
terms String? // full terms and conditions
|
|
penalties String? // penalty clauses
|
|
forcemajeure String? // force majeure clause
|
|
governingLaw String? // applicable law
|
|
|
|
// Status and tracking
|
|
status ContractStatus @default(DRAFT)
|
|
signedDate DateTime?
|
|
signedByFarmer Boolean @default(false)
|
|
signedByBuyer Boolean @default(false)
|
|
farmerSignature String? // signature data or URL
|
|
buyerSignature String? // signature data or URL
|
|
witnessName String?
|
|
witnessSignature String?
|
|
|
|
// Performance tracking
|
|
totalDelivered Decimal? @default(0)
|
|
totalPaid Decimal? @default(0)
|
|
deliveryCount Int @default(0)
|
|
|
|
// Renewal and amendments
|
|
renewalDate DateTime?
|
|
amendmentCount Int @default(0)
|
|
parentContractId String? // for contract renewals
|
|
|
|
// Documentation
|
|
documentUrl String? // contract document
|
|
attachmentUrls String[] // supporting documents
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
buyer Buyer @relation(fields: [buyerId], references: [id])
|
|
product Product? @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
parentContract Contract? @relation("ContractRenewal", fields: [parentContractId], references: [id])
|
|
renewalContracts Contract[] @relation("ContractRenewal")
|
|
procurements Procurement[] // deliveries under this contract
|
|
|
|
@@map("contracts")
|
|
}
|
|
|
|
model Notification {
|
|
id String @id @default(cuid())
|
|
title String
|
|
message String
|
|
type NotificationType
|
|
category NotificationCategory @default(GENERAL)
|
|
priority Priority @default(NORMAL)
|
|
|
|
// Recipients
|
|
recipientId String? // specific user ID
|
|
recipientType UserRole? // or broadcast to user type
|
|
recipientIds String[] // multiple specific users
|
|
|
|
// Targeting
|
|
farmerIds String[] // specific farmers
|
|
buyerIds String[] // specific buyers
|
|
region String? // geographic targeting
|
|
productIds String[] // product-specific notifications
|
|
|
|
// Content and media
|
|
content String? // detailed content/body
|
|
imageUrl String?
|
|
actionUrl String? // deep link or action URL
|
|
actionLabel String? // button text
|
|
|
|
// Scheduling
|
|
scheduledAt DateTime? // for scheduled notifications
|
|
expiresAt DateTime? // expiration date
|
|
|
|
// Status tracking
|
|
status NotificationStatus @default(PENDING)
|
|
sentAt DateTime?
|
|
deliveredCount Int @default(0)
|
|
readCount Int @default(0)
|
|
clickCount Int @default(0)
|
|
|
|
// Metadata
|
|
source String? // system, admin, automated, etc.
|
|
sourceId String? // reference to source entity
|
|
tags String[] // for categorization
|
|
metadata Json? // additional data
|
|
|
|
// Tracking
|
|
isRead Boolean @default(false)
|
|
readAt DateTime?
|
|
isClicked Boolean @default(false)
|
|
clickedAt DateTime?
|
|
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
recipients NotificationRecipient[]
|
|
|
|
@@map("notifications")
|
|
}
|
|
|
|
model NotificationRecipient {
|
|
id String @id @default(cuid())
|
|
notificationId String
|
|
userId String
|
|
isRead Boolean @default(false)
|
|
readAt DateTime?
|
|
isClicked Boolean @default(false)
|
|
clickedAt DateTime?
|
|
isDelivered Boolean @default(false)
|
|
deliveredAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
notification Notification @relation(fields: [notificationId], references: [id], onDelete: Cascade)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([notificationId, userId])
|
|
@@map("notification_recipients")
|
|
}
|
|
|
|
model Season {
|
|
id String @id @default(cuid())
|
|
name String // e.g., "Wet Season 2024", "Dry Season 2024"
|
|
seasonType SeasonType
|
|
year Int
|
|
|
|
// Timeline
|
|
startDate DateTime
|
|
endDate DateTime
|
|
|
|
// Weather characteristics
|
|
avgRainfall Decimal? // mm
|
|
avgTemperature Float? // celsius
|
|
avgHumidity Decimal? // percentage
|
|
|
|
// Agricultural phases
|
|
plantingStart DateTime?
|
|
plantingEnd DateTime?
|
|
growingStart DateTime?
|
|
growingEnd DateTime?
|
|
harvestStart DateTime?
|
|
harvestEnd DateTime?
|
|
|
|
// Region and scope
|
|
region String?
|
|
province String?
|
|
country String @default("Indonesia")
|
|
|
|
// Crop recommendations
|
|
recommendedCrops String[] // suitable crops for this season
|
|
notRecommendedCrops String[] // crops to avoid
|
|
|
|
// Market expectations
|
|
expectedDemand DemandLevel?
|
|
priceOutlook PriceTrend?
|
|
marketNotes String?
|
|
|
|
// Agricultural activities
|
|
activities Json? // structured data for farming activities
|
|
|
|
// Status
|
|
isActive Boolean @default(true)
|
|
isCurrent Boolean @default(false)
|
|
|
|
description String?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
plots PlotSeason[]
|
|
harvests SeasonHarvest[]
|
|
weatherData SeasonWeather[]
|
|
|
|
@@unique([seasonType, year, region])
|
|
@@map("seasons")
|
|
}
|
|
|
|
model PlotSeason {
|
|
id String @id @default(cuid())
|
|
plotId String
|
|
seasonId String
|
|
productId String?
|
|
variantId String?
|
|
|
|
// Planting details
|
|
plantedDate DateTime?
|
|
plantedArea Decimal? // hectares actually planted
|
|
seedVariety String?
|
|
|
|
// Expected outcomes
|
|
expectedYield Decimal? // kg per hectare
|
|
expectedHarvest Decimal? // total kg expected
|
|
expectedHarvestDate DateTime?
|
|
|
|
// Actual outcomes
|
|
actualYield Decimal? // kg per hectare
|
|
actualHarvest Decimal? // total kg harvested
|
|
actualHarvestDate DateTime?
|
|
|
|
status PlantingStatus @default(PLANNED)
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
// Relations
|
|
plot Plot @relation(fields: [plotId], references: [id])
|
|
season Season @relation(fields: [seasonId], references: [id])
|
|
product Product? @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
|
|
@@unique([plotId, seasonId])
|
|
@@map("plot_seasons")
|
|
}
|
|
|
|
model SeasonHarvest {
|
|
id String @id @default(cuid())
|
|
seasonId String
|
|
farmerId String
|
|
productId String
|
|
variantId String?
|
|
|
|
totalQuantity Decimal
|
|
averageQuality QualityGrade
|
|
totalValue Decimal
|
|
|
|
harvestCount Int @default(1)
|
|
firstHarvest DateTime
|
|
lastHarvest DateTime?
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
season Season @relation(fields: [seasonId], references: [id])
|
|
farmer Farmer @relation(fields: [farmerId], references: [id])
|
|
product Product @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
|
|
@@map("season_harvests")
|
|
}
|
|
|
|
model SeasonWeather {
|
|
id String @id @default(cuid())
|
|
seasonId String
|
|
region String
|
|
|
|
// Aggregated weather data
|
|
totalRainfall Decimal? // mm
|
|
avgTemperature Float? // celsius
|
|
minTemperature Float? // celsius
|
|
maxTemperature Float? // celsius
|
|
avgHumidity Decimal? // percentage
|
|
|
|
// Extreme events
|
|
droughtDays Int? @default(0)
|
|
floodDays Int? @default(0)
|
|
stormCount Int? @default(0)
|
|
|
|
// Impact assessment
|
|
cropDamage Decimal? // percentage
|
|
yieldImpact Decimal? // percentage change
|
|
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
season Season @relation(fields: [seasonId], references: [id])
|
|
|
|
@@unique([seasonId, region])
|
|
@@map("season_weather")
|
|
}
|
|
|
|
model MarketDemand {
|
|
id String @id @default(cuid())
|
|
productId String
|
|
variantId String?
|
|
region String
|
|
demandLevel DemandLevel
|
|
estimatedVolume Decimal?
|
|
priceRange String?
|
|
season String?
|
|
factors String[] // factors affecting demand
|
|
forecastDate DateTime
|
|
forecastBy String?
|
|
accuracy Decimal? // percentage
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
|
|
// Relations
|
|
product Product @relation(fields: [productId], references: [id])
|
|
variant ProductVariant? @relation(fields: [variantId], references: [id])
|
|
|
|
@@map("market_demand")
|
|
}
|
|
|
|
// Enums
|
|
enum UserRole {
|
|
FARMER
|
|
BUYER
|
|
ADMINISTRATOR
|
|
}
|
|
|
|
enum QualityGrade {
|
|
A
|
|
B
|
|
C
|
|
}
|
|
|
|
enum ProcurementStatus {
|
|
PENDING
|
|
QUALITY_ASSESSMENT
|
|
APPROVED
|
|
REJECTED
|
|
IN_TRANSIT
|
|
DELIVERED
|
|
INVOICED
|
|
PAID
|
|
COMPLETED
|
|
CANCELLED
|
|
PARTIALLY_REJECTED
|
|
}
|
|
|
|
enum TrainingStatus {
|
|
ENROLLED
|
|
IN_PROGRESS
|
|
COMPLETED
|
|
DROPPED
|
|
}
|
|
|
|
enum CertificationStatus {
|
|
PENDING
|
|
APPROVED
|
|
REJECTED
|
|
EXPIRED
|
|
}
|
|
|
|
enum ArticleStatus {
|
|
DRAFT
|
|
PUBLISHED
|
|
ARCHIVED
|
|
}
|
|
|
|
enum ModifierSelectionType {
|
|
DROPDOWN
|
|
INPUT
|
|
}
|
|
|
|
enum NominalType {
|
|
NOMINAL
|
|
PERCENTAGE
|
|
}
|
|
|
|
enum RuleCondition {
|
|
EQUALS
|
|
LESS_THAN
|
|
GREATER_THAN
|
|
BETWEEN
|
|
}
|
|
|
|
enum Gender {
|
|
MALE
|
|
FEMALE
|
|
OTHER
|
|
}
|
|
|
|
enum IdentityType {
|
|
KTP // Indonesian ID Card
|
|
PASSPORT
|
|
DRIVING_LICENSE
|
|
OTHER
|
|
}
|
|
|
|
// EducationLevel enum converted to table above
|
|
|
|
enum FarmerStatus {
|
|
ACTIVE
|
|
INACTIVE
|
|
SUSPENDED
|
|
PENDING_VERIFICATION
|
|
BLACKLISTED
|
|
}
|
|
|
|
enum AttachmentType {
|
|
PROFILE_PHOTO
|
|
ID_CARD_FRONT
|
|
ID_CARD_BACK
|
|
FARMING_LICENSE
|
|
LAND_CERTIFICATE
|
|
BANK_STATEMENT
|
|
CONTRACT
|
|
CERTIFICATE
|
|
OTHER_DOCUMENT
|
|
}
|
|
|
|
enum MaritalStatus {
|
|
SINGLE
|
|
MARRIED
|
|
DIVORCED
|
|
WIDOWED
|
|
SEPARATED
|
|
}
|
|
|
|
// Religion enum converted to table above
|
|
|
|
enum LandOwnership {
|
|
OWNER
|
|
TENANT
|
|
SHARECROPPER
|
|
COOPERATIVE_MEMBER
|
|
GOVERNMENT_LEASE
|
|
FAMILY_LAND
|
|
OTHER
|
|
}
|
|
|
|
enum WaterSource {
|
|
RAIN_FED
|
|
IRRIGATION_CANAL
|
|
WELL
|
|
RIVER
|
|
POND
|
|
GROUNDWATER
|
|
SPRING
|
|
MIXED
|
|
}
|
|
|
|
enum IrrigationType {
|
|
FLOOD
|
|
SPRINKLER
|
|
DRIP
|
|
FURROW
|
|
MANUAL
|
|
NONE
|
|
}
|
|
|
|
enum SlopeType {
|
|
FLAT
|
|
GENTLE
|
|
MODERATE
|
|
STEEP
|
|
VERY_STEEP
|
|
}
|
|
|
|
enum ClimateType {
|
|
TROPICAL_WET
|
|
TROPICAL_DRY
|
|
SUBTROPICAL
|
|
TEMPERATE
|
|
HIGHLAND
|
|
}
|
|
|
|
enum RoadType {
|
|
PAVED
|
|
GRAVEL
|
|
DIRT
|
|
FOOTPATH
|
|
NO_ACCESS
|
|
}
|
|
|
|
enum FarmOwnership {
|
|
PRIVATE_OWNED
|
|
LEASED
|
|
SHARECROPPED
|
|
COOPERATIVE
|
|
GOVERNMENT
|
|
COMMUNAL
|
|
FAMILY_INHERITED
|
|
}
|
|
|
|
enum FarmingSystem {
|
|
MONOCULTURE
|
|
POLYCULTURE
|
|
MIXED_FARMING
|
|
ORGANIC
|
|
CONVENTIONAL
|
|
INTEGRATED
|
|
PERMACULTURE
|
|
AGROFORESTRY
|
|
}
|
|
|
|
enum FarmAttachmentType {
|
|
MAIN_PHOTO
|
|
AERIAL_PHOTO
|
|
SOIL_PHOTO
|
|
CROP_PHOTO
|
|
INFRASTRUCTURE_PHOTO
|
|
LAND_CERTIFICATE
|
|
SURVEY_MAP
|
|
WATER_SOURCE_PHOTO
|
|
ENTRANCE_PHOTO
|
|
BOUNDARY_PHOTO
|
|
EQUIPMENT_PHOTO
|
|
STORAGE_PHOTO
|
|
OTHER_DOCUMENT
|
|
}
|
|
|
|
enum PaymentMethod {
|
|
CASH
|
|
BANK_TRANSFER
|
|
MOBILE_MONEY
|
|
CHECK
|
|
DIGITAL_WALLET
|
|
CREDIT
|
|
BARTER
|
|
INSTALLMENT
|
|
}
|
|
|
|
enum ProcurementAttachmentType {
|
|
PRODUCT_PHOTO
|
|
QUALITY_ASSESSMENT_PHOTO
|
|
WEIGHING_PHOTO
|
|
PACKAGING_PHOTO
|
|
LOADING_PHOTO
|
|
DELIVERY_PHOTO
|
|
CONTRACT_DOCUMENT
|
|
INVOICE
|
|
RECEIPT
|
|
PAYMENT_PROOF
|
|
QUALITY_CERTIFICATE
|
|
TRANSPORT_DOCUMENT
|
|
REJECTION_PHOTO
|
|
SIGNATURE_DOCUMENT
|
|
OTHER_DOCUMENT
|
|
}
|
|
|
|
// Input Management Enums
|
|
enum InputType {
|
|
SEED
|
|
FERTILIZER
|
|
PESTICIDE
|
|
HERBICIDE
|
|
FUNGICIDE
|
|
INSECTICIDE
|
|
EQUIPMENT_RENTAL
|
|
FUEL
|
|
IRRIGATION_WATER
|
|
MULCH
|
|
COMPOST
|
|
LIME
|
|
OTHER
|
|
}
|
|
|
|
enum ScheduleStatus {
|
|
PENDING
|
|
SCHEDULED
|
|
IN_PROGRESS
|
|
COMPLETED
|
|
CANCELLED
|
|
OVERDUE
|
|
}
|
|
|
|
enum SupplierType {
|
|
SEED_SUPPLIER
|
|
FERTILIZER_SUPPLIER
|
|
PESTICIDE_SUPPLIER
|
|
EQUIPMENT_SUPPLIER
|
|
GENERAL_SUPPLIER
|
|
COOPERATIVE
|
|
GOVERNMENT_AGENCY
|
|
}
|
|
|
|
// Labor Management Enums
|
|
enum WorkerRole {
|
|
PERMANENT
|
|
SEASONAL
|
|
DAILY
|
|
CONTRACTOR
|
|
SUPERVISOR
|
|
FOREMAN
|
|
SPECIALIST
|
|
}
|
|
|
|
enum SkillLevel {
|
|
BEGINNER
|
|
INTERMEDIATE
|
|
ADVANCED
|
|
EXPERT
|
|
}
|
|
|
|
enum ContractType {
|
|
PERMANENT
|
|
TEMPORARY
|
|
SEASONAL
|
|
PROJECT_BASED
|
|
DAILY
|
|
}
|
|
|
|
enum WorkType {
|
|
PLANTING
|
|
WEEDING
|
|
FERTILIZING
|
|
HARVESTING
|
|
IRRIGATION
|
|
PEST_CONTROL
|
|
SOIL_PREPARATION
|
|
PRUNING
|
|
GENERAL_MAINTENANCE
|
|
EQUIPMENT_OPERATION
|
|
PROCESSING
|
|
PACKAGING
|
|
TRANSPORT
|
|
}
|
|
|
|
enum PaymentStatus {
|
|
PENDING
|
|
APPROVED
|
|
PAID
|
|
OVERDUE
|
|
CANCELLED
|
|
}
|
|
|
|
// Equipment & Asset Enums
|
|
enum EquipmentType {
|
|
TRACTOR
|
|
HARVESTER
|
|
PLANTER
|
|
CULTIVATOR
|
|
IRRIGATION_SYSTEM
|
|
SPRAYER
|
|
THRESHER
|
|
MOWER
|
|
TOOLS
|
|
VEHICLE
|
|
PROCESSING_EQUIPMENT
|
|
STORAGE_EQUIPMENT
|
|
}
|
|
|
|
enum EquipmentCondition {
|
|
EXCELLENT
|
|
GOOD
|
|
FAIR
|
|
POOR
|
|
NEEDS_REPAIR
|
|
OUT_OF_ORDER
|
|
}
|
|
|
|
enum EquipmentStatus {
|
|
ACTIVE
|
|
INACTIVE
|
|
MAINTENANCE
|
|
REPAIR
|
|
RETIRED
|
|
}
|
|
|
|
enum MaintenanceType {
|
|
PREVENTIVE
|
|
CORRECTIVE
|
|
EMERGENCY
|
|
OVERHAUL
|
|
INSPECTION
|
|
CALIBRATION
|
|
}
|
|
|
|
enum AssetType {
|
|
BUILDING
|
|
LAND_IMPROVEMENT
|
|
INFRASTRUCTURE
|
|
VEHICLE
|
|
MACHINERY
|
|
FURNITURE
|
|
TECHNOLOGY
|
|
OTHER
|
|
}
|
|
|
|
enum AssetCondition {
|
|
NEW
|
|
EXCELLENT
|
|
GOOD
|
|
FAIR
|
|
POOR
|
|
DAMAGED
|
|
}
|
|
|
|
// Buyer Enums
|
|
enum BuyerType {
|
|
INDIVIDUAL
|
|
WHOLESALER
|
|
RETAILER
|
|
PROCESSOR
|
|
EXPORTER
|
|
COOPERATIVE
|
|
GOVERNMENT
|
|
RESTAURANT
|
|
HOTEL
|
|
}
|
|
|
|
enum BusinessSize {
|
|
MICRO
|
|
SMALL
|
|
MEDIUM
|
|
LARGE
|
|
ENTERPRISE
|
|
}
|
|
|
|
enum BuyerStatus {
|
|
ACTIVE
|
|
INACTIVE
|
|
SUSPENDED
|
|
PENDING_VERIFICATION
|
|
BLACKLISTED
|
|
}
|
|
|
|
enum ReviewType {
|
|
PAYMENT_TIMELINESS
|
|
QUALITY_REQUIREMENTS
|
|
COMMUNICATION
|
|
OVERALL_EXPERIENCE
|
|
PRICE_FAIRNESS
|
|
}
|
|
|
|
// Pest & Disease Enums
|
|
enum PestDiseaseType {
|
|
PEST
|
|
DISEASE
|
|
WEED
|
|
NUTRIENT_DEFICIENCY
|
|
VIRUS
|
|
FUNGUS
|
|
BACTERIA
|
|
}
|
|
|
|
enum SeverityLevel {
|
|
LOW
|
|
MEDIUM
|
|
HIGH
|
|
CRITICAL
|
|
CATASTROPHIC
|
|
}
|
|
|
|
// Financial Enums
|
|
enum TransactionType {
|
|
INCOME
|
|
EXPENSE
|
|
INVESTMENT
|
|
LOAN
|
|
LOAN_PAYMENT
|
|
INSURANCE_PAYMENT
|
|
TAX_PAYMENT
|
|
GRANT
|
|
SUBSIDY
|
|
REFUND
|
|
}
|
|
|
|
enum TransactionStatus {
|
|
PENDING
|
|
APPROVED
|
|
COMPLETED
|
|
REJECTED
|
|
CANCELLED
|
|
FAILED
|
|
}
|
|
|
|
// Notification Enums
|
|
enum NotificationType {
|
|
SYSTEM
|
|
ANNOUNCEMENT
|
|
ALERT
|
|
REMINDER
|
|
PROMOTION
|
|
UPDATE
|
|
WARNING
|
|
INFO
|
|
SUCCESS
|
|
ERROR
|
|
}
|
|
|
|
enum NotificationCategory {
|
|
GENERAL
|
|
PROCUREMENT
|
|
PAYMENT
|
|
QUALITY
|
|
WEATHER
|
|
PRICE_ALERT
|
|
TRAINING
|
|
CERTIFICATION
|
|
MAINTENANCE
|
|
HARVEST
|
|
PLANTING
|
|
MARKET
|
|
CONTRACT
|
|
COMPLIANCE
|
|
}
|
|
|
|
enum NotificationStatus {
|
|
PENDING
|
|
SCHEDULED
|
|
SENT
|
|
DELIVERED
|
|
FAILED
|
|
CANCELLED
|
|
EXPIRED
|
|
}
|
|
|
|
// Communication Enums
|
|
enum MessageType {
|
|
PERSONAL
|
|
BROADCAST
|
|
NOTIFICATION
|
|
ALERT
|
|
SYSTEM
|
|
ANNOUNCEMENT
|
|
}
|
|
|
|
enum Priority {
|
|
LOW
|
|
NORMAL
|
|
HIGH
|
|
URGENT
|
|
CRITICAL
|
|
}
|
|
|
|
enum MessageStatus {
|
|
SENT
|
|
DELIVERED
|
|
READ
|
|
FAILED
|
|
PENDING
|
|
}
|
|
|
|
// Contract Enums
|
|
enum AgreementType {
|
|
PURCHASE_AGREEMENT
|
|
SUPPLY_CONTRACT
|
|
EXCLUSIVE_SUPPLY
|
|
SEASONAL_CONTRACT
|
|
FORWARD_CONTRACT
|
|
SPOT_CONTRACT
|
|
CONSIGNMENT
|
|
PARTNERSHIP
|
|
}
|
|
|
|
enum ContractStatus {
|
|
DRAFT
|
|
PENDING_REVIEW
|
|
PENDING_SIGNATURE
|
|
ACTIVE
|
|
FULFILLED
|
|
EXPIRED
|
|
TERMINATED
|
|
CANCELLED
|
|
BREACH
|
|
RENEWED
|
|
}
|
|
|
|
// Season Enums
|
|
enum SeasonType {
|
|
WET_SEASON
|
|
DRY_SEASON
|
|
TRANSITION
|
|
YEAR_ROUND
|
|
SPRING
|
|
SUMMER
|
|
FALL
|
|
WINTER
|
|
}
|
|
|
|
enum PlantingStatus {
|
|
PLANNED
|
|
PLANTED
|
|
GROWING
|
|
FLOWERING
|
|
FRUITING
|
|
HARVESTING
|
|
HARVESTED
|
|
FAILED
|
|
ABANDONED
|
|
}
|
|
|
|
// Market Intelligence Enums
|
|
enum PriceTrend {
|
|
RISING
|
|
FALLING
|
|
STABLE
|
|
VOLATILE
|
|
}
|
|
|
|
enum DemandLevel {
|
|
VERY_LOW
|
|
LOW
|
|
MODERATE
|
|
HIGH
|
|
VERY_HIGH
|
|
EXCESSIVE
|
|
}
|