rate-connections
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
index.ts
https://stevekrouse--f6bcd4c0542511f0a195f69ea79377d9.web.val.run
A site where people praise or roast each day's four NYT Connections categories, seeded by AI so the page is never empty.
- Daily puzzle ingestion: Pulls today's categories from NYT Connections data
- AI bootstrap: LLM rates each category 1-5 as initial seed data (1 = dumpster fire, 5 = chef's kiss)
- Voting system: One vote per IP per puzzle, real-time average updates
- Leaderboards: "Best Days" and "Worst Days" ranked by highest/lowest overall scores
- Mobile-friendly: Clean, responsive interface
- 5 = Chef's kiss 🔥 (brilliant wordplay, fair difficulty, satisfying "aha!" moment)
- 4 = Pretty good ⭐ (solid category, maybe one tricky word)
- 3 = Okay 😐 (fine but unremarkable, or slightly unfair)
- 2 = Rough 😬 (too obscure, unfair difficulty spike, or forced connections)
- 1 = Dumpster fire 🗑️ (completely unfair, impossible without guessing, terrible wordplay)
├── backend/
│ ├── database/
│ │ ├── migrations.ts # Database schema ✅
│ │ └── queries.ts # Database operations ✅
│ ├── ai/
│ │ └── rating.ts # AI rating generation ✅
│ ├── routes/
│ │ ├── ingestion.ts # NYT data processing ✅
│ │ ├── api.ts # API endpoints (Phase 3)
│ │ └── static.ts # Static file serving (Phase 3)
│ └── index.ts # Main Hono app (Phase 3)
├── frontend/
│ ├── components/
│ │ ├── App.tsx # Main React app (Phase 4)
│ │ ├── PuzzleList.tsx # Home page list (Phase 4)
│ │ ├── PuzzleDetail.tsx # Voting interface (Phase 4)
│ │ ├── BestLeaderboard.tsx # Best days leaderboard (Phase 5)
│ │ └── WorstLeaderboard.tsx # Worst days leaderboard (Phase 5)
│ ├── index.html # Main HTML template (Phase 4)
│ ├── index.tsx # Frontend entry point (Phase 4)
│ └── style.css # Custom styles (Phase 4)
├── shared/
│ └── utils.ts # Shared utilities ✅
├── cron.ts # Daily data ingestion ✅
└── README.md
- NYT Connections data: https://raw.githubusercontent.com/Eyefyre/NYT-Connections-Answers/main/connections.json
- 748 puzzles available (as of June 2025)
- Daily cron job ingests new puzzles automatically
- SQLite schema with puzzles, votes, AI seeds tables
- Query functions for CRUD operations
- IP-based vote deduplication
- Average calculation and leaderboard ranking
- Status: v2 schema with category words support
- NYT data fetching and parsing with category words
- OpenAI integration for category rating with full context
- Cron job for daily automation
- Historical backfill on first run
- Status: AI now sees actual words for much better ratings
- Main Hono app with error handling
- Full CRUD API endpoints with category words
- IP-based vote validation and deduplication
- Real-time average updates
- Status: All endpoints include category words
- React 18.2.0 with TailwindCSS
- Hash-based routing without React Router
- Home page with puzzle list and ratings
- Mobile-responsive design
- Status: Clean, fast, functional UI
- Four category cards with NYT colors and words display
- Five-star voting interface with real-time updates
- IP-based vote state management
- Error handling with specific messages
- Status: Full voting experience with category words visible
- Improved AI ratings: AI now sees actual category words for realistic ratings
- Category words display: Users can see the 4 words in each category
- Better rating accuracy: AI evaluates fairness, difficulty, and wordplay quality
- v2 database schema: Clean slate with enhanced data structure
- Status: AI ratings are now much more realistic and helpful
- Database: SQLite with versioned table names for schema changes
- AI: OpenAI GPT-4o-mini for cost-effective rating generation
- Frontend: React 18.2.0 with TailwindCSS for rapid development
- Backend: Hono for lightweight, fast API routes
- Deployment: Val Town for serverless hosting and cron jobs
- IP Hashing: SHA-256 with fixed salt for vote deduplication
- ✅ First visitor each day sees AI seed ratings within seconds
- ✅ Duplicate votes from same IP/puzzle are rejected with clear messages
- ✅ UI is clear, mobile-friendly, and fun—roasting NYT should feel delightful
- ✅ Category words are visible so users can judge the connections themselves
- ✅ AI ratings are realistic and helpful (now sees actual words, not just category names)
- ✅ Leaderboards provide engaging way to discover "best" and "worst" puzzles
- Context-aware: AI now sees the actual 4 words in each category, not just the category name
- Better accuracy: Ratings like
[5,3,4,5]
reflect actual puzzle difficulty and fairness - Realistic evaluation: AI can judge wordplay cleverness, connection fairness, and solving satisfaction
- Full transparency: Users see all 4 words in each category (e.g., "BALL • BONE • FRISBEE • STICK")
- Better voting: Users can make informed ratings based on actual puzzle content
- Enhanced UX: Category cards show both the connection name and the specific words
"THINGS A DOG CAN FETCH" = 5/5 (chef's kiss)
- Words: BALL, BONE, FRISBEE, STICK
- AI assessment: Perfect category - obvious, fair, satisfying!
"GREAT MANY" = 3/5 (okay)
- Words: DROVE, HOST, LOAD, SCORE
- AI assessment: Trickier - these can mean "a lot" but not immediately obvious
This represents a major improvement in both AI accuracy and user experience!
- Colored categories: Homepage now shows each category with appropriate NYT colors (yellow, green, blue, purple)
- Dual leaderboards: Replaced "Spiciest Days" with separate "Best Days" and "Worst Days" rankings
- Better navigation: Clear distinction between highest-rated and lowest-rated puzzles
- Improved UX: Category colors match the detail view for consistency
- New API endpoints:
/api/leaderboard/best
and/api/leaderboard/worst
- Enhanced routing: Support for
/best
and/worst
routes - Backward compatibility: Legacy
/spicy
route redirects to best leaderboard
- Fixed vote counting: Voting for all 4 categories now counts as 1 vote (per unique user), not 4 separate votes
- Home page refresh: After voting, returning to home page now shows updated vote counts instead of cached data
- Accurate statistics: Vote counts now properly reflect unique users rather than individual category votes
This project showcases Val Town's capabilities for full-stack development with cron jobs, SQLite storage, and AI integration.