SaguiDesk SaguiDesk

Documentação · versão 2.0.1

SaguiDesk 2.0.1

Help desk em PHP puro e MySQL, sem Composer e sem framework. Você descompacta, abre o instalador no navegador e em um minuto tem uma central de atendimento com painel da equipe, área do cliente, e-mails automáticos e relatórios.

Dashboard da equipe no SaguiDesk 2.0.1

Requisitos

ItemMínimoObservação
PHP7.4Testado até 8.3
BancoMySQL 5.7 ou MariaDB 10.3utf8mb4
Extensões PHPpdo_mysql, openssl, mbstring, fileinfozip é opcional (exportação .xlsx)
Servidor webApache ou LiteSpeed com mod_rewrite, Nginx, ou php -SExemplo de Nginx incluído
Permissão de escritaPasta raiz, storage/, assets/brand/O instalador verifica tudo

Instalar na hospedagem

  1. Baixe o sagui_desk_v2.0.1.zip e envie o conteúdo da pasta saguidesk para public_html/ (ou para uma subpasta ou subdomínio) pelo Gerenciador de Arquivos.
  2. No painel da hospedagem, crie um banco MySQL e um usuário com acesso total a ele. Anote nome do banco, usuário e senha.
  3. Acesse https://seudominio.com.br/install/. O instalador confere os requisitos e mostra em vermelho o que faltar.
  4. Preencha o banco, o nome do sistema, a URL e o administrador. Clique em Instalar SaguiDesk.
  5. Pronto: entre com o e-mail e a senha do administrador.
Instalador web do SaguiDesk

Depois de instalar

  • Apague a pasta /install. Ela já fica bloqueada pelo arquivo storage/installed.lock, mas apagar é a prática recomendada.
  • Guarde uma cópia da APP_KEY do .env.php. Sem ela os dados criptografados (telefones, senha SMTP) não podem ser lidos.
  • Ative o HTTPS: o cookie de sessão passa a ser Secure automaticamente.

Rodar localmente

Para testar no seu computador antes de publicar. No instalador há botões de atalho que preenchem os dados do banco de cada pacote.

MAMP (macOS)

  1. Copie a pasta saguidesk para /Applications/MAMP/htdocs/ e clique em Start no MAMP.
  2. Abra http://localhost:8888/saguidesk/.
  3. No bloco do banco, clique em MAMP: servidor 127.0.0.1, porta 8889, usuário e senha root.

XAMPP, WAMP ou Laragon

Copie para htdocs (XAMPP) ou www (WAMP/Laragon), abra http://localhost/saguidesk/ e use o atalho XAMPP / WAMP / Laragon: porta 3306, usuário root, senha vazia.

Servidor embutido do PHP

Com PHP e MySQL instalados (no Mac, brew install php mysql):

cd saguidesk
php -S localhost:8000 router.php

O router.php faz o papel do .htaccess: rotas amigáveis e bloqueio das pastas internas.

Dados de demonstração

Marque Criar dados de demonstração no instalador para já começar com tickets, um atendente e dois clientes. Senha de todas as contas: Demo1234.

PerfilE-mail
Atendenteatendente@demo.local
Clientecliente@demo.local
Clientefernanda@demo.local

Exclua essas contas em Admin → Usuários antes de colocar o sistema em produção.

Instalação manual

Para quem prefere não usar o instalador:

  1. Crie o banco e importe saguidesk.sql pelo phpMyAdmin.
  2. Copie .env.example.php para .env.php e preencha os dados.
  3. Gere a chave de criptografia e cole em APP_KEY.
  4. Crie o administrador na tabela users com role = 'admin' e a senha gerada por password_hash().
  5. Crie o arquivo vazio storage/installed.lock.
# chave AES-256 (32 bytes em base64)
php -r "echo base64_encode(random_bytes(32)), PHP_EOL;"

# hash da senha do admin
php -r "echo password_hash('SuaSenha123', PASSWORD_DEFAULT), PHP_EOL;"

Arquivo .env.php

Gerado pelo instalador na raiz do sistema. Guarda credenciais e nunca deve ser versionado (já está no .gitignore).

ChavePara que serve
APP_URLEndereço do sistema, sem barra no final. Usado nos links dos e-mails.
APP_DEBUGtrue mostra erros na tela. Use só em desenvolvimento.
APP_TIMEZONEFuso padrão (o painel pode sobrescrever).
APP_KEYChave AES-256 dos dados criptografados. Trocar a chave torna esses dados ilegíveis.
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSConexão MySQL.
SMTP_*Padrões de e-mail. O que for preenchido em Admin → Configurações tem prioridade.
SESSION_REGENERATERegenera o ID da sessão no login. Mude para false se algum LiteSpeed antigo derrubar a sessão logo após entrar.

Configurações do painel

Em Admin → Configurações, dividido em cinco abas:

AbaO que dá para ajustar
GeralNome do sistema, empresa, fuso horário e se clientes podem criar conta sozinhos.
AparênciaLogotipo (PNG, JPG ou WEBP até 2 MB), cor de destaque com prévia ao vivo, tema padrão claro ou escuro, frase do login e texto do rodapé.
E-mail / SMTPServidor, porta, segurança, usuário, senha (gravada com AES-256), remetente e quais notificações enviar. Botão de envio de teste.
SegurançaTempo de sessão por inatividade, tamanho mínimo de senha, tentativas de login e tempo de bloqueio.
Tickets e anexosTamanho máximo por arquivo, arquivos por mensagem, extensões permitidas e fechamento automático de tickets resolvidos.
Configurações de aparência

E-mail e SMTP

O SaguiDesk tem cliente SMTP próprio, sem bibliotecas externas. Com o SMTP desligado (padrão), cada e-mail é gravado em storage/logs/mail.log, inclusive o link de recuperação de senha. É assim que você testa tudo em localhost.

ProvedorServidorPorta / segurança
Hostingersmtp.hostinger.com465 / SSL
Gmail / Google Workspacesmtp.gmail.com587 / STARTTLS (senha de app)
Microsoft 365smtp.office365.com587 / STARTTLS
cPanel genéricomail.seudominio.com.br465 / SSL

Notificações automáticas (cada uma pode ser desligada):

  • Abertura: confirmação para o cliente e aviso para a equipe (o responsável, ou os atendentes do departamento, ou os administradores).
  • Resposta: quando a equipe responde, o cliente recebe; quando o cliente responde, a equipe recebe. Notas internas nunca geram e-mail.
  • Fechamento: o cliente é avisado e convidado a avaliar o atendimento.

Perfis e permissões

Administrador

Acesso total, inclusive criar outros administradores.

Atendente

Atende tickets com as permissões que você escolher.

Cliente

Abre e acompanha somente os próprios chamados.

Permissões atribuíveis a cada atendente em Admin → Usuários:

PermissãoLibera
tickets.view_allVer tickets de todos os clientes. Sem ela, o atendente vê os atribuídos a ele e os sem responsável do seu departamento.
tickets.manageAlterar status, prioridade, departamento e responsável; ações em massa.
tickets.deleteExcluir tickets e seus anexos.
users.manageGerenciar usuários (um atendente nunca concede permissões que não tem).
departments.manageCriar, editar e excluir departamentos.
reports.viewRelatórios e exportação PDF/Excel.
logs.viewLogs de atividade.
settings.manageConfigurações do sistema.
Gestão de usuários

Tickets

Cada ticket recebe um código público curto, como SD-4F7K2Q, que não revela quantos chamados existem.

Status

StatusQuando acontece
AbertoTicket novo, ainda sem resposta da equipe.
Em andamentoA equipe está trabalhando, ou o cliente respondeu depois de uma resposta da equipe.
Aguardando clientePadrão após uma resposta da equipe.
ResolvidoMarcado pela equipe. Fecha sozinho após N dias (configurável).
FechadoEncerrado pela equipe ou pelo cliente. Pode ser reaberto.

Na tela do ticket

  • Responder ou nota interna: a nota fica destacada em amarelo e o cliente nunca a vê.
  • Depois de responder: escolha se o ticket vai para "Aguardando cliente", fica "Em andamento" ou vira "Resolvido".
  • Quem responde primeiro assume o ticket se ele estiver sem responsável.
  • Mudanças de status, prioridade, departamento e responsável viram eventos na linha do tempo.
  • Na lateral: dados do cliente, tempos de 1ª resposta e resolução e os outros chamados dele.
  • Ctrl/⌘ + Enter envia a resposta.
Conversa de um ticket com nota interna

Lista e ações em massa

Filtre por status, prioridade, departamento e responsável, busque por assunto, código, nome ou e-mail e ordene por prioridade. Marque vários tickets para mudar status, atribuir ou excluir de uma vez. Tickets aguardando a equipe aparecem com um ponto colorido.

Anexos

Arraste arquivos para o formulário. O sistema confere a extensão, o tamanho e o conteúdo real do arquivo; um .php renomeado para .jpg é recusado. Os arquivos ficam em storage/uploads, fora do alcance da web, e só são entregues a quem pode ver o ticket.

Painel do cliente

O cliente vê quantos chamados estão com a equipe, quantos aguardam resposta dele e o histórico completo. Respostas novas da equipe ganham o selo Nova resposta. Ao encerrar, ele avalia o atendimento com 1 a 5 estrelas e um comentário opcional; a média aparece no dashboard e nos relatórios.

Painel do cliente em tema claro

Dashboard

Atualiza sozinho a cada 20 segundos e pausa quando a aba fica em segundo plano. Mostra:

  • Em aberto, aguardando a equipe, urgentes e sem responsável
  • Novos e resolvidos hoje
  • Tempo médio de 1ª resposta e de resolução (30 dias)
  • Satisfação média (CSAT) e número de avaliações
  • Gráfico de abertos x resolvidos dos últimos 14 dias
  • Distribuição por status, prioridade e departamento, e ranking da equipe

O sino do topo conta, para a equipe, os tickets esperando resposta; para o cliente, os que a equipe respondeu.

Relatórios PDF e Excel

Em Admin → Relatórios, filtre por período (atalhos de 7, 30 e 90 dias e mês atual), status, prioridade, departamento e responsável. A tela mostra o resumo, o desempenho por responsável e a lista de tickets.

  • PDF: A4 paisagem, com cabeçalho na cor do sistema, cartões de resumo, tabela paginada e "Página X de Y".
  • Excel (.xlsx): cabeçalho fixo, autofiltro e números como número. Sem a extensão zip no servidor, gera .xls.
Relatórios com filtros

Logs de atividade

Registra logins, falhas e bloqueios de login, abertura, resposta, alteração e exclusão de tickets, mudanças em usuários e configurações, exportações e falhas de e-mail, com usuário, data e IP. Filtre por tipo, pessoa, período ou texto.

Logs de atividade

Segurança

CamadaComo o SaguiDesk protege
Senhaspassword_hash() com rehash automático e política de tamanho mínimo com letras e números.
Força brutaBloqueio por e-mail e por IP após N tentativas, pelo tempo configurado.
Recuperação de senhaToken de uso único com validade de 60 min; só o hash SHA-256 fica no banco; a resposta não revela se o e-mail existe.
Dados sensíveisAES-256-GCM (autenticado) para telefone e senha SMTP.
SQL InjectionPrepared statements reais em 100% das consultas.
XSSEscape de toda saída e Content-Security-Policy sem scripts inline.
CSRFToken em todos os formulários; requisições sem token são recusadas.
SessãoCookie HttpOnly, SameSite e Secure; ID regenerado no login; vínculo com o navegador; expiração por inatividade e tempo máximo de 12 h.
AnexosLista branca de extensões, verificação de MIME, nome aleatório, pasta bloqueada e download com checagem de permissão.
ExportaçõesProteção contra formula injection no Excel.

Estrutura e rotas

saguidesk/
├── index.php            front controller
├── router.php           roteador para php -S
├── .htaccess            rotas amigáveis e bloqueios
├── nginx.conf.example
├── .env.example.php
├── saguidesk.sql
├── AGENTS.md            guia para agentes de código (Codex etc.)
├── install/             instalador web
├── app/
│   ├── bootstrap.php    configuração, erros, cabeçalhos, sessão
│   ├── routes.php       todas as rotas
│   ├── helpers.php      e(), url(), flash(), icon()…
│   ├── Core/            DB, Auth, Session, Crypto, Csrf, Mailer, PdfReport, XlsxWriter…
│   ├── Controllers/
│   └── Views/
├── assets/              css, js, logotipo enviado
└── storage/             anexos, logs, lock (bloqueado na web)
RotaTelaAcesso
/login, /register, /forgotEntrar, criar conta, recuperar senhaPúblico
/dashboardDashboard (equipe) ou Início (cliente)Logado
/tickets, /tickets/new, /tickets/{id}Lista, novo chamado, conversaLogado
/adminAtalho para o dashboard da equipeEquipe
/admin/usersUsuáriosusers.manage
/admin/departmentsDepartamentosdepartments.manage
/admin/reportsRelatórios e exportaçãoreports.view
/admin/logsLogslogs.view
/admin/settingsConfiguraçõessettings.manage
/profileMeu perfil e troca de senhaLogado
/api/stats, /api/notificationsJSON do dashboard e do sinoLogado

Banco de dados

Nove tabelas InnoDB em utf8mb4, com chaves estrangeiras:

TabelaConteúdo
usersContas, papel, permissões (JSON), telefone criptografado
departmentsÁreas de atendimento
ticketsChamados, código público, tempos, avaliação
ticket_repliesMensagens, notas internas e eventos
attachmentsMetadados dos anexos
password_resetsHash dos tokens de recuperação
login_attemptsTentativas para o bloqueio de força bruta
activity_logsAuditoria
settingsConfigurações do painel (chave/valor)

Personalizar o código

O pacote traz um AGENTS.md com a arquitetura e as regras do projeto, lido automaticamente por agentes de código como Codex e Claude Code. As regras que valem para qualquer alteração:

  • Manter compatibilidade com PHP 7.4 (nada de match, union types ou ?->).
  • SQL só pela classe DB, com placeholders.
  • Escapar toda saída com e(); nenhum JavaScript inline (a CSP bloqueia).
  • Todo formulário POST com csrf_field().
Quero…Onde mexer
Nova rotaapp/routes.php
Nova configuração do painelSettings::DEFAULTS, aba em Views/admin/settings.php e AdminController::saveSettings
Nova permissãoAuth::PERMISSIONS (aparece sozinha no formulário de usuário)
Nova métrica no dashboardCore/Stats.php e assets/js/app.js
Novo e-mail automáticoCore/Notifier.php e Views/emails/layout.php
Cores e layoutassets/css/app.css (variáveis de tema)

Vindo da 1.x

A 2.0 é uma reescrita completa, com outro banco de dados. Não existe atualização automática:

  1. Instale a 2.0.1 em uma pasta ou subdomínio novo, com um banco novo.
  2. Recrie departamentos e atendentes; clientes podem se cadastrar sozinhos.
  3. Mantenha a 1.x no ar, só para consulta, até encerrar os chamados antigos.

A base de conhecimento da 1.x não existe na 2.0.

Solução de problemas

SintomaSolução
404 em /login no ApacheAtive o mod_rewrite e AllowOverride All.
"Não conectou no MySQL" no MAMPServidor 127.0.0.1 (não localhost), porta 8889, usuário e senha root.
Logout logo depois de entrarNo .env.php, 'SESSION_REGENERATE' => false.
"Sessão expirada" ao enviar formulárioA página ficou aberta além do tempo de sessão. Recarregue e envie de novo.
Anexo grande falhaAumente upload_max_filesize e post_max_size no php.ini.
E-mails não chegamUse Enviar teste em Configurações → E-mail; o erro do servidor aparece na tela e em Logs.
Datas com horário erradoAjuste o fuso em Configurações → Geral.
Ver o erro real de uma tela branca'APP_DEBUG' => true no .env.php ou leia storage/logs/php-error.log.

Changelog

2.0.1 · outubro de 2026

  • Reescrita completa, compatível com PHP 7.4 a 8.3
  • Dashboard com atualização automática, CSAT e gráfico de 14 dias
  • Papéis Admin/Atendente/Cliente e 8 permissões granulares
  • Departamentos, notas internas, eventos na linha do tempo e ações em massa
  • Anexos com verificação de conteúdo e download protegido
  • Avaliação de atendimento de 1 a 5 estrelas
  • Cliente SMTP próprio, notificações e envio de teste
  • Relatórios PDF e Excel sem bibliotecas externas
  • Logotipo, cor de destaque e tema claro/escuro
  • AES-256-GCM, CSP, recuperação de senha com token de uso único
  • Instalador com detecção de MAMP e dados de demonstração

1.0.0 · dezembro de 2025

Primeira versão estável. Baixar 1.0.0

Pronto para instalar?

Grátis, open source (licença MIT) e sem mensalidade.

Baixar SaguiDesk 2.0.1

sagui_desk_v2.0.1.zip · 134 KB