import { db } from '../db/db_index' import { users, userDetails, orders, orderItems, complaints, notifCreds, unloggedUserTokens, userIncidents, orderStatus } from '../db/schema' import { eq, sql, desc, asc, count, max, inArray } from 'drizzle-orm' export async function createUserByMobile(mobile: string): Promise { const [newUser] = await db .insert(users) .values({ name: null, email: null, mobile, }) .returning() return newUser } export async function getUserByMobile(mobile: string): Promise { const [existingUser] = await db .select() .from(users) .where(eq(users.mobile, mobile)) .limit(1) return existingUser || null } export async function getUnresolvedComplaintsCount(): Promise { const result = await db .select({ count: count(complaints.id) }) .from(complaints) .where(eq(complaints.isResolved, false)) return result[0]?.count || 0 } export async function getAllUsersWithFilters( limit: number, cursor?: number, search?: string ): Promise<{ users: any[]; hasMore: boolean }> { const whereConditions = [] if (search && search.trim()) { whereConditions.push(sql`${users.mobile} LIKE ${`%${search.trim()}%`}`) } if (cursor) { whereConditions.push(sql`${users.id} > ${cursor}`) } const usersList = await db .select({ id: users.id, name: users.name, mobile: users.mobile, createdAt: users.createdAt, }) .from(users) .where(whereConditions.length > 0 ? sql.join(whereConditions, sql` AND `) : undefined) .orderBy(asc(users.id)) .limit(limit + 1) const hasMore = usersList.length > limit const usersToReturn = hasMore ? usersList.slice(0, limit) : usersList return { users: usersToReturn, hasMore } } export async function getOrderCountsByUserIds(userIds: number[]): Promise<{ userId: number; totalOrders: number }[]> { if (userIds.length === 0) return [] return await db .select({ userId: orders.userId, totalOrders: count(orders.id), }) .from(orders) .where(sql`${orders.userId} IN (${sql.join(userIds, sql`, `)})`) .groupBy(orders.userId) } export async function getLastOrdersByUserIds(userIds: number[]): Promise<{ userId: number; lastOrderDate: Date | null }[]> { if (userIds.length === 0) return [] return await db .select({ userId: orders.userId, lastOrderDate: max(orders.createdAt), }) .from(orders) .where(sql`${orders.userId} IN (${sql.join(userIds, sql`, `)})`) .groupBy(orders.userId) } export async function getSuspensionStatusesByUserIds(userIds: number[]): Promise<{ userId: number; isSuspended: boolean }[]> { if (userIds.length === 0) return [] return await db .select({ userId: userDetails.userId, isSuspended: userDetails.isSuspended, }) .from(userDetails) .where(sql`${userDetails.userId} IN (${sql.join(userIds, sql`, `)})`) } export async function getUserBasicInfo(userId: number): Promise { const user = await db .select({ id: users.id, name: users.name, mobile: users.mobile, createdAt: users.createdAt, }) .from(users) .where(eq(users.id, userId)) .limit(1) return user[0] || null } export async function getUserSuspensionStatus(userId: number): Promise { const userDetail = await db .select({ isSuspended: userDetails.isSuspended, }) .from(userDetails) .where(eq(userDetails.userId, userId)) .limit(1) return userDetail[0]?.isSuspended ?? false } export async function getUserOrders(userId: number): Promise { return await db .select({ id: orders.id, readableId: orders.readableId, totalAmount: orders.totalAmount, createdAt: orders.createdAt, isFlashDelivery: orders.isFlashDelivery, }) .from(orders) .where(eq(orders.userId, userId)) .orderBy(desc(orders.createdAt)) } export async function getOrderStatusesByOrderIds(orderIds: number[]): Promise<{ orderId: number; isDelivered: boolean; isCancelled: boolean }[]> { if (orderIds.length === 0) return [] return await db .select({ orderId: orderStatus.orderId, isDelivered: orderStatus.isDelivered, isCancelled: orderStatus.isCancelled, }) .from(orderStatus) .where(sql`${orderStatus.orderId} IN (${sql.join(orderIds, sql`, `)})`) } export async function getItemCountsByOrderIds(orderIds: number[]): Promise<{ orderId: number; itemCount: number }[]> { if (orderIds.length === 0) return [] return await db .select({ orderId: orderItems.orderId, itemCount: count(orderItems.id), }) .from(orderItems) .where(sql`${orderItems.orderId} IN (${sql.join(orderIds, sql`, `)})`) .groupBy(orderItems.orderId) } export async function upsertUserSuspension(userId: number, isSuspended: boolean): Promise { const existingDetail = await db .select({ id: userDetails.id }) .from(userDetails) .where(eq(userDetails.userId, userId)) .limit(1) if (existingDetail.length > 0) { await db .update(userDetails) .set({ isSuspended }) .where(eq(userDetails.userId, userId)) } else { await db .insert(userDetails) .values({ userId, isSuspended, }) } } export async function searchUsers(search?: string): Promise { if (search && search.trim()) { return await db .select({ id: users.id, name: users.name, mobile: users.mobile, }) .from(users) .where(sql`${users.mobile} LIKE ${`%${search.trim()}%`} OR ${users.name} LIKE ${`%${search.trim()}%`}`) } else { return await db .select({ id: users.id, name: users.name, mobile: users.mobile, }) .from(users) } } export async function getAllNotifCreds(): Promise<{ userId: number, token: string }[]> { return await db .select({ userId: notifCreds.userId, token: notifCreds.token }) .from(notifCreds) } export async function getAllUnloggedTokens(): Promise<{ token: string }[]> { return await db .select({ token: unloggedUserTokens.token }) .from(unloggedUserTokens) } export async function getNotifTokensByUserIds(userIds: number[]): Promise<{ token: string }[]> { return await db .select({ token: notifCreds.token }) .from(notifCreds) .where(inArray(notifCreds.userId, userIds)) } export async function getUserIncidentsWithRelations(userId: number): Promise { return await db.query.userIncidents.findMany({ where: eq(userIncidents.userId, userId), with: { order: { with: { orderStatus: true, }, }, addedBy: true, }, orderBy: desc(userIncidents.dateAdded), }) } export async function createUserIncident( userId: number, orderId: number | undefined, adminComment: string | undefined, adminUserId: number, negativityScore: number | undefined ): Promise { const [incident] = await db.insert(userIncidents) .values({ userId, orderId, adminComment, addedBy: adminUserId, negativityScore, }) .returning() return incident }