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.
Viewing readonly version of main branch: v45View latest version
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
- Leaderboard: "Spiciest Days" ranked by highest 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)
│ │ └── Leaderboard.tsx # Spiciest days (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: 20 puzzles ingested with AI ratings
- NYT data fetching and parsing
- OpenAI integration for category rating
- Cron job for daily automation
- Historical backfill on first run
- Status: AI generating realistic ratings, cron job active
Detailed Plan:
- Main Hono app (
backend/index.ts
)- Error handling middleware
- CORS setup (automatic in Val Town)
- Route organization
- API endpoints (
backend/routes/api.ts
)GET /api/puzzles
- List all puzzles with overall scoresGET /api/puzzle/:date
- Detailed puzzle with category statsPOST /api/vote
- Submit vote with IP validationGET /api/leaderboard
- Spiciest days rankingPOST /api/ingest
- Manual data refresh (admin)
- Static file serving (
backend/routes/static.ts
)- Serve frontend files with proper content types
- Index.html with initial data injection
- IP extraction and validation
- Request/response type safety
Detailed Plan:
- HTML template (
frontend/index.html
)- TailwindCSS integration
- React 18.2.0 setup
- Error capture script
- Meta tags and favicon
- React app structure (
frontend/index.tsx
)- Router setup for multiple pages
- Global state management
- API client functions
- Home page (
frontend/components/PuzzleList.tsx
)- Reverse-chronological puzzle list
- Overall score display (1-5 scale)
- Date navigation
- Mobile-responsive grid
- Basic styling (
frontend/style.css
)- Custom CSS for puzzle cards
- Rating star components
- Responsive breakpoints
Detailed Plan:
- Puzzle page (
frontend/components/PuzzleDetail.tsx
)- Four category cards with NYT colors (yellow, green, blue, purple)
- Current average and vote count per category
- Five-star radio controls for voting
- Real-time updates after vote submission
- IP-based vote state management
- Voting logic
- Form validation and submission
- Optimistic UI updates
- Error handling with specific messages
- Disable controls after voting
- Auto-refresh for today's puzzle
- Polling every few minutes
- WebSocket consideration for real-time updates
Detailed Plan:
- Leaderboard page (
frontend/components/Leaderboard.tsx
)- Puzzles ranked by overall average (highest first)
- Newest ties first
- Pagination for large datasets
- Filter options (date range, minimum votes)
- Navigation & UX
- Header with site branding
- Breadcrumb navigation
- Loading states and skeletons
- Error boundaries
- Mobile optimization
- Touch-friendly voting controls
- Responsive typography
- Swipe navigation consideration
- Val Town badge
- Fixed position corner badge
- "Built on Val Town" link
Detailed Plan:
- Caching strategy
- API response caching
- Static asset optimization
- Database query optimization
- Advanced features
- Search/filter puzzles
- Category-specific leaderboards
- Vote history (anonymous)
- Export data functionality
- Analytics & monitoring
- Usage tracking
- Error monitoring
- Performance metrics
- 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
- 🔄 Auto-refresh keeps today's puzzle current with new votes
- 🔄 Leaderboard provides engaging way to discover "spiciest" puzzles
This project showcases Val Town's capabilities for full-stack development with cron jobs, SQLite storage, and AI integration.