# nginx DO HOST no BVIP para o ambiente de TESTE -- __DOMINIO__
#
# GERADO por scripts/deploy-teste.sh a partir de
# docker/nginx/teste-host.conf.modelo. Não edite em /etc/nginx: a próxima
# rodada do script reescreve. Mude o modelo e rode o script.
#
# O que este arquivo faz, e o que deixa para o nginx de DENTRO do contêiner:
#
#   aqui     TLS, noindex, as rotas NEGADAS neste endereço público, e a tela
#            nova (React) em /novo/, na MESMA origem do ERP -- a /adm/api
#            autentica pelo cookie de sessão do ERP, que vale só para o host
#            que o emitiu (frontend/vite.config.ts);
#   lá       a proteção de caminho (PHP em upload, .txt/.sql soltos, phpinfo,
#            dotfiles) -- docker/nginx/default.conf, o mesmo do
#            desenvolvimento e o modelo da produção. Não duplicar.

server {
    listen 80;
    listen [::]:80;
    server_name __DOMINIO__;

    # A renovação do certificado passa por aqui (certbot --webroot).
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
        default_type text/plain;
    }

    location / {
        # O noindex também no redirecionamento: o 301 é a primeira resposta
        # que um robô vê do endereço.
        add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl__HTTP2_NO_LISTEN__;
    listen [::]:443 ssl__HTTP2_NO_LISTEN__;
__HTTP2_DIRETIVA__
    server_name __DOMINIO__;

    ssl_certificate     /etc/letsencrypt/live/__DOMINIO__/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/__DOMINIO__/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_session_cache   shared:SSL_franquiabv_teste:10m;

    # Nunca indexar, e só por HTTPS daqui em diante (HSTS: o navegador deixa de
    # mandar os cookies num http:// digitado). Repetidos em cada `location` que
    # declara o próprio add_header: no nginx, o add_header de uma location
    # CANCELA o do server.
    add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
    add_header Strict-Transport-Security "max-age=31536000" always;
__AUTH__
    # Acompanha o client_max_body_size do contêiner: o menor vence.
    client_max_body_size 64M;

    location = /robots.txt {
        default_type text/plain;
        add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
        add_header Strict-Transport-Security "max-age=31536000" always;
        return 200 "User-agent: *\nDisallow: /\n";
    }

    # ------------------------------------------------------------------
    # NEGADAS NESTE ENDEREÇO PÚBLICO. As rotinas por URL se protegem com um
    # token fixo que está no código (D5); duas delas cobram pelo Asaas de
    # PRODUÇÃO (D3) e outras mandam WhatsApp e notificação. Em teste nenhuma
    # roda: não há cron, e aqui elas não chegam ao PHP por estes caminhos.
    # Quem precisar de uma rotina roda de dentro do servidor, por
    # 127.0.0.1:__PORTA_APP__ -- e NUNCA as duas do Asaas
    # (relatoriosRoyaltiesFaturasGerar/Atualizar).
    #
    # O MESMO CONTROLADOR, POR OUTRO CAMINHO: as rotas genéricas dos módulos
    # (/mod-<módulo>/<controlador>/<ação>) aceitam o apelido de qualquer
    # controlador registrado, e `cronJob` e `whatsapp` são globais -- com uma
    # sessão do ERP e o token, /mod-cadastros/cronJob/<rotina> rodava a rotina
    # (revisão adversarial, 25/09/2026). O `visagismo` de /mod-* é a tela do
    # ERP, e não a do aplicativo: fica.
    #
    # EM QUALQUER GRAFIA (~*): com `^~` e `=`, /API/cronjobs passava pelo 403 e
    # chegava ao PHP. Lá não roteia -- as rotas do Laminas distinguem
    # maiúsculas --, mas a garantia daqui não pode depender disso. E sem a barra
    # final também: /api/cronjobs.
    #
    # Os CHATBOTS de /rh, /ajudantevip, /invencivel e /motivacionalvip são
    # páginas públicas com o chatbot da conta de PRODUÇÃO do Zapier: cada
    # conversa aqui gastaria a conta real, e a chamada sai do navegador de quem
    # abre -- o corte de saída do contêiner não a alcança.
    #
    # As locations de regex valem na ordem em que aparecem, e antes do
    # `location /`: ficam aqui, antes de tudo o que é regex.
    # ------------------------------------------------------------------
    location ~* ^/api/(cronjobs|marketing|visagismo|unidade)(/|$)   { return 403; }  # rotinas; visagismo: upload público + IA paga; unidade: vendas reais pelo hash, sem login
    location ~* ^/api/cupons/cuponsvalidarvencimento(/|$)           { return 403; }
    location ~* ^/mod-[^/]+/(cronjob|whatsapp)(/|$)                 { return 403; }  # o apelido global pela rota genérica; o whatsapp desconecta sessão real
    location ~* ^/autenticacao/migrar-senhas(/|$)                   { return 403; }  # D2: fora do código; negada por garantia
    location ~* ^/ocra_service_manager_yuml                         { return 403; }  # rota de depuração de biblioteca
    location ~* ^/index\.php/                                       { return 403; }  # o mesmo roteamento, por outro caminho
    location ~* ^/(rh|ajudantevip|invencivel|motivacionalvip)(/|$)  { return 403; }  # chatbots da conta de produção

    # ------------------------------------------------------------------
    # A TELA NOVA (React), construída com --base=/novo/. Sem roteador no
    # cliente hoje: só /novo/ e /novo/assets/* são pedidos. O asset que falta
    # responde 404, e não o index.html -- um chunk velho em cache daria uma
    # tela branca com HTML no lugar de JavaScript.
    # ------------------------------------------------------------------
    location = /novo {
        return 301 /novo/;
    }

    location ^~ /novo/assets/ {
        root __FRONT_RAIZ__;
        try_files $uri =404;
        add_header Cache-Control "public, max-age=31536000, immutable" always;
        add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
        add_header Strict-Transport-Security "max-age=31536000" always;
    }

    location ^~ /novo/ {
        root __FRONT_RAIZ__;
        index index.html;
        try_files $uri $uri/ =404;
        add_header Cache-Control "no-cache" always;
        add_header X-Robots-Tag "noindex, nofollow, noarchive" always;
        add_header Strict-Transport-Security "max-age=31536000" always;
    }

    # ------------------------------------------------------------------
    # O ERP, na pilha Docker do teste.
    # ------------------------------------------------------------------
    location / {
        proxy_pass http://127.0.0.1:__PORTA_APP__;

        # O Host passa INTACTO: a sessão do PHP é emitida para o domínio que
        # ele anuncia, e a tela nova depende dela (vite.config.ts).
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $host;

        # Relatórios pesados passam de 60 s; o padrão cortaria com 504.
        proxy_read_timeout 300;
        proxy_connect_timeout 30;

        # Os cookies do ERP saem sem Secure (o `setcookie` do login e do
        # token_web não o pede). Marcados aqui, não viajam num http://. O
        # proxy_cookie_path funciona no nginx 1.18; o proxy_cookie_flags, não.
        proxy_cookie_path / "/; Secure";
    }
}
