freshyo/packages/db_helper_sqlite/src/user-apis/stores.ts
2026-08-15 10:34:28 +05:30

128 lines
3.8 KiB
TypeScript

import { db } from '../db/db_index'
import { productInfo, productSkus, storeInfo } from '../db/schema'
import { and, asc, eq, inArray } from 'drizzle-orm'
import type { InferSelectModel } from 'drizzle-orm'
import type { UserStoreDetailData, UserStoreProductData, UserStoreSummaryData, StoreSummary } from '@packages/shared'
import { composeSkuName, composeUnitNotation } from '../lib/sku-features'
type StoreRow = InferSelectModel<typeof storeInfo>
const getStringArray = (value: unknown): string[] | null => {
if (!Array.isArray(value)) return null
return value.map((item) => String(item))
}
export async function getStoreSummaries(): Promise<UserStoreSummaryData[]> {
const storesData = await db.select({
id: storeInfo.id,
name: storeInfo.name,
description: storeInfo.description,
imageUrl: storeInfo.imageUrl,
}).from(storeInfo)
const skus = await db.query.productSkus.findMany({
with: { product: true, marketStats: true },
orderBy: asc(productSkus.id),
})
const activeSkus = skus.filter((sku) => !sku.marketStats?.isSuspended && !sku.isDeleted)
const skusByStore = new Map<number, typeof skus>()
for (const sku of activeSkus) {
const storeId = sku.product?.storeId
if (storeId == null) continue
if (!skusByStore.has(storeId)) skusByStore.set(storeId, [])
skusByStore.get(storeId)!.push(sku)
}
return storesData.map((store) => {
const storeSkus = skusByStore.get(store.id) || []
const sampleProducts = storeSkus.slice(0, 3).map((sku) => ({
id: sku.id,
name: sku.product?.name ?? sku.name ?? 'Unknown',
images: getStringArray(sku.images),
}))
return {
id: store.id,
name: store.name,
description: store.description ?? null,
imageUrl: store.imageUrl ?? null,
productCount: storeSkus.length,
sampleProducts,
}
})
}
export async function getStoreDetail(storeId: number): Promise<UserStoreDetailData | null> {
const storeData = await db.query.storeInfo.findFirst({
where: eq(storeInfo.id, storeId),
columns: {
id: true,
name: true,
description: true,
imageUrl: true,
},
})
if (!storeData) {
return null
}
const storeProductIds = await db
.select({ id: productInfo.id })
.from(productInfo)
.where(eq(productInfo.storeId, storeId))
const productIdArr = storeProductIds.map((p) => p.id)
const skus = productIdArr.length > 0
? await db.query.productSkus.findMany({
where: inArray(productSkus.productId, productIdArr),
with: {
product: true,
features: true,
marketStats: true,
},
})
: []
const products: UserStoreProductData[] = skus
.filter((sku) => !sku.marketStats?.isSuspended && !sku.isDeleted)
.map((sku) => {
const features = sku.features || []
const marketStats = sku.marketStats
return {
id: sku.id,
name: composeSkuName(sku.product?.name ?? 'Unknown', features, sku.name),
shortDescription: sku.product?.shortDescription ?? null,
price: marketStats?.ourPrice ? String(marketStats.ourPrice) : '0',
marketPrice: marketStats?.marketPrice ? String(marketStats.marketPrice) : null,
incrementStep: sku.product?.incrementStep ?? 1,
unit: composeUnitNotation(features),
unitNotation: composeUnitNotation(features),
images: getStringArray(sku.images),
isOutOfStock: marketStats?.isOutOfStock ?? false,
productQuantity: 1,
}
})
return {
store: {
id: storeData.id,
name: storeData.name,
description: storeData.description ?? null,
imageUrl: storeData.imageUrl ?? null,
},
products,
}
}
export async function getStoresSummary(): Promise<StoreSummary[]> {
return db.query.storeInfo.findMany({
columns: {
id: true,
name: true,
description: true,
},
})
}