/** * User Database Service * CRUD operations for users */ import prisma from './prisma'; import type { User, UserType, Prisma } from '@prisma/client'; import type { PaginationOptions, PaginatedResult } from './types'; import { createPaginatedResult } from './types'; // Create a new user export async function createUser(data: { email: string; name: string; walletAddress?: string; passwordHash?: string; avatarUrl?: string; bio?: string; latitude?: number; longitude?: number; address?: string; city?: string; country?: string; userType?: UserType; }): Promise { return prisma.user.create({ data: { ...data, userType: data.userType || 'CONSUMER', }, }); } // Get user by ID export async function getUserById(id: string): Promise { return prisma.user.findUnique({ where: { id }, }); } // Get user by email export async function getUserByEmail(email: string): Promise { return prisma.user.findUnique({ where: { email }, }); } // Get user by wallet address export async function getUserByWalletAddress(walletAddress: string): Promise { return prisma.user.findUnique({ where: { walletAddress }, }); } // Update user export async function updateUser( id: string, data: Prisma.UserUpdateInput ): Promise { return prisma.user.update({ where: { id }, data, }); } // Delete user export async function deleteUser(id: string): Promise { return prisma.user.delete({ where: { id }, }); } // Get all users with pagination export async function getUsers( options: PaginationOptions = {}, filters?: { userType?: UserType; city?: string; country?: string; } ): Promise> { const page = options.page || 1; const limit = options.limit || 20; const skip = (page - 1) * limit; const where: Prisma.UserWhereInput = {}; if (filters?.userType) where.userType = filters.userType; if (filters?.city) where.city = { contains: filters.city, mode: 'insensitive' }; if (filters?.country) where.country = { contains: filters.country, mode: 'insensitive' }; const [users, total] = await Promise.all([ prisma.user.findMany({ where, skip, take: limit, orderBy: { createdAt: 'desc' }, }), prisma.user.count({ where }), ]); return createPaginatedResult(users, total, page, limit); } // Get users by type export async function getUsersByType(userType: UserType): Promise { return prisma.user.findMany({ where: { userType }, orderBy: { name: 'asc' }, }); } // Update last login export async function updateLastLogin(id: string): Promise { return prisma.user.update({ where: { id }, data: { lastLoginAt: new Date() }, }); } // Search users export async function searchUsers( query: string, options: PaginationOptions = {} ): Promise> { const page = options.page || 1; const limit = options.limit || 20; const skip = (page - 1) * limit; const where: Prisma.UserWhereInput = { OR: [ { name: { contains: query, mode: 'insensitive' } }, { email: { contains: query, mode: 'insensitive' } }, { city: { contains: query, mode: 'insensitive' } }, ], }; const [users, total] = await Promise.all([ prisma.user.findMany({ where, skip, take: limit, orderBy: { name: 'asc' }, }), prisma.user.count({ where }), ]); return createPaginatedResult(users, total, page, limit); } // Get user with their plants export async function getUserWithPlants(id: string) { return prisma.user.findUnique({ where: { id }, include: { ownedPlants: { orderBy: { registeredAt: 'desc' }, }, }, }); } // Get user with their farms export async function getUserWithFarms(id: string) { return prisma.user.findUnique({ where: { id }, include: { verticalFarms: { include: { zones: true, }, }, }, }); } // Get user statistics export async function getUserStats(id: string) { const [ plantCount, farmCount, transportEventsSent, transportEventsReceived, supplyCommitments, ] = await Promise.all([ prisma.plant.count({ where: { ownerId: id } }), prisma.verticalFarm.count({ where: { ownerId: id } }), prisma.transportEvent.count({ where: { senderId: id } }), prisma.transportEvent.count({ where: { receiverId: id } }), prisma.supplyCommitment.count({ where: { growerId: id } }), ]); return { plantCount, farmCount, transportEventsSent, transportEventsReceived, supplyCommitments, }; }