Sistema completo de gestão de chamados de TI com módulo de reembolso, integração Microsoft 365, IA e notificações multicanal.
- Visão geral
- Stack tecnológica
- Estrutura do projeto
- Pré-requisitos
- Instalação — Ambiente de desenvolvimento
- Variáveis de ambiente
- Funcionalidades
- API — Rotas principais
- Banco de dados
- Deploy em produção
- Fluxo de desenvolvimento
O IT Help Desk é uma aplicação web interna para gerenciamento de chamados de suporte de TI. Além do core de tickets, inclui módulo de reembolso integrado com o Uno ERP, fluxo de aprovação, notificações via e-mail/Teams/push, análise com IA e relatórios exportáveis em PDF.
URL de produção: https://helpdesk.novoambiente.com.br
Frontend
| Tecnologia | Uso |
|---|---|
| React 18 + Vite | Framework e build |
| TailwindCSS | Estilização |
| Zustand | Gerenciamento de estado |
| React Router v6 | Navegação |
| Axios | HTTP client com interceptor de refresh token |
| MSAL.js | Autenticação Microsoft 365 |
Backend
| Tecnologia | Uso |
|---|---|
| Node.js + Express | API REST |
| better-sqlite3 | Banco de dados SQLite |
| jsonwebtoken | Access token (1h) + Refresh token (7 dias) |
| bcryptjs | Hash de senhas |
| web-push | Web Push Notifications (VAPID) |
| @azure/msal-node | SSO Azure AD |
| node-fetch | Chamadas externas (Graph API, Uno ERP, CNPJá) |
| multer | Upload de arquivos |
Infraestrutura
| Tecnologia | Uso |
|---|---|
| Ubuntu 24.04 LTS | Sistema operacional |
| DigitalOcean | Cloud (2 vCPU / 2 GB RAM) |
| PM2 | Process manager + boot automático |
| nginx | Proxy reverso + SSL termination |
| Let's Encrypt / Certbot | Certificado HTTPS gratuito |
| UFW | Firewall (portas 22, 80, 443) |
| Fail2ban | Proteção contra brute force |
| Logrotate | Rotação de logs (14 dias) |
/home/flavio/helpdesk/
├── backend/
│ ├── src/
│ │ ├── db/
│ │ │ ├── connection.js
│ │ │ └── migrate_*.js # Scripts de migration
│ │ ├── middleware/
│ │ │ ├── auth.js # authenticate + authorize
│ │ │ └── errorHandler.js
│ │ ├── routes/
│ │ │ ├── auth.js
│ │ │ ├── users.js
│ │ │ ├── teams.js
│ │ │ ├── categories.js
│ │ │ ├── tickets.js
│ │ │ ├── approvals.js
│ │ │ ├── attachments.js
│ │ │ ├── notifications.js
│ │ │ ├── dashboard.js
│ │ │ ├── hierarchy.js
│ │ │ ├── ai.js
│ │ │ ├── suppliers.js
│ │ │ ├── reimbursements.js
│ │ │ ├── audit.js
│ │ │ ├── push.js
│ │ │ └── reports.js
│ │ ├── services/
│ │ │ ├── tokenService.js # Access + refresh token
│ │ │ ├── auditService.js # Log de auditoria
│ │ │ ├── notificationService.js # Email + Teams + Push
│ │ │ ├── pushService.js # Web Push (VAPID)
│ │ │ ├── msalService.js # Azure AD OAuth
│ │ │ ├── aiService.js # Claude API
│ │ │ ├── schedulerService.js # Relatório semanal automático
│ │ │ ├── cnpjService.js # CNPJá API
│ │ │ └── unoService.js # Uno ERP API
│ │ └── server.js
│ ├── data/
│ │ └── helpdesk.db # SQLite (não versionado)
│ ├── uploads/ # Anexos (não versionado)
│ └── .env # Variáveis de ambiente (não versionado)
└── frontend/
├── public/
│ └── sw.js # Service Worker (Web Push)
└── src/
├── components/ui/
│ ├── Layout.jsx # Sidebar + topbar + modais globais
│ ├── FieldTooltip.jsx # Tooltip ? por campo
│ ├── PageHelpModal.jsx # Painel de ajuda contextual
│ ├── GlobalSearch.jsx # Busca global com overlay
│ ├── ShortcutsModal.jsx # Painel de atalhos
│ ├── AiTypingHint.jsx # Dica de IA ao digitar título
│ ├── DuplicateDetector.jsx # Detecção de chamados similares
│ ├── TicketSummary.jsx # Resumo IA do histórico
│ └── RootCause.jsx # Badge + selector de causa raiz
├── hooks/
│ ├── useKeyboardShortcuts.js
│ └── usePushNotifications.js
├── pages/
│ ├── LoginPage.jsx
│ ├── AuthCallback.jsx
│ ├── DashboardPage.jsx
│ ├── TicketsPage.jsx
│ ├── TicketDetailPage.jsx
│ ├── NewTicketPage.jsx
│ ├── KanbanPage.jsx
│ ├── ApprovalsPage.jsx
│ ├── ReimbursementsPage.jsx
│ ├── ReimbursementDashboardPage.jsx
│ ├── NewReimbursementPage.jsx
│ ├── ReportsPage.jsx
│ ├── WeeklyReportPage.jsx
│ ├── UsersPage.jsx
│ ├── TeamsPage.jsx
│ ├── CategoriesPage.jsx
│ ├── AuditPage.jsx
│ └── ProfilePage.jsx
├── services/
│ └── api.js # Axios + interceptor refresh token
├── store/
│ └── authStore.js # Zustand (user, tokens)
└── utils/
└── helpers.js # Formatação, constantes, errorMsg
- Node.js 22+
- npm 10+
- Git
# 1. Clonar o repositório
git clone https://github.com/FlavioSenos/helpdesk.git
cd helpdesk
# 2. Instalar dependências do backend
cd backend
npm install
# 3. Criar o arquivo .env (ver seção abaixo)
cp .env.example .env
# edite o .env com suas configurações
# 4. Rodar as migrations (na ordem)
node src/db/migrate.js
node src/db/migrate_hierarchy.js
node src/db/migrate_oauth_state.js
node src/db/migrate_teams_email.js
node src/db/migrate_security_reimbursement.js
node src/db/migrate_reimbursement_permission.js
node src/db/migrate_push.js
node src/db/migrate_root_cause.js
# 5. Iniciar o backend em modo dev
npm run dev
# API disponível em http://localhost:3001
# 6. Em outro terminal — instalar e iniciar o frontend
cd ../frontend
npm install
npm run dev
# App disponível em http://localhost:5173Arquivo: backend/.env
# ── Servidor ──────────────────────────────────────────────────────────────────
PORT=3001
NODE_ENV=development
# ── Banco de dados ────────────────────────────────────────────────────────────
DB_PATH=./data/helpdesk.db
UPLOAD_PATH=./uploads
MAX_FILE_SIZE_MB=20
# ── JWT ───────────────────────────────────────────────────────────────────────
# Gere com: openssl rand -hex 32
JWT_SECRET=sua_chave_secreta_aqui
JWT_EXPIRES_IN=1h
# ── CORS ──────────────────────────────────────────────────────────────────────
ALLOWED_ORIGINS=http://localhost:5173
FRONTEND_URL=http://localhost:5173
# ── Azure AD / Microsoft 365 ──────────────────────────────────────────────────
AZURE_TENANT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
AZURE_CLIENT_SECRET=seu_client_secret
AZURE_REDIRECT_URI=http://localhost:5173/api/auth/callback
# Domínios permitidos para auto-registro via SSO (separados por vírgula)
SSO_ALLOWED_DOMAINS=novoambiente.com.br,novacorporativo.com.br
# ── Microsoft Graph (envio de e-mail) ─────────────────────────────────────────
GRAPH_SENDER_EMAIL=ti@novoambiente.com.br
# ── Teams ─────────────────────────────────────────────────────────────────────
TEAMS_WEBHOOK_URL=https://outlook.office.com/webhook/...
# ── Web Push (VAPID) ──────────────────────────────────────────────────────────
# Gere com: node -e "const wp=require('web-push'); const k=wp.generateVAPIDKeys(); console.log(k)"
VAPID_EMAIL=admin@helpdesk.local
VAPID_PUBLIC_KEY=sua_chave_publica_vapid
VAPID_PRIVATE_KEY=sua_chave_privada_vapid
# ── Inteligência Artificial ───────────────────────────────────────────────────
# Obtenha em: https://console.anthropic.com
ANTHROPIC_API_KEY=sk-ant-...
# ── Uno ERP ───────────────────────────────────────────────────────────────────
UNO_API_URL=http://ipservidor:8080/NomeAplicacao
UNO_API_TOKEN=seu_bearer_token_uno
# ── CNPJá ─────────────────────────────────────────────────────────────────────
# Plano gratuito funciona sem key; com assinatura coloque o token aqui
CNPJA_API_KEY=seu_token_cnpjaCiclo de vida completo — tickets percorrem os status: Aberto → Em andamento → Aguardando → Aguard. Autorização → Resolvido / Cancelado.
SLA automático por prioridade:
| Prioridade | Prazo |
|---|---|
| 🔴 Crítico | 4 horas |
| 🟠 Alto | 8 horas |
| 🔵 Médio | 24 horas |
| 🟢 Baixo | 72 horas |
Causa raiz obrigatória ao resolver — ao clicar em Resolver, abre modal pedindo a classificação:
| Causa | Ícone |
|---|---|
| Erro do usuário | 👤 |
| Bug no sistema | 🐛 |
| Indisponibilidade | 🔴 |
| Processo não documentado | 📋 |
| Acesso / Permissão | 🔑 |
| N/A | — |
Os dados de causa raiz alimentam o gráfico no Dashboard e podem ser filtrados nos relatórios.
Outros recursos:
- Categorias em árvore pai/filho com prioridade padrão por categoria
- Tags por ticket
- Atribuição individual, coletiva ou por equipe
- Upload de anexos até 20MB
- Histórico completo de movimentações com audit log
- Comentários internos
- Kanban por status
- Detecção automática de chamados duplicados por IA ao digitar
- Dica de IA com animação de digitação ao abrir novo chamado (após 4+ caracteres no título)
Quatro perfis de acesso:
| Perfil | O que pode fazer |
|---|---|
| Usuário | Abre chamados, vê apenas os próprios |
| Atendente | Atende chamados, vê todos os tickets |
| Gestor | Aprova autorizações, gerencia equipes, vê todos |
| Admin | Acesso total ao sistema |
Hierarquia de supervisão — configurada em Admin → Usuários → aba Hierarquia. Um supervisor vê os chamados de todos os subordinados diretos e indiretos (recursivo, N níveis). O gerente vê o supervisor que vê os analistas.
Filtros de escopo na listagem: "Meus chamados" e "Minha equipe".
Login local — e-mail + senha com bcrypt. Rate limiting de 30 tentativas por 15 minutos.
SSO Microsoft 365 — fluxo OAuth2 Authorization Code Flow com MSAL. Usuários de domínios permitidos são criados automaticamente como "Usuário" no primeiro login. Domínios não autorizados são bloqueados com mensagem clara.
Tokens:
- Access token JWT assinado — expira em 1 hora
- Refresh token de 64 bytes armazenado no banco — expira em 7 dias
- Rotação automática: cada uso do refresh token gera um novo par
- Renovação transparente via interceptor Axios — o usuário não percebe a expiração
- Todas as sessões são revogadas ao trocar a senha
Proteções:
- State parameter OAuth — proteção CSRF no callback SSO
- Helmet — headers de segurança HTTP
- Rate limiting por rota (auth, IA, CNPJá)
- UFW firewall + Fail2ban no servidor
Log de auditoria — registra automaticamente: login, logout, falhas de autenticação, criação/alteração de usuários, mudanças de perfil, troca de senha, aprovações, criação de fornecedores e envios ao ERP. Visível em Admin → Auditoria com filtros por ação, status e período.
Formulário em 3 etapas integrado ao fluxo de chamados:
Etapa 1 — Dados gerais
Título, descrição, prioridade, seleção de aprovador (apenas usuários com permissão can_approve_reimbursement) e upload de nota fiscal.
Etapa 2 — Fornecedor Busca por CNPJ com consulta em tempo real à Receita Federal via CNPJá. Dados preenchidos automaticamente. Fornecedor já cadastrado é selecionado sem re-cadastro. O solicitante cadastra livremente sem aprovação adicional.
Etapa 3 — Título ERP Campos do título Uno ERP: cód. empresa, cód. título, cód. parcela, cód. espécie, cód. colaborador, centro de custo, conta financeira, sub-conta, cód. banco, C/C, valor, vencimento e observação. Todos com tooltip explicando o campo.
Integração Uno ERP:
- Endpoint:
POST /api/v1/financeiro/contaspagar - Autenticação: Bearer token (
UNO_API_TOKEN) - Envio manual após aprovação — botão "Enviar ERP" na listagem
- Reenvio automático em caso de erro — botão "Reenviar" aparece em vermelho
Dashboard financeiro (/reimbursements/dashboard):
- Total solicitado, enviado ao ERP, pendente de aprovação
- Alerta para erros de integração
- Top fornecedores por valor
- Distribuição por centro de custo
- Evolução mensal dos últimos 6 meses
Todas as notificações são disparadas automaticamente pelos eventos do sistema.
| Canal | Quando |
|---|---|
| In-app (sino) | Toda movimentação de tickets que envolve o usuário |
| E-mail (Graph API) | Abertura, atualização, atribuição, comentário, aprovação |
| Teams (Webhook) | Abertura, atualização, aprovação — via Adaptive Cards |
| E-mail de equipe | Abertura e/ou atualização (configurável por equipe) |
| Web Push | Toda movimentação + aprovações (requer ativação pelo usuário) |
Badge na aba do browser — (N) IT Help Desk quando há notificações não lidas.
Web Push — ativado em Perfil → "Ativar notificações push". Usa Service Worker com VAPID keys geradas automaticamente. Aprovações ficam visíveis até o usuário interagir. Funciona mesmo com o browser minimizado.
Todas as features de IA usam o modelo claude-haiku-4-5-20251001 via API da Anthropic. Rate limit: 20 requisições por minuto.
Resumo automático do histórico — botão "Resumir histórico com IA" na aba Histórico do ticket. Retorna: situação atual, o que já foi feito, próximos passos e tempo em aberto. Colapsável e atualizável.
Detecção de duplicatas — analisa automaticamente ao digitar título e descrição (debounce 1.5s). Se encontrar chamados similares abertos, exibe aviso amarelo com grau de similaridade e motivo. O usuário pode ver o chamado duplicado ou ignorar e continuar.
Dica ao abrir chamado — após digitar 4+ caracteres no título, aparece uma mensagem com animação de digitação orientando o usuário a incluir o máximo de contexto relevante (quando começou, mensagem de erro, o que já tentou). Fecha manualmente, não volta na mesma sessão.
Relatório semanal — gerado toda segunda-feira às 10h e enviado por e-mail para admins e gestores. Também disponível sob demanda em IA → Relatório Semanal. Contém: resumo executivo, destaques positivos, pontos de atenção, recomendações acionáveis e previsão para a próxima semana.
Página unificada em /reports com 3 abas e exportação em PDF.
SLA — cumprido vs violado por período, detalhado por prioridade, com gráfico de volume diário. Filtros rápidos de 7, 30 e 90 dias.
Atendentes — volume de chamados, resolvidos, em aberto, tempo médio de resolução e SLA violado por pessoa.
Categorias — top 20 categorias por volume com tempo médio, chamados de alta prioridade, tendência semanal e tags mais usadas.
Exportar PDF — gera PDF do conteúdo visível via jsPDF + html2canvas. Suporta múltiplas páginas automaticamente.
Atalhos de teclado (não funcionam em campos de texto):
| Tecla | Ação |
|---|---|
N |
Novo chamado |
R |
Novo reembolso |
K |
Kanban |
A |
Autorizações |
D |
Dashboard |
G |
Relatórios |
/ |
Busca global |
? |
Painel de atalhos |
Esc |
Fechar modais |
Busca global — overlay com debounce de 300ms buscando tickets, usuários e categorias em paralelo. Navegação por ↑↓ e Enter.
Tooltips por campo — ícone ? ao lado de cada label em todos os formulários. Ao passar o mouse, exibe descrição detalhada, exemplos práticos e avisos de preenchimento.
Ajuda contextual — botão "Ajuda" na topbar (ao lado do sino). Abre painel lateral com explicação detalhada de cada funcionalidade da tela atual. Disponível em 12 páginas.
POST /api/auth/login Login local
GET /api/auth/azure Iniciar fluxo SSO (retorna URL)
GET /api/auth/callback Callback OAuth Azure AD
POST /api/auth/refresh Renovar access token
POST /api/auth/logout Revogar refresh token
GET /api/auth/me Perfil do usuário autenticado
POST /api/auth/change-password Trocar senha
GET /api/tickets Listar (com filtros e paginação)
POST /api/tickets Criar
GET /api/tickets/:id Detalhe completo
PATCH /api/tickets/:id Atualizar (status, prioridade, causa raiz)
DELETE /api/tickets/:id Remover (admin)
POST /api/tickets/:id/assign Atribuir
POST /api/tickets/:id/comment Comentar
GET /api/approvals Listar
POST /api/approvals Solicitar
PATCH /api/approvals/:id Responder
GET /api/approvals/respond/:token Link por e-mail
GET /api/approvals/reimbursement-approvers Aprovadores de reembolso
GET /api/reimbursements Listar
GET /api/reimbursements/dashboard Métricas financeiras
GET /api/reimbursements/:id Detalhe
POST /api/reimbursements Criar
POST /api/reimbursements/:id/sync-uno Enviar ao Uno ERP
GET /api/suppliers Listar
GET /api/suppliers/cnpj/:cnpj Consultar CNPJ (Receita Federal)
GET /api/suppliers/uno/search?nome= Buscar no Uno ERP
POST /api/suppliers Cadastrar
PATCH /api/suppliers/:id Atualizar
POST /api/ai/summarize/:ticketId Resumo do histórico
POST /api/ai/duplicates Detectar chamados similares
GET /api/ai/weekly-report Gerar relatório semanal
GET /api/reports/sla SLA por período e prioridade
GET /api/reports/agents Volume por atendente
GET /api/reports/categories Top categorias e tags
GET /api/reports/overview Visão geral para PDF
GET /api/dashboard Métricas do dashboard
GET /api/hierarchy Listar hierarquia
POST /api/hierarchy Vincular supervisor
DELETE /api/hierarchy Remover vínculo
GET /api/push/vapid-key Chave pública VAPID
POST /api/push/subscribe Registrar subscription push
POST /api/push/unsubscribe Remover subscription
GET /api/audit Log de auditoria (admin)
GET /api/audit/stats Resumo de auditoria
GET /api/health Health check
SQLite3 — arquivo único em backend/data/helpdesk.db.
Tabelas principais:
| Tabela | Descrição |
|---|---|
users |
Usuários com perfil, hierarquia e permissões |
teams |
Equipes com e-mail de notificação |
team_members |
Relação usuário ↔ equipe |
categories |
Categorias em árvore com prioridade padrão |
tickets |
Chamados com SLA, causa raiz e tipo |
ticket_assignees |
Atribuições de chamados |
ticket_tags |
Tags por ticket |
ticket_history |
Histórico completo de movimentações |
approvals |
Fluxo de autorização com token para e-mail |
attachments |
Metadados de arquivos anexados |
notifications |
Notificações in-app |
refresh_tokens |
Tokens de renovação com TTL |
oauth_states |
States OAuth com TTL de 10 minutos |
audit_logs |
Log completo de ações sensíveis |
push_subscriptions |
Subscriptions Web Push por usuário |
user_hierarchy |
Vínculos supervisor → subordinado |
suppliers |
Fornecedores com dados da Receita Federal |
reimbursements |
Campos do título Uno ERP por ticket |
# No servidor
ssh root@helpdesk.novoambiente.com.br
cd /opt/it-helpdesk
# Receber atualizações
git pull
# Rodar migrations (apenas quando houver novos arquivos migrate_*)
cd backend && node src/db/migrate_*.js
# Build do frontend
cd ../frontend && npm run build
# Reiniciar API
pm2 restart helpdesk-api
# Verificar status
pm2 status
pm2 logs helpdesk-api --lines 50Logs:
/var/log/helpdesk/api-out-0.log # Saída normal
/var/log/helpdesk/api-error-0.log # Erros
Nginx: /etc/nginx/sites-available/helpdesk
PM2 ecosystem: backend/ecosystem.config.cjs
# 1. Desenvolver localmente em /home/flavio/helpdesk
# 2. Testar com npm run dev (backend) e npm run dev (frontend)
# 3. Commit e push
git add .
git commit -m "feat: descrição da feature"
git push origin main
# 4. No servidor
ssh root@helpdesk.novoambiente.com.br
cd /opt/it-helpdesk
git pull
# rodar migrations se necessário
cd frontend && npm run build
pm2 restart helpdesk-apiImportante: o arquivo .env, o banco helpdesk.db e a pasta uploads/ não são versionados. Mantenha um backup do .env de produção em local seguro.
- Acesse portal.azure.com → App registrations → New registration
- Nome:
IT HelpDesk| Tipo:Accounts in this organizational directory only - Redirect URI:
https://helpdesk.novoambiente.com.br/api/auth/callback - Copie o Application (client) ID →
AZURE_CLIENT_ID - Copie o Directory (tenant) ID →
AZURE_TENANT_ID - Certificates & secrets → New client secret → copie o valor →
AZURE_CLIENT_SECRET - API permissions → Microsoft Graph → Delegated:
openid,profile,email,User.Read - API permissions → Microsoft Graph → Application:
Mail.Send - Grant admin consent
Desenvolvido para uso interno — Novo Ambiente / Nova Corporativo