You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+32-18Lines changed: 32 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,12 +17,12 @@
17
17
|**🎯 Taste Profile Quiz**| Rate 10 well-known games and answer preference questions to build a personalized recommendation engine |
18
18
|**🤖 Personalized Recommendations**| Content-based filtering scores games on complexity, theme, mechanics, and player count match |
19
19
|**🎭 Mood-Based Discovery**| Browse by "Quick Party Game", "Deep Strategy", "Cozy Two-Player", and 5 more moods |
20
-
|**🔍 Search & Filter**| Search 55+ real board games with filters for players, complexity, and playtime |
21
-
|**📋 Game Detail Pages**| Full info, price comparison across retailers, reviews, similar games, play logging |
20
+
|**🔍 Search & Filter**| Search 85+ real board games with filters for players, complexity, and playtime |
21
+
|**📋 Game Detail Pages**| Full info, current prices, seeded deals, reviews, similar games, and play logging |
22
22
|**📚 Collection Management**| Track owned games and wishlist with shelf view and sorting |
23
-
|**📝 Play Logging**| Log plays with date, player count, winner, rating, and notes |
24
-
|**📊 Stats Dashboard**| Charts for plays per month, complexity distribution, top categories, ratings |
25
-
|**💰 Price Tracker**| Compare prices across Amazon, Target, and more with deal alert setup|
23
+
|**📝 Play Logging**| Log plays with date, player count, winner, optional score, rating, and notes |
24
+
|**📊 Stats Dashboard**| Charts for plays per month, complexity distribution, top categories, ratings, and recent scores|
25
+
|**💰 Price Tracker**| Compare retailer snapshots, surface active deals, and set deal alerts|
26
26
27
27
## 🚀 Quick Start
28
28
@@ -34,7 +34,7 @@ npm install
34
34
npm run dev
35
35
```
36
36
37
-
Open [http://localhost:3000](http://localhost:3000) — that's it! The SQLite database is created and seeded automatically with 55 real board games on first run.
37
+
Open [http://localhost:3000](http://localhost:3000) — that's it! In non-production environments the SQLite database is created and reseeded automatically on first access with a rich demo dataset (85 board games, 12 personas, play history, reviews, collections, wishlists, price alerts, and active deals).
38
38
39
39
## 🛠 Tech Stack
40
40
@@ -65,9 +65,12 @@ src/
65
65
│ ├── price-alerts/ # Deal alert subscriptions
66
66
│ └── health/ # Service health check
67
67
├── components/ # Shared UI components
68
-
├── data/games.ts # 55 real board games seed data
68
+
├── data/
69
+
│ ├── games.ts # Base board game catalog data
70
+
│ └── seed/ # Seed catalog, personas, and deal definitions
@@ -92,32 +95,43 @@ SQLite with the following tables:
92
95
93
96
| Table | Purpose |
94
97
| --- | --- |
95
-
|`games`| Game catalog (55 seeded entries) |
96
-
|`price_history`| Retailer prices per game |
97
-
|`users`| User accounts (demo single-user MVP) |
98
+
|`games`| Game catalog (85 seeded entries) |
99
+
|`price_history`| Historical retailer price snapshots per game |
100
+
|`game_deals`| Current seeded deals with discount metadata |
101
+
|`users`| Seeded personas plus runtime-created users |
98
102
|`sessions`| Opaque session tokens |
99
103
|`quiz_answers`| Game ratings and preference answers |
100
104
|`collection`| Owned/wishlist items |
101
-
|`play_logs`| Play history with ratings |
105
+
|`play_logs`| Play history with winners, ratings, and optional scores|
102
106
|`reviews`| User game reviews |
103
107
|`price_alerts`| Deal alert subscriptions |
108
+
|`seed_metadata`| Seed dataset version tracking |
104
109
105
110
## 🎮 Seed Data
106
111
107
-
The database includes 55 real board games spanning all complexity levels:
112
+
The demo dataset is intentionally rich and deterministic:
108
113
109
-
-**Heavy**: Gloomhaven, Brass: Birmingham, Spirit Island
110
-
-**Medium-Heavy**: Terraforming Mars, Scythe, Twilight Imperium
111
-
-**Medium**: Wingspan, 7 Wonders, Pandemic Legacy
112
-
-**Gateway**: Catan, Ticket to Ride, Azul
113
-
-**Light/Party**: Codenames, Coup, Love Letter
114
+
-**85 real games** with accurate mechanics, themes, player counts, playtimes, and complexity spread from **1.0 (`No Thanks!`)** to **5.0 (`Advanced Squad Leader`)**
115
+
-**12 user personas** with distinct tastes, collection sizes, wishlists, quiz answers, and price alerts
116
+
-**216 seeded play logs** with dates, player counts, winners, ratings, and scores
117
+
-**60 seeded reviews** with short, medium, and long-form text
118
+
-**Historical price snapshots** for every retailer listing plus **active deals** for a large portion of the catalog
119
+
-**Edge cases** including unicode names (`zoë_meeples`, `señor_carton`, `Café`, `Jórvík`) and long descriptions for heavier narrative titles
120
+
121
+
### Seed Behavior
122
+
123
+
-**Guarded in production** by default — automatic reseeding only runs outside production unless `GAMESCOUT_ALLOW_PRODUCTION_SEED=1`
124
+
-**Idempotent** — the seeder truncates seed-managed tables and re-inserts a known-good dataset version
125
+
-**Transactional** — catalog, personas, logs, reviews, and pricing data are inserted in a single transaction
126
+
-**Conventionally placed** — catalog and persona definitions live in `src/data/seed/`, while orchestration lives in `src/lib/seed.ts`
114
127
115
128
## 📜 Available Scripts
116
129
117
130
| Command | Description |
118
131
| --- | --- |
119
132
|`npm run dev`| Start development server with hot reload |
120
133
|`npm run build`| Create optimized production build |
134
+
|`GAMESCOUT_ALLOW_PRODUCTION_SEED=1 npm run start`| Allow one-time automatic seeding while running the production server |
121
135
|`npm run start`| Run production server |
122
136
|`npm run lint`| Run ESLint checks |
123
137
|`npm run lint:types`| TypeScript type checking (`tsc --noEmit`) |
ORDER BY featured DESC, discount_pct DESC, sale_price ASC`
55
+
)
56
+
.all(Number(id))asDealRow[];
39
57
40
58
// Reviews
41
59
constreviews=db
@@ -75,13 +93,14 @@ export async function GET(
75
93
// Play logs for this game
76
94
constplayLogs=db
77
95
.prepare(
78
-
`SELECT pl.id, pl.played_at, pl.players, pl.winner, pl.rating, pl.notes, g.name as game_name FROM play_logs pl JOIN games g ON pl.game_id = g.id WHERE pl.user_id = ? AND pl.game_id = ? ORDER BY pl.played_at DESC`
96
+
`SELECT pl.id, pl.played_at, pl.players, pl.winner, pl.rating, pl.score, pl.notes, g.name as game_name FROM play_logs pl JOIN games g ON pl.game_id = g.id WHERE pl.user_id = ? AND pl.game_id = ? ORDER BY pl.played_at DESC`
0 commit comments