feat: QA test suite (12 stages, 205 tests) + Chrome DevTools MCP config
- Add tests/ directory with 12 bash/curl/jq test stages covering all API endpoints - Add tests/lib/common.sh shared library with assertions and helpers - Add tests/run-all.sh orchestrator script - Update CLAUDE.md with test data reference and DevTools MCP docs - Increase dev rate limit to 5000 for test suite runs - Configure Chrome DevTools MCP in project settings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
152
CLAUDE.md
152
CLAUDE.md
@@ -1,68 +1,118 @@
|
||||
# Marketplace Project Notes
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Full-stack marketplace application with two domains: a **classified listings marketplace** (buy/sell items) and a **rental platform** (apartments, houses, cars, bicycles). Includes admin/moderation tools, Stripe payments, real-time chat via Socket.io, and subscription tiers.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Monorepo** using npm workspaces (`client/` and `server/`)
|
||||
- **Client**: React 19 + TypeScript + Vite + Tailwind CSS 4 (port 5173)
|
||||
- **Server**: Express + TypeScript + Prisma ORM + PostgreSQL (port 3000)
|
||||
- **Real-time**: Socket.io for messaging and notifications
|
||||
- **Payments**: Stripe (listings, rentals, subscriptions, promotions)
|
||||
- **Auth**: JWT access tokens (15min) + httpOnly refresh token cookies (7 days), bcrypt passwords
|
||||
- **Validation**: Zod schemas on server (`server/src/validators/`), TypeScript on client
|
||||
- **State management**: React Context API (AuthContext), no Redux/Zustand
|
||||
- **Client path alias**: `@/*` maps to `client/src/*`
|
||||
|
||||
## Commands
|
||||
|
||||
### Development
|
||||
```bash
|
||||
docker start marketplace-postgres # Start PostgreSQL (required)
|
||||
npm run dev # Run client + server together
|
||||
npm run dev:client # Client only (port 5173)
|
||||
npm run dev:server # Server only (port 3000)
|
||||
```
|
||||
|
||||
### Database
|
||||
```bash
|
||||
npm run db:generate --workspace=server # Regenerate Prisma client
|
||||
npm run db:push --workspace=server # Push schema to DB (no migration)
|
||||
npm run db:migrate --workspace=server # Create and apply migration
|
||||
npm run db:seed --workspace=server # Seed test data
|
||||
npm run db:studio --workspace=server # Open Prisma Studio GUI
|
||||
```
|
||||
|
||||
Schema location: `server/prisma/schema.prisma`
|
||||
|
||||
### Build & Lint
|
||||
```bash
|
||||
npm run build # Build both client and server
|
||||
npm run lint # ESLint (client only)
|
||||
```
|
||||
|
||||
### Testing (QA Suite)
|
||||
```bash
|
||||
bash tests/run-all.sh # Run all 12 stages locally
|
||||
bash tests/stage-02-auth.sh # Run single stage
|
||||
BASE_URL=https://marketplace.173.212.212.157.sslip.io bash tests/run-all.sh # Against production
|
||||
```
|
||||
Tests location: `tests/` — 12 stage scripts, `tests/lib/common.sh` shared library. Requires: bash, curl, jq.
|
||||
|
||||
### Seed Data
|
||||
|
||||
| Email | ID | Role | Landlord | Key data |
|
||||
|-------|-----|------|----------|----------|
|
||||
| alice.chen@example.com | user-alice | SUPER_ADMIN | No | Listings 01,06,11. Offers, bookings, PRO subscription |
|
||||
| bob.martinez@example.com | user-bob | ADMIN | No | Listings 08,10,15 |
|
||||
| carol.nguyen@example.com | user-carol | MODERATOR | No | Listings 02,05,12. Blocked user-david |
|
||||
| david.kim@example.com | user-david | USER | Yes (verified) | Rentals 01,02,06,07. Listings 04,07,13 |
|
||||
| eva.johnson@example.com | user-eva | USER | Yes | Rentals 03,04,05. Listings 03,09,14 |
|
||||
|
||||
All passwords: `password123`
|
||||
|
||||
**Key IDs**: listings `listing-01`..`listing-15` | rentals `rental-01`..`rental-07` | bookings `booking-01`..`booking-04` | offers `offer-01`..`offer-10`
|
||||
|
||||
## Database: PostgreSQL via Docker
|
||||
|
||||
Container name: `marketplace-postgres`
|
||||
Image: `postgres:17-alpine`
|
||||
Volume: `marketplace-pgdata` (persistent local data)
|
||||
Container: `marketplace-postgres` | Image: `postgres:17-alpine` | Volume: `marketplace-pgdata`
|
||||
|
||||
### Start database
|
||||
Connection string: `postgresql://marketplace:marketplace_dev@localhost:5432/marketplace`
|
||||
|
||||
If container was deleted, recreate:
|
||||
```bash
|
||||
docker start marketplace-postgres
|
||||
docker run -d --name marketplace-postgres \
|
||||
-e POSTGRES_USER=marketplace -e POSTGRES_PASSWORD=marketplace_dev -e POSTGRES_DB=marketplace \
|
||||
-p 5432:5432 -v marketplace-pgdata:/var/lib/postgresql/data \
|
||||
--restart unless-stopped postgres:17-alpine
|
||||
```
|
||||
|
||||
### Stop database (frees memory)
|
||||
```bash
|
||||
docker stop marketplace-postgres
|
||||
```
|
||||
## Key Server Patterns
|
||||
|
||||
### Check status
|
||||
```bash
|
||||
docker ps -f name=marketplace-postgres
|
||||
```
|
||||
- **Routes**: `server/src/routes/` — RESTful endpoints, admin routes nested under `routes/admin/`
|
||||
- **Middleware**: `authenticate` (required auth), `optionalAuth` (anonymous OK), `requireRole` (role check), `checkBanned`, `validate` (Zod)
|
||||
- **Prisma client**: imported from `server/src/config/database.ts`
|
||||
- **Environment config**: `server/src/config/env.ts`
|
||||
- **File uploads**: Multer to `server/uploads/`, served statically
|
||||
- **User roles**: USER, MODERATOR, ADMIN, SUPER_ADMIN — role hierarchy enforced via `requireRole` middleware
|
||||
|
||||
### Connection string
|
||||
```
|
||||
postgresql://marketplace:marketplace_dev@localhost:5432/marketplace
|
||||
```
|
||||
## Key Client Patterns
|
||||
|
||||
### If container was deleted, recreate:
|
||||
```bash
|
||||
docker run -d \
|
||||
--name marketplace-postgres \
|
||||
-e POSTGRES_USER=marketplace \
|
||||
-e POSTGRES_PASSWORD=marketplace_dev \
|
||||
-e POSTGRES_DB=marketplace \
|
||||
-p 5432:5432 \
|
||||
-v marketplace-pgdata:/var/lib/postgresql/data \
|
||||
--restart unless-stopped \
|
||||
postgres:17-alpine
|
||||
```
|
||||
- **Router**: `client/src/router.tsx` — React Router v7 with `createBrowserRouter`
|
||||
- **Auth guards**: `<RequireAuth>` wraps protected routes, `<RequireRole>` checks roles
|
||||
- **API client**: `client/src/api/client.ts` — fetch wrapper that handles auth headers and token refresh
|
||||
- **UI components**: `client/src/components/ui/` — Button, Input, Modal, Card, Badge, DataTable, etc.
|
||||
- **Pages organized by domain**: root pages, `pages/admin/`, `pages/landlord/`
|
||||
|
||||
Data persists in the `marketplace-pgdata` Docker volume even if the container is removed.
|
||||
## Chrome DevTools MCP (Browser Testing)
|
||||
|
||||
## Running the app
|
||||
Chrome DevTools MCP is configured for automated browser testing. It launches an isolated, telemetry-free Chrome instance.
|
||||
|
||||
1. Start database: `docker start marketplace-postgres`
|
||||
2. Server: `npm run dev:server` (port 3000)
|
||||
3. Client: `npm run dev:client` (port 5173)
|
||||
4. Or both: `npm run dev`
|
||||
- **Config location**: `~/.claude.json` → `mcpServers.chrome-devtools` (NOT `~/.claude/settings.json`)
|
||||
- **Binary**: `/opt/homebrew/bin/chrome-devtools-mcp` (installed globally via npm)
|
||||
- **Chrome profile**: `/tmp/chrome-mcp-profile` (isolated, no Google account)
|
||||
- **Key flags**: `--isolated` (auto-launches Chrome), `--disable-sync`, `--disable-background-networking`
|
||||
- **Usage**: Available automatically when Claude Code starts. Use `take_snapshot`, `click`, `fill`, `navigate_page`, `take_screenshot` etc.
|
||||
- **If MCP won't start**: Kill zombie processes (`pkill -f chrome-devtools-mcp`), remove lock (`rm /tmp/chrome-mcp-profile/SingletonLock`), restart Claude Code
|
||||
|
||||
## Seed data
|
||||
## Key Env Vars (server/.env)
|
||||
|
||||
```bash
|
||||
cd server && npx tsx prisma/seed.ts
|
||||
```
|
||||
|
||||
Test users (all password: `password123`):
|
||||
- alice.chen@example.com
|
||||
- bob.smith@example.com
|
||||
- carol.jones@example.com
|
||||
- david.wilson@example.com
|
||||
- eva.martinez@example.com
|
||||
|
||||
## Key env vars (server/.env)
|
||||
|
||||
- `DATABASE_URL` — PostgreSQL connection
|
||||
- `DATABASE_URL` — PostgreSQL connection string
|
||||
- `JWT_SECRET` / `JWT_REFRESH_SECRET` — Token signing
|
||||
- `GOOGLE_MAPS_API_KEY` — Location autocomplete
|
||||
- `STRIPE_SECRET_KEY` / `STRIPE_PUBLISHABLE_KEY` — Payments (optional for dev)
|
||||
- `CLIENT_URL` — CORS origin (default: http://localhost:5173)
|
||||
|
||||
Reference in New Issue
Block a user