# Parallel v2 Deployment on WHM/cPanel

This runbook installs v2 beside the existing Atlas instance, verifies it on a temporary subdomain, and then changes the production document root. It assumes the confirmed clean-start condition: there is no production business data to migrate.

## Release layout

```text
/home/wiziv/atlas-os-v1/          existing rollback copy
/home/wiziv/atlas-os-v2/          this release
atlas-v2.wiziv.net                temporary verification host
atlas.wiziv.net                   final production host
```

Only each release’s `public/` directory may be a web document root. Never expose the Laravel project root.

## 1. Preflight

In WHM/cPanel, confirm:

- PHP 8.4 is selected for the temporary and production hosts.
- Ctype, cURL, DOM, Fileinfo, Filter, Hash, Mbstring, OpenSSL, PCRE, PDO MySQL, Session, Tokenizer, and XML are enabled.
- Composer 2 and the PHP 8.4 CLI path are available.
- AutoSSL is valid and Force HTTPS Redirect is enabled.
- The existing v1 directory remains untouched as the rollback release.

Useful commands:

```bash
php -v
php -m
composer --version
```

## 2. Create an isolated v2 database

In **MySQL Databases**, create a clean database and dedicated user, for example:

```text
Database: wiziv_atlas_v2
User:     wiziv_atlas_v2
```

Grant that user privileges only on the v2 database. Use the actual cPanel-prefixed names in `.env`.

## 3. Create the verification domain

In **Domains**, create `atlas-v2.wiziv.net` with document root relative to the account home:

```text
atlas-os-v2/public
```

Enable AutoSSL and Force HTTPS Redirect. cPanel may restrict changes to a main domain’s document root; this plan assumes `atlas.wiziv.net` is a manageable subdomain/addon domain. If it is the cPanel main domain, perform final cutover by swapping the release directory behind its fixed `public_html` arrangement during a short maintenance window.

## 4. Upload and configure

Extract this package to:

```text
/home/wiziv/atlas-os-v2
```

Then:

```bash
cd /home/wiziv/atlas-os-v2
cp .env.example .env
composer install --no-dev --optimize-autoloader
composer validate --strict
composer audit
```

Set at least:

```dotenv
APP_ENV=production
APP_DEBUG=false
APP_URL=https://atlas-v2.wiziv.net
APP_TIMEZONE=Africa/Cairo
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
DB_DATABASE=wiziv_atlas_v2
DB_USERNAME=wiziv_atlas_v2
DB_PASSWORD=use-a-unique-generated-secret
SESSION_SECURE_COOKIE=true
ATLAS_AI_ENABLED=false
```

Do not copy an `APP_KEY`, database password, or `.env` from another application.

The supplied source baseline has no `composer.lock`; the first staging `composer install` resolves supported stable dependencies and creates it. Retain that generated lock with the accepted v2 release and use `composer install`—not `composer update`—for subsequent deployments of the same release.

## 5. Initialize the clean application

```bash
cd /home/wiziv/atlas-os-v2
php artisan key:generate
php artisan migrate --force
php artisan atlas:admin
php artisan optimize
php artisan atlas:status
```

For one repeatable staging check, enable PDO SQLite for the isolated test database and run:

```bash
bash tools/verify-release.sh
```

Do not run `--seed` in production. The demonstration password and example records are local-only.

## 6. Permissions

The cPanel account user should own the files. Laravel needs write access only where expected:

```bash
chmod -R u+rwX,g+rwX storage bootstrap/cache
```

Do not use `777`. Evidence remains under `storage/app/private` and is never exposed by a public storage link.

## 7. Verification gate

Open `https://atlas-v2.wiziv.net` and complete this smoke test:

1. Sign in and confirm `/up` returns HTTP 200.
2. Create an operating cycle and one relationship.
3. Create an opportunity, accept a proposal, and convert it into a project.
4. Add a milestone and a linked commitment; confirm both appear in project context.
5. Create an account and invoice; record a partial collection and confirm `Part Paid` plus correct outstanding value.
6. Try an overpayment and confirm it is rejected.
7. Upload/download a private evidence file and inspect its audit event.
8. Sign in as each practical role and verify hidden/forbidden actions.
9. Check mobile width and, on staging only, temporarily set a user locale to `ar` in the database to verify shell direction.
10. Run `php artisan atlas:status` again and inspect `storage/logs/laravel.log` for new errors.

Cutover is blocked by any failed check, tenant leak, wrong balance, broken download, or unreviewed production error.

## 8. Production cutover

Because there is no existing production business data, no migration window or dual-write is needed.

1. In the v2 `.env`, change `APP_URL=https://atlas.wiziv.net`.
2. Run:

```bash
cd /home/wiziv/atlas-os-v2
php artisan optimize:clear
php artisan optimize
php artisan atlas:status
```

3. In cPanel **Domains**, change `atlas.wiziv.net` document root to `atlas-os-v2/public`.
4. Open a new private browser session and repeat the login, dashboard, workflow, finance, evidence, and `/up` checks.
5. Keep v1 and the staging hostname for the agreed observation period; restrict staging access after cutover.

## 9. Rollback

If a material fault appears, change the production document root back to the preserved v1 `public/` directory. This is a code rollback only; v2 uses its own database and v1 has no production data. Do not delete either database until the v2 acceptance period is complete.

## 10. Scheduler and operations

Add one cPanel cron entry after verifying the exact PHP 8.4 binary:

```cron
* * * * * cd /home/wiziv/atlas-os-v2 && /usr/local/bin/ea-php84 artisan schedule:run >> /dev/null 2>&1
```

There is no required long-running queue worker in v2. Before enabling queued notifications or imports, configure a supervised worker and include `php artisan reload` in deployments.

Daily backup scope after launch:

- v2 MySQL database
- `.env` through a protected secrets process
- `storage/app/private`
- application release and deployment log

Test restoration on a non-production hostname; a scheduled backup without a restoration test is not accepted evidence.
