Cara, que comentário valioso, muito obrigado! Os dois pontos são falhas reais e eu tinha deixado passar.
O do caminho relativo é sério, já que qualquer um poderia baixar o .sqlite com as conversas. Vou mover o arquivo pra fora da raiz pública.
A sobreposição também faz todo sentido: se o lote passar de 1 minuto, o cliente recebe resposta dobrada. Vou marcar como “processando” com UPDATE ... RETURNING antes de começar e ativar WAL + busy_timeout no PHP pra evitar o “database is locked” nos picos.
É por isso que vale compartilhar, a comunidade acha o que a gente não vê. Vou atualizar o post com essas correções e te dar o crédito!