# TheSol Chat Server Environment Compatibility Plan

Date: 2026-04-26  
Purpose: Make deployment safe on unknown hosting environments: Apache, Nginx, IIS, shared hosting, VPS, cPanel, Plesk, Windows, Linux, MariaDB, MySQL, cron/no-cron.

## 1. Compatibility Goal

The application must not depend on one local XAMPP layout. Every production deployment must define or verify these environment capabilities before launch:

- PHP version and extensions.
- Database engine/version and credentials.
- Web server type and security rules.
- Writable private storage outside the public web root.
- Writable runtime storage for uploads/cache/logs.
- Cron/worker capability for queue and cleanup jobs.
- HTTPS/proxy behavior.
- File upload limits and execution restrictions.
- Error logging and log rotation.

## 1A. Dynamic Product Rule

TheSol Chat should behave like a configurable product, not a static project copy. Future fixes must prefer this order:

1. Admin/database setting for business behavior that an admin should control.
2. Environment variable for deployment/runtime behavior that changes per server.
3. Runtime detection for server capabilities when reliable.
4. Safe local default only as a fallback.

Avoid hardcoded URLs, credentials, absolute paths, feature limits, queue limits, debug flags, webhook endpoints, model settings, API toggles, or server assumptions unless they are true product constants.

## 2. Required PHP Runtime

Recommended:

- PHP 8.1 or 8.2.
- `mysqli`
- `curl`
- `json`
- `mbstring`
- `openssl`
- `fileinfo`
- `zip` if imports/exports require archives.
- `gd` or `imagick` if image processing is enabled.
- `pdo` and `pdo_pgsql` only if external PostgreSQL database training / OTP lookup is used.
- `imap` only if email piping is used.

Required PHP settings baseline:

```ini
display_errors = Off
log_errors = On
memory_limit = 256M
post_max_size = 32M
upload_max_filesize = 25M
max_execution_time = 120
max_input_vars = 10000
```

For large embedding/database training jobs, use CLI workers with higher memory/time limits instead of web requests.

## 3. Required Database Runtime

Supported target:

- MariaDB 10.4+ or MySQL 5.7+/8.0+.
- InnoDB enabled.
- `utf8mb4` support.
- Ability to add indexes and columns through migration scripts.

Before production:

- Apply database production upgrade pack from [DATABASE_PRODUCTION_READINESS_2026-04-26.md](DATABASE_PRODUCTION_READINESS_2026-04-26.md).
- Create `sb_schema_migrations`.
- Confirm foreign keys are enabled.
- Run backup before every migration.

## 4. Private Storage Requirement

Sensitive generated files must live outside public web root.

Production must define one private writable directory, for example:

- Linux/cPanel: `/home/account/chatbot-private`
- Linux VPS: `/var/lib/thesol-chat/private`
- Windows/IIS: `D:\sites\thesol-chat-private`
- XAMPP local: `D:\xampp\chatbot-private`

Set this path using environment variable:

```text
SB_PRIVATE_PATH=/absolute/path/outside/public/root
```

The app derives:

```text
SB_EMBEDDINGS_PATH = SB_PRIVATE_PATH + /embeddings
```

If `SB_PRIVATE_PATH` is not defined, the app falls back to a sibling `chatbot-private` folder outside the current `htdocs`-style root. This fallback is acceptable for local/dev, but production should explicitly set the environment variable.

## 5. Web Server Security Rules

Apache `.htaccess` has been added locally, but not every server honors `.htaccess`. Production must apply equivalent rules for its actual web server.

### Apache / cPanel / Plesk

Use included `.htaccess` rules:

- Block `config.php`.
- Block `install*.php`.
- Block `logs/`.
- Block `uploads/embeddings/`.
- Block `_debug*.php`, `_test*.php`, `_smoke*.php`, `_migrate*.php`.

Verify with HTTP requests after upload.

### Nginx

Add equivalent server block rules:

```nginx
location ~* /config\.php$ { deny all; }
location ~* /install.*\.php$ { deny all; }
location ^~ /logs/ { deny all; }
location ^~ /uploads/embeddings/ { deny all; }
location ~* (^|/)_(debug|test|smoke|migrate).*\.php$ { deny all; }
location ~* \.(log|sql|bak|old|zip)$ { deny all; }
```

### IIS

Use URL Rewrite / `web.config` deny rules:

```xml
<configuration>
  <system.webServer>
    <security>
      <requestFiltering>
        <hiddenSegments>
          <add segment="logs" />
          <add segment="embeddings" />
        </hiddenSegments>
        <fileExtensions>
          <add fileExtension=".log" allowed="false" />
          <add fileExtension=".sql" allowed="false" />
          <add fileExtension=".bak" allowed="false" />
          <add fileExtension=".old" allowed="false" />
        </fileExtensions>
      </requestFiltering>
    </security>
    <rewrite>
      <rules>
        <rule name="Block maintenance scripts" stopProcessing="true">
          <match url="(^|.*/?)_(debug|test|smoke|migrate).*\.php$" />
          <action type="CustomResponse" statusCode="403" statusReason="Forbidden" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

## 6. Cron and Worker Compatibility

The product should support three modes:

1. Full VPS/server access: run queue workers and cleanup jobs through systemd/supervisor/cron.
2. cPanel/shared hosting: run scheduled PHP scripts through cPanel cron.
3. No cron available: admin-triggered cleanup/queue fallback, but this is not ideal for production.

Required jobs:

- Queue worker for async OpenAI jobs.
- Cleanup old queue rows.
- Cleanup expired chat/embedding cache.
- Cleanup old OTP sessions.
- Cleanup/rotate logs.

Recommended Linux cron examples:

```cron
* * * * * /usr/bin/php /path/to/Chatbot/logs/queue_worker.php --max=10 >/dev/null 2>&1
0 2 * * * /usr/bin/php /path/to/Chatbot/cron.php cleanup >/dev/null 2>&1
```

Queue worker location may change later because production maintenance scripts should not live in a public directory.

## 7. Uploads and Permissions

Writable by PHP:

- `uploads/`
- `media/` if admin uploads branding/assets.
- private `SB_PRIVATE_PATH`.
- runtime log directory.

Not executable:

- `uploads/`
- `media/`
- private storage.
- logs.

Recommended permissions on Linux:

- Directories: `750` or `755` depending on PHP user setup.
- Files: `640` or `644`.
- Never use `777` in production unless the host gives no alternative.

## 8. URL and HTTPS Compatibility

Before production:

- `SB_URL` must exactly match the public HTTPS URL.
- Force HTTPS at web-server level.
- If behind proxy/CDN, ensure PHP sees HTTPS correctly or configure secure cookie detection.
- Set cookie domain only when required.
- Test admin, frontend widget, uploads, AJAX, and service worker paths after changing URL.

## 9. Environment Variables Recommended for Production

`config.php` now supports env-first values for deployment-facing settings. Use env vars where possible:

```text
SB_URL=https://example.com/chat
SB_PRIVATE_PATH=/absolute/private/path
SB_LOG_PATH=/absolute/private/path/logs
SB_LOG_MAX_BYTES=10485760
SB_DB_HOST=...
SB_DB_NAME=...
SB_DB_USER=...
SB_DB_PASSWORD=...
SB_DB_PORT=3306
SB_DB_PERSISTENT=true
SB_QUEUE_ENABLED=true
SB_QUEUE_MAX_CONCURRENT=50
SB_QUEUE_WORKER_TIMEOUT=120
SB_QUEUE_CHAT_CACHE_TTL=300
SB_DEBUG=false
SB_CROSS_DOMAIN=false
SB_ENCRYPTION_KEY=stable-secret-generated-once
```

Local fallback values remain in `config.php` for development, but production should define env vars rather than editing code for each server.

## 10. Phase Compatibility Rules

### Applies To Completed P0-1 and P0-2

- Do not rely only on `.htaccess`; add Nginx/IIS equivalents when server type is known.
- Do not hardcode Windows/XAMPP paths; use `SB_PRIVATE_PATH`.
- Verify with real HTTP requests after upload.
- Keep sensitive artifacts outside public web root.

### Applies To P0-3 and Next Observability Work

- Production must log errors even when `display_errors=Off`; this is now configured through `SB_LOG_PATH`.
- Log path must be writable on Linux and Windows and should be outside public web root.
- Product/application logs use redaction before writing through `sb_log_event()`.
- `SB_LOG_MAX_BYTES` controls simple application-log rotation.
- Add host-level rotation for PHP `error.log` where the server/panel does not rotate it automatically.
- Never log OTP values, API keys, tokens, raw webhook bodies, or full employee records.

### Applies To Database Phases

- Migrations must be compatible with MariaDB 10.4+ and MySQL 5.7/8.0 where possible.
- Avoid `ADD COLUMN IF NOT EXISTS` unless target DB supports it; use migration checks when needed.
- Always backup first.
- Keep SQL scripts idempotent.

### Applies To Queue/OpenAI Phases

- Support environments with and without long-running workers.
- If daemon workers are unavailable, provide cron-based batch worker mode.
- Avoid relying on shell functions not available on shared hosting.

### Applies To Upload/Security Phases

- Enforce restrictions in application code, not only web-server config.
- Add Apache, Nginx, and IIS deny examples for all sensitive directories.
- Ensure `fileinfo` is installed for MIME checks.

## 11. Deployment Compatibility Checklist

Before marking any server production-ready:

- PHP version checked.
- Required extensions checked.
- MySQL/MariaDB version checked.
- `SB_URL` set to HTTPS production URL.
- `SB_PRIVATE_PATH` set and writable.
- `uploads/`, `media/`, logs writable.
- Sensitive directories blocked by actual web-server rules.
- Direct HTTP tests return 403 for blocked paths.
- Database migrations applied and recorded.
- Cron/worker mode selected and tested.
- Error logging enabled and display errors disabled.
- Admin login tested.
- Save settings tested.
- Conversation load/send tested.
- WhatsApp webhook tested.
- OpenAI troubleshoot tested.
- OTP flow tested if enabled.
- Queue worker tested if enabled.
