# Circle World Technology — Installation Guide

## Requirements

| Requirement | Minimum Version |
|---|---|
| PHP | 8.1+ (8.2 recommended) |
| MySQL / MariaDB | 5.7+ / 10.4+ |
| Apache or Nginx | Any modern version |
| Composer | 2.x |
| PHP Extensions | `pdo_mysql`, `mbstring`, `openssl`, `fileinfo`, `gd`, `zip` |

---

## Step 1 — Upload Files

Upload the contents of the `circleworld/` folder to your server.

- **cPanel/Shared Hosting:** Upload to `public_html/`
- **VPS/Dedicated:** Upload to `/var/www/html/` or your preferred web root

Your directory should look like this after uploading:

```
public_html/
├── app/
├── config/
├── database/
├── public/
├── routes/
├── storage/
├── vendor/
├── .env.example
├── composer.json
└── index.php
```

> **Note:** The `public/` folder is the actual web root. Point your domain to `public_html/public/` if your host allows it — otherwise see Step 6.

---

## Step 2 — Install Composer Dependencies

If you are on a VPS with SSH access:

```bash
cd /var/www/html
composer install --no-dev --optimize-autoloader
```

If you are on shared hosting **without** SSH, the `vendor/` folder is already included in the ZIP — no action needed.

---

## Step 3 — Create the Database

1. Log in to **phpMyAdmin** or your database manager.
2. Create a new database, e.g. `circleworld_db` with collation `utf8mb4_unicode_ci`.
3. Create a database user and grant it **all privileges** on that database.
4. Open the **SQL** tab and paste the contents of:

```
database/migrations/001_create_tables.sql
```

5. Click **Go** to run the migration. This creates all 9 tables.

6. *(Optional)* To load sample data (products, services, portfolio items, default admin), also run:

```
database/seeders/001_seed_data.sql
```

---

## Step 4 — Configure Environment

1. In your file manager, **rename** `.env.example` to `.env`.
2. Open `.env` and fill in the values:

```env
# ── Application ────────────────────────────────
APP_NAME="Circle World Technology"
APP_URL=https://circleworld.com.ng
APP_ENV=production
APP_DEBUG=false

# ── Database ────────────────────────────────────
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=circleworld_db
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_password
DB_CHARSET=utf8mb4

# ── Mail (SMTP) ─────────────────────────────────
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=info@circleworld.com.ng
MAIL_PASSWORD=your_smtp_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=info@circleworld.com.ng
MAIL_FROM_NAME="Circle World Technology"

# ── Paystack ────────────────────────────────────
PAYSTACK_PUBLIC_KEY=pk_live_xxxxxxxxxxxxxxxxxxxx
PAYSTACK_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxx

# ── Flutterwave ─────────────────────────────────
FLUTTERWAVE_PUBLIC_KEY=FLWPUBK-xxxxxxxxxxxxxxxxxxxx-X
FLUTTERWAVE_SECRET_KEY=FLWSECK-xxxxxxxxxxxxxxxxxxxx-X
FLUTTERWAVE_ENCRYPTION_KEY=xxxxxxxxxxxxxxxxxxxx

# ── Monnify ─────────────────────────────────────
MONNIFY_API_KEY=MK_xxxxxxxxxxxxxxxxxxxx
MONNIFY_SECRET_KEY=xxxxxxxxxxxxxxxxxxxx
MONNIFY_CONTRACT_CODE=xxxxxxxxxxxxxxxxxxxx
MONNIFY_BASE_URL=https://api.monnify.com

# ── Storage ─────────────────────────────────────
STORAGE_PATH=storage
RECEIPTS_PATH=storage/receipts

# ── Session ─────────────────────────────────────
SESSION_NAME=cw_session
SESSION_LIFETIME=7200
```

> **Tip:** Get your payment keys from your Paystack dashboard (`dashboard.paystack.com`), Flutterwave (`dashboard.flutterwave.com`), or Monnify (`app.monnify.com`).

---

## Step 5 — Set Folder Permissions

Run these commands over SSH, or set permissions via your file manager:

```bash
chmod -R 775 storage/
chmod -R 775 storage/receipts/
chmod 600 .env
```

The `storage/receipts/` folder is where generated PDF receipts are cached. It must be writable by the web server.

---

## Step 6 — Web Server Configuration

### Apache (`.htaccess` — already included)

The project ships with a `.htaccess` in the `public/` folder. Ensure **mod_rewrite** is enabled:

```bash
sudo a2enmod rewrite
sudo systemctl restart apache2
```

If your domain points to the root (not `public/`), add an extra `.htaccess` in the root:

```apache
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
```

### Nginx

Replace `example.com` with your domain:

```nginx
server {
    listen 80;
    server_name circleworld.com.ng www.circleworld.com.ng;
    root /var/www/html/public;
    index index.php;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
    }

    location ~ /\.env {
        deny all;
    }

    location ~ /\. {
        deny all;
    }
}
```

Reload Nginx after editing:

```bash
sudo nginx -t && sudo systemctl reload nginx
```

---

## Step 7 — Default Admin Login

After running the seeder, log in at:

```
https://circleworld.com.ng/admin/login
```

| Field | Value |
|---|---|
| Email | `admin@circleworld.com.ng` |
| Password | `Admin@1234` |

> **Important:** Change the admin password immediately after your first login via **Admin → Profile**.

---

## Step 8 — SSL Certificate (HTTPS)

Always run the site over HTTPS in production. Using Let's Encrypt on Ubuntu/Debian:

```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d circleworld.com.ng -d www.circleworld.com.ng
```

Then update `APP_URL` in `.env` to use `https://`.

---

## Verification Checklist

After installation, confirm each item works:

- [ ] Homepage loads at your domain
- [ ] Admin login works at `/admin/login`
- [ ] A test product/service is visible on the site
- [ ] Submitting a contact form saves a message in **Admin → Messages**
- [ ] Placing a test order goes to the payment gateway
- [ ] A PDF receipt is generated after a successful test payment
- [ ] Payment confirmation email is received (check spam if not)
- [ ] Tracking page works at `/tracking?id=CW-XXXXXXXX`
- [ ] Admin can post a status update and the customer receives the notification email

---

## Troubleshooting

**White screen / 500 error**
- Set `APP_DEBUG=true` in `.env` temporarily to see the error, then set it back to `false`.
- Check PHP error log: `/var/log/php/error.log` or cPanel **Error Logs**.

**Database connection failed**
- Double-check `DB_HOST`, `DB_USERNAME`, `DB_PASSWORD`, `DB_DATABASE` in `.env`.
- On shared hosting `DB_HOST` is usually `localhost`.

**Emails not sending**
- Confirm SMTP credentials are correct.
- Try port `465` with `ssl` or port `587` with `tls`.
- Check whether your hosting blocks outbound port 465/587 (common on shared hosting — use a transactional email service like Brevo, Mailgun, or Amazon SES instead).

**PDF receipts not generating**
- Ensure the `storage/receipts/` directory exists and is writable (`chmod 775`).
- Confirm the `gd` or `imagick` PHP extension is enabled.

**Payments not redirecting back**
- Make sure `APP_URL` in `.env` exactly matches your domain (no trailing slash).
- Add your domain to the allowed callback URLs in your Paystack/Flutterwave dashboard.

---

## File Structure Reference

```
circleworld/
├── app/
│   ├── Controllers/       # Route controllers (Admin, Payment, Receipt, etc.)
│   ├── Core/              # Framework core (Router, DB, Mail, Auth, etc.)
│   ├── Models/            # Database models (Order, User, Product, etc.)
│   ├── Services/          # Business logic (ReceiptService, etc.)
│   └── Views/             # HTML templates
│       ├── admin/         # Admin panel views
│       ├── layouts/       # Master layout files
│       └── ...            # Public-facing pages
├── config/                # App configuration files
├── database/
│   ├── migrations/        # SQL table creation scripts
│   └── seeders/           # SQL seed data
├── public/                # Web root (index.php, assets, CSS, JS)
├── routes/
│   ├── web.php            # Public routes
│   └── admin.php          # Admin routes
├── storage/
│   └── receipts/          # Generated PDF receipts (auto-created)
├── vendor/                # Composer dependencies (Dompdf, PHPMailer, etc.)
├── .env.example           # Environment template
└── composer.json
```

---

*Circle World Technology — circleworld.com.ng*
