feat(30-01): add popular-items-by-tags query to discovery service
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,14 @@
|
||||
import { and, count, desc, eq, isNotNull, lt, sql } from "drizzle-orm";
|
||||
import { and, count, desc, eq, inArray, isNotNull, lt, sql } from "drizzle-orm";
|
||||
import { db as prodDb } from "../../db/index.ts";
|
||||
import { globalItems, setupItems, setups, users } from "../../db/schema.ts";
|
||||
import {
|
||||
globalItemTags,
|
||||
globalItems,
|
||||
items,
|
||||
setupItems,
|
||||
setups,
|
||||
tags,
|
||||
users,
|
||||
} from "../../db/schema.ts";
|
||||
|
||||
type Db = typeof prodDb;
|
||||
|
||||
@@ -125,3 +133,53 @@ export async function getTrendingCategories(
|
||||
itemCount: r.itemCount,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get popular global items filtered by tag names, ordered by owner count descending.
|
||||
* Owner count = number of user items linked to each global item via globalItemId.
|
||||
*/
|
||||
export async function getPopularItemsByTags(
|
||||
db: Db = prodDb,
|
||||
tagNames: string[],
|
||||
limit = 24,
|
||||
): Promise<
|
||||
Array<{
|
||||
id: number;
|
||||
brand: string | null;
|
||||
model: string;
|
||||
category: string | null;
|
||||
weightGrams: number | null;
|
||||
priceCents: number | null;
|
||||
imageFilename: string | null;
|
||||
description: string | null;
|
||||
ownerCount: number;
|
||||
}>
|
||||
> {
|
||||
if (tagNames.length === 0) return [];
|
||||
|
||||
const rows = await db
|
||||
.select({
|
||||
id: globalItems.id,
|
||||
brand: globalItems.brand,
|
||||
model: globalItems.model,
|
||||
category: globalItems.category,
|
||||
weightGrams: globalItems.weightGrams,
|
||||
priceCents: globalItems.priceCents,
|
||||
imageFilename: globalItems.imageFilename,
|
||||
description: globalItems.description,
|
||||
ownerCount: sql<number>`CAST(COUNT(DISTINCT ${items.id}) AS INT)`,
|
||||
})
|
||||
.from(globalItems)
|
||||
.innerJoin(globalItemTags, eq(globalItemTags.globalItemId, globalItems.id))
|
||||
.innerJoin(tags, eq(tags.id, globalItemTags.tagId))
|
||||
.leftJoin(items, eq(items.globalItemId, globalItems.id))
|
||||
.where(inArray(tags.name, tagNames))
|
||||
.groupBy(globalItems.id)
|
||||
.orderBy(
|
||||
desc(sql<number>`COUNT(DISTINCT ${items.id})`),
|
||||
desc(globalItems.id),
|
||||
)
|
||||
.limit(limit);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user