# Setup

```bash
cp portal/.env.example portal/.env
cp platform/.env.example platform/.env
cp gateway/.env.example gateway/.env
bash scripts/bootstrap.sh
bash scripts/dev-up.sh
```

Entradas úteis:

- portal real + NVR: `http://localhost:8080/nvr/`
- portal raiz: `http://localhost:8080/`
- gateway local: `http://localhost:9080/`
- Mailpit: `http://localhost:8025/`

Comandos úteis:

```bash
bash scripts/test.sh
php scripts/check-real-portal-package.php
php gateway/bin/gateway health:check
```

```bash
bash scripts/install-services.sh
bash scripts/build-final.sh
php scripts/check-mysql-mariadb-contract.php
```

## Banco central oficial

- stack final padronizada em **MariaDB/MySQL**;
- contrato oficial do runtime: `DB_CONNECTION=mysql`, `DB_PORT=3306`, `DB_CHARSET=utf8mb4`, `DB_COLLATION=utf8mb4_unicode_ci` e `DB_SESSION_TIMEZONE=+00:00`;
- compatibilidade transitória com o portal principal: o runtime também lê `DB_CENTRAL_*` quando o ambiente compartilhado ainda usa a nomenclatura legada;
- `pdo_mysql`, cliente `mysql` e `mysqldump` formam o baseline operacional esperado.

## Contrato canônico da integração central

- chaves canônicas do portal/SSO central no NVR: `CENTRAL_APP_URL`, `CENTRAL_API_URL`, `CENTRAL_SHARED_SECRET`, `CENTRAL_PRODUCT_CODE`, `CENTRAL_TIMEOUT`, `CENTRAL_SSO_ENABLED`, `CENTRAL_INTROSPECTION_ENABLED`, `CENTRAL_SSO_ISSUER`, `CENTRAL_SSO_AUDIENCE`, `CENTRAL_SSO_TTL_SECONDS`, `CENTRAL_SSO_CLOCK_SKEW_SECONDS`, `CENTRAL_SSO_AUTO_PROVISION_TENANT`, `CENTRAL_SSO_AUTO_PROVISION_SITE`, `CENTRAL_SSO_SYNC_PLATFORM_ADMIN`;
- `CENTRAL_APP_URL` é a raiz oficial do portal/central; `CENTRAL_API_URL` é a base canônica da API e, quando omitida, pode ser derivada como `CENTRAL_APP_URL + /api`;
- aliases `SSO_CENTRAL_*` permanecem apenas como compatibilidade transitória e sempre perdem precedência para `CENTRAL_*` / `CENTRAL_SSO_*`;
- o contrato canônico do banco central permanece em `DB_*`; aliases `DB_CENTRAL_*` continuam apenas como compatibilidade transitória documentada.

## Subdiretório em /public

- `APP_BASE_PATH=nvr` e `SESSION_COOKIE_PATH=/nvr` já refletem o layout compartilhado padrão do runtime NVR;
- o portal real continua respondendo na raiz e publica o NVR em `/nvr` via bridge público;
- para trocar o prefixo, ajuste `APP_BASE_PATH`, `NVR_LOCATION_PREFIX` e `INSTALL_ROOT` antes de executar `bash scripts/install-services.sh`;
- o instalador renderiza os templates de Nginx, Apache, systemd, supervisor e cron de forma consistente;
- o pacote completo pode permanecer em `/var/www/portal-principal/public/nvr` sem arquivos operacionais soltos fora da aplicação.

## Topologia operacional desta rodada

- `shared-web` representa o host virtual compartilhado com o **portal real**;
- `php`, `platform-queue` e `platform-scheduler` cobrem o runtime do portal + NVR integrado;
- `gateway-daemon` e `gateway-web` cobrem o runtime local do gateway;
- `mailpit` cobre o SMTP de desenvolvimento;
- `mariadb` e `redis` reproduzem os serviços centrais e auxiliares necessários para o fluxo real.

## Assinatura de mídia entre /platform e /gateway

- configure o mesmo `NVR_MEDIA_SHARED_SECRET` em `platform/.env` e `gateway/.env`;
- mantenha `NVR_MEDIA_SIGNING_ALGORITHM=sha256` nas duas pontas;
- mantenha os mesmos valores de `NVR_MEDIA_URL_TTL_SECONDS`, `NVR_MEDIA_CLOCK_TOLERANCE_SECONDS` e `NVR_MEDIA_SIGNATURE_PAYLOAD_VERSION`;
- `php platform/scripts/deploy-preflight.php --runtime=install` valida divergência real entre `platform` e `gateway/.env` antes do deploy.

## Imagem PHP compartilhada e bootstrap oficial

- a imagem `deploy/docker/php/Dockerfile` agora materializa `pdo_mysql`, `pdo_sqlite`, `sqlite3`, `redis`, `mbstring`, `pcntl`, `opcache`, cliente `mysql` e `composer`;
- o serviço `php` do compose sobe pelo wrapper `scripts/run-shared-php.sh`, que materializa o vendor Laravel do `platform` antes de expor o front door do portal;
- `platform/scripts/boot-http.sh`, `boot-queue.sh`, `boot-scheduler.sh` e `migrate.sh` também fecham esse mesmo bootstrap, evitando drift entre HTTP, fila, scheduler e manutenção.
