Skip to content

sspboyd/read-a-thon-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Read-a-thon App

A working proof-of-concept in knowledge-preserving AI-assisted development.

A web app built with a methodology-first approach:

  • architecture and constraints documented before code was written,
  • conventions captured as they emerged from real data and runtime failures,
  • and every significant decision recorded in DECISIONS.md with its rationale.

The app replaces a Google Sheets-based workflow used by school volunteers to track student reading performance, run weighted prize draws, and export records for archiving.

Development process

Key architecture and product decisions are recorded in DECISIONS.md with their rationale -- not just what was built, but why, and what it ruled out. Entries cover data residency constraints, authentication model, validation policy, and conventions that emerged from runtime failures and real historical data.

Live: https://read-a-thon-app.vercel.app

See Screenshots at the end of this document.

What it does

  • Data entry — keyboard-driven entry of student reading records by a single volunteer (~150 students per year)
  • Winner draws — weighted random draws for reading prizes (per grade), book review prizes, and class prize (highest total minutes)
  • Student review — all entered students grouped by grade with minutes, reviews, and ballot counts
  • CSV export — full data export for archiving
  • Auto-cleanup — student records are hard-deleted after the configured retention period (default: 60 days post-event)

Tech stack

  • Next.js 15 (App Router) + TypeScript
  • Supabase — PostgreSQL hosted in ca-central-1 (Canada), UK-owned company
  • Prisma — schema migrations and type-safe DB access
  • Tailwind CSS — monospace design system
  • NextAuth v5 — single shared password, all routes protected
  • Vercel — hosting, serverless functions, cron jobs

Local development

npm install
npm run dev        # starts dev server at http://localhost:3000
npm run lint       # ESLint
npm test           # Vitest unit tests (ballot logic, draw logic)

Environment variables

Copy .env.example to .env.local and fill in:

DATABASE_URL=        # Supabase transaction pooler (port 6543, ?pgbouncer=true)
DIRECT_URL=          # Supabase session pooler (port 5432, for migrations)
AUTH_SECRET=         # Random secret: openssl rand -base64 32
APP_PASSWORD=        # Shared login password
CRON_SECRET=         # Secret for the /api/cron/cleanup endpoint

Database

npx prisma migrate dev     # apply schema changes
npx prisma studio          # browse data locally
npx prisma generate        # regenerate client after schema edits without migrating

To seed with real data from the 2026 export:

npx tsx scripts/seed-csv.ts

Privacy and data

  • Every route requires authentication — no public-facing pages
  • Full student names are stored; privacy is enforced by access control, not data truncation
  • Database hosted in Canada (ca-central-1), not the United States
  • Student names never appear in URLs, logs, or error messages
  • Student records are hard-deleted after dataRetentionDays (configurable per event); the CSV export is the long-term archive

Key decisions

See DECISIONS.md for the reasoning behind major architecture and product choices.

Screenshots

Landing page and main dashboard Landing page and main dashboard

Volunteer Guide Volunteer Guide

Student reading data entry Student reading data entry

New Reading Event Setup New Reading Event Setup

About

A working proof-of-concept in knowledge-preserving AI-assisted development.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors