import { sqliteTable, integer, text, real, uniqueIndex, primaryKey, check, customType, } from 'drizzle-orm/sqlite-core' import { relations, sql } from 'drizzle-orm' import { coerceDate } from '../lib/date' const jsonText = (name: string) => customType<{ data: T | null; driverData: string | null }>({ dataType() { return 'text' }, toDriver(value) { if (value === undefined || value === null) return null return JSON.stringify(value) }, fromDriver(value) { if (value === null || value === undefined) return null try { return JSON.parse(String(value)) as T } catch { return null } }, })(name) const numericText = (name: string) => customType<{ data: string | null; driverData: string | null }>({ dataType() { return 'text' }, toDriver(value) { if (value === undefined || value === null) return null return String(value) }, fromDriver(value) { if (value === null || value === undefined) return null return String(value) }, })(name) const timestampText = (name: string) => customType<{ data: Date; driverData: string | number | null }>({ dataType() { return 'text' }, toDriver(value) { if (value === undefined || value === null) return null if (value instanceof Date) return value.toISOString() return String(value) }, fromDriver(value) { if (value === null || value === undefined) return new Date(0) return coerceDate(value) || new Date(0) }, })(name) const staffRoleValues = ['super_admin', 'admin', 'marketer', 'delivery_staff'] as const const staffPermissionValues = ['crud_product', 'make_coupon', 'crud_staff_users'] as const const uploadStatusValues = ['pending', 'claimed'] as const const paymentStatusValues = ['pending', 'success', 'cod', 'failed'] as const const productTypeValues = ['item', 'combo'] as const export const staffRoleEnum = (name: string) => text(name, { enum: staffRoleValues }) export const staffPermissionEnum = (name: string) => text(name, { enum: staffPermissionValues }) export const uploadStatusEnum = (name: string) => text(name, { enum: uploadStatusValues }) export const paymentStatusEnum = (name: string) => text(name, { enum: paymentStatusValues }) export const productTypeEnum = (name: string) => text(name, { enum: productTypeValues }) export const users = sqliteTable('users', { id: integer().primaryKey({ autoIncrement: true }), name: text(), email: text(), mobile: text(), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_email: uniqueIndex('unique_email').on(t.email), })) export const userDetails = sqliteTable('user_details', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id).unique(), bio: text('bio'), dateOfBirth: timestampText('date_of_birth'), gender: text('gender'), occupation: text('occupation'), profileImage: text('profile_image'), isSuspended: integer('is_suspended', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), updatedAt: timestampText('updated_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const userCreds = sqliteTable('user_creds', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), userPassword: text('user_password').notNull(), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const addressZones = sqliteTable('address_zones', { id: integer().primaryKey({ autoIncrement: true }), zoneName: text('zone_name').notNull(), addedAt: timestampText('added_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const addressAreas = sqliteTable('address_areas', { id: integer().primaryKey({ autoIncrement: true }), placeName: text('place_name').notNull(), zoneId: integer('zone_id').references(() => addressZones.id), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const addresses = sqliteTable('addresses', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), name: text('name').notNull(), phone: text('phone').notNull(), addressLine1: text('address_line1').notNull(), addressLine2: text('address_line2'), city: text('city').notNull(), state: text('state').notNull(), pincode: text('pincode').notNull(), isDefault: integer('is_default', { mode: 'boolean' }).notNull().default(false), latitude: real('latitude'), longitude: real('longitude'), googleMapsUrl: text('google_maps_url'), adminLatitude: real('admin_latitude'), adminLongitude: real('admin_longitude'), zoneId: integer('zone_id').references(() => addressZones.id), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const staffRoles = sqliteTable('staff_roles', { id: integer().primaryKey({ autoIncrement: true }), roleName: staffRoleEnum('role_name').notNull(), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_role_name: uniqueIndex('unique_role_name').on(t.roleName), })) export const staffPermissions = sqliteTable('staff_permissions', { id: integer().primaryKey({ autoIncrement: true }), permissionName: staffPermissionEnum('permission_name').notNull(), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_permission_name: uniqueIndex('unique_permission_name').on(t.permissionName), })) export const staffRolePermissions = sqliteTable('staff_role_permissions', { id: integer().primaryKey({ autoIncrement: true }), staffRoleId: integer('staff_role_id').notNull().references(() => staffRoles.id), staffPermissionId: integer('staff_permission_id').notNull().references(() => staffPermissions.id), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_role_permission: uniqueIndex('unique_role_permission').on(t.staffRoleId, t.staffPermissionId), })) export const staffUsers = sqliteTable('staff_users', { id: integer().primaryKey({ autoIncrement: true }), name: text().notNull(), password: text().notNull(), staffRoleId: integer('staff_role_id').references(() => staffRoles.id), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const storeInfo = sqliteTable('store_info', { id: integer().primaryKey({ autoIncrement: true }), name: text().notNull(), description: text(), imageUrl: text('image_url'), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), owner: integer('owner').notNull().references(() => staffUsers.id), }) export const units = sqliteTable('units', { id: integer().primaryKey({ autoIncrement: true }), shortNotation: text('short_notation').notNull(), fullName: text('full_name').notNull(), }, (t) => ({ unq_short_notation: uniqueIndex('unique_short_notation').on(t.shortNotation), })) export const productInfo = sqliteTable('product_info', { id: integer().primaryKey({ autoIncrement: true }), name: text().notNull(), shortDescription: text('short_description'), longDescription: text('long_description'), storeId: integer('store_id').references(() => storeInfo.id), incrementStep: real('increment_step').notNull().default(1), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), productType: productTypeEnum('product_type').notNull().default('item'), }) export const productSkus = sqliteTable('product_skus', { id: integer().primaryKey({ autoIncrement: true }), productId: integer('product_id').notNull().references(() => productInfo.id), name: text(), images: jsonText('images'), isOffer: integer('is_offer', { mode: 'boolean' }).notNull().default(false), isComboOnly: integer('is_combo_only', { mode: 'boolean' }).notNull().default(false), isDeleted: integer('is_deleted', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const productMarketStats = sqliteTable('product_market_stats', { id: integer().primaryKey({ autoIncrement: true }), skuId: integer('sku_id').notNull().references(() => productSkus.id).unique(), marketPrice: numericText('market_price'), ourPrice: numericText('our_price').notNull(), isFlashAvailable: integer('is_flash_available', { mode: 'boolean' }).notNull().default(false), flashPrice: numericText('flash_price'), isOutOfStock: integer('is_out_of_stock', { mode: 'boolean' }).notNull().default(false), isSuspended: integer('is_suspended', { mode: 'boolean' }).notNull().default(false), }) export const skuFeatures = sqliteTable('sku_features', { id: integer().primaryKey({ autoIncrement: true }), skuId: integer('sku_id').notNull().references(() => productSkus.id), featureName: text('feature_name'), featureValue: text('feature_value').notNull(), }, (t) => ({ unq_sku_feature_name: uniqueIndex('unique_sku_feature_name').on(t.skuId, t.featureName), })) export const productCombos = sqliteTable('product_combos', { id: integer().primaryKey({ autoIncrement: true }), comboSkuId: integer('combo_sku_id').notNull().references(() => productSkus.id), skuId: integer('sku_id').notNull().references(() => productSkus.id), }, (t) => ({ unq_combo_sku: uniqueIndex('unique_combo_sku_item').on(t.comboSkuId, t.skuId), })) export const productGroupInfo = sqliteTable('product_group_info', { id: integer().primaryKey({ autoIncrement: true }), groupName: text('group_name').notNull(), description: text(), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const productGroupMembership = sqliteTable('product_group_membership', { productId: integer('product_id').notNull().references(() => productSkus.id), groupId: integer('group_id').notNull().references(() => productGroupInfo.id), addedAt: timestampText('added_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ pk: primaryKey({ columns: [t.productId, t.groupId], name: 'product_group_membership_pk' }), })) export const homeBanners = sqliteTable('home_banners', { id: integer().primaryKey({ autoIncrement: true }), name: text('name').notNull(), imageUrl: text('image_url').notNull(), description: text('description'), skuIds: jsonText('sku_ids'), redirectUrl: text('redirect_url'), serialNum: integer('serial_num'), isActive: integer('is_active', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), lastUpdated: timestampText('last_updated').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const productReviews = sqliteTable('product_reviews', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), productId: integer('product_id').notNull().references(() => productInfo.id), reviewBody: text('review_body').notNull(), imageUrls: jsonText('image_urls').$defaultFn(() => []), reviewTime: timestampText('review_time').notNull().default(sql`CURRENT_TIMESTAMP`), ratings: real('ratings').notNull(), adminResponse: text('admin_response'), adminResponseImages: jsonText('admin_response_images').$defaultFn(() => []), }, (t) => ({ ratingCheck: check('rating_check', sql`${t.ratings} >= 1 AND ${t.ratings} <= 5`), })) export const uploadUrlStatus = sqliteTable('upload_url_status', { id: integer().primaryKey({ autoIncrement: true }), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), key: text('key').notNull(), status: uploadStatusEnum('status').notNull().default('pending'), }) export const productTagInfo = sqliteTable('product_tag_info', { id: integer().primaryKey({ autoIncrement: true }), tagName: text('tag_name').notNull().unique(), tagDescription: text('tag_description'), imageUrl: text('image_url'), isDashboardTag: integer('is_dashboard_tag', { mode: 'boolean' }).notNull().default(false), relatedStores: jsonText('related_stores').$defaultFn(() => []), sortOrder: jsonText('sort_order').$defaultFn(() => []), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const productTags = sqliteTable('product_tags', { id: integer().primaryKey({ autoIncrement: true }), productId: integer('product_id').notNull().references(() => productSkus.id), tagId: integer('tag_id').notNull().references(() => productTagInfo.id), assignedAt: timestampText('assigned_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_product_tag: uniqueIndex('unique_product_tag').on(t.productId, t.tagId), })) export const deliverySlotInfo = sqliteTable('delivery_slot_info', { id: integer().primaryKey({ autoIncrement: true }), deliveryTime: timestampText('delivery_time').notNull(), freezeTime: timestampText('freeze_time').notNull(), isActive: integer('is_active', { mode: 'boolean' }).notNull().default(true), isFlash: integer('is_flash', { mode: 'boolean' }).notNull().default(false), isCapacityFull: integer('is_capacity_full', { mode: 'boolean' }).notNull().default(false), deliverySequence: jsonText>('delivery_sequence').$defaultFn(() => ({})), groupIds: jsonText('group_ids').$defaultFn(() => []), skuIds: jsonText('sku_ids').$defaultFn(() => []), }) export const vendorSnippets = sqliteTable('vendor_snippets', { id: integer().primaryKey({ autoIncrement: true }), snippetCode: text('snippet_code').notNull().unique(), slotId: integer('slot_id').references(() => deliverySlotInfo.id), isPermanent: integer('is_permanent', { mode: 'boolean' }).notNull().default(false), skuIds: jsonText('sku_ids').notNull(), validTill: timestampText('valid_till'), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const specialDeals = sqliteTable('special_deals', { id: integer().primaryKey({ autoIncrement: true }), skuId: integer('sku_id').notNull().references(() => productSkus.id), quantity: numericText('quantity').notNull(), price: numericText('price').notNull(), validTill: timestampText('valid_till').notNull(), }) export const paymentInfoTable = sqliteTable('payment_info', { id: integer().primaryKey({ autoIncrement: true }), status: text().notNull(), gateway: text().notNull(), orderId: text('order_id'), token: text('token'), merchantOrderId: text('merchant_order_id').notNull().unique(), payload: jsonText('payload'), }) export const orders = sqliteTable('orders', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), addressId: integer('address_id').notNull().references(() => addresses.id), slotId: integer('slot_id').references(() => deliverySlotInfo.id), isCod: integer('is_cod', { mode: 'boolean' }).notNull().default(false), isOnlinePayment: integer('is_online_payment', { mode: 'boolean' }).notNull().default(false), paymentInfoId: integer('payment_info_id').references(() => paymentInfoTable.id), totalAmount: numericText('total_amount').notNull(), deliveryCharge: numericText('delivery_charge').notNull().default('0'), readableId: integer('readable_id').notNull(), adminNotes: text('admin_notes'), userNotes: text('user_notes'), orderGroupId: text('order_group_id'), orderGroupProportion: numericText('order_group_proportion'), isFlashDelivery: integer('is_flash_delivery', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const orderItems = sqliteTable('order_items', { id: integer().primaryKey({ autoIncrement: true }), orderId: integer('order_id').notNull().references(() => orders.id), skuId: integer('sku_id').notNull().references(() => productSkus.id), quantity: text('quantity').notNull(), price: numericText('price').notNull(), discountedPrice: numericText('discounted_price'), is_packaged: integer('is_packaged', { mode: 'boolean' }).notNull().default(false), is_package_verified: integer('is_package_verified', { mode: 'boolean' }).notNull().default(false), }) export const orderStatus = sqliteTable('order_status', { id: integer().primaryKey({ autoIncrement: true }), orderTime: timestampText('order_time').notNull().default(sql`CURRENT_TIMESTAMP`), userId: integer('user_id').notNull().references(() => users.id), orderId: integer('order_id').notNull().references(() => orders.id), isPackaged: integer('is_packaged', { mode: 'boolean' }).notNull().default(false), isDelivered: integer('is_delivered', { mode: 'boolean' }).notNull().default(false), isCancelled: integer('is_cancelled', { mode: 'boolean' }).notNull().default(false), cancelReason: text('cancel_reason'), isCancelledByAdmin: integer('is_cancelled_by_admin', { mode: 'boolean' }), paymentStatus: paymentStatusEnum('payment_state').notNull().default('pending'), cancellationUserNotes: text('cancellation_user_notes'), cancellationAdminNotes: text('cancellation_admin_notes'), cancellationReviewed: integer('cancellation_reviewed', { mode: 'boolean' }).notNull().default(false), cancellationReviewedAt: timestampText('cancellation_reviewed_at'), refundCouponId: integer('refund_coupon_id').references(() => coupons.id), }) export const payments = sqliteTable('payments', { id: integer().primaryKey({ autoIncrement: true }), status: text().notNull(), gateway: text().notNull(), orderId: integer('order_id').notNull().references(() => orders.id), token: text('token'), merchantOrderId: text('merchant_order_id').notNull().unique(), payload: jsonText('payload'), }) export const refunds = sqliteTable('refunds', { id: integer().primaryKey({ autoIncrement: true }), orderId: integer('order_id').notNull().references(() => orders.id), refundAmount: numericText('refund_amount'), refundStatus: text('refund_status').default('none'), merchantRefundId: text('merchant_refund_id'), refundProcessedAt: timestampText('refund_processed_at'), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const keyValStore = sqliteTable('key_val_store', { key: text('key').primaryKey(), value: text(), }) export const notifications = sqliteTable('notifications', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), title: text().notNull(), body: text().notNull(), type: text(), isRead: integer('is_read', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const productCategories = sqliteTable('product_categories', { id: integer().primaryKey({ autoIncrement: true }), name: text().notNull(), description: text(), }) export const cartItems = sqliteTable('cart_items', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), skuId: integer('sku_id').notNull().references(() => productSkus.id), quantity: numericText('quantity').notNull(), addedAt: timestampText('added_at').notNull().default(sql`CURRENT_TIMESTAMP`), }, (t) => ({ unq_user_sku: uniqueIndex('unique_user_sku').on(t.userId, t.skuId), })) export const complaints = sqliteTable('complaints', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), orderId: integer('order_id').references(() => orders.id), complaintBody: text('complaint_body').notNull(), images: jsonText('images'), response: text('response'), isResolved: integer('is_resolved', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const coupons = sqliteTable('coupons', { id: integer().primaryKey({ autoIncrement: true }), couponCode: text('coupon_code').notNull().unique(), isUserBased: integer('is_user_based', { mode: 'boolean' }).notNull().default(false), discountPercent: numericText('discount_percent'), flatDiscount: numericText('flat_discount'), minOrder: numericText('min_order'), skuIds: jsonText('sku_ids'), createdBy: integer('created_by').notNull().references(() => staffUsers.id), maxValue: numericText('max_value'), isApplyForAll: integer('is_apply_for_all', { mode: 'boolean' }).notNull().default(false), validTill: timestampText('valid_till'), maxLimitForUser: integer('max_limit_for_user'), isInvalidated: integer('is_invalidated', { mode: 'boolean' }).notNull().default(false), exclusiveApply: integer('exclusive_apply', { mode: 'boolean' }).notNull().default(false), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const couponUsage = sqliteTable('coupon_usage', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), couponId: integer('coupon_id').notNull().references(() => coupons.id), orderId: integer('order_id').references(() => orders.id), orderItemId: integer('order_item_id').references(() => orderItems.id), usedAt: timestampText('used_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const couponApplicableUsers = sqliteTable('coupon_applicable_users', { id: integer().primaryKey({ autoIncrement: true }), couponId: integer('coupon_id').notNull().references(() => coupons.id), userId: integer('user_id').notNull().references(() => users.id), }, (t) => ({ unq_coupon_user: uniqueIndex('unique_coupon_user').on(t.couponId, t.userId), })) export const couponApplicableProducts = sqliteTable('coupon_applicable_products', { id: integer().primaryKey({ autoIncrement: true }), couponId: integer('coupon_id').notNull().references(() => coupons.id), skuId: integer('sku_id').notNull().references(() => productSkus.id), }, (t) => ({ unq_coupon_sku: uniqueIndex('unique_coupon_sku').on(t.couponId, t.skuId), })) export const userIncidents = sqliteTable('user_incidents', { id: integer().primaryKey({ autoIncrement: true }), userId: integer('user_id').notNull().references(() => users.id), orderId: integer('order_id').references(() => orders.id), dateAdded: timestampText('date_added').notNull().default(sql`CURRENT_TIMESTAMP`), adminComment: text('admin_comment'), addedBy: integer('added_by').references(() => staffUsers.id), negativityScore: integer('negativity_score'), }) export const reservedCoupons = sqliteTable('reserved_coupons', { id: integer().primaryKey({ autoIncrement: true }), secretCode: text('secret_code').notNull().unique(), couponCode: text('coupon_code').notNull(), discountPercent: numericText('discount_percent'), flatDiscount: numericText('flat_discount'), minOrder: numericText('min_order'), skuIds: jsonText('sku_ids'), maxValue: numericText('max_value'), validTill: timestampText('valid_till'), maxLimitForUser: integer('max_limit_for_user'), exclusiveApply: integer('exclusive_apply', { mode: 'boolean' }).notNull().default(false), isRedeemed: integer('is_redeemed', { mode: 'boolean' }).notNull().default(false), redeemedBy: integer('redeemed_by').references(() => users.id), redeemedAt: timestampText('redeemed_at'), createdBy: integer('created_by').notNull().references(() => staffUsers.id), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), }) export const notifCreds = sqliteTable('notif_creds', { id: integer().primaryKey({ autoIncrement: true }), token: text().notNull().unique(), addedAt: timestampText('added_at').notNull().default(sql`CURRENT_TIMESTAMP`), userId: integer('user_id').notNull().references(() => users.id), lastVerified: timestampText('last_verified'), }) export const unloggedUserTokens = sqliteTable('unlogged_user_tokens', { id: integer().primaryKey({ autoIncrement: true }), token: text().notNull().unique(), addedAt: timestampText('added_at').notNull().default(sql`CURRENT_TIMESTAMP`), lastVerified: timestampText('last_verified'), }) export const userNotifications = sqliteTable('user_notifications', { id: integer().primaryKey({ autoIncrement: true }), title: text('title').notNull(), imageUrl: text('image_url'), createdAt: timestampText('created_at').notNull().default(sql`CURRENT_TIMESTAMP`), body: text('body').notNull(), applicableUsers: jsonText('applicable_users'), }) // Relations export const usersRelations = relations(users, ({ many, one }) => ({ addresses: many(addresses), orders: many(orders), notifications: many(notifications), cartItems: many(cartItems), userCreds: one(userCreds), coupons: many(coupons), couponUsages: many(couponUsage), applicableCoupons: many(couponApplicableUsers), userDetails: one(userDetails), notifCreds: many(notifCreds), userIncidents: many(userIncidents), })) export const userCredsRelations = relations(userCreds, ({ one }) => ({ user: one(users, { fields: [userCreds.userId], references: [users.id] }), })) export const staffUsersRelations = relations(staffUsers, ({ one, many }) => ({ role: one(staffRoles, { fields: [staffUsers.staffRoleId], references: [staffRoles.id] }), coupons: many(coupons), stores: many(storeInfo), })) export const addressesRelations = relations(addresses, ({ one, many }) => ({ user: one(users, { fields: [addresses.userId], references: [users.id] }), orders: many(orders), zone: one(addressZones, { fields: [addresses.zoneId], references: [addressZones.id] }), })) export const unitsRelations = relations(units, ({}) => ({ // Units are no longer linked to products/SKUs; kept as a reference table. })) export const productInfoRelations = relations(productInfo, ({ one, many }) => ({ store: one(storeInfo, { fields: [productInfo.storeId], references: [storeInfo.id] }), skus: many(productSkus), tags: many(productTags), reviews: many(productReviews), groups: many(productGroupMembership), })) export const productSkusRelations = relations(productSkus, ({ one, many }) => ({ product: one(productInfo, { fields: [productSkus.productId], references: [productInfo.id] }), features: many(skuFeatures), marketStats: one(productMarketStats), specialDeals: many(specialDeals), orderItems: many(orderItems), cartItems: many(cartItems), applicableCoupons: many(couponApplicableProducts), comboItems: many(productCombos, { relationName: 'comboSku' }), })) export const productMarketStatsRelations = relations(productMarketStats, ({ one }) => ({ sku: one(productSkus, { fields: [productMarketStats.skuId], references: [productSkus.id] }), })) export const skuFeaturesRelations = relations(skuFeatures, ({ one }) => ({ sku: one(productSkus, { fields: [skuFeatures.skuId], references: [productSkus.id] }), })) export const productCombosRelations = relations(productCombos, ({ one }) => ({ comboSku: one(productSkus, { fields: [productCombos.comboSkuId], references: [productSkus.id], relationName: 'comboSku', }), sku: one(productSkus, { fields: [productCombos.skuId], references: [productSkus.id], }), })) export const productTagInfoRelations = relations(productTagInfo, ({ many }) => ({ products: many(productTags), })) export const productTagsRelations = relations(productTags, ({ one }) => ({ sku: one(productSkus, { fields: [productTags.productId], references: [productSkus.id] }), tag: one(productTagInfo, { fields: [productTags.tagId], references: [productTagInfo.id] }), })) export const deliverySlotInfoRelations = relations(deliverySlotInfo, ({ many }) => ({ orders: many(orders), vendorSnippets: many(vendorSnippets), })) export const specialDealsRelations = relations(specialDeals, ({ one }) => ({ sku: one(productSkus, { fields: [specialDeals.skuId], references: [productSkus.id] }), })) export const ordersRelations = relations(orders, ({ one, many }) => ({ user: one(users, { fields: [orders.userId], references: [users.id] }), address: one(addresses, { fields: [orders.addressId], references: [addresses.id] }), slot: one(deliverySlotInfo, { fields: [orders.slotId], references: [deliverySlotInfo.id] }), orderItems: many(orderItems), payment: one(payments), paymentInfo: one(paymentInfoTable, { fields: [orders.paymentInfoId], references: [paymentInfoTable.id] }), orderStatus: many(orderStatus), refunds: many(refunds), couponUsages: many(couponUsage), userIncidents: many(userIncidents), })) export const orderItemsRelations = relations(orderItems, ({ one }) => ({ order: one(orders, { fields: [orderItems.orderId], references: [orders.id] }), sku: one(productSkus, { fields: [orderItems.skuId], references: [productSkus.id] }), })) export const orderStatusRelations = relations(orderStatus, ({ one }) => ({ order: one(orders, { fields: [orderStatus.orderId], references: [orders.id] }), user: one(users, { fields: [orderStatus.userId], references: [users.id] }), refundCoupon: one(coupons, { fields: [orderStatus.refundCouponId], references: [coupons.id] }), })) export const paymentInfoRelations = relations(paymentInfoTable, ({ one }) => ({ order: one(orders, { fields: [paymentInfoTable.id], references: [orders.paymentInfoId] }), })) export const paymentsRelations = relations(payments, ({ one }) => ({ order: one(orders, { fields: [payments.orderId], references: [orders.id] }), })) export const refundsRelations = relations(refunds, ({ one }) => ({ order: one(orders, { fields: [refunds.orderId], references: [orders.id] }), })) export const notificationsRelations = relations(notifications, ({ one }) => ({ user: one(users, { fields: [notifications.userId], references: [users.id] }), })) export const productCategoriesRelations = relations(productCategories, ({}) => ({})) export const cartItemsRelations = relations(cartItems, ({ one }) => ({ user: one(users, { fields: [cartItems.userId], references: [users.id] }), sku: one(productSkus, { fields: [cartItems.skuId], references: [productSkus.id] }), })) export const complaintsRelations = relations(complaints, ({ one }) => ({ user: one(users, { fields: [complaints.userId], references: [users.id] }), order: one(orders, { fields: [complaints.orderId], references: [orders.id] }), })) export const couponsRelations = relations(coupons, ({ one, many }) => ({ creator: one(staffUsers, { fields: [coupons.createdBy], references: [staffUsers.id] }), usages: many(couponUsage), applicableUsers: many(couponApplicableUsers), applicableProducts: many(couponApplicableProducts), })) export const couponUsageRelations = relations(couponUsage, ({ one }) => ({ user: one(users, { fields: [couponUsage.userId], references: [users.id] }), coupon: one(coupons, { fields: [couponUsage.couponId], references: [coupons.id] }), order: one(orders, { fields: [couponUsage.orderId], references: [orders.id] }), orderItem: one(orderItems, { fields: [couponUsage.orderItemId], references: [orderItems.id] }), })) export const userDetailsRelations = relations(userDetails, ({ one }) => ({ user: one(users, { fields: [userDetails.userId], references: [users.id] }), })) export const notifCredsRelations = relations(notifCreds, ({ one }) => ({ user: one(users, { fields: [notifCreds.userId], references: [users.id] }), })) export const userNotificationsRelations = relations(userNotifications, ({}) => ({ // No relations needed for now })) export const storeInfoRelations = relations(storeInfo, ({ one, many }) => ({ owner: one(staffUsers, { fields: [storeInfo.owner], references: [staffUsers.id] }), products: many(productInfo), })) export const couponApplicableUsersRelations = relations(couponApplicableUsers, ({ one }) => ({ coupon: one(coupons, { fields: [couponApplicableUsers.couponId], references: [coupons.id] }), user: one(users, { fields: [couponApplicableUsers.userId], references: [users.id] }), })) export const couponApplicableProductsRelations = relations(couponApplicableProducts, ({ one }) => ({ coupon: one(coupons, { fields: [couponApplicableProducts.couponId], references: [coupons.id] }), sku: one(productSkus, { fields: [couponApplicableProducts.skuId], references: [productSkus.id] }), })) export const reservedCouponsRelations = relations(reservedCoupons, ({ one }) => ({ redeemedUser: one(users, { fields: [reservedCoupons.redeemedBy], references: [users.id] }), creator: one(staffUsers, { fields: [reservedCoupons.createdBy], references: [staffUsers.id] }), })) export const productReviewsRelations = relations(productReviews, ({ one }) => ({ user: one(users, { fields: [productReviews.userId], references: [users.id] }), product: one(productInfo, { fields: [productReviews.productId], references: [productInfo.id] }), })) export const addressZonesRelations = relations(addressZones, ({ many }) => ({ addresses: many(addresses), areas: many(addressAreas), })) export const addressAreasRelations = relations(addressAreas, ({ one }) => ({ zone: one(addressZones, { fields: [addressAreas.zoneId], references: [addressZones.id] }), })) export const productGroupInfoRelations = relations(productGroupInfo, ({ many }) => ({ memberships: many(productGroupMembership), })) export const productGroupMembershipRelations = relations(productGroupMembership, ({ one }) => ({ sku: one(productSkus, { fields: [productGroupMembership.productId], references: [productSkus.id] }), group: one(productGroupInfo, { fields: [productGroupMembership.groupId], references: [productGroupInfo.id] }), })) export const homeBannersRelations = relations(homeBanners, ({}) => ({ // Relations for skuIds array would be more complex, skipping for now })) export const staffRolesRelations = relations(staffRoles, ({ many }) => ({ staffUsers: many(staffUsers), rolePermissions: many(staffRolePermissions), })) export const staffPermissionsRelations = relations(staffPermissions, ({ many }) => ({ rolePermissions: many(staffRolePermissions), })) export const staffRolePermissionsRelations = relations(staffRolePermissions, ({ one }) => ({ role: one(staffRoles, { fields: [staffRolePermissions.staffRoleId], references: [staffRoles.id] }), permission: one(staffPermissions, { fields: [staffRolePermissions.staffPermissionId], references: [staffPermissions.id] }), })) export const userIncidentsRelations = relations(userIncidents, ({ one }) => ({ user: one(users, { fields: [userIncidents.userId], references: [users.id] }), order: one(orders, { fields: [userIncidents.orderId], references: [orders.id] }), addedBy: one(staffUsers, { fields: [userIncidents.addedBy], references: [staffUsers.id] }), })) export const vendorSnippetsRelations = relations(vendorSnippets, ({ one }) => ({ slot: one(deliverySlotInfo, { fields: [vendorSnippets.slotId], references: [deliverySlotInfo.id] }), }))