# Installation Guide

Complete setup instructions for the Flyer Crawler local development environment.

---

## Quick Reference

| Setup Method      | Best For                    | Time   | Document Section                                    |
| ----------------- | --------------------------- | ------ | --------------------------------------------------- |
| Quick Start       | Already have Postgres/Redis | 5 min  | [Quick Start](#quick-start)                         |
| Dev Container     | Full production-like setup  | 15 min | [Dev Container](#development-container-recommended) |
| Manual Containers | Learning the components     | 20 min | [Podman Setup](#podman-setup-manual)                |

---

## Prerequisites

### Required Software

| Software       | Minimum Version | Purpose              | Download                                        |
| -------------- | --------------- | -------------------- | ----------------------------------------------- |
| Node.js        | 20.x            | Runtime              | [nodejs.org](https://nodejs.org/)               |
| Podman Desktop | 4.x             | Container management | [podman-desktop.io](https://podman-desktop.io/) |
| Git            | 2.x             | Version control      | [git-scm.com](https://git-scm.com/)             |

### Windows-Specific Requirements

| Requirement | Purpose                        | Setup Command                      |
| ----------- | ------------------------------ | ---------------------------------- |
| WSL 2       | Linux compatibility for Podman | `wsl --install` (admin PowerShell) |

### Verify Installation

```bash
# Check all prerequisites
node --version      # Expected: v20.x or higher
podman --version    # Expected: podman version 4.x or higher
git --version       # Expected: git version 2.x or higher
wsl --list -v       # Expected: Shows WSL 2 distro
```

---

## Quick Start

If you already have PostgreSQL and Redis configured externally:

```bash
# 1. Clone the repository
git clone https://gitea.projectium.com/flyer-crawler/flyer-crawler.git
cd flyer-crawler

# 2. Install dependencies
npm install

# 3. Create .env.local (see Environment section below)

# 4. Run in development mode
npm run dev
```

**Access Points**:

- Frontend: `http://localhost:5173`
- Backend API: `http://localhost:3001`

---

## Development Container (Recommended)

The dev container provides a complete, production-like environment.

### What's Included

| Service    | Purpose                  | Port       |
| ---------- | ------------------------ | ---------- |
| Node.js    | API server, worker, Vite | 3001, 5173 |
| PostgreSQL | Database with PostGIS    | 5432       |
| Redis      | Cache and job queues     | 6379       |
| NGINX      | HTTPS reverse proxy      | 443        |
| Bugsink    | Error tracking           | 8443       |
| Logstash   | Log aggregation          | -          |
| PM2        | Process management       | -          |

### Setup Steps

#### Step 1: Initialize Podman

```bash
# Windows: Start Podman Desktop, or from terminal:
podman machine init
podman machine start
```

#### Step 2: Start Dev Container

```bash
# Start all services
podman-compose -f compose.dev.yml up -d

# View logs (optional)
podman-compose -f compose.dev.yml logs -f
```

**Expected Output**:

```text
[+] Running 3/3
 - Container flyer-crawler-postgres  Started
 - Container flyer-crawler-redis     Started
 - Container flyer-crawler-dev       Started
```

#### Step 3: Verify Services

```bash
# Check containers are running
podman ps

# Check PM2 processes
podman exec -it flyer-crawler-dev pm2 status
```

**Expected PM2 Status**:

```text
+---------------------------+--------+-------+
| name                      | status | cpu   |
+---------------------------+--------+-------+
| flyer-crawler-api-dev     | online | 0%    |
| flyer-crawler-worker-dev  | online | 0%    |
| flyer-crawler-vite-dev    | online | 0%    |
+---------------------------+--------+-------+
```

#### Step 4: Access Application

| Service     | URL                      | Notes                        |
| ----------- | ------------------------ | ---------------------------- |
| Frontend    | `https://localhost`      | NGINX proxies to Vite        |
| Backend API | `http://localhost:3001`  | Express server               |
| Bugsink     | `https://localhost:8443` | Login: admin@localhost/admin |

### SSL Certificate Setup (Optional but Recommended)

To eliminate browser security warnings:

**Windows**:

1. Double-click `certs/mkcert-ca.crt`
2. Click "Install Certificate..."
3. Select "Local Machine" > Next
4. Select "Place all certificates in the following store"
5. Browse > Select "Trusted Root Certification Authorities" > OK
6. Click Next > Finish
7. Restart browser

**Other Platforms**: See [`certs/README.md`](../../certs/README.md)

### Managing the Dev Container

| Action    | Command                                     |
| --------- | ------------------------------------------- |
| Start     | `podman-compose -f compose.dev.yml up -d`   |
| Stop      | `podman-compose -f compose.dev.yml down`    |
| View logs | `podman-compose -f compose.dev.yml logs -f` |
| Restart   | `podman-compose -f compose.dev.yml restart` |
| Rebuild   | `podman-compose -f compose.dev.yml build`   |

---

## Podman Setup (Manual)

For understanding the individual components or custom configurations.

### Step 1: Install Prerequisites on Windows

```powershell
# Run in administrator PowerShell
wsl --install
```

Restart computer after WSL installation.

### Step 2: Initialize Podman

1. Launch **Podman Desktop**
2. Follow the setup wizard to initialize Podman machine
3. Start the Podman machine

Or from terminal:

```bash
podman machine init
podman machine start
```

### Step 3: Create Podman Network

```bash
podman network create flyer-crawler-net
```

### Step 4: Create PostgreSQL Container

```bash
podman run -d \
  --name flyer-crawler-postgres \
  --network flyer-crawler-net \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e POSTGRES_DB=flyer_crawler_dev \
  -p 5432:5432 \
  -v flyer-crawler-pgdata:/var/lib/postgresql/data \
  docker.io/postgis/postgis:15-3.3
```

### Step 5: Create Redis Container

```bash
podman run -d \
  --name flyer-crawler-redis \
  --network flyer-crawler-net \
  -p 6379:6379 \
  -v flyer-crawler-redis:/data \
  docker.io/library/redis:alpine
```

### Step 6: Initialize Database

```bash
# Wait for PostgreSQL to be ready
podman exec flyer-crawler-postgres pg_isready -U postgres

# Install required extensions
podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "
  CREATE EXTENSION IF NOT EXISTS postgis;
  CREATE EXTENSION IF NOT EXISTS pg_trgm;
  CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";
"

# Apply schema
podman exec -i flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev < sql/master_schema_rollup.sql
```

### Step 7: Create Node.js Container

```bash
# Create volume for node_modules
podman volume create node_modules_cache

# Run Ubuntu container with project mounted
podman run -it \
  --name flyer-dev \
  --network flyer-crawler-net \
  -p 3001:3001 \
  -p 5173:5173 \
  -v "$(pwd):/app" \
  -v "node_modules_cache:/app/node_modules" \
  ubuntu:latest
```

### Step 8: Configure Container Environment

Inside the container:

```bash
# Update and install dependencies
apt-get update
apt-get install -y curl git

# Install Node.js 20
curl -sL https://deb.nodesource.com/setup_20.x | bash -
apt-get install -y nodejs

# Navigate to project and install
cd /app
npm install

# Start development server
npm run dev
```

### Container Management Commands

| Action         | Command                        |
| -------------- | ------------------------------ |
| Stop container | Press `Ctrl+C`, then `exit`    |
| Restart        | `podman start -a -i flyer-dev` |
| Remove         | `podman rm flyer-dev`          |
| List running   | `podman ps`                    |
| List all       | `podman ps -a`                 |

---

## Environment Configuration

### Create .env.local

Create `.env.local` in the project root with your configuration:

```bash
# Database (adjust host based on your setup)
DB_HOST=localhost        # Use 'postgres' if inside dev container
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=flyer_crawler_dev

# Redis (adjust host based on your setup)
REDIS_URL=redis://localhost:6379  # Use 'redis://redis:6379' inside container

# Application
NODE_ENV=development
PORT=3001
FRONTEND_URL=http://localhost:5173

# Authentication (generate secure values)
JWT_SECRET=your-secret-at-least-32-characters-long

# AI Services
GEMINI_API_KEY=your-google-gemini-api-key
GOOGLE_MAPS_API_KEY=your-google-maps-api-key  # Optional
```

**Generate Secure Secrets**:

```bash
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
```

### Environment Differences

| Variable    | Host Development         | Inside Dev Container |
| ----------- | ------------------------ | -------------------- |
| `DB_HOST`   | `localhost`              | `postgres`           |
| `REDIS_URL` | `redis://localhost:6379` | `redis://redis:6379` |

See [ENVIRONMENT.md](ENVIRONMENT.md) for complete variable reference.

---

## Seeding Development Data

Create test accounts and sample data:

```bash
npm run seed
```

### What the Seed Script Does

1. Rebuilds database schema from `sql/master_schema_rollup.sql`
2. Creates test user accounts:
   - `admin@example.com` (admin user)
   - `user@example.com` (regular user)
3. Copies test flyer images to `public/flyer-images/`
4. Creates sample flyer with items
5. Seeds watched items and shopping list

### Test Images

The seed script copies these files from `src/tests/assets/`:

- `test-flyer-image.jpg`
- `test-flyer-icon.png`

Images are served by NGINX at `/flyer-images/`.

---

## Verification Checklist

After installation, verify everything works:

- [ ] **Containers running**: `podman ps` shows postgres and redis
- [ ] **Database accessible**: `podman exec flyer-crawler-postgres psql -U postgres -c "SELECT 1;"`
- [ ] **Frontend loads**: Open `http://localhost:5173` (or `https://localhost` for dev container)
- [ ] **API responds**: `curl http://localhost:3001/health`
- [ ] **Tests pass**: `npm run test:unit` (or in container: `podman exec -it flyer-crawler-dev npm run test:unit`)
- [ ] **Type check passes**: `npm run type-check`

---

## Troubleshooting

### Podman Machine Won't Start

```bash
# Reset Podman machine
podman machine rm
podman machine init
podman machine start
```

### Port Already in Use

```bash
# Find process using port
netstat -ano | findstr :5432

# Option: Use different port
podman run -d --name flyer-crawler-postgres -p 5433:5432 ...
# Then set DB_PORT=5433 in .env.local
```

### Database Extensions Missing

```bash
podman exec flyer-crawler-postgres psql -U postgres -d flyer_crawler_dev -c "
  CREATE EXTENSION IF NOT EXISTS postgis;
  CREATE EXTENSION IF NOT EXISTS pg_trgm;
  CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";
"
```

### Permission Denied on Windows Paths

Use `MSYS_NO_PATHCONV=1` prefix:

```bash
MSYS_NO_PATHCONV=1 podman exec flyer-crawler-dev /path/to/script.sh
```

### Tests Fail with Timezone Errors

Tests must run in the dev container, not on Windows host:

```bash
# CORRECT
podman exec -it flyer-crawler-dev npm test

# INCORRECT (may fail with TZ errors)
npm test
```

---

## Next Steps

| Goal                  | Document                                               |
| --------------------- | ------------------------------------------------------ |
| Quick setup guide     | [QUICKSTART.md](QUICKSTART.md)                         |
| Environment variables | [ENVIRONMENT.md](ENVIRONMENT.md)                       |
| Database schema       | [DATABASE.md](../architecture/DATABASE.md)             |
| Authentication setup  | [AUTHENTICATION.md](../architecture/AUTHENTICATION.md) |
| Dev container details | [DEV-CONTAINER.md](../development/DEV-CONTAINER.md)    |
| Deployment            | [DEPLOYMENT.md](../operations/DEPLOYMENT.md)           |

---

Last updated: January 2026
