Files
nick-doc/07 - Development/Local Setup.md

291 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Local Setup
tags: [development]
---
# Local Setup
This guide walks you through running both repositories of the marketplace stack on your workstation. The platform is split into two services:
- **Backend** — Node.js 22+ / Express 5 / PostgreSQL 16 / Redis 8 / Socket.IO, served on port `5001`.
- **Frontend** — Next.js 16 / React 19 / MUI v7, served on port `8083` (or `3000` in Docker dev).
By the end of this page you will have the API running locally with PostgreSQL + Redis containers, a seeded set of test accounts, and the Next.js dashboard talking to it through your browser. For ongoing reference see [[Environment Variables]], [[Project Structure]], and [[Scripts]].
---
## 1. Prerequisites
Install the following before you start:
| Tool | Version | Why |
|------|---------|-----|
| Node.js | `>= 22` (backend), `>= 20` (frontend) | Runtime |
| Yarn | `1.22.22` (Classic) | Pinned via `packageManager` field |
| Docker Desktop | latest | Runs PostgreSQL + Redis + (optionally) backend/frontend |
| Git | `>= 2.40` | SSH-based clone from Gitea |
| OpenSSL | system default | For generating local secrets |
| `ngrok` (optional) | latest | For webhook testing — see [[Scripts#start-ngrok-sh]] |
> [!tip] Use a single Node version manager (`nvm`, `fnm`, or `volta`) and pin to `22`. Yarn Classic is required — do **not** upgrade to Berry, the lockfiles are incompatible.
You also need an SSH key registered with Gitea. The Git server runs on a non-standard port (`222`), so add an entry to `~/.ssh/config`:
```ssh
Host git.manko.yoga
HostName git.manko.yoga
Port 222
User git
IdentityFile ~/.ssh/id_ed25519
```
Verify connectivity:
```bash
ssh -T git@git.manko.yoga -p 222
```
You should see a Gitea welcome line. If you see "Permission denied (publickey)", upload your public key to your Gitea profile first.
---
## 2. Clone the repos
The two repos are siblings — keep them next to each other (the production compose file references `../frontend` from the backend folder):
```bash
mkdir -p ~/code && cd ~/code
git clone ssh://git@git.manko.yoga:222/nick/backend.git
git clone ssh://git@git.manko.yoga:222/nick/frontend.git
```
Switch each repo to the active integration branch for the stack you are testing. As of 2026-05-31, the dev stack work is on `integrate-main-into-development`:
```bash
cd ~/code/backend && git checkout integrate-main-into-development
cd ~/code/frontend && git checkout integrate-main-into-development
```
> [!warning] `main`/`master` is the production branch and is consumed by the Watchtower auto-update flow. Never push WIP commits there. See [[Git Workflow]].
---
## 3. Install dependencies
Backend uses **npm** for scripts but `yarn install` for lockfile parity with Docker, while the frontend is pure Yarn:
```bash
# Backend
cd ~/code/backend
yarn install --frozen-lockfile
# Frontend
cd ~/code/frontend
yarn install --frozen-lockfile
```
Both installs take 25 minutes on a cold cache. If `node-gyp`/`sharp` fail on macOS, install Xcode CLT (`xcode-select --install`).
---
## 4. Configure `.env` files
Each repo ships example files. Copy them and fill in secrets — full reference is in [[Environment Variables]].
### Backend (`/Users/mojtabaheidari/code/backend/.env.local`)
`docker-compose.dev.yml` reads `.env.local`. The container expects at minimum:
```bash
NODE_ENV=development
PORT=5001
PG_URL=postgresql://postgres:postgres@postgres:5432/marketplace
REDIS_URI=redis://redis:6379
JWT_SECRET=$(openssl rand -hex 32)
JWT_EXPIRES_IN=1h
REFRESH_TOKEN_EXPIRES_IN=30d
FRONTEND_URL=http://localhost:8083
MAX_FILE_SIZE=10485760
UPLOAD_PATH=/app/uploads
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
```
> [!note] `MONGODB_URI` / `MONGO_URI` / `MONGO_CONNECT_MODE` are **no longer used**. MongoDB has been fully removed from the backend runtime (v2.9.12+). The only database layer is PostgreSQL + Drizzle ORM. `PG_URL` is required.
For payments, OpenAI, SMTP, etc., refer to [[Environment Variables]].
### Frontend
Three env files already exist; pick the one that matches your scenario:
| File | When to use |
|------|-------------|
| `.env.local` | Local Next dev (`yarn dev`) — points at `http://localhost:5001` |
| `.env.development` | Docker compose dev — points at `dev.amn.gg` via Nginx |
| `.env.production` | Production build — points at `amn.gg` |
Next.js automatically picks `.env.local` for `next dev`. Do **not** check this file in if you change secrets.
---
## 5. Start the backend
You have two equivalent paths.
### Option A — All-in-Docker (recommended)
Builds the backend image, brings up PostgreSQL + Redis + backend on `nickapp-network`, and mounts `./src` for hot reload:
```bash
cd ~/code/backend
npm run docker:dev
```
Follow logs:
```bash
npm run docker:dev:logs
```
Stop:
```bash
npm run docker:dev:down
```
### Option B — Local Node + Docker datastores
Run only the datastores in Docker and the API on the host:
```bash
cd ~/code/backend
docker compose -f docker-compose.dev.yml up -d postgres redis
npm run dev # ts-node + nodemon on port 5001
```
Override `PG_URL=postgresql://postgres:postgres@localhost:5432/marketplace` in `.env` if you take this route, since `postgres` only resolves inside the compose network.
> [!tip] If port `5001` is already in use, set `PORT=5002` in `.env.local` and update `NEXT_PUBLIC_API_URL` in the frontend env to match.
---
## 5a. Apply database migrations
After starting the PostgreSQL container (and before seeding), apply all Drizzle migrations to create the 32-table schema:
```bash
cd ~/code/backend
npx drizzle-kit migrate
```
This runs the 19 migration files (00000019) and brings the database schema up to date. You only need to run this once on a fresh database, or after pulling commits that include new migration files.
> [!note] If you are using Option A (All-in-Docker), run this from the host after the `postgres` container is healthy but before the backend service connects.
---
## 6. Seed test data
Once PostgreSQL is healthy and migrations have been applied, populate it with default users, categories, addresses, and templates:
```bash
cd ~/code/backend
npm run seed:all # users + addresses (clears existing)
npm run seed:categories # marketplace taxonomy
```
`seed:all` creates the canonical test accounts (password `Moji6364` for all):
| Role | Email |
|------|-------|
| Admin | `admin@marketplace.com` |
| Buyer | `buyer@marketplace.com` |
| Seller | `seller@marketplace.com` |
| Seller (alt) | `seller2@marketplace.com` |
You can also enable auto-seeding on container start by adding `AUTO_SEED_ON_START=true` to `.env.local`. Auto-seed runs only when the `users` table has no non-admin entries — safe to leave on.
See [[Scripts#seed-scripts]] for the full list (`seed:users`, `seed:addresses`, `seed:categories`, `seed:all`, plus `createSupportUser.ts`, `createTestRequest.ts`, etc.).
---
## 7. Start the frontend
```bash
cd ~/code/frontend
yarn dev
```
Next.js starts on **port 8083** (`next dev -p 8083 --turbopack`). The dashboard is at:
- http://localhost:8083 — landing
- http://localhost:8083/auth/jwt/sign-in — login
- http://localhost:8083/dashboard — authenticated area
If you used the Docker compose dev workflow with the production-mode container, port `3000` may also be exposed; check the compose output.
---
## 8. Verify
Run these smoke checks before you start coding:
```bash
# Backend health (should return JSON with success: true)
curl -s http://localhost:5001/health | jq .
# API root
curl -s http://localhost:5001/ | jq .
# Login (returns JWT)
curl -s -X POST http://localhost:5001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@marketplace.com","password":"Moji6364"}' | jq .
```
In the browser, open http://localhost:8083, log in with `admin@marketplace.com / Moji6364`, and confirm the dashboard loads. If chat or notification badges show up, sockets connected too.
> [!tip] Tail backend logs in a separate terminal: `npm run docker:dev:logs`. Look for `Connected to PostgreSQL`, `User connected`, and `Server running on port 5001`.
---
## 9. Common issues
| Symptom | Fix |
|---------|-----|
| `EADDRINUSE :::5001` | Another process owns the port — `lsof -i :5001` then `kill`, or change `PORT`. |
| `ECONNREFUSED 127.0.0.1:5432` | PostgreSQL container is down — `docker compose -f docker-compose.dev.yml ps` to check. |
| `ECONNREFUSED 127.0.0.1:6379` | Redis container is down — `docker compose -f docker-compose.dev.yml ps` to check. |
| `relation "users" does not exist` | Migrations have not been applied — run `npx drizzle-kit migrate` from the backend folder. |
| CORS errors in the browser | `FRONTEND_URL` in backend `.env.local` must exactly match the origin you open in the browser (scheme + host + port). |
| `yarn install` hangs on `sharp` | Run `yarn config set network-timeout 600000` and retry. |
| `next dev` fails with module-not-found after a `git pull` | Run `yarn install` again — Next 16 is sensitive to drift in `react`/`react-dom`. |
| Sockets do not connect | Confirm `NEXT_PUBLIC_SOCKET_URL` matches the backend origin and that no browser extension blocks WebSockets. |
---
## 10. Quick reset
If your local state gets weird, the backend ships a one-shot reset script:
```bash
cd ~/code/backend
./scripts/reset-server.sh
```
This stops the dev compose stack, restarts it, runs health checks against PostgreSQL / Redis / `/health`, and probes the login endpoint with the seeded admin user. Output is colourised and ends with the canonical test credentials. See [[Scripts#reset-server-sh]] for details.
> [!warning] `reset-server.sh` does **not** drop volumes by default. To wipe the database, uncomment the `down -v` line in the script or run `docker compose -f docker-compose.dev.yml down -v` first. You will need to re-run `npx drizzle-kit migrate` and `npm run seed:all` after a volume wipe.
---
## Next steps
- Walk the codebase via [[Project Structure]].
- Read [[Coding Standards]] before opening your first PR.
- Run the test suites — [[Testing]].
- Inspect what runs in each container — [[Docker Setup]] (Operations).
- For shipping changes through CI, see [[CI-CD Pipeline]] (Operations).