# cPanel Production Deployment & Server Configuration Guide
## Primon Digital Hotel Platform (Luxury Website + PMS + Booking Engine)

This production manual provides an end-to-end operational guide for deploying the **Primon Digital Hotel Platform** to standard cPanel, Apache, and LiteSpeed hosting environments with PHP 8.2 or 8.4 and MySQL/MariaDB.

---

## Table of Contents
1. [Pre-Deployment Requirements & PHP Extension Audit](#1-pre-deployment-requirements--php-extension-audit)
2. [cPanel Directory Architecture & File Upload](#2-cpanel-directory-architecture--file-upload)
3. [Step-by-Step: Creating the MySQL Database in cPanel](#3-step-by-step-creating-the-mysql-database-in-cpanel)
4. [Step-by-Step: Environment (.env) Configuration](#4-step-by-step-environment-env-configuration)
5. [Step-by-Step: Web-Based Guided Installer (/install)](#5-step-by-step-web-based-guided-installer-install)
6. [Step-by-Step: Command Line (SSH / Terminal) Provisioning](#6-step-by-step-command-line-ssh--terminal-provisioning)
7. [Step-by-Step: Creating or Resetting Super Admin Credentials](#7-step-by-step-creating-or-resetting-super-admin-credentials)
8. [Storage Symlink & File Permissions Setup](#8-storage-symlink--file-permissions-setup)
9. [Automated Cron Job (Scheduler & Night Audit)](#9-automated-cron-job-scheduler--night-audit)
10. [SSL Certificate & HTTPS Enforcement](#10-ssl-certificate--https-enforcement)
11. [Troubleshooting & Common cPanel Pitfalls](#11-troubleshooting--common-cpanel-pitfalls)

---

## 1. Pre-Deployment Requirements & PHP Extension Audit

Before uploading files, log into your cPanel dashboard and verify your PHP environment:

### A. Set PHP Version (MultiPHP Manager)
1. In cPanel, search for and open **MultiPHP Manager**.
2. Select your domain name (`yourdomain.com`).
3. Set the PHP version to **PHP 8.2** or **PHP 8.3 / 8.4**.
4. Click **Apply**.

### B. Required PHP Extensions (MultiPHP INI Editor / Select PHP Version)
Ensure the following PHP modules are enabled:
- `pdo` and `pdo_mysql` (Database drivers for MySQL/MariaDB)
- `openssl` (Secure token encryption & HTTPS requests)
- `mbstring` (Multibyte string processing)
- `curl` (Pesapal 3.0 API gateway communication)
- `fileinfo` (Image and voucher PDF mime validation)
- `gd` or `imagick` (Image processing & responsive thumbnails)
- `zip` (Package extraction & export handling)
- `intl` (Currency formatting & localized dates)
- `json` (Inertia.js and API responses)
- `xml` / `ctype` / `bcmath`

### C. Recommended PHP Directives (MultiPHP INI Editor)
```ini
memory_limit = 256M
max_execution_time = 300
upload_max_filesize = 32M
post_max_size = 32M
allow_url_fopen = On
```

---

## 2. cPanel Directory Architecture & File Upload

For maximum security, never upload raw Laravel core application files directly into `public_html`. Keep the application core one level above `public_html`.

### Recommended Folder Layout:
```
/home/username/
├── primon_app/               <-- Laravel application root (Private, not accessible via browser)
│   ├── app/
│   ├── bootstrap/
│   ├── config/
│   ├── database/
│   ├── routes/
│   ├── storage/
│   ├── vendor/
│   ├── .env
│   └── artisan
└── public_html/              <-- Web root (Only contents of Laravel's public/ folder)
    ├── build/                <-- Compiled Vite React/CSS assets
    ├── images/               <-- Hero & Room photography
    ├── favicon.ico
    ├── robots.txt
    └── index.php
```

### Upload Steps:
1. **Compress the project** (excluding `/node_modules` and local `.git`):
   Ensure `vendor/` and `public/build/` are already built before compressing.
2. In cPanel **File Manager**, create a folder named `primon_app` in `/home/username/`.
3. Upload and extract your project zip into `/home/username/primon_app`.
4. Move all contents inside `/home/username/primon_app/public/` into `/home/username/public_html/`.
5. Open `/home/username/public_html/index.php` in File Manager code editor, and update lines 12–20 to point to `primon_app`:
   ```php
   // Determine if the application is in maintenance mode...
   if (file_exists($maintenance = __DIR__.'/../primon_app/storage/framework/maintenance.php')) {
       require $maintenance;
   }

   // Register the Composer autoloader...
   require __DIR__.'/../primon_app/vendor/autoload.php';

   // Bootstrap Laravel and handle the request...
   (require_once __DIR__.'/../primon_app/bootstrap/app.php')
       ->handleRequest(Request::capture());
   ```

---

## 3. Step-by-Step: Creating the MySQL Database in cPanel

### Step 1: Open MySQL Database Wizard
1. In cPanel, navigate to the **Databases** section and click **MySQL® Database Wizard**.

### Step 2: Create Database Name
1. Enter a database name, e.g. `hotel`.
   - Your full database name will become: `cpaneluser_hotel`.
2. Click **Next Step**.

### Step 3: Create Database User
1. Enter a database username, e.g. `hoteluser`.
   - Your full username will become: `cpaneluser_hoteluser`.
2. Generate or enter a strong password (e.g. `K@mpala#Primon2026!`).
3. Record the **Database Name**, **Username**, and **Password** safely.
4. Click **Create User**.

### Step 4: Grant User Privileges
1. Check the box: **ALL PRIVILEGES**.
2. Click **Make Changes** / **Next Step**.
3. You will receive a success message confirming the user was assigned to the database.

---

## 4. Step-by-Step: Environment (.env) Configuration

In cPanel File Manager, ensure hidden files are visible (Settings ➔ Show Hidden Files), then create or edit `/home/username/primon_app/.env`:

```env
APP_NAME="Primon Hotel"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://yourdomain.com

APP_LOCALE=en
APP_FALLBACK_LOCALE=en

LOG_CHANNEL=daily
LOG_LEVEL=error

# MySQL Connection (From Step 3 above)
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=cpaneluser_hotel
DB_USERNAME=cpaneluser_hoteluser
DB_PASSWORD="YourSecurePasswordHere"

SESSION_DRIVER=database
SESSION_LIFETIME=120

CACHE_STORE=database
QUEUE_CONNECTION=database

# Pesapal 3.0 Payment Gateway (Optional for testing)
PESAPAL_ENV=sandbox
PESAPAL_CONSUMER_KEY=
PESAPAL_CONSUMER_SECRET=
PESAPAL_IPN_ID=
```

Generate your application encryption key:
- If you have SSH access, run: `php artisan key:generate --force`.
- Or ensure `APP_KEY=base64:...` is copied from your configured environment.

---

## 5. Step-by-Step: Web-Based Guided Installer (/install)

If you do not have SSH terminal access, use the platform's built-in web wizard:

1. Open your browser and visit:
   `https://yourdomain.com/install`
2. **Step 1 — Requirements Verification:**
   - Automatically inspects PHP version (>= 8.2), PDO MySQL, OpenSSL, Mbstring, cURL, FileInfo, and folder write permissions.
   - All checkmarks should display green. Click **Continue to Database**.
3. **Step 2 — Database Connection:**
   - Select **MySQL / MariaDB**.
   - Input your cPanel Host (`127.0.0.1`), Database Name (`cpaneluser_hotel`), Username, and Password.
   - Click **Test MySQL Connection** to verify credentials before proceeding.
   - Click **Continue to Hotel Settings**.
4. **Step 3 — Hotel Profile & Contacts:**
   - Property Name: `Primon Hotel`
   - Location: `Naalya, Kampala, Uganda`
   - Phone: `0782195634`
   - Email: `reservations@primonhotel.com`
   - Click **Continue to Admin Setup**.
5. **Step 4 — Super Administrator Setup:**
   - Enter your Administrator Name (e.g. `General Manager`).
   - Enter your Master Admin Email (e.g. `admin@primonhotel.com`).
   - Enter your Master Password (minimum 8 characters).
   - Click **Execute Database Install & Launch**.
6. **Step 5 — Platform Ready:**
   - The wizard will migrate 14 database tables, seed room inventory and rate plans, create your super admin account, and place an `installed.lock` file in `storage/` to prevent tampering.
   - Click **Open Executive PMS Dashboard** to log in immediately.

---

## 6. Step-by-Step: Command Line (SSH / Terminal) Provisioning

If you have cPanel **Terminal** or SSH access enabled:

```bash
# 1. Navigate to the core app directory
cd /home/username/primon_app

# 2. Clear any old caches
php artisan optimize:clear

# 3. Generate App Key (if not already generated)
php artisan key:generate --force

# 4. Run all migrations & inventory seeders against MySQL
php artisan migrate --force --seed

# 5. Lock the web installer for security
php artisan storage:link
touch storage/installed.lock

# 6. Optimize route and config caches for production speed
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

---

## 7. Step-by-Step: Creating or Resetting Super Admin Credentials

If you ever need to create or reset the Super Admin account directly from cPanel Terminal:

```bash
cd /home/username/primon_app
php artisan tinker
```

Inside the interactive Tinker console, paste:

```php
use App\Models\User;
use App\Models\Role;
use Illuminate\Support\Facades\Hash;

$superRole = Role::firstOrCreate(
    ['name' => 'super_admin'],
    ['display_name' => 'Super Administrator', 'description' => 'Unrestricted access']
);

$user = User::updateOrCreate(
    ['email' => 'admin@primonhotel.com'],
    [
        'name' => 'General Manager',
        'phone' => '0782195634',
        'role_name' => 'super_admin',
        'password' => Hash::make('YourSecurePasswordHere'),
        'is_active' => true,
        'email_verified_at' => now(),
    ]
);

$user->roles()->syncWithoutDetaching([$superRole->id]);

echo "Super admin created: " . $user->email . "\n";
exit;
```

You can now log in at: `https://yourdomain.com/login` with your configured email and password.

---

## 8. Storage Symlink & File Permissions Setup

### A. Directory Permissions
In cPanel File Manager, ensure the following permissions are set:
- `/home/username/primon_app/storage/` ➔ **775** (Recursively)
- `/home/username/primon_app/bootstrap/cache/` ➔ **775** (Recursively)
- All files inside ➔ **664**

### B. Storage Symlink
Guest invoices, registration cards, and uploaded room photos reside in `storage/app/public`.
1. If SSH is available, run:
   ```bash
   cd /home/username/public_html
   ln -s /home/username/primon_app/storage/app/public storage
   ```
2. If SSH is **not** available, create a simple script in `public_html/symlink.php`:
   ```php
   <?php
   symlink('/home/username/primon_app/storage/app/public', __DIR__.'/storage');
   echo "Storage symlink created successfully!";
   ```
   Visit `https://yourdomain.com/symlink.php` once in your browser, then delete `symlink.php`.

---

## 9. Automated Cron Job (Scheduler & Night Audit)

Primon Hotel Platform includes automated background hotel routines:
- Auto-expiring unpaid booking holds after 15 minutes.
- Auto-compiling daily manager flash revenue reports.
- Dispatching pre-arrival preference WhatsApp/email reminders 48h prior to arrival.
- Dispatching post-stay review requests 24h after checkout.

### Adding the Cron in cPanel:
1. In cPanel, navigate to **Advanced** ➔ **Cron Jobs**.
2. Under **Add New Cron Job**, set Common Settings to: **Once Per Minute (`* * * * *`)**.
3. In the **Command** field, enter:
   ```bash
   /usr/local/bin/php /home/username/primon_app/artisan schedule:run >> /dev/null 2>&1
   ```
   *(Replace `/usr/local/bin/php` with your cPanel PHP binary path, e.g. `/usr/bin/php` or `/opt/cpanel/ea-php82/root/usr/bin/php`).*
4. Click **Add New Cron Job**.

---

## 10. SSL Certificate & HTTPS Enforcement

1. In cPanel, open **SSL/TLS Status**.
2. Click **Run AutoSSL** to obtain a free Let's Encrypt / Sectigo certificate for your domain.
3. Ensure HTTPS is enforced by verifying `public_html/.htaccess` contains:
   ```apache
   RewriteEngine On
   RewriteCond %{HTTPS} off
   RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
   ```

---

## 11. Troubleshooting & Common cPanel Pitfalls

| Issue | Cause | Solution |
|---|---|---|
| **500 Internal Server Error** | Missing `.env`, permissions on `storage/`, or bad path in `index.php`. | Check `primon_app/storage/logs/laravel.log` and ensure `storage/` is permission `775`. Verify paths in `public_html/index.php`. |
| **White Screen on Frontend** | Old compiled Vite assets or missing app key. | Verify `public_html/build/manifest.json` exists. Run `php artisan key:generate` and clear browser cache. |
| **Database Connection Refused** | Incorrect MySQL credentials or wrong host. | In cPanel MySQL Wizard, ensure user has **ALL PRIVILEGES** assigned to the database. Use `127.0.0.1` as `DB_HOST`. |
| **Vite JS/CSS 404 Not Found** | Asset files missing from `public_html/build/`. | Copy the entire `build/` folder from `primon_app/public/build/` into `public_html/build/`. |
| **Installer shows "Already installed"** | An `installed.lock` file exists in `storage/`. | If re-installing is intended, delete `primon_app/storage/installed.lock`. |

---

*Primon Digital Hotel Platform • Engineering Operations Team • Naalya, Kampala, Uganda*
