# Shared Hosting Deployment Guide

This guide walks through deploying Quaeriva on shared hosting environments (such as cPanel, Plesk, DirectAdmin, and LiteSpeed/Apache servers).

---

## 1. Overview & Architecture

Quaeriva is engineered to run seamlessly on standard shared hosting environments without needing SSH access, Composer, Node.js, or background daemon processes.

### Database Configuration Precedence

Quaeriva resolves database credentials using the following hierarchy:

1. **`config/database.local.php`** (Highest priority — generated automatically by the Web Installer, or manually copied from `config/database.local.example.php`).
2. **Root `.env` file** (`DB_HOST`, `DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`).
3. **Default Local Fallback** (`127.0.0.1`, user `root`, empty password — intended for local development environments only).

---

## 2. Step-by-Step Installation on Shared Hosting

### Step 1: Create Database & User in cPanel

1. Log into your hosting control panel (e.g., cPanel).
2. Go to **MySQL Databases** (or **MySQL Database Wizard**).
3. Create a new database (e.g., `account_askdb`).
4. Create a new MySQL user with a strong password (e.g., `account_askuser`).
5. **Add User to Database** and check **ALL PRIVILEGES**.

> [!IMPORTANT]
> Shared hosts prepend your hosting account username to database and user names (e.g. `cpaneluser_dbname`). You must enter the full prefixed name.

### Step 2: Upload Files

1. Prefer the generated release archive for hosting. It is built from the same Git source but omits tests, developer documentation, runtime data, and Git metadata.
2. Upload it to your hosting account (e.g., inside `public_html/` or a subdirectory such as `public_html/ask/`) and extract it in place.

A full Git checkout also uses the same application code. If you deliberately deploy a checkout in the project-root document-root layout, keep the shipped root `.htaccess`: it explicitly refuses `.git/`, `.github/`, `tests/`, `docs/`, configuration, and other non-public paths. Pointing the document root at `public/` remains safer.

### Step 3: Run the Web Installer

1. In your browser, navigate to the installer URL:
   - For domain root: `https://example.com/install`
   - For subdirectory: `https://example.com/ask/install`
2. Fill in the installation fields:
   - **Database Host**: Usually `localhost` on shared hosting (rather than `127.0.0.1`).
   - **Database Name**: Your full database name (e.g., `account_askdb`).
   - **Database Username**: Your full user name (e.g., `account_askuser`).
   - **Database Password**: The password set during database user creation.
   - **Public Site URL**: The trusted HTTPS origin only (for example, `https://example.com`).
   - **Site Path**: Automatically detected (e.g., `/ask` or blank for root).
   - **Admin Path**: Customizable admin segment (default: `admin`).
   - **Administrator Account**: Name, email, and password.
3. Click **Install Quaeriva**.
4. The installer automatically migrates all schema tables, creates the admin user, writes `config/database.local.php`, and places the installation lock `.quaeriva-installed.lock`.

---

## 3. Customizing the Admin Path

To change the admin panel URL path:

### Method A: During Installation
Enter your desired URL segment in the *Admin path* field during setup (e.g., `studio` or `management`).

### Method B: From the Admin Panel
Navigate to **Settings** → **General** → **Admin path** and save your changes.

### Method C: Via Configuration Files
You can set or change the admin path manually by either:
- Setting `APP_ADMIN_PATH=yourpath` in `.env`
- Or creating/updating `config/site.local.php`:
  ```php
  <?php
  return [
      'admin_path' => 'yourpath',
  ];
  ```

---

## 4. Troubleshooting Common Issues

### 503 "The service is temporarily unavailable" / "تعذر إتمام العملية: الخدمة غير متاحة مؤقتاً"

* **Symptom**: When attempting to sign in or submit forms, the page displays error 503 with the above message.
* **Cause**: The application cannot establish a connection to MySQL or the database tables have not been migrated yet.
* **Resolution**:
  1. Ensure you have run the web installer at `/install`.
  2. Verify that `config/database.local.php` exists and contains correct host (`localhost`), database name, username, and password.
  3. Verify that the database user has been granted `ALL PRIVILEGES` in cPanel.

### 404 Not Found on Admin Panel

* **Cause**: If `APP_ADMIN_PATH` or `config/site.local.php` changed the admin path, the default `/admin` URL will return 404.
* **Resolution**: Use the custom admin URL segment configured in your settings.

### 403 Forbidden on Project Root

* **Cause**: Missing directory routing in root `.htaccess`.
* **Resolution**: Ensure the shipped `.htaccess` file is present in the project root with the rule `RewriteRule ^$ public/index.php [L]`.

### 403 Forbidden on every page, right after uploading

* **Symptom**: Every URL answers 403, including `/install`. The PHP error log is empty; the *server* log says `file permission is restricted for script: /home/user/site/public/index.php`.
* **Cause**: LiteSpeed and suPHP refuse to execute a PHP file that is writable by group or other. Uploading over FTP, or extracting an archive that carries `0666` modes, leaves every file in that state. Nothing is wrong with the code — the server declines to run it.
* **Resolution** — directories `755`, files `644`:
  * **cPanel File Manager**: open the installation folder → `Select All` → `Permissions`. Tick **Recurse into subdirectories**, choose **Apply to directories only**, set `0755`. Repeat with **Apply to files only** and `0644`.
  * **FileZilla**: right-click the folder → `File permissions` → `755`, tick `Recurse into subdirectories` + `Apply to directories only`. Repeat with `644` + `Apply to files only`.
  * **SSH**:

    ```bash
    find /path/to/site -type d -exec chmod 755 {} + && find /path/to/site -type f -exec chmod 644 {} +
    ```
* **Never use `777`.** `storage/` and `storage/logs/` need `755` — writable by the owner is enough, and cPanel rejects world-writable directories anyway.
* The installer's requirements screen reports this condition and repairs it where PHP is permitted to; `php bin/doctor.php` prints a `File permissions` line for the same check.

### Settings in the admin panel appear to save but nothing changes

1. Open **Administration → System** and inspect the reported base path, its
   source, and any ambiguity warning. On a subfolder installation, set
   `APP_BASE_URL` explicitly in `.env` when the reported path is ambiguous or
   does not match the public URL.
2. Inspect `storage/logs/app.log` and match the failing request by its
   `request_id`. If no matching POST reaches the application, verify the
   routing controls below.
3. Ensure the shipped root `.htaccess` contains
   `RewriteRule ^admin(?:/(.*))?$ public/index.php [QSA,L]`. The physical
   `admin/` directory can otherwise make Apache redirect a bare panel POST to
   `/admin/` as GET and discard the form body.

## Project-root admin POST routing

When the project root itself is the document root, `admin/` is a physical directory. Apache `mod_dir` normally redirects `/admin` to `/admin/`; a redirected POST can be retried as GET and lose the submitted form body. Quaeriva therefore ships `admin/.htaccess` with `DirectorySlash Off`, and the root rewrite sends both forms through `public/index.php`. Do not delete this file from a hosting archive.

---

Verify PHP 8.2+, PDO MySQL, OpenSSL and writable storage. cURL is needed for Telegram/Turnstile. Common failures: missing pdo_mysql, blocked outbound SMTP ports, disabled mod_rewrite/AllowOverride, wrong document root/base path, unreadable `.htaccess`, non-writable storage, HTTPS cookie mismatch or an over-restrictive CSP.
