# Production Deployment and Rollback

## Required runtime

Use PHP supported by the selected Laravel 13 release, Composer 2, MySQL 8+ (preferred), HTTPS, required PHP extensions, and a writable `storage/` plus `bootstrap/cache/`. Redis is recommended for production queue/cache/locks.

## First deployment

```bash
composer install --no-dev --optimize-autoloader
cp .env.example .env
php artisan key:generate
# edit .env: APP_ENV=production, APP_DEBUG=false, APP_URL, DB_*, mail/providers, Redis
php artisan migrate --force
php artisan db:seed --class=EssentialSeeder --force
php artisan optimize
```

Create the first administrator interactively or with protected deployment secrets:

```bash
php artisan clinic:create-admin admin@example.com "Clinic Admin" --organization=smart-clinic
```

Never run `ClinicDemoSeeder` on production.

## Web server

Point the virtual host document root to `<project>/public`, not the project root. Force HTTPS. Do not expose `.env`, `storage`, `vendor`, database dumps or logs.

## Worker

Example Supervisor concept:

```ini
[program:smart-clinic-worker]
command=php /var/www/smart-clinic/artisan queue:work --sleep=2 --tries=4 --timeout=120
numprocs=2
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
redirect_stderr=true
stdout_logfile=/var/log/smart-clinic-worker.log
```

After deployments run `php artisan queue:restart`.

## Scheduler

Cron (every minute):

```cron
* * * * * cd /var/www/smart-clinic && php artisan schedule:run >> /dev/null 2>&1
```

## Recommended production `.env`

```dotenv
APP_ENV=production
APP_DEBUG=false
APP_TIMEZONE=Asia/Karachi
CACHE_STORE=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=database
LOG_CHANNEL=json_stderr
LOG_LEVEL=warning
CLINIC_ENFORCE_HTTPS=true
```

Keep all DB, Redis, WhatsApp, SMTP and other provider credentials in server secrets/environment variables only.

## Health and monitoring

- Health endpoint: `/up`
- Admin operational metrics: `GET /api/v1/admin/system/metrics`
- Alert on HTTP 5xx/error rate, failed queue jobs, database storage/capacity, disk usage and backup failures.
- Review `failed_jobs` and application logs.
- Use centralized exception tracking if available.

## Backups

Back up MySQL automatically and encrypt backups at rest. Retain according to clinic/legal policy. Perform periodic restore drills into an isolated environment; a backup is not considered valid until restore has been tested. Follow `docs/BACKUP_RESTORE.md`.

## Zero/low-downtime deployment sequence

```bash
php artisan down --retry=20
# deploy release / composer install
php artisan migrate --force
php artisan optimize
php artisan queue:restart
php artisan up
```

For high-availability environments, use atomic release directories and load-balancer draining rather than maintenance mode.

## Rollback

1. Stop routing traffic to the bad release or enable maintenance mode.
2. Roll application code back to the previous release.
3. Only run `migrate:rollback` when the specific migration is confirmed backward-safe; destructive schema rollback can lose data.
4. If data was corrupted, restore the verified backup according to the incident plan.
5. Clear/rebuild config/route caches and restart workers.
6. Run smoke tests for login, bootstrap, patient search, availability, booking, queue and payments before reopening traffic.
