54 lines
1.3 KiB
TypeScript
54 lines
1.3 KiB
TypeScript
import { db } from "@/db";
|
|
import { sql } from "drizzle-orm";
|
|
|
|
export type FormSubmissionStats = {
|
|
totalAnswers: number;
|
|
queueNumber: number | null;
|
|
};
|
|
|
|
export async function getFormSubmissionStats(
|
|
formIds: string[],
|
|
discordId: string | null
|
|
): Promise<Map<string, FormSubmissionStats>> {
|
|
if (formIds.length === 0) {
|
|
return new Map();
|
|
}
|
|
|
|
const rows = await db.execute<{
|
|
formId: string;
|
|
totalAnswers: number;
|
|
queueNumber: number | null;
|
|
}>(sql`
|
|
with ranked_submissions as (
|
|
select
|
|
form_id,
|
|
user_discord_id,
|
|
count(*) over (partition by form_id)::integer as total_answers,
|
|
row_number() over (
|
|
partition by form_id
|
|
order by submitted_at asc, id asc
|
|
)::integer as queue_number
|
|
from form.submission
|
|
where form_id in (${sql.join(formIds.map((formId) => sql`${formId}`), sql`, `)})
|
|
)
|
|
select
|
|
form_id as "formId",
|
|
max(total_answers)::integer as "totalAnswers",
|
|
max(queue_number) filter (
|
|
where user_discord_id = ${discordId}
|
|
)::integer as "queueNumber"
|
|
from ranked_submissions
|
|
group by form_id
|
|
`);
|
|
|
|
return new Map(
|
|
rows.map((row) => [
|
|
row.formId,
|
|
{
|
|
totalAnswers: row.totalAnswers,
|
|
queueNumber: row.queueNumber,
|
|
},
|
|
])
|
|
);
|
|
}
|