mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-02-04 10:54:44 -05:00
v2
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import type { PageServerLoad } from './$types';
|
||||
import type { PageServerLoad, Actions } from './$types';
|
||||
import { db } from '$lib/server/db';
|
||||
import { dailyVerses } from '$lib/server/db/schema';
|
||||
import { eq, sql } from 'drizzle-orm';
|
||||
import { dailyVerses, dailyCompletions } from '$lib/server/db/schema';
|
||||
import { eq, sql, asc } from 'drizzle-orm';
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { fetchRandomVerse } from '$lib/server/bible-api';
|
||||
import { getBookById } from '$lib/server/bible';
|
||||
import type { DailyVerse } from '$lib/server/db/schema';
|
||||
@@ -43,3 +44,60 @@ export const load: PageServerLoad = async () => {
|
||||
correctBook
|
||||
};
|
||||
};
|
||||
|
||||
export const actions: Actions = {
|
||||
submitCompletion: async ({ request }) => {
|
||||
const formData = await request.formData();
|
||||
const anonymousId = formData.get('anonymousId') as string;
|
||||
const date = formData.get('date') as string;
|
||||
const guessCount = parseInt(formData.get('guessCount') as string, 10);
|
||||
|
||||
// Validation
|
||||
if (!anonymousId || !date || isNaN(guessCount) || guessCount < 1) {
|
||||
return fail(400, { error: 'Invalid data' });
|
||||
}
|
||||
|
||||
const completedAt = new Date();
|
||||
|
||||
try {
|
||||
// Insert with duplicate prevention
|
||||
await db.insert(dailyCompletions).values({
|
||||
id: crypto.randomUUID(),
|
||||
anonymousId,
|
||||
date,
|
||||
guessCount,
|
||||
completedAt,
|
||||
});
|
||||
} catch (err: any) {
|
||||
if (err?.code === 'SQLITE_CONSTRAINT_UNIQUE' || err?.message?.includes('UNIQUE')) {
|
||||
return fail(409, { error: 'Already submitted' });
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
// Calculate statistics
|
||||
const allCompletions = await db
|
||||
.select()
|
||||
.from(dailyCompletions)
|
||||
.where(eq(dailyCompletions.date, date))
|
||||
.orderBy(asc(dailyCompletions.completedAt));
|
||||
|
||||
const totalSolves = allCompletions.length;
|
||||
|
||||
// Solve rank: position in time-ordered list
|
||||
const solveRank = allCompletions.findIndex(c => c.anonymousId === anonymousId) + 1;
|
||||
|
||||
// Guess rank: count how many had FEWER guesses (ties get same rank)
|
||||
const betterGuesses = allCompletions.filter(c => c.guessCount < guessCount).length;
|
||||
const guessRank = betterGuesses + 1;
|
||||
|
||||
// Average guesses
|
||||
const totalGuesses = allCompletions.reduce((sum, c) => sum + c.guessCount, 0);
|
||||
const averageGuesses = Math.round((totalGuesses / totalSolves) * 10) / 10;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
stats: { solveRank, guessRank, totalSolves, averageGuesses }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user