A premium peer-to-peer marketplace for buying, selling, and trading board games — with structured condition grading, fair market value guidance, and local-first discovery.
- Premium marketplace — Browse nearby board game listings with condition grading, FMV indicators, and seller reputation
- 6-step listing wizard — Structured condition grading, component checklist, photo guidance, and market-aware pricing
- Game market detail — Price history charts, active listings, fair market value range, and similar games
- Trade matching — Have/want list matching with trade proposal modal
- User profiles & dashboard — Public seller profiles with reviews, plus private dashboard with sales analytics, watchlists, and saved searches
- Local SQLite database — Zero-config development with automatic schema creation and guarded, idempotent, deterministic seed data
┌─────────────────────────────────────────────────────┐
│ Next.js App Router │
│ ┌──────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ Pages │ │ API │ │ Components │ │
│ │ (SSR) │ │ Routes │ │ (Client + Server)│ │
│ └────┬─────┘ └────┬─────┘ └───────────────────┘ │
│ │ │ │
│ ┌────▼──────────────▼─────┐ │
│ │ Repository Layer │ (db/*.repo.ts) │
│ │ + Mapper Functions │ (db/mappers.ts) │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ better-sqlite3 │ (shelftrade.db) │
│ │ + guarded auto-seed on │ │
│ │ boot (transactional) │ │
│ └─────────────────────────┘ │
└─────────────────────────────────────────────────────┘
| Layer | Technology |
|---|---|
| Framework | Next.js 14 App Router |
| Language | TypeScript (strict mode) |
| Styling | Tailwind CSS with semantic tokens |
| Database | better-sqlite3 / SQLite |
| Charts | Recharts |
| Icons | Lucide React |
Prerequisites: Node.js 20+ (see .nvmrc)
# Clone and install
git clone https://github.com/your-org/shelftrade.git
cd shelftrade
npm install
# Start development server
npm run devOpen http://localhost:3000. In non-production environments, the database is created and seeded automatically on first run.
ShelfTrade ships with a richer deterministic demo dataset designed to exercise the marketplace, profile, dashboard, and trade flows end-to-end:
- 64 real board games with publishers, categories, and player-count metadata
- 16 user profiles with varied reputation, review, and transaction totals
- 112 listings spread across all five condition grades with realistic pricing bands
- 60 transactions (including 54 completed) with paired buyer/seller reviews and price history support
- Trade haves/wants, 30 watchlist entries, and 18 saved searches for realistic discovery states
- Edge cases including games with zero listings, extreme prices, and users with no completed trades
Seeding is transactional, idempotent by SEED_VERSION, and guarded in production. The app skips boot-time seeding when NODE_ENV=production unless you explicitly opt in with SHELFTRADE_ALLOW_PRODUCTION_SEED=true.
| Command | Description |
|---|---|
npm run dev |
Start dev server with hot reload |
npm run build |
Production build |
npm run start |
Serve production build |
npm run lint |
ESLint check |
npm run typecheck |
TypeScript type verification |
npm run format |
Auto-format with Prettier |
npm run format:check |
Verify formatting (CI) |
src/
├── app/ # Next.js App Router
│ ├── api/ # REST API endpoints ({data, error} shape)
│ │ ├── dashboard/ # GET /api/dashboard
│ │ ├── games/ # GET /api/games, GET /api/games/[id]
│ │ ├── listings/ # GET|POST /api/listings, GET /api/listings/[id]
│ │ ├── price-history/ # GET /api/price-history/[gameId]
│ │ ├── trade/ # GET /api/trade/matches
│ │ └── users/ # GET /api/users/[username]
│ ├── dashboard/ # Private user dashboard
│ ├── games/[id]/ # Game market detail page
│ ├── listings/ # Listing detail + create wizard
│ ├── marketplace/ # Browse & filter listings
│ ├── profile/[username]/ # Public seller profile
│ └── trade/ # Trade matching
├── components/ # React UI components
│ └── listing-create/ # 6-step wizard step components
├── hooks/ # Custom React hooks (useFocusTrap)
└── lib/ # Shared logic
├── db/ # Database layer (connection, repos, mappers)
├── api.ts # API helpers (jsonSuccess, parseEnum, etc.)
├── seed.ts # Deterministic seed data
├── types.ts # TypeScript interfaces & constants
└── utils.ts # Formatting & utility functions
| Route | Description |
|---|---|
/ |
Landing page with featured listings and value props |
/marketplace |
Browse all listings with search, filters, and sorting |
/games/[id] |
Game detail with price history, FMV, and active listings |
/listings/create |
6-step seller listing wizard |
/listings/[id] |
Individual listing detail page |
/trade |
Trade matching based on have/want lists |
/profile/[username] |
Public seller profile with reviews |
/dashboard |
Private dashboard (seeded user: alice) |
All API endpoints return a consistent { data, error } JSON shape.
// Success: { data: T, error: null }
// Error: { data: null, error: "message" }curl http://localhost:3000/api/health
# → { "status": "healthy", "timestamp": "...", "version": "0.1.0" }See src/lib/types.ts for complete type definitions.
| Variable | Default | Description |
|---|---|---|
NEXT_PUBLIC_BASE_URL |
https://shelftrade.app |
Public base URL for metadata and SEO |
PORT |
3000 |
Development server port |
NODE_ENV |
development |
Runtime environment |
SHELFTRADE_ENABLE_SEED |
true outside production |
Set to false to disable automatic seed bootstrapping |
SHELFTRADE_ALLOW_PRODUCTION_SEED |
false |
Must be true before seed bootstrapping is allowed in production |
No .env file is required for local development — all variables have sensible defaults.
See CONTRIBUTING.md for development setup, coding conventions, and submission guidelines.