# Operação atual (produção)

Documento vivo. As lacunas marcadas com **[A CONFIRMAR]** exigem acesso ao
servidor e precisam ser preenchidas antes da Fase 1 — a migração de banco
depende de saber como o deploy e os backups funcionam hoje.

Atualizado em 16/08/2026.

---

## Infraestrutura

| Item | Valor | Origem |
|---|---|---|
| Domínio | https://franquiabv.com.br/ | `config/autoload/global.php` |
| Host do banco | `localhost` (mesma máquina da aplicação) | `doctrine.global.php` e o dump |
| Outro servidor | `barbeariavip.cloud` — MySQL 8.4.7 / Ubuntu 25.04 | ver abaixo |
| Caminho da aplicação | `/var/www/franquiabv.com.br/public_html` | estrutura do snapshot |
| VPS | 4 vCPU, 16 GB RAM, 200 GB NVMe | informado pelo responsável |
| Servidor web | **nginx** | informado pelo responsável |
| Banco (produção) | **MySQL 8.4.7 sobre Ubuntu 25.04** | coleta de 19/08/2026, no próprio servidor |
| Schema | 83 tabelas InnoDB, charset utf8mb3 | `mysql.sql` (dump de 16/08/2026) |
| Volume | ~16,3 milhões de registros | informado pelo responsável |
| PHP | **8.1** | deduzido do `composer.lock` (ver abaixo) |
| Composer | **2.2.x** | `plugin-api 2.2.0` no `composer.lock` |
| Sistema operacional do app | **[A CONFIRMAR]** | rodar `cat /etc/os-release` |
| Certificado TLS | **[A CONFIRMAR]** — emissor e renovação (Let's Encrypt? painel?) | |

### Existem dois servidores de banco, com versões diferentes

Os dumps trazem procedências distintas, e isso precisa ser esclarecido:

| Dump | Host | Versão |
|---|---|---|
| Abril/2026 (e o `mysql.sql` original) | `barbeariavip.cloud` | MySQL 8.4.7 / Ubuntu 25.04 |
| 16/08/2026, tirado no servidor de produção | `localhost` | MySQL 8.0.46 / Ubuntu 22.04 |

Como a aplicação conecta em `localhost` (`doctrine.global.php`), **a produção é a
8.4.7**, confirmado pela coleta de 19/08/2026 rodando no próprio servidor de
produção. A leitura anterior, de que seria 8.0.46, estava invertida: aquele é o
número das réplicas. O `barbeariavip.cloud` é outra máquina — provavelmente o servidor de
replicação mencionado pelo responsável.

**[A CONFIRMAR]** — vale entender essa diferença antes da Fase 1. Replicar de
8.0 para 8.4 é caminho de upgrade suportado, mas o inverso não é, e uma réplica
numa versão major diferente da origem muda o que se pode fazer com ela (por
exemplo, promovê-la em caso de falha). Se a réplica for mesmo o alvo do BI (ver
D9), a diferença de versão também afeta o comportamento de consultas.

O ambiente de desenvolvimento foi alinhado ao **8.0**, que é a produção.

### Como a versão do PHP foi determinada

Não por inspeção do servidor, e sim pelo `composer.lock`, ao tentar instalar as
dependências no container: `laminas/laminas-cache 3.6.0` exige
`~7.4 || ~8.0 || ~8.1` e `laminas-cache-storage-adapter-filesystem 2.3.0` exige
`~8.0 || ~8.1 || ~8.2`. Cruzando com o `composer.json` (`~8.1 || ~8.2 || ~8.3`),
resta **8.1**. Em 8.3 o `composer install` falha.

A coluna `usuarios.senha_php83` sugeria 8.3 e levou à hipótese errada — pelo
visto foi preparação para uma migração que não se concretizou, o que é coerente
com o script de migração de senhas ter ficado publicado sem nunca ser removido.

Vale confirmar com `php -v` no servidor assim que houver acesso, mas a evidência
do lock é forte.

*Nota de 08/11/2026 (a fatia 130, o D11):* a dedução acima é sobre o lock **da
produção**, o da importação. O do repositório mudou (`laminas-cache` 3.13.0, que
aceita do 8.1 ao 8.4) e aceita do 8.1 ao 8.3; o `vendor/` novo sobe na janela do
corte (`procedimento-de-corte-etapa-1.md`, a leitura 8).

### Configuração do nginx

O `public/.htaccess` existe no projeto mas **não tem efeito**: é resquício do
esqueleto do Laminas e o nginx não lê esse arquivo. Todo o roteamento vem da
configuração do nginx no servidor.

**[A CONFIRMAR]** — copiar o `server {}` de produção para cá. Duas perguntas
específicas, ambas com impacto de segurança:

1. A configuração impede execução de PHP dentro de `public/arquivos`,
   `public/contratos`, `public/banners`, `public/assistentes`, `public/vip-class`
   e `public/layout/img/avatar`? São diretórios onde o sistema grava arquivos
   enviados por usuários. Sem essa regra, um `.php` enviado como "contrato" é
   executado pelo servidor.
2. Existe alguma regra que bloqueie arquivos de dado soltos na raiz do webroot
   (`.txt`, `.log`, `.sql`)? É o que teria contido o problema do Dia 0.

O `docker/nginx/default.conf` deste repositório tem as duas regras e serve de
referência.

## Aplicação

- **Framework:** Laminas MVC 3.7, Doctrine ORM, 8 módulos.
- **Cache de configuração:** desativado (`config_cache_enabled => false` em
  `config/application.config.php`). Não é preciso limpar cache no deploy.
- **OPcache:** **[A CONFIRMAR]**. Se `opcache.validate_timestamps` estiver em 1,
  passar para 0 em produção é um ganho de desempenho gratuito — mas exige
  recarregar o PHP-FPM a cada deploy.
- **Credenciais:** desde 15/08/2026 ficam em `config/autoload/local.php`, que não
  é versionado e precisa existir no servidor. Sem ele o sistema não sobe.

## Deploy

**[A CONFIRMAR]** — item mais importante desta lista.

- Como o código chega ao servidor hoje? (FTP, SSH, `git pull`, painel?)
- Quem tem acesso?
- Existe janela de manutenção ou o deploy é feito com o sistema no ar?
- Há algum passo manual depois de subir os arquivos?

## Backups

**[A CONFIRMAR]**

- O banco é copiado com que frequência? Para onde?
- Os uploads (`public/arquivos`, `contratos`, `vip-class`, fotos de perfil —
  cerca de 340 MB) entram no backup? Eles não estão no Git de propósito, por
  conterem dados pessoais, então dependem inteiramente do backup.
- Alguma restauração já foi testada?
- Por quanto tempo os backups são retidos? (relevante para a apuração LGPD:
  os backups anteriores a 15/08/2026 contêm as oito credenciais em texto claro)

## Tarefas agendadas

Os crons não são scripts de linha de comando: são **rotas HTTP** em
`/api/cronjobs/*`, disparadas externamente. São 29 rotinas, entre elas o
recálculo dos painéis, a geração de faturas de royalties, a contabilização de
NPS e os envios de marketing.

Além dos crons por HTTP, o banco tem **dois eventos agendados próprios**,
confirmados pelo dump completo de 16/08:

| Evento | Frequência | O que faz |
|---|---|---|
| `limpar_push_app_24h` | 1 hora | limpa `push_app` com mais de 24 h |
| `evt_agendas_exclusoes_limpar` | 1 dia | limpa `agendas_exclusoes` com mais de 60 dias |

Não há trigger, procedure, function nem view. Ver débito D26 — o PostgreSQL não
tem event scheduler, então essas duas rotinas precisam de destino definido antes
da migração.

**[A CONFIRMAR]** — `SELECT @@event_scheduler;` no servidor. Um evento marcado
`ENABLE` num MySQL com o scheduler desligado nunca executa, e as tabelas estariam
crescendo sem que ninguém perceba.

**[A CONFIRMAR]** — copiar o `crontab -l` do servidor para cá, registrando:

- Quais das 29 rotas são efetivamente chamadas e com que frequência
- Qual mecanismo dispara (curl? wget? serviço externo de cron?)
- Se há alguma proteção nessas rotas (ver débito D4 em `debitos-tecnicos.md`)

## Integrações externas

| Integração | Uso | Credencial |
|---|---|---|
| OneSignal | Push mobile (o web push, segundo app, era código morto e saiu do código em 10/10/2026) | `local.php` |
| Firebase (FCM) | Push mobile direto pelo Google, a troca do OneSignal decidida em 10/10/2026; desligado até `push.provedor` pedir (`docs/notificacoes-push-comparativo.md`) | `local.php`: o caminho do JSON da conta de serviço, fora do repositório |
| Evolution API (`evolution.linkwise.digital`) | WhatsApp | Por unidade, na coluna `unidades.whatsapp_api_key` |
| WAHA (`waha.linkwise.digital`) | WhatsApp (provedor alternativo) | Idem |
| Zoomtec (`api.zoomtec.com.br`) | Geração de texto e imagem (visagismo, assistentes) | `local.php` |
| iAgente SMS | Envio de SMS | `local.php` |
| Yungas | Faturamento e NPS (crons `yungas*`) | **[A CONFIRMAR]** |
| Asaas | Coluna `unidades.asaas_id` sugere cobrança | **[A CONFIRMAR]** se está ativa |
| Sistema de BI externo | Consultas analíticas | **[A CONFIRMAR]** — ver débito D9 |

## Aplicativo móvel

Consome 20 endpoints em `/api/aplicativo/*` mais 3 de visagismo. Autentica com
token fixo embutido no código. A convivência de endpoints `V2` e `V3` indica
versões antigas ainda em uso no parque.

**[A CONFIRMAR]** — cruzar os logs do nginx dos últimos 90 dias com os endpoints
versionados para saber quais versões precisam continuar funcionando durante toda
a migração.

## Sistema de BI externo

Lê o MySQL de produção diretamente, com consultas cruzadas pesadas.

**[A CONFIRMAR]** — ver débito D9. É o consumidor que quebra na Fase 1 se não for
mapeado, e o que impede a rotação da senha do banco sem coordenação.
