/** * Database Types and Utilities * Type helpers for working with Prisma and the database */ import type { Prisma } from '@prisma/client'; // Re-export Prisma types for convenience export type { User, Plant, TransportEvent, VerticalFarm, GrowingZone, CropBatch, GrowingRecipe, SeedBatch, HarvestBatch, ConsumerPreference, DemandSignal, SupplyCommitment, MarketMatch, SeasonalPlan, DemandForecast, PlantingRecommendation, ResourceUsage, FarmAnalytics, AuditLog, BlockchainBlock, } from '@prisma/client'; // Common query options export interface PaginationOptions { page?: number; limit?: number; cursor?: string; } export interface SortOptions { field: string; direction: 'asc' | 'desc'; } // Location-based query options export interface LocationFilter { latitude: number; longitude: number; radiusKm: number; } // Date range filter export interface DateRangeFilter { start: Date; end: Date; } // Create input types for common operations export type CreateUserInput = Prisma.UserCreateInput; export type UpdateUserInput = Prisma.UserUpdateInput; export type CreatePlantInput = Prisma.PlantCreateInput; export type UpdatePlantInput = Prisma.PlantUpdateInput; export type CreateTransportEventInput = Prisma.TransportEventCreateInput; export type UpdateTransportEventInput = Prisma.TransportEventUpdateInput; export type CreateVerticalFarmInput = Prisma.VerticalFarmCreateInput; export type UpdateVerticalFarmInput = Prisma.VerticalFarmUpdateInput; export type CreateCropBatchInput = Prisma.CropBatchCreateInput; export type UpdateCropBatchInput = Prisma.CropBatchUpdateInput; // Result types with includes export type PlantWithOwner = Prisma.PlantGetPayload<{ include: { owner: true }; }>; export type PlantWithLineage = Prisma.PlantGetPayload<{ include: { owner: true; parentPlant: true; childPlants: true; }; }>; export type TransportEventWithParties = Prisma.TransportEventGetPayload<{ include: { sender: true; receiver: true; plants: true; }; }>; export type VerticalFarmWithZones = Prisma.VerticalFarmGetPayload<{ include: { owner: true; zones: true; cropBatches: true; }; }>; // Utility type for pagination results export interface PaginatedResult { items: T[]; total: number; page: number; limit: number; totalPages: number; hasMore: boolean; } // Helper function to calculate distance between two points (Haversine formula) export function calculateDistanceKm( lat1: number, lon1: number, lat2: number, lon2: number ): number { const R = 6371; // Earth's radius in km const dLat = toRad(lat2 - lat1); const dLon = toRad(lon2 - lon1); const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return R * c; } function toRad(deg: number): number { return deg * (Math.PI / 180); } // Helper to create pagination result export function createPaginatedResult( items: T[], total: number, page: number, limit: number ): PaginatedResult { const totalPages = Math.ceil(total / limit); return { items, total, page, limit, totalPages, hasMore: page < totalPages, }; }