import { sql, type SQL } from "drizzle-orm"; export function parseMediaQuery(params: URLSearchParams) { const integer = (key: string, fallback: number, max: number) => { const value = Number(params.get(key)); return Number.isInteger(value) && value > 0 ? Math.min(value, max) : fallback; }; const date = (key: string) => { const value = params.get(key) || ""; return /^\d{4}-\d{2}-\d{2}$/.test(value) && Number.isFinite(Date.parse(value)) ? value : ""; }; return { page: integer("page", 1, 100000), pageSize: integer("pageSize", 40, 100), search: (params.get("search") || "").trim().slice(0, 128), type: ["image", "video"].includes(params.get("type") || "") ? params.get("type")! : "all", model: params.get("model") || "", featured: params.get("featured") === "true", startDate: date("startDate"), endDate: date("endDate"), }; } export function mediaRecordsQuery(params: ReturnType) { const conditions: SQL[] = [sql`true`]; if (params.search) conditions.push( sql`exists (select 1 from "User" u where u.id=m."userId" and (u.name ilike ${`%${params.search}%`} or u.email ilike ${`%${params.search}%`}))`, ); if (params.startDate) conditions.push(sql`m."createdAt" >= ${params.startDate}::date`); if (params.endDate) conditions.push(sql`m."createdAt" < ${params.endDate}::date + interval '1 day'`); if (params.model) conditions.push(sql`(m."modelId" = ${params.model} or m."modelId" in (select id::text from "AiModel" where "modelId"=${params.model}))`); const where = sql.join(conditions, sql` and `); const videoFilters: SQL[] = [sql`true`]; if (params.startDate) videoFilters.push(sql`v."createdAt">=${params.startDate}::date - interval '8 hours'`); if (params.endDate) videoFilters.push(sql`v."createdAt"<${params.endDate}::date+interval '16 hours'`); if (params.model) videoFilters.push(sql`(v."video_metadata"->>'model'=${params.model} or v."video_metadata"->>'model' in (select id::text from "AiModel" where "modelId"=${params.model}))`); if (params.search) videoFilters.push( sql`exists (select 1 from "User" u where u.id=c."userId" and (u.name ilike ${`%${params.search}%`} or u.email ilike ${`%${params.search}%`}))`, ); return sql` with video_candidates as materialized ( select v.id, v."chatId", v."createdAt" + interval '8 hours' as "createdAt", v."video_metadata", c."userId", coalesce(nullif(v."permanent_video_url", ''), nullif(v."temporary_video_url", ''), (regexp_match(t.body, ']+src="([^"]+)"', 'i'))[1], (regexp_match(t.body, '(https?://[^[:space:]"<>]+\\.mp4[^[:space:]"<>)]*)', 'i'))[1]) as url from "Message_v2" v join "Chat" c on c.id=v."chatId" cross join lateral (select case when jsonb_typeof(v.parts::jsonb)='array' then (select string_agg(p->>'text', E'\\n') from jsonb_array_elements(v.parts::jsonb) p) else v.parts::jsonb #>> '{}' end as body) t where ${params.type !== "image" && !params.featured} and v.role='assistant' and ${sql.join(videoFilters, sql` and `)} and (v."permanent_video_url" is not null or v."temporary_video_url" is not null or v.parts::text ilike '%>'model', url from video_candidates where url is not null ), filtered as not materialized (select * from media m where ${where}), totals as (select count(*)::int as total, count(*) filter(where kind='image')::int as images, count(*) filter(where kind='video')::int as videos from filtered), page_rows as ( select * from filtered order by "createdAt" desc, kind, id desc limit ${params.pageSize} offset ${(params.page - 1) * params.pageSize} ) select t.total, t.images as "totalImages", t.videos as "totalVideos", coalesce((select jsonb_agg(jsonb_build_object( 'id', case when p.kind='video' then 'video-'||p.id::text else p.id::text end, 'recordType',p.kind,'userId',p."userId",'userName',u.name,'userEmail',u.email,'userDepartment',u.department, 'createdAt',p."createdAt",'modelId',p."modelId",'chatId',coalesce(g."chatId",v."chatId"), 'thumbnailUrl',coalesce(p.url,g."thumbnailUrl"),'originalUrl',coalesce(p.url,g."originalUrl"),'videoUrl',p.url, 'prompt',coalesce(g.prompt,v."video_metadata"->>'prompt'),'imageSize',coalesce(g."imageSize",v."video_metadata"->>'resolution'), 'isFeatured',coalesce(g."isFeatured",false),'featuredCategory',g."featuredCategory",'featuredAt',g."featuredAt" + interval '8 hours' ) order by p."createdAt" desc,p.kind,p.id desc) from page_rows p left join "User" u on u.id=p."userId" left join "GeneratedImage" g on p.kind='image' and g.id=p.id left join "Message_v2" v on p.kind='video' and v.id=p.id),'[]'::jsonb) as records from totals t`; }