From 90911b8fca2f62ac9a25f8d2b817b57ee2658146 Mon Sep 17 00:00:00 2001 From: Abdul Kholik Sobary Date: Tue, 8 Jul 2025 12:55:56 +0700 Subject: [PATCH] refactor: Consolidate training and certification models into a unified schema - Added TrainingInvitation and TrainingAttendance models to manage invitations and attendance tracking for training sessions. - Enhanced the Training model with additional fields for scheduling, location management, and group management. - Introduced enums for TrainingLocationType and AttendanceStatus to standardize location types and attendance tracking. - Removed outdated schemas related to attachments, financial records, and other domains to streamline the schema structure. - Updated documentation to reflect changes and improve clarity on training and certification management. --- rancangan_schema/schema.prisma | 187 ++++++++++++-- schemas/README.md | 214 ---------------- schemas/attachments.prisma | 45 ---- schemas/base.prisma | 205 --------------- schemas/communication.prisma | 160 ------------ schemas/farm.prisma | 249 ------------------- schemas/financial.prisma | 68 ----- schemas/knowledge.prisma | 33 --- schemas/market.prisma | 63 ----- schemas/operations.prisma | 439 --------------------------------- schemas/pest-disease.prisma | 86 ------- schemas/procurement.prisma | 284 --------------------- schemas/product.prisma | 169 ------------- schemas/reference.prisma | 76 ------ schemas/season.prisma | 196 --------------- schemas/training.prisma | 119 --------- schemas/user.prisma | 261 -------------------- schemas/weather.prisma | 66 ----- 18 files changed, 170 insertions(+), 2750 deletions(-) delete mode 100644 schemas/README.md delete mode 100644 schemas/attachments.prisma delete mode 100644 schemas/base.prisma delete mode 100644 schemas/communication.prisma delete mode 100644 schemas/farm.prisma delete mode 100644 schemas/financial.prisma delete mode 100644 schemas/knowledge.prisma delete mode 100644 schemas/market.prisma delete mode 100644 schemas/operations.prisma delete mode 100644 schemas/pest-disease.prisma delete mode 100644 schemas/procurement.prisma delete mode 100644 schemas/product.prisma delete mode 100644 schemas/reference.prisma delete mode 100644 schemas/season.prisma delete mode 100644 schemas/training.prisma delete mode 100644 schemas/user.prisma delete mode 100644 schemas/weather.prisma diff --git a/rancangan_schema/schema.prisma b/rancangan_schema/schema.prisma index a7e4920..ba066ba 100644 --- a/rancangan_schema/schema.prisma +++ b/rancangan_schema/schema.prisma @@ -367,8 +367,10 @@ model Farmer { bankAccounts FarmerBankAccount[] vehicles FarmerVehicle[] farms Farm[] - trainings FarmerTraining[] - certifications FarmerCertification[] + trainings FarmerTraining[] + certifications FarmerCertification[] + trainingInvitations TrainingInvitation[] + trainingAttendances TrainingAttendance[] procurements Procurement[] harvests Harvest[] attachments FarmerAttachment[] @@ -2315,14 +2317,33 @@ model WeatherForecast { } // Training & Certification Domain -// Contains training programs, certifications, and farmer development +// Contains training programs, certifications, farmer development, and group training management +// Features: batch training, invitation system, attendance tracking, location management, documentation // Training-specific Enums enum TrainingStatus { - ENROLLED - IN_PROGRESS - COMPLETED - DROPPED + ENROLLED // Farmer enrolled in training program + IN_PROGRESS // Currently participating in training + COMPLETED // Successfully completed training + DROPPED // Dropped out of training program +} + +enum TrainingLocationType { + VILLAGE_HALL // Training held at village hall/balai desa + FARM_FIELD // Field training at farm/kebun + FARMER_HOME // Training at farmer's home + COOPERATIVE // Training at cooperative office + GOVERNMENT_OFFICE // Training at government facility + ONLINE // Virtual/online training + OTHER // Other location type +} + +enum AttendanceStatus { + INVITED // Farmer invited to training + CONFIRMED // Farmer confirmed attendance + ATTENDED // Farmer attended the training + ABSENT // Farmer was absent + CANCELLED // Invitation/attendance cancelled } enum CertificationStatus { @@ -2335,27 +2356,48 @@ enum CertificationStatus { // Training Models model Training { id String @id @default(cuid()) - title String - description String? - content String? - category String - duration Int? // in minutes - level String? // beginner, intermediate, advanced - prerequisites String? - maxParticipants Int? // Maximum number of participants - createdBy String? // Admin who created the training + title String // Training title/name + description String? // Training description + content String? // Training content/materials + category String // Training category (e.g., "Pest Management", "Organic Farming") + duration Int? // Training duration in minutes + level String? // Training level: beginner, intermediate, advanced + prerequisites String? // Prerequisites for joining training + maxParticipants Int? // Maximum number of participants allowed + createdBy String? // Admin ID who created the training + + // Training schedule and location management + scheduledDate DateTime? // Date when training is scheduled + startTime DateTime? // Training start time + endTime DateTime? // Training end time + locationType TrainingLocationType? // Type of training location + location String? // Specific location name/description + locationAddress String? // Full address of training location + locationGPS Json? // GeoJSON point for precise location coordinates + + // Group/batch management for farmer groups + batchName String? // Name identifier for the training batch + targetGroup String? // Description of target audience/group + kelompokTaniIds String[] // Array of farmer group IDs (SH/kelompok tani) participating + isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt // Relations - farmerTrainings FarmerTraining[] + farmerTrainings FarmerTraining[] // Individual farmer training records + trainingInvitations TrainingInvitation[] // Training invitations sent to farmers + trainingAttendances TrainingAttendance[] // Attendance records for the training + trainingDocuments TrainingDocument[] // Photos, videos, and documents related to training @@index([category]) @@index([level]) @@index([isActive]) @@index([duration]) @@index([createdBy]) + @@index([scheduledDate]) + @@index([locationType]) + @@index([batchName]) @@map("trainings") } @@ -2390,6 +2432,117 @@ model FarmerTraining { @@map("farmer_trainings") } +model TrainingInvitation { + id String @id @default(cuid()) + trainingId String // Reference to Training + farmerId String // Reference to Farmer being invited + invitedBy String? // Admin ID who created the invitation + invitedAt DateTime @default(now()) // When invitation was sent + message String? // Custom invitation message for the farmer + + // Response tracking - farmer's response to invitation + responseStatus AttendanceStatus @default(INVITED) // Current status of farmer's response + respondedAt DateTime? // When farmer responded to invitation + responseNote String? // Farmer's note/comment when responding + + // Reminder system for follow-up + reminderSent Boolean @default(false) // Whether reminder has been sent + reminderSentAt DateTime? // When last reminder was sent + reminderCount Int @default(0) // Number of reminders sent + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + training Training @relation(fields: [trainingId], references: [id], onDelete: Cascade) + farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade) + + @@unique([trainingId, farmerId]) // One invitation per farmer per training + @@index([trainingId]) + @@index([farmerId]) + @@index([responseStatus]) + @@index([invitedAt]) + @@index([reminderSent]) + @@map("training_invitations") +} + +model TrainingAttendance { + id String @id @default(cuid()) + trainingId String // Reference to Training + farmerId String // Reference to Farmer + attendanceStatus AttendanceStatus @default(INVITED) // Attendance status + + // Check-in/out tracking system for training sessions + checkInTime DateTime? // When farmer checked in to training + checkOutTime DateTime? // When farmer checked out of training + checkInBy String? // Admin ID who recorded the check-in + checkOutBy String? // Admin ID who recorded the check-out + + // Participation evaluation and feedback + participationScore Float? // 1-5 rating of farmer's participation quality + completedTasks Boolean @default(false) // Whether farmer completed training tasks + feedback String? // Farmer's feedback about the training experience + + notes String? // Additional notes about attendance + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + training Training @relation(fields: [trainingId], references: [id], onDelete: Cascade) + farmer Farmer @relation(fields: [farmerId], references: [id], onDelete: Cascade) + + @@unique([trainingId, farmerId]) // One attendance record per farmer per training + @@index([trainingId]) + @@index([farmerId]) + @@index([attendanceStatus]) + @@index([checkInTime]) + @@index([participationScore]) + @@map("training_attendances") +} + +model TrainingDocument { + id String @id @default(cuid()) + trainingId String // Reference to Training + title String // Document title/name + description String? // Document description + fileUrl String // URL/path to the file + fileName String // Original filename + fileSize Int? // File size in bytes + mimeType String? // File MIME type (image/jpeg, video/mp4, etc.) + + // Document type and categorization + documentType String? // Type: photo, video, certificate, handout, presentation, etc. + category String? // Category: documentation, material, certificate, evaluation + + // Metadata and tracking information + uploadedBy String? // User ID who uploaded the document + takenBy String? // Person who took the photo/video (photographer/videographer) + takenAt DateTime? // When the photo/video was taken during training + gpsLocation Json? // GeoJSON point coordinates where photo/video was taken + + // Verification and quality control + isVerified Boolean @default(false) // Whether document has been verified by admin + verifiedBy String? // Admin ID who verified the document + verifiedAt DateTime? // When document was verified + + // Access control + isPublic Boolean @default(false) // Whether document is visible to training participants + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Relations + training Training @relation(fields: [trainingId], references: [id], onDelete: Cascade) + + @@index([trainingId]) + @@index([documentType]) + @@index([category]) + @@index([isVerified]) + @@index([isPublic]) + @@index([uploadedBy]) + @@index([takenAt]) + @@map("training_documents") +} + model Certification { id String @id @default(cuid()) name String diff --git a/schemas/README.md b/schemas/README.md deleted file mode 100644 index 60fad6e..0000000 --- a/schemas/README.md +++ /dev/null @@ -1,214 +0,0 @@ -# Split Schema Structure - -This directory contains the split version of the agricultural platform's Prisma schema, organized by domain for better maintainability and team collaboration. - -## Directory Structure - -``` -schemas/ -├── README.md # This file -├── base.prisma # Generator, datasource, and shared enums -├── user.prisma # User management (User, Farmer, Buyer, Administrator) -├── reference.prisma # Reference data (Country, Currency, Religion, EducationLevel) -├── farm.prisma # Farm management (Farm, Plot, SoilTest, FarmAttachment) -├── product.prisma # Product system (Product, ProductVariant, modifiers) -├── procurement.prisma # Trading (Procurement, Contract, Harvest) -├── season.prisma # Seasonal planning (Season, PlotSeason, analytics) -├── operations.prisma # Operations (Input, Labor, Equipment, Assets) -├── financial.prisma # Financial records and transactions -├── communication.prisma # Notifications and messaging -├── weather.prisma # Weather data and forecasts -├── training.prisma # Training and certification -├── market.prisma # Market intelligence and pricing -├── knowledge.prisma # Articles and knowledge base -├── attachments.prisma # File and attachment management -└── pest-disease.prisma # Pest, disease, and review management -``` - -## Benefits of Split Schema - -### 1. **Better Organization** -- Logical grouping by business domain -- Easier to find specific models -- Reduced cognitive load when working on specific features -- Clear separation of concerns - -### 2. **Team Collaboration** -- Multiple developers can work on different schema files simultaneously -- Reduced merge conflicts -- Clear ownership boundaries -- Focused code reviews - -### 3. **Maintainability** -- Easier to understand and modify specific domains -- Better debugging and troubleshooting -- Cleaner dependency management -- Improved documentation per domain - -### 4. **Performance Benefits** -- Faster schema compilation for individual domains -- Easier to identify bottlenecks -- Better indexing strategy per domain -- Optimized queries per business area - -## How to Use Split Schema - -### Option 1: Replace Original Schema -1. **Backup original schema.prisma**: - ```bash - mv schema.prisma schema.prisma.backup - ``` - -2. **Use split schema directory**: - ```bash - # Prisma will automatically read all .prisma files in the directory - npx prisma generate - npx prisma migrate dev - ``` - -### Option 2: Parallel Development -Keep both structures and choose based on your needs: -- Use original `schema.prisma` for production -- Use `schemas/` directory for development and feature work -- Gradually migrate teams to split structure - -## Domain Responsibilities - -### **Core Domains** -- **user.prisma**: Authentication, user profiles, role management -- **reference.prisma**: Master data (countries, currencies, education levels) -- **farm.prisma**: Farm infrastructure, plots, soil management - -### **Business Domains** -- **product.prisma**: Product catalog, variants, quality modifiers -- **procurement.prisma**: Trading, contracts, harvest management -- **season.prisma**: Agricultural cycles, seasonal planning -- **operations.prisma**: Daily operations, labor, equipment - -### **Support Domains** -- **financial.prisma**: Financial tracking, transactions -- **communication.prisma**: Notifications, messaging -- **weather.prisma**: Climate data, forecasts -- **training.prisma**: Education, certifications - -### **Analytics Domains** -- **market.prisma**: Market intelligence, pricing -- **knowledge.prisma**: Content management -- **attachments.prisma**: File management -- **pest-disease.prisma**: Agricultural health tracking - -## File Size Comparison - -| Structure | File Count | Lines per File | Total Lines | -|-----------|------------|----------------|-------------| -| Original | 1 file | ~1,800 lines | 1,800 | -| Split | 15 files | ~120-300 lines| 1,800 | - -## Cross-Domain Relationships - -The split maintains all relationships between domains: - -```prisma -// farmer.prisma references farm.prisma -model Farmer { - farms Farm[] // → farm.prisma -} - -// farm.prisma references farmer.prisma -model Farm { - farmer Farmer @relation(...) // → user.prisma -} -``` - -## Migration Strategy - -### Phase 1: Parallel Structure -- Keep original schema.prisma -- Create split structure alongside -- Use for new feature development - -### Phase 2: Team Adoption -- Train teams on domain boundaries -- Establish ownership per domain -- Use split structure for reviews - -### Phase 3: Full Migration -- Move production to split structure -- Archive original schema.prisma -- Update CI/CD pipelines - -## Best Practices - -### 1. **Domain Boundaries** -- Keep related models together -- Minimize cross-domain dependencies -- Use clear naming conventions - -### 2. **Shared Elements** -- Keep shared enums in base.prisma -- Document cross-domain relationships -- Maintain consistent data types - -### 3. **Team Workflow** -- Assign domain ownership -- Review changes by domain -- Coordinate cross-domain changes - -### 4. **Development** -- Test schema compilation regularly -- Validate relationships across files -- Monitor performance impact - -## Troubleshooting - -### Common Issues - -1. **Duplicate Models/Enums**: - - Ensure original schema.prisma is not in the same directory - - Check for naming conflicts across files - -2. **Missing Relations**: - - Verify cross-file relationships are properly defined - - Check import paths and model references - -3. **Compilation Errors**: - - Run `npx prisma validate` to check schema integrity - - Verify all referenced models exist across files - -### Validation Commands - -```bash -# Validate entire schema -npx prisma validate - -# Generate client to test compilation -npx prisma generate - -# Check database sync -npx prisma migrate dev --create-only -``` - -## Future Enhancements - -### Potential Improvements -1. **Microservice Extraction**: Easier to identify service boundaries -2. **Database Sharding**: Clear data partitioning strategies -3. **Team Scaling**: Better support for large development teams -4. **Domain-Driven Design**: Enhanced DDD implementation - -### Monitoring -- Track file modification patterns -- Monitor domain interaction frequency -- Identify optimization opportunities - -## Support - -For questions about the split schema structure: -1. Check this README for common issues -2. Review domain documentation in each file -3. Validate schema compilation with Prisma CLI -4. Contact the database team for complex migrations - ---- - -**Note**: This split structure maintains full compatibility with the original schema.prisma. All relationships, constraints, and data types remain identical. \ No newline at end of file diff --git a/schemas/attachments.prisma b/schemas/attachments.prisma deleted file mode 100644 index 19903c2..0000000 --- a/schemas/attachments.prisma +++ /dev/null @@ -1,45 +0,0 @@ -// Attachment Management Domain -// Contains all attachment and file management models - -// Attachment-specific Enums -enum AttachmentType { - PROFILE_PHOTO - ID_CARD_FRONT - ID_CARD_BACK - FARMING_LICENSE - LAND_CERTIFICATE - BANK_STATEMENT - CONTRACT - CERTIFICATE - OTHER_DOCUMENT -} - -// Attachment Models -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) - - @@index([farmerId]) - @@index([type]) - @@index([isVerified]) - @@index([uploadedBy]) - @@index([createdAt]) - @@index([mimeType]) - @@map("farmer_attachments") -} \ No newline at end of file diff --git a/schemas/base.prisma b/schemas/base.prisma deleted file mode 100644 index 2783bd3..0000000 --- a/schemas/base.prisma +++ /dev/null @@ -1,205 +0,0 @@ -// This is the base Prisma schema file -// Contains generator, datasource, and shared enums - -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "postgresql" - url = env("DATABASE_URL") -} - -// Shared Enums - Used across multiple domains - -// Core User Management Enums -enum UserRole { - FARMER - BUYER - ADMINISTRATOR -} - -enum Gender { - MALE - FEMALE - OTHER -} - -enum MaritalStatus { - SINGLE - MARRIED - DIVORCED - WIDOWED - SEPARATED -} - -enum IdentityType { - KTP // Indonesian ID Card - PASSPORT - DRIVING_LICENSE - OTHER -} - -// Quality and Status Enums -enum QualityGrade { - A - B - C -} - -enum PaymentMethod { - CASH - BANK_TRANSFER - MOBILE_MONEY - CHECK - DIGITAL_WALLET - CREDIT - BARTER - INSTALLMENT -} - -enum PaymentStatus { - PENDING - APPROVED - PAID - OVERDUE - CANCELLED -} - -enum ScheduleStatus { - PENDING - SCHEDULED - IN_PROGRESS - COMPLETED - CANCELLED - OVERDUE -} - -// Geographic and Environmental Enums -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 -} - -// Agricultural Enums -enum WorkType { - PLANTING - WEEDING - FERTILIZING - HARVESTING - IRRIGATION - PEST_CONTROL - SOIL_PREPARATION - PRUNING - GENERAL_MAINTENANCE - EQUIPMENT_OPERATION - PROCESSING - PACKAGING - TRANSPORT -} - -enum InputType { - SEED - FERTILIZER - PESTICIDE - HERBICIDE - FUNGICIDE - INSECTICIDE - EQUIPMENT_RENTAL - FUEL - IRRIGATION_WATER - MULCH - COMPOST - LIME - OTHER -} - -enum SeverityLevel { - LOW - MEDIUM - HIGH - CRITICAL - CATASTROPHIC -} - -// Communication and Priority Enums -enum Priority { - LOW - NORMAL - HIGH - URGENT - CRITICAL -} - -enum MessageType { - PERSONAL - BROADCAST - NOTIFICATION - ALERT - SYSTEM - ANNOUNCEMENT -} - -enum MessageStatus { - SENT - DELIVERED - READ - FAILED - PENDING -} - -// Market Intelligence Enums -enum PriceTrend { - RISING - FALLING - STABLE - VOLATILE -} - -enum DemandLevel { - VERY_LOW - LOW - MODERATE - HIGH - VERY_HIGH - EXCESSIVE -} \ No newline at end of file diff --git a/schemas/communication.prisma b/schemas/communication.prisma deleted file mode 100644 index d53959b..0000000 --- a/schemas/communication.prisma +++ /dev/null @@ -1,160 +0,0 @@ -// Communication & Notifications Domain -// Contains Notification, Message, and communication models - -// Communication-specific 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 Models -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[] - - @@index([type]) - @@index([category]) - @@index([priority]) - @@index([status]) - @@index([scheduledAt]) - @@index([recipientType]) - @@index([region]) - @@index([createdAt]) - @@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]) - @@index([notificationId]) - @@index([userId]) - @@index([isRead]) - @@index([isDelivered]) - @@index([createdAt]) - @@map("notification_recipients") -} - -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 - - @@index([senderId]) - @@index([receiverId]) - @@index([messageType]) - @@index([isRead]) - @@index([sentAt]) - @@index([deliveryStatus]) - @@map("messages") -} \ No newline at end of file diff --git a/schemas/farm.prisma b/schemas/farm.prisma deleted file mode 100644 index 83f045f..0000000 --- a/schemas/farm.prisma +++ /dev/null @@ -1,249 +0,0 @@ -// Farm Management Domain -// Contains Farm, Plot, and related farming infrastructure models - -// Farm-specific Enums -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 -} - -// Farm Models -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[] - - @@index([farmCode]) - @@index([farmerId]) - @@index([latitude, longitude]) - @@index([isActive]) - @@index([establishedYear]) - @@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[] - - @@index([farmId]) - @@index([productId, variantId]) - @@index([plantedDate]) - @@index([isActive]) - @@map("plots") -} - -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) - - @@index([farmId]) - @@index([type]) - @@index([isVerified]) - @@index([createdAt]) - @@map("farm_attachments") -} - -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]) - - @@index([testCode]) - @@index([farmId, plotId]) - @@index([testDate]) - @@index([testLaboratory]) - @@map("soil_tests") -} \ No newline at end of file diff --git a/schemas/financial.prisma b/schemas/financial.prisma deleted file mode 100644 index 193c9a1..0000000 --- a/schemas/financial.prisma +++ /dev/null @@ -1,68 +0,0 @@ -// Financial Management Domain -// Contains financial records, transactions, and currency models - -// Financial-specific Enums -enum TransactionType { - INCOME - EXPENSE - INVESTMENT - LOAN - LOAN_PAYMENT - INSURANCE_PAYMENT - TAX_PAYMENT - GRANT - SUBSIDY - REFUND -} - -enum TransactionStatus { - PENDING - APPROVED - COMPLETED - REJECTED - CANCELLED - FAILED -} - -// Financial Models -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]) - - @@index([farmerId, farmId]) - @@index([type]) - @@index([transactionDate]) - @@index([status]) - @@index([category]) - @@index([paymentMethod]) - @@index([amount]) - @@map("financial_records") -} \ No newline at end of file diff --git a/schemas/knowledge.prisma b/schemas/knowledge.prisma deleted file mode 100644 index 6e826c5..0000000 --- a/schemas/knowledge.prisma +++ /dev/null @@ -1,33 +0,0 @@ -// Knowledge Management Domain -// Contains articles, content management, and knowledge base - -// Knowledge-specific Enums -enum ArticleStatus { - DRAFT - PUBLISHED - ARCHIVED -} - -// Knowledge Models -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 - - @@index([category]) - @@index([status]) - @@index([publishedAt]) - @@index([author]) - @@index([views]) - @@index([title]) - @@map("articles") -} \ No newline at end of file diff --git a/schemas/market.prisma b/schemas/market.prisma deleted file mode 100644 index 2aab051..0000000 --- a/schemas/market.prisma +++ /dev/null @@ -1,63 +0,0 @@ -// Market Intelligence Domain -// Contains market prices, demand analysis, and business intelligence - -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]) - - @@index([productId, variantId]) - @@index([market, region]) - @@index([priceDate]) - @@index([qualityGrade]) - @@index([trend]) - @@index([verified]) - @@index([price]) - @@map("market_prices") -} - -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]) - - @@index([productId, variantId]) - @@index([region]) - @@index([demandLevel]) - @@index([forecastDate]) - @@index([season]) - @@index([accuracy]) - @@map("market_demand") -} \ No newline at end of file diff --git a/schemas/operations.prisma b/schemas/operations.prisma deleted file mode 100644 index e1f5252..0000000 --- a/schemas/operations.prisma +++ /dev/null @@ -1,439 +0,0 @@ -// Operations Management Domain -// Contains Input management, Labor, Equipment, and daily operations - -// Operations-specific Enums -enum SupplierType { - SEED_SUPPLIER - FERTILIZER_SUPPLIER - PESTICIDE_SUPPLIER - EQUIPMENT_SUPPLIER - GENERAL_SUPPLIER - COOPERATIVE - GOVERNMENT_AGENCY -} - -enum WorkerRole { - PERMANENT - SEASONAL - DAILY - CONTRACTOR - SUPERVISOR - FOREMAN - SPECIALIST -} - -enum SkillLevel { - BEGINNER - INTERMEDIATE - ADVANCED - EXPERT -} - -enum ContractType { - PERMANENT - TEMPORARY - SEASONAL - PROJECT_BASED - DAILY -} - -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 -} - -// Operations Models -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]) - - @@index([farmId, plotId]) - @@index([inputType]) - @@index([applicationDate]) - @@index([supplier]) - @@index([expiryDate]) - @@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]) - - @@index([farmId, plotId]) - @@index([scheduledDate]) - @@index([status]) - @@index([inputType]) - @@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 - - @@index([supplierType]) - @@index([isActive]) - @@index([name]) - @@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[] - - @@index([workerCode]) - @@index([farmerId]) - @@index([role]) - @@index([isActive]) - @@index([contractType]) - @@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]) - - @@index([farmerId, farmId]) - @@index([workDate]) - @@index([workType]) - @@index([paymentStatus]) - @@index([workerId]) - @@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]) - - @@index([farmerId, farmId]) - @@index([scheduledDate]) - @@index([status]) - @@index([workType]) - @@index([workerId]) - @@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[] - - @@index([equipmentCode]) - @@index([farmerId]) - @@index([type]) - @@index([status]) - @@index([nextMaintenance]) - @@index([isActive]) - @@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]) - - @@index([equipmentId]) - @@index([serviceDate]) - @@index([maintenanceType]) - @@index([nextServiceDue]) - @@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]) - - @@index([equipmentId]) - @@index([usageDate]) - @@index([farmId, plotId]) - @@index([workType]) - @@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]) - - @@index([assetCode]) - @@index([farmerId]) - @@index([type]) - @@index([condition]) - @@index([isActive]) - @@map("assets") -} \ No newline at end of file diff --git a/schemas/pest-disease.prisma b/schemas/pest-disease.prisma deleted file mode 100644 index ef22e0c..0000000 --- a/schemas/pest-disease.prisma +++ /dev/null @@ -1,86 +0,0 @@ -// Pest & Disease Management Domain -// Contains pest, disease, and agricultural health tracking - -// Pest & Disease Enums -enum PestDiseaseType { - PEST - DISEASE - WEED - NUTRIENT_DEFICIENCY - VIRUS - FUNGUS - BACTERIA -} - -enum ReviewType { - PAYMENT_TIMELINESS - QUALITY_REQUIREMENTS - COMMUNICATION - OVERALL_EXPERIENCE - PRICE_FAIRNESS -} - -// Pest & Disease Models -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]) - - @@index([farmId, plotId]) - @@index([type]) - @@index([severity]) - @@index([identifiedDate]) - @@index([resolved]) - @@index([name]) - @@index([recurrence]) - @@map("pest_disease_records") -} - -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]) - - @@index([buyerId]) - @@index([farmerId]) - @@index([reviewType]) - @@index([rating]) - @@index([procurementId]) - @@index([createdAt]) - @@map("buyer_reviews") -} \ No newline at end of file diff --git a/schemas/procurement.prisma b/schemas/procurement.prisma deleted file mode 100644 index 2948c4f..0000000 --- a/schemas/procurement.prisma +++ /dev/null @@ -1,284 +0,0 @@ -// Procurement & Trading Domain -// Contains Procurement, Contract, Harvest, and related trading models - -// Procurement-specific Enums -enum ProcurementStatus { - PENDING - QUALITY_ASSESSMENT - APPROVED - REJECTED - IN_TRANSIT - DELIVERED - INVOICED - PAID - COMPLETED - CANCELLED - PARTIALLY_REJECTED -} - -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 -} - -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 -} - -// Procurement Models -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[] - - @@index([farmerId, farmId]) - @@index([harvestDate]) - @@index([variantId]) - @@index([qualityGrade]) - @@index([plotId]) - @@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[] - - @@index([procurementCode]) - @@index([farmerId, buyerId]) - @@index([status]) - @@index([procurementDate]) - @@index([variantId]) - @@index([qualityGrade]) - @@index([paymentMethod]) - @@map("procurements") -} - -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 - - @@index([contractNumber]) - @@index([farmerId, buyerId]) - @@index([status]) - @@index([startDate, endDate]) - @@index([productId, variantId]) - @@index([signedDate]) - @@map("contracts") -} - -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) - - @@index([procurementId]) - @@index([type]) - @@index([isVerified]) - @@index([createdAt]) - @@map("procurement_attachments") -} \ No newline at end of file diff --git a/schemas/product.prisma b/schemas/product.prisma deleted file mode 100644 index 73743be..0000000 --- a/schemas/product.prisma +++ /dev/null @@ -1,169 +0,0 @@ -// Product Management Domain -// Contains Product, ProductVariant, modifiers, and pricing models - -// Product-specific Enums -enum ModifierSelectionType { - DROPDOWN - INPUT -} - -enum NominalType { - NOMINAL - PERCENTAGE -} - -enum RuleCondition { - EQUALS - LESS_THAN - GREATER_THAN - BETWEEN -} - -// Product Models -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[] - - @@index([code]) - @@index([category]) - @@index([isActive]) - @@index([name]) - @@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[] - - @@index([code]) - @@index([productId]) - @@index([isActive]) - @@index([basePrice]) - @@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]) - @@index([productId]) - @@index([isActive]) - @@index([selectionType]) - @@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 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 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]) - - @@index([productId, variantId]) - @@index([effectiveDate]) - @@index([qualityGrade]) - @@index([region]) - @@map("price_history") -} \ No newline at end of file diff --git a/schemas/reference.prisma b/schemas/reference.prisma deleted file mode 100644 index 9d65690..0000000 --- a/schemas/reference.prisma +++ /dev/null @@ -1,76 +0,0 @@ -// Reference Data Domain -// Contains normalized reference tables for countries, currencies, education, religion - -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[] - - @@index([name]) - @@index([level]) - @@index([isActive]) - @@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[] - - @@index([code]) - @@index([isActive]) - @@index([name]) - @@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") - - @@index([code]) - @@index([region]) - @@index([continent]) - @@index([isActive]) - @@index([name]) - @@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[] - - @@index([name]) - @@index([isActive]) - @@map("religions") -} \ No newline at end of file diff --git a/schemas/season.prisma b/schemas/season.prisma deleted file mode 100644 index a1b568b..0000000 --- a/schemas/season.prisma +++ /dev/null @@ -1,196 +0,0 @@ -// Season & Cycle Management Domain -// Contains Season planning, PlotSeason tracking, and seasonal analytics - -// Season-specific 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 -} - -// Season Models -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]) - @@index([seasonType, year]) - @@index([region]) - @@index([startDate, endDate]) - @@index([isActive]) - @@index([isCurrent]) - @@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]) - @@index([plotId, seasonId]) - @@index([status]) - @@index([plantedDate]) - @@index([productId, variantId]) - @@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]) - - @@index([seasonId, farmerId]) - @@index([productId, variantId]) - @@index([firstHarvest]) - @@index([averageQuality]) - @@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]) - @@index([seasonId, region]) - @@index([totalRainfall]) - @@index([avgTemperature]) - @@map("season_weather") -} \ No newline at end of file diff --git a/schemas/training.prisma b/schemas/training.prisma deleted file mode 100644 index 6d958bb..0000000 --- a/schemas/training.prisma +++ /dev/null @@ -1,119 +0,0 @@ -// Training & Certification Domain -// Contains training programs, certifications, and farmer development - -// Training-specific Enums -enum TrainingStatus { - ENROLLED - IN_PROGRESS - COMPLETED - DROPPED -} - -enum CertificationStatus { - PENDING - APPROVED - REJECTED - EXPIRED -} - -// Training Models -model Training { - id String @id @default(cuid()) - title String - description String? - content String? - category String - duration Int? // in minutes - level String? // beginner, intermediate, advanced - prerequisites String? - maxParticipants Int? // Maximum number of participants - createdBy String? // Admin who created the training - isActive Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - // Relations - farmerTrainings FarmerTraining[] - - @@index([category]) - @@index([level]) - @@index([isActive]) - @@index([duration]) - @@index([createdBy]) - @@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? - assignedBy String? // Admin who assigned the farmer to training - assignedAt DateTime? // When the assignment was made - assignmentReason String? // Reason for assignment - deadline DateTime? // Expected completion deadline - 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]) - @@index([farmerId]) - @@index([trainingId]) - @@index([status]) - @@index([completedAt]) - @@index([progress]) - @@index([assignedBy]) - @@index([assignedAt]) - @@index([deadline]) - @@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[] - - @@index([name]) - @@index([isActive]) - @@index([validityPeriod]) - @@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]) - @@index([farmerId]) - @@index([certificationId]) - @@index([status]) - @@index([expiryDate]) - @@index([issuedDate]) - @@map("farmer_certifications") -} \ No newline at end of file diff --git a/schemas/user.prisma b/schemas/user.prisma deleted file mode 100644 index cd5a3ef..0000000 --- a/schemas/user.prisma +++ /dev/null @@ -1,261 +0,0 @@ -// User Management Domain -// Contains User, Farmer, Buyer, Administrator models and related enums - -// User Status Enums -enum FarmerStatus { - ACTIVE - INACTIVE - SUSPENDED - PENDING_VERIFICATION - BLACKLISTED -} - -enum BuyerStatus { - ACTIVE - INACTIVE - SUSPENDED - PENDING_VERIFICATION - BLACKLISTED -} - -enum BuyerType { - INDIVIDUAL - WHOLESALER - RETAILER - PROCESSOR - EXPORTER - COOPERATIVE - GOVERNMENT - RESTAURANT - HOTEL -} - -enum BusinessSize { - MICRO - SMALL - MEDIUM - LARGE - ENTERPRISE -} - -enum LandOwnership { - OWNER - TENANT - SHARECROPPER - COOPERATIVE_MEMBER - GOVERNMENT_LEASE - FAMILY_LAND - OTHER -} - -// User Models -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[] - - @@index([farmerCode]) - @@index([userId]) - @@index([status]) - @@index([joinedAt]) - @@index([latitude, longitude]) - @@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[] - - @@index([buyerCode]) - @@index([userId]) - @@index([status]) - @@index([buyerType]) - @@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) - - @@index([adminCode]) - @@index([userId]) - @@map("administrators") -} \ No newline at end of file diff --git a/schemas/weather.prisma b/schemas/weather.prisma deleted file mode 100644 index 0aebc13..0000000 --- a/schemas/weather.prisma +++ /dev/null @@ -1,66 +0,0 @@ -// Weather & Climate Domain -// Contains weather data, forecasts, and climate tracking - -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]) - - @@index([farmId, plotId]) - @@index([latitude, longitude]) - @@index([date]) - @@index([weatherCondition]) - @@index([dataSource]) - @@index([temperature]) - @@index([rainfall]) - @@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]) - - @@index([farmId, plotId]) - @@index([latitude, longitude]) - @@index([forecastDate]) - @@index([weatherCondition]) - @@index([source]) - @@index([confidence]) - @@map("weather_forecasts") -} \ No newline at end of file