freshyo/packages/db_helper_sqlite/src/stores/store-helpers.ts
2026-03-26 17:16:56 +05:30

294 lines
7.8 KiB
TypeScript

// Store Helpers - Database operations for cache initialization
// These are used by stores in apps/backend/src/stores/
import { db } from '../db/db_index'
import {
homeBanners,
productInfo,
units,
productSlots,
deliverySlotInfo,
specialDeals,
storeInfo,
productTags,
productTagInfo,
userIncidents,
} from '../db/schema'
import { eq, and, gt, sql, isNotNull, asc } from 'drizzle-orm'
// ============================================================================
// BANNER STORE HELPERS
// ============================================================================
export interface BannerData {
id: number
name: string
imageUrl: string | null
serialNum: number | null
productIds: number[] | null
createdAt: Date
}
export async function getAllBannersForCache(): Promise<BannerData[]> {
return db.query.homeBanners.findMany({
where: isNotNull(homeBanners.serialNum),
orderBy: asc(homeBanners.serialNum),
})
}
// ============================================================================
// PRODUCT STORE HELPERS
// ============================================================================
export interface ProductBasicData {
id: number
name: string
shortDescription: string | null
longDescription: string | null
price: string
marketPrice: string | null
images: unknown
isOutOfStock: boolean
storeId: number | null
unitShortNotation: string
incrementStep: number
productQuantity: number
isFlashAvailable: boolean
flashPrice: string | null
}
export interface StoreBasicData {
id: number
name: string
description: string | null
}
export interface DeliverySlotData {
productId: number
id: number
deliveryTime: Date
freezeTime: Date
isCapacityFull: boolean
}
export interface SpecialDealData {
productId: number
quantity: string
price: string
validTill: Date
}
export interface ProductTagData {
productId: number
tagName: string
}
export async function getAllProductsForCache(): Promise<ProductBasicData[]> {
const results = await db
.select({
id: productInfo.id,
name: productInfo.name,
shortDescription: productInfo.shortDescription,
longDescription: productInfo.longDescription,
price: productInfo.price,
marketPrice: productInfo.marketPrice,
images: productInfo.images,
isOutOfStock: productInfo.isOutOfStock,
storeId: productInfo.storeId,
unitShortNotation: units.shortNotation,
incrementStep: productInfo.incrementStep,
productQuantity: productInfo.productQuantity,
isFlashAvailable: productInfo.isFlashAvailable,
flashPrice: productInfo.flashPrice,
})
.from(productInfo)
.innerJoin(units, eq(productInfo.unitId, units.id))
return results.map((product) => ({
...product,
price: String(product.price ?? '0'),
marketPrice: product.marketPrice ? String(product.marketPrice) : null,
flashPrice: product.flashPrice ? String(product.flashPrice) : null,
}))
}
export async function getAllStoresForCache(): Promise<StoreBasicData[]> {
return db.query.storeInfo.findMany({
columns: { id: true, name: true, description: true },
})
}
export async function getAllDeliverySlotsForCache(): Promise<DeliverySlotData[]> {
return db
.select({
productId: productSlots.productId,
id: deliverySlotInfo.id,
deliveryTime: deliverySlotInfo.deliveryTime,
freezeTime: deliverySlotInfo.freezeTime,
isCapacityFull: deliverySlotInfo.isCapacityFull,
})
.from(productSlots)
.innerJoin(deliverySlotInfo, eq(productSlots.slotId, deliverySlotInfo.id))
.where(
and(
eq(deliverySlotInfo.isActive, true),
eq(deliverySlotInfo.isCapacityFull, false),
gt(deliverySlotInfo.deliveryTime, sql`CURRENT_TIMESTAMP`)
)
)
}
export async function getAllSpecialDealsForCache(): Promise<SpecialDealData[]> {
const results = await db
.select({
productId: specialDeals.productId,
quantity: specialDeals.quantity,
price: specialDeals.price,
validTill: specialDeals.validTill,
})
.from(specialDeals)
.where(gt(specialDeals.validTill, sql`CURRENT_TIMESTAMP`))
return results.map((deal) => ({
...deal,
quantity: String(deal.quantity ?? '0'),
price: String(deal.price ?? '0'),
}))
}
export async function getAllProductTagsForCache(): Promise<ProductTagData[]> {
return db
.select({
productId: productTags.productId,
tagName: productTagInfo.tagName,
})
.from(productTags)
.innerJoin(productTagInfo, eq(productTags.tagId, productTagInfo.id))
}
// ============================================================================
// PRODUCT TAG STORE HELPERS
// ============================================================================
export interface TagBasicData {
id: number
tagName: string
tagDescription: string | null
imageUrl: string | null
isDashboardTag: boolean
relatedStores: unknown
}
export interface TagProductMapping {
tagId: number
productId: number
}
export async function getAllTagsForCache(): Promise<TagBasicData[]> {
return db
.select({
id: productTagInfo.id,
tagName: productTagInfo.tagName,
tagDescription: productTagInfo.tagDescription,
imageUrl: productTagInfo.imageUrl,
isDashboardTag: productTagInfo.isDashboardTag,
relatedStores: productTagInfo.relatedStores,
})
.from(productTagInfo)
}
export async function getAllTagProductMappings(): Promise<TagProductMapping[]> {
return db
.select({
tagId: productTags.tagId,
productId: productTags.productId,
})
.from(productTags)
}
// ============================================================================
// SLOT STORE HELPERS
// ============================================================================
export interface SlotWithProductsData {
id: number
deliveryTime: Date
freezeTime: Date
isActive: boolean
isCapacityFull: boolean
productSlots: Array<{
product: {
id: number
name: string
productQuantity: number
shortDescription: string | null
price: string
marketPrice: string | null
unit: { shortNotation: string } | null
store: { id: number; name: string; description: string | null } | null
images: unknown
isOutOfStock: boolean
storeId: number | null
}
}>
}
export async function getAllSlotsWithProductsForCache(): Promise<SlotWithProductsData[]> {
const now = new Date()
return db.query.deliverySlotInfo.findMany({
where: and(
eq(deliverySlotInfo.isActive, true),
gt(deliverySlotInfo.deliveryTime, now)
),
with: {
productSlots: {
with: {
product: {
with: {
unit: true,
store: true,
},
},
},
},
},
orderBy: asc(deliverySlotInfo.deliveryTime),
}) as Promise<SlotWithProductsData[]>
}
// ============================================================================
// USER NEGATIVITY STORE HELPERS
// ============================================================================
export interface UserNegativityData {
userId: number
totalNegativityScore: number
}
export async function getAllUserNegativityScores(): Promise<UserNegativityData[]> {
const results = await db
.select({
userId: userIncidents.userId,
totalNegativityScore: sql`sum(${userIncidents.negativityScore})`,
})
.from(userIncidents)
.groupBy(userIncidents.userId)
return results.map((result) => ({
userId: result.userId,
totalNegativityScore: Number(result.totalNegativityScore ?? 0),
}))
}
export async function getUserNegativityScore(userId: number): Promise<number> {
const [result] = await db
.select({
totalNegativityScore: sql`sum(${userIncidents.negativityScore})`,
})
.from(userIncidents)
.where(eq(userIncidents.userId, userId))
.limit(1)
return Number(result?.totalNegativityScore ?? 0)
}