75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
import { db } from "@/db";
|
|
import { submissions } from "@/db/schema";
|
|
import { asc, count, inArray } 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 totals = await db
|
|
.select({
|
|
formId: submissions.formId,
|
|
totalAnswers: count(),
|
|
})
|
|
.from(submissions)
|
|
.where(inArray(submissions.formId, formIds))
|
|
.groupBy(submissions.formId);
|
|
|
|
const stats = new Map<string, FormSubmissionStats>(
|
|
totals.map((row) => [
|
|
row.formId,
|
|
{
|
|
totalAnswers: row.totalAnswers,
|
|
queueNumber: null,
|
|
},
|
|
])
|
|
);
|
|
|
|
if (!discordId) {
|
|
return stats;
|
|
}
|
|
|
|
const orderedSubmissions = await db
|
|
.select({
|
|
formId: submissions.formId,
|
|
userDiscordId: submissions.userDiscordId,
|
|
})
|
|
.from(submissions)
|
|
.where(inArray(submissions.formId, formIds))
|
|
.orderBy(
|
|
asc(submissions.formId),
|
|
asc(submissions.submittedAt),
|
|
asc(submissions.id)
|
|
);
|
|
|
|
const queueByForm = new Map<string, number>();
|
|
const lastUserQueueByForm = new Map<string, number>();
|
|
|
|
for (const submission of orderedSubmissions) {
|
|
const queueNumber = (queueByForm.get(submission.formId) ?? 0) + 1;
|
|
queueByForm.set(submission.formId, queueNumber);
|
|
if (submission.userDiscordId === discordId) {
|
|
lastUserQueueByForm.set(submission.formId, queueNumber);
|
|
}
|
|
}
|
|
|
|
for (const [formId, queueNumber] of lastUserQueueByForm) {
|
|
const current = stats.get(formId) ?? {
|
|
totalAnswers: queueByForm.get(formId) ?? 0,
|
|
queueNumber: null,
|
|
};
|
|
stats.set(formId, { ...current, queueNumber });
|
|
}
|
|
|
|
return stats;
|
|
}
|