mirror of
https://github.com/pupperpowell/bibdle.git
synced 2026-02-04 02:44:43 -05:00
updated ranking formula
This commit is contained in:
21
.env.example
Normal file
21
.env.example
Normal file
@@ -0,0 +1,21 @@
|
||||
DATABASE_URL=example.db
|
||||
|
||||
# nodemailer
|
||||
SMTP_USERNAME=email@example.com
|
||||
SMTP_TOKEN=TOKEN
|
||||
SMTP_SERVER=smtp.example.com
|
||||
SMTP_PORT=port
|
||||
# note from mail provider: Enable TLS or SSL on the external service if it is supported.
|
||||
|
||||
# sign in with Discord
|
||||
|
||||
# sign in with google
|
||||
|
||||
# sign in with apple
|
||||
AUTH_SECRET=your-random-secret-here
|
||||
APPLE_ID=com.yourcompany.yourapp.client
|
||||
APPLE_TEAM_ID=your-team-id
|
||||
APPLE_KEY_ID=your-key-id
|
||||
APPLE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
|
||||
your-private-key-here
|
||||
-----END PRIVATE KEY-----"
|
||||
31
analyze_top_users.sh
Executable file
31
analyze_top_users.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
# analyze_top_users.sh
|
||||
# Analyzes the daily_completions table to find the top 10 anonymous IDs by completion count
|
||||
|
||||
# Set database path from argument or default to dev.db
|
||||
DB_PATH="${1:-dev.db}"
|
||||
|
||||
# Check if database file exists
|
||||
if [ ! -f "$DB_PATH" ]; then
|
||||
echo "Error: Database file not found: $DB_PATH"
|
||||
echo "Usage: $0 [database_path]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run the analysis query
|
||||
sqlite3 "$DB_PATH" <<EOF
|
||||
.mode column
|
||||
.headers on
|
||||
.width 36 16 16 17
|
||||
|
||||
SELECT
|
||||
anonymous_id,
|
||||
COUNT(*) as completion_count,
|
||||
MIN(date) as first_completion,
|
||||
MAX(date) as latest_completion
|
||||
FROM daily_completions
|
||||
GROUP BY anonymous_id
|
||||
ORDER BY completion_count DESC
|
||||
LIMIT 10;
|
||||
EOF
|
||||
34
daily_completions_report.sh
Executable file
34
daily_completions_report.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
DB_PATH="./local.db"
|
||||
|
||||
# Check if database exists
|
||||
if [ ! -f "$DB_PATH" ]; then
|
||||
echo "Error: Database not found at $DB_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Query for daily completions on 2026-02-01 with ranking
|
||||
echo "Daily Completions for 2026-02-01"
|
||||
echo "================================="
|
||||
echo ""
|
||||
printf "%-12s %-10s %-6s\n" "Anonymous ID" "Guesses" "Rank"
|
||||
printf "%-12s %-10s %-6s\n" "------------" "-------" "----"
|
||||
|
||||
# Execute query with custom column mode
|
||||
sqlite3 "$DB_PATH" <<SQL
|
||||
.mode column
|
||||
.headers off
|
||||
.width 12 10 6
|
||||
SELECT
|
||||
SUBSTR(anonymous_id, 1, 10) as anon_id,
|
||||
guess_count,
|
||||
RANK() OVER (ORDER BY guess_count ASC) as rank
|
||||
FROM daily_completions
|
||||
WHERE date = '2026-02-01'
|
||||
ORDER BY rank, guess_count;
|
||||
SQL
|
||||
|
||||
echo ""
|
||||
echo "Total entries:"
|
||||
sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM daily_completions WHERE date = '2026-02-01';"
|
||||
@@ -1,7 +1,5 @@
|
||||
import { integer, sqliteTable, text, index, unique } from 'drizzle-orm/sqlite-core';
|
||||
|
||||
import { sql } from 'drizzle-orm';
|
||||
|
||||
export const user = sqliteTable('user', { id: text('id').primaryKey(), age: integer('age') });
|
||||
|
||||
export const session = sqliteTable('session', {
|
||||
|
||||
@@ -91,13 +91,20 @@ export const actions: Actions = {
|
||||
const betterGuesses = allCompletions.filter(c => c.guessCount < guessCount).length;
|
||||
const guessRank = betterGuesses + 1;
|
||||
|
||||
// Count ties: how many have the SAME guessCount (excluding self)
|
||||
const tiedCount = allCompletions.filter(c => c.guessCount === guessCount && c.anonymousId !== anonymousId).length;
|
||||
|
||||
// Average guesses
|
||||
const totalGuesses = allCompletions.reduce((sum, c) => sum + c.guessCount, 0);
|
||||
const averageGuesses = Math.round((totalGuesses / totalSolves) * 10) / 10;
|
||||
|
||||
// Percentile: what percentage of people you beat (100 - your rank percentage)
|
||||
const betterOrEqualCount = allCompletions.filter(c => c.guessCount <= guessCount).length;
|
||||
const percentile = Math.round((betterOrEqualCount / totalSolves) * 100);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
stats: { solveRank, guessRank, totalSolves, averageGuesses }
|
||||
stats: { solveRank, guessRank, totalSolves, averageGuesses, tiedCount, percentile }
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,11 +44,9 @@ export const POST: RequestHandler = async ({ request }) => {
|
||||
// Solve rank: position in time-ordered list
|
||||
const solveRank = allCompletions.findIndex(c => c.anonymousId === anonymousId) + 1;
|
||||
|
||||
// Guess rank: count how many DISTINCT guess counts are better (grouped ranking)
|
||||
const uniqueBetterGuessCounts = new Set(
|
||||
allCompletions.filter(c => c.guessCount < guessCount).map(c => c.guessCount)
|
||||
);
|
||||
const guessRank = uniqueBetterGuessCounts.size + 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;
|
||||
|
||||
// Count ties: how many have the SAME guessCount (excluding self)
|
||||
const tiedCount = allCompletions.filter(c => c.guessCount === guessCount && c.anonymousId !== anonymousId).length;
|
||||
@@ -110,11 +108,9 @@ export const GET: RequestHandler = async ({ url }) => {
|
||||
// Solve rank: position in time-ordered list
|
||||
const solveRank = allCompletions.findIndex(c => c.anonymousId === anonymousId) + 1;
|
||||
|
||||
// Guess rank: count how many DISTINCT guess counts are better (grouped ranking)
|
||||
const uniqueBetterGuessCounts = new Set(
|
||||
allCompletions.filter(c => c.guessCount < guessCount).map(c => c.guessCount)
|
||||
);
|
||||
const guessRank = uniqueBetterGuessCounts.size + 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;
|
||||
|
||||
// Count ties: how many have the SAME guessCount (excluding self)
|
||||
const tiedCount = allCompletions.filter(c => c.guessCount === guessCount && c.anonymousId !== anonymousId).length;
|
||||
|
||||
Reference in New Issue
Block a user