Thanks for your interest in contributing to GamePulse! This guide will help you get from zero to your first PR.
- Node.js 20+ (use
nvm useif you have nvm installed) - npm 10+
- A code editor with TypeScript and Tailwind CSS support (VS Code recommended)
# 1. Fork and clone the repository
git clone https://github.com/<your-username>/gamepulse.git
cd gamepulse
# 2. Install dependencies
npm install
# 3. Start the dev server
npm run dev
# 4. Open http://localhost:3000The SQLite database seeds automatically on first run. No additional setup is needed.
GamePulse follows a layered architecture:
Pages (app/) → Queries (lib/queries/) → Database (lib/db/)
↓
Scoring (lib/scoring.ts)
Taste (lib/taste.ts)
app/— Next.js App Router pages. Each route is a server component that calls query functions directly.components/— Reusable UI components.search-autocomplete.tsx,client-widgets.tsx, andaction-forms.tsxare client components ("use client").lib/queries/— Data access layer split by domain (games, critics, feed, user, dashboard).lib/db/— Database connection singleton, schema definition, and seed data.lib/scoring.ts— Scoring algorithms: cosine similarity, Pearson correlation, consensus badges, personalized predictions.lib/actions.ts— Server Actions for mutations (reviews, follows, watchlist, newsletter).
| Script | Use When |
|---|---|
npm run dev |
Active development with hot reload |
npm run build |
Verify production build works |
npm run lint |
Check for ESLint issues |
npm run type-check |
Check TypeScript types without building |
npm run check |
Full CI gate: type-check → lint → build |
npm run clean |
Reset database and build artifacts |
# Run all checks (type-check → lint → build)
npm run checkAll three stages must pass. The CI pipeline will run these automatically on your PR.
- Strict mode is enabled — no
anytypes, no unchecked indexed access - Use explicit return types on exported functions
- Prefer
typeoverinterfacefor object shapes (project convention) - Use path aliases:
@/lib/...,@/components/...
- Tailwind CSS only — no custom CSS files except
globals.css - Follow the existing design system:
rounded-[2rem]cards,rose-500accents,slate-950text - Use the shared components from
gamepulse-ui.tsx(PageShell,SectionHeading,ScoreCard, etc.)
- Server components by default; add
"use client"only when needed (hooks, event handlers, browser APIs) - Forms use Server Actions via
useActionState+SubmitButtonfor pending states - Toast notifications via
useToast()from@/components/toast
- All queries go in
lib/queries/— never callgetDb()directly from page components - Seed data lives in
lib/db/seeds/— one file per entity type - Bump
SEED_VERSIONinlib/db/seed.tswhen changing seed data
- Files:
kebab-case.tsx - Components:
PascalCase - Functions:
camelCase - Types:
PascalCase(e.g.,GameCardData,CriticReview) - Database columns:
snake_case
The current user is hardcoded via getCurrentUser() in lib/queries/user.ts. All server actions operate as the seeded "alex" user. This is intentional for the MVP demo — a real auth layer (NextAuth.js) is on the roadmap.
The SQLite database is ephemeral and auto-seeds. Don't commit data/*.db files (they're gitignored). If your database gets into a bad state, run npm run clean and restart the dev server.
- One concern per PR — keep changes focused and reviewable
- Descriptive title — use conventional commit style:
feat: add game comparison view,fix: correct score rounding,docs: update API examples - Description — explain what changed and why, not just how
- Self-review — check the diff before requesting review
- Tests — add tests for new utility functions in
lib/
- Check the docs/ folder for the PRD, code review, and UX review documents
- Open an issue for bugs or feature requests
- Start a discussion for questions or ideas
Thank you for helping make GamePulse better! 🎲