CAFÉ AURORA — WEB II — CHECKPOINT DO CAPÍTULO 8

Este checkpoint serve para conferência ou retomada depois da construção prática.
Ele inclui os capítulos anteriores e acrescenta a atualização do andamento das mensagens.

COMO EXECUTAR
1. Abra a pasta cafe-aurora-web2 no VS Code.
2. Confira o PHP, o driver SQLite e a sintaxe:
   php -v
   php -m | findstr /I "PDO sqlite"
   php -l src/inicializar-banco.php
   php -l public/admin/painel.php
   php -l public/admin/atualizar-status.php
3. Execute novamente o inicializador, mesmo que o banco já exista:
   php src/inicializar-banco.php
4. Se ainda não houver credencial, crie uma:
   php src/criar-administrador.php
5. Inicie o servidor:
   php -S localhost:8000 -t public
6. Envie mensagens em http://localhost:8000/contato.php.
7. Entre em http://localhost:8000/admin/entrar.php.
8. Altere uma mensagem de Nova para Em atendimento e depois para Respondida.
9. Atualize a página e confirme que o estado foi preservado no banco.
10. Aplique um filtro por assunto, atualize um estado e confirme que o filtro continua ativo.

O QUE FOI ACRESCENTADO
- evolução da tabela existente sem apagar mensagens;
- migração agrupada em uma transação;
- colunas status e atualizada_em;
- estados permitidos: nova, em_atendimento e respondida;
- formulário POST separado para cada registro;
- identificação numérica do registro por campo oculto;
- validação do ID, do estado e do filtro de retorno;
- token CSRF em cada alteração;
- UPDATE preparado com marcador para status e ID;
- cláusula WHERE obrigatória para alterar somente uma linha;
- conferência da quantidade de linhas afetadas;
- mensagem temporária de sucesso ou erro;
- redirecionamento 303 e preservação do filtro atual.

CONFIRA
- executar o inicializador mais de uma vez não apaga registros;
- mensagens antigas recebem o estado Nova;
- acessar atualizar-status.php por GET retorna 405;
- remover ou alterar o token CSRF retorna 403;
- enviar ID zero, negativo ou inexistente não altera outra mensagem;
- enviar um estado inventado é rejeitado;
- cada atualização modifica somente o registro identificado;
- recarregar o painel não repete o UPDATE;
- o filtro por assunto permanece depois da atualização;
- a data da última atualização aparece no painel.

IMPORTANTE
- nunca execute UPDATE sem verificar sua cláusula WHERE;
- campos ocultos continuam sendo dados externos e precisam de validação;
- o navegador não decide quais estados são válidos; o PHP e o banco também protegem a regra;
- a migração desta etapa é pequena e didática; sistemas maiores usam ferramentas próprias de migração;
- o próximo capítulo concluirá o CRUD com exclusão controlada e política de retenção.
