# Installation & Deployment – JobPortal

## Requirements

- PHP 8.2+ with extensions: pdo_mysql, mbstring, openssl, fileinfo, json
- MySQL 8.0+ or MariaDB 10.5+
- Apache with mod_rewrite **or** Nginx
- Composer (recommended)
- Writable directories: `storage/`, `storage/uploads/`, `storage/logs/`

## Quick install

```bash
# 1. Dependencies
composer install

# 2. Environment
cp .env.example .env
# Edit DB_*, APP_URL, APP_KEY, MAIL_*
php -r "echo bin2hex(random_bytes(32)), PHP_EOL;"  # paste into APP_KEY

# 3. Database
mysql -u root -p -e "CREATE DATABASE jobportal CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -p jobportal < database/migrations/001_create_schema.sql

# 4. Seeders
php database/seeders/AdminSeeder.php
php database/seeders/CategoriesSeeder.php
php database/seeders/PackagesSeeder.php   # RWF premium packages

# 5. Permissions
chmod -R 775 storage
# Ensure web server user can write storage/uploads

# 6. Document root MUST be /public
# Apache example: DocumentRoot /var/www/jobportal/public
```

### Development server

```bash
cd public && php -S localhost:8000
```

### Default Super Admin

- Email: `admin@jobportal.local`
- Password: `Admin@12345`  
**Change immediately after first login.**

## Cron jobs (production)

```cron
# Expire jobs past deadline
0 1 * * * cd /var/www/jobportal && php cron/expire_jobs.php >> storage/logs/cron.log 2>&1

# Expire premium pins
0 2 * * * cd /var/www/jobportal && php cron/expire_premium.php >> storage/logs/cron.log 2>&1
```

## Nginx snippet

```nginx
server {
    listen 80;
    server_name jobs.example.com;
    root /var/www/jobportal/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    location ~* /storage/uploads/(cvs|company_docs)/ {
        deny all;
    }
}
```

## HTTPS

Terminate TLS at the reverse proxy or use Let's Encrypt. Set `APP_URL` to `https://...`.  
Session cookies already use `httponly` and `SameSite=Lax`; enable `secure` when HTTPS is on.

## Payment (RWF)

Default flow is **manual / Mobile Money reference**.  
Connect MTN MoMo, Stripe, or PayPal by implementing webhook handlers that call `PaymentService::completePayment()` only after server-side verification. Never activate premium from a browser redirect alone.

## OAuth (optional)

Set `GOOGLE_*` and `FACEBOOK_*` in `.env`. Social login structure is prepared; complete provider callbacks when API keys are available.
