# Installation Workflow

Professional web installer, similar in spirit to WHMCS/Perfex-style commercial PHP SaaS installers. Runs once, locks itself after success.

## Guard Rail

`app/Controllers/Install/*` is only reachable if `writable/install.lock` does **not** exist. On successful completion, the installer writes this lock file and every subsequent hit to `/install` redirects to `/` — preventing re-running the installer against a live production system (a common real-world security hole in cheap PHP installers).

## Step 1 — Server Requirement Check

Automated checks, all must pass (or show clear red/green status) before "Next" is enabled:

- PHP version ≥ 8.3
- Required extensions: `intl`, `mbstring`, `json`, `curl`, `mysqli`, `gd` or `imagick`, `zip`, `openssl`, `fileinfo`
- `php.ini`: `upload_max_filesize`, `post_max_size`, `memory_limit` meet minimums
- Composer dependencies present (`vendor/` exists)

## Step 2 — Folder Permission Check

Verifies write access to:
- `writable/` (CI4 cache, logs, session, uploads)
- `writable/uploads/`
- `public/assets/uploads/` (or configured storage path)
- `.env` file location (must be writable to generate config)

Shows exact `chmod`/ownership fix commands per failing path.

## Step 3 — Database Configuration

Form fields: DB host, port, database name, username, password, table prefix (optional). "Test Connection" button (AJAX) before allowing Next. On success, installer attempts `CREATE DATABASE IF NOT EXISTS` if the supplied user has privilege; otherwise instructs the user to pre-create it.

## Step 4 — Application Configuration

- App name, app URL (auto-detected, editable)
- Default timezone, default locale (`en` / `ur`)
- Default currency (PKR default, editable)
- Environment (`production` recommended, `development` allowed with warning)

## Step 5 — Admin Account Creation

- Super Admin name, email, password (strength-validated), confirm password
- This becomes the first `users` row with `role_id` = super_admin, `agency_id` = NULL

## Step 6 — SMTP Configuration

- Host, port, encryption (TLS/SSL), username, password, from-name, from-email
- "Send Test Email" button before proceeding (optional — can Skip and configure later from Admin → Settings)

## Step 7 — Payment Configuration

- Toggle which gateways to enable at launch: Stripe, PayPal, JazzCash, Easypaisa, Bank Transfer
- API keys/secrets per enabled gateway (stored encrypted, see Security Plan §Encryption at Rest)
- Can be entirely skipped and configured later — platform functions in "billing disabled" trial mode if skipped

## Step 8 — Install Application

On confirmation, runs sequentially (progress bar via AJAX polling a job-status endpoint, not a single blocking request — avoids PHP timeout on shared hosting):

1. Write `.env` from collected config
2. `php spark migrate` — run all migrations (full schema from `03-database-schema.sql`, expressed as CI4 migration classes)
3. `php spark db:seed MasterSeeder` — seed roles, permissions, default subscription plans, credit costs, notification templates, job categories
4. Create Super Admin user (bcrypt/argon2id hash)
5. Create storage folders (`writable/uploads/`, `storage/agencies/`, per-module subfolders)
6. Generate `writable/install.lock`
7. Register cron job entries (writes a `crontab.txt` reference file with the exact lines to add — the installer cannot edit the host's system crontab directly for security reasons, so Step 8 ends with **copy-paste instructions** + a "Verify Cron" self-test endpoint the admin can hit after adding them)
8. Redirect to `/admin/login` with a success banner

## Failure Handling

Any step failure shows the exact error (DB error text, permission path, etc.) without aborting silently. Partial-install state is safe to resume — each step is idempotent (checks "already done?" before re-running), so refreshing mid-install doesn't corrupt state.

## Post-Install

Admin → Settings retains all Step 4/6/7 fields, editable anytime — installer values are just the initial seed, not a one-time-only config.
