# Local Development

## 1. Database connection

Local database credentials belong in the untracked file:

```text
config/database.local.php
```

Create it from the example.

PowerShell:

```powershell
Copy-Item config\database.local.example.php config\database.local.php
```

Then edit the copied file for the local MySQL database. `config/database.local.php` is ignored by Git and is not overwritten by a normal source-code upgrade.

The example intentionally contains no database name, username, or password. Fill them for your local MySQL/MariaDB instance. A local `root` account may be convenient on a disposable workstation, but never copy local root/blank-password credentials to hosting.

For a fresh local install, leave the database empty and use `/install`, exactly as you would on hosting. If you intentionally imported an older development/demo database, apply only pending migrations:

```powershell
php bin/migrate.php
```

Do not rerun the first-install wizard over an existing demo database.

## 2. Diagnose the exact code and database being used

From the **project root** run:

```powershell
Get-Content VERSION
php bin/doctor.php
```

`bin/doctor.php` reports the project root, version, base path, PDO MySQL availability, database configuration source, connected database, and pending migrations.

If the browser shows a different version from `VERSION`, the PHP server is serving another extracted project folder or an older running process.

## 3. Start PHP's built-in server

Run this command from the **project root**, not from inside `public/`:

```powershell
php -S 127.0.0.1:8003 -t public public/router.php
```

The dedicated `public/router.php` also handles arbitrary configured subdirectory mounts by stripping `APP_BASE_URL` before resolving real files under `public/assets/...`.

The default development base path is the web root, so open:

```text
http://127.0.0.1:8003/
```

Login:

```text
http://127.0.0.1:8003/login
```

Administration after login:

```text
http://127.0.0.1:8003/admin?page=overview
```

Language management:

```text
http://127.0.0.1:8003/admin?page=languages
```

System diagnostics:

```text
http://127.0.0.1:8003/admin?page=system
```

## 4. Simulate an arbitrary subdirectory

The application never assumes a folder called `ask`. To simulate a deployment below `/community`, set only the centralized base path before starting the server:

```powershell
$env:APP_BASE_URL="/community"
php -S 127.0.0.1:8003 -t public public/router.php
```

Then open:

```text
http://127.0.0.1:8003/community/
http://127.0.0.1:8003/community/admin?page=overview
```

Remove the temporary environment value later with:

```powershell
Remove-Item Env:APP_BASE_URL
```

## 5. Stop and restart

Stop the built-in server with:

```text
Ctrl+C
```

Then run the start command again.

There is no persistent PDO database connection that must be manually disconnected. A normal web request releases its database connection when that request ends. Restart the local PHP process when you want to be certain that you are executing a newly extracted code tree or changed process-level environment variables.

## 6. Admin verification

Read-only dashboard/database check:

```powershell
php bin/admin-smoke.php
```

Transactional write verification:

```powershell
php bin/admin-smoke.php --write
```

Write mode exercises administration persistence and rolls its test changes back before exit.

## 7. Run the verification suite

```powershell
php bin/run-all-tests.php
```

If PDO MySQL is not loaded, database-required suites are reported as **SKIP**, not as false failures. Install/enable `pdo_mysql` and point `config/database.local.php` at a disposable MySQL/MariaDB server to exercise them. CI uses strict mode:

```powershell
php bin/run-all-tests.php --strict
```

Strict mode fails when even one suite is skipped, so it is suitable for GitHub release gates.
