Files
Reem-Notas/config/routes.rb

213 lines
11 KiB
Ruby

# config/routes.rb
Rails.application.routes.draw do
# Devise — login padrão para admin/gerente/operador
devise_for :users, path: 'auth',
controllers: { sessions: 'users/sessions' },
path_names: {
sign_in: 'login',
sign_out: 'logout',
password: 'senha'
}
# Root — redireciona por role
root 'dashboard#index'
# Fim de linha para quem está autenticado mas o perfil não libera nenhuma tela.
# Existe para o "acesso negado" ter para onde ir sem cair em loop com a raiz.
get '/sem-acesso', to: 'paginas#sem_acesso', as: :sem_acesso
# Dashboard principal (admin/gerente/operador)
get '/dashboard', to: 'dashboard#index', as: :dashboard
get '/dashboard/relatorio_financeiro', to: 'dashboard#relatorio_financeiro', as: :dashboard_relatorio_financeiro
# Entregas em aberto do período (o que há por trás do card "N pendentes")
get '/dashboard/pendentes', to: 'dashboard#pendentes', as: :dashboard_pendentes
# Dashboard de análise de entregas por operação (UBS Norte, EMAD, ...)
get '/dashboard/operacoes', to: 'operacoes_dashboard#index', as: :operacoes_dashboard
# Planilha da operação (tabela espelho pesquisável, página própria)
get '/dashboard/operacoes/planilha', to: 'operacoes_dashboard#planilha', as: :operacoes_planilha
# Download .xlsx da planilha Entregas preenchida (modelo entregue ao cliente)
get '/dashboard/operacoes/planilha/baixar', to: 'operacoes_dashboard#baixar_planilha', as: :operacoes_planilha_baixar
# Painel motorista
get '/motorista', to: 'motorista/dashboard#index', as: :motorista_dashboard
# Extrato do período do motorista em PDF (o painel já mostra o total e as
# consolidações que compõem o valor na própria tela).
get '/motorista/totais/pdf', to: 'motorista/dashboard#totais_pdf', as: :motorista_totais_pdf
# Login motorista — PIN de 4 dígitos + acesso via QR Code do extrato
get '/motorista/login', to: 'motorista/sessoes#new', as: :motorista_login
post '/motorista/login', to: 'motorista/sessoes#create'
get '/motorista/acesso/:token', to: 'motorista/sessoes#acesso_qr', as: :motorista_acesso_qr
# Consolidações
resources :consolidacoes do
collection do
get :veiculos_disponiveis # JSON — veículos do(s) motorista(s) no período (form nova consolidação)
get :operacoes_disponiveis # JSON — tabelas de operação (gade_entregas_*)
get :dados_da_operacao # JSON — motoristas/veículos/período da(s) operação(ões)
get :buscar_nf # JSON — busca a NF na rastreio (nota avulsa)
post :avulsa # cria consolidação avulsa a partir de uma NF
get :arquivadas # Histórico — consolidações arquivadas
# Arquivamento em lote a partir da própria lista (?visao=lista). Coleção e
# não membro: o alvo é o CONJUNTO selecionado, não uma consolidação.
post :arquivar_em_lote
# PDF do modo de visualização "Por motorista" (/consolidacoes?visao=
# motoristas): o total de cada um no período e as consolidações que
# compõem o valor.
get :totais_pdf
end
member do
get :wizard # Passo 1 — selecionar motorista
post :finalizar
post :finalizar_parcial # arquiva veículos pendentes e finaliza (só os consolidados)
post :arquivar
post :reativar # Restaura uma consolidação arquivada
post :registrar_pagamento # Marca 1 motorista (ou todos) como pago
post :cancelar_pagamento # Estorna o pagamento de 1 motorista (ou todos)
post :arquivar_motorista # Arquiva 1 motorista da consolidação (reversível)
post :desarquivar_motorista # Restaura um motorista arquivado
delete :excluir_motorista # Exclui de vez 1 motorista (admin/gerente)
post :adicionar_motorista # Adiciona/restaura 1 motorista nesta consolidação
get :preview_extrato
get :gerar_pdf_relatorio
get :gerar_pdf_extrato
get :gerar_pdf_financeiro # relatório financeiro da consolidação
end
resources :consolidacao_entregas, only: [] do
collection do
get :validar # Passo 2 — toggles de classificação
post :classificar # toggle individual (JSON)
post :classificar_em_massa # ações em massa (JSON)
get :revisar # Passo 3 — revisão do motorista
post :fechar_veiculo # consolida (fecha) um veículo do motorista
post :reabrir_veiculo # reabre um veículo já consolidado
post :arquivar_veiculo # tira um veículo do gate (reversível)
post :desarquivar_veiculo # restaura um veículo arquivado
get :buscar_nf # JSON — busca a NF na SimpleRoute (apontamento manual)
post :apontar # cria apontamento manual a partir da NF
post :apontar_manual # apontamento 100% manual (sem rastreio)
post :apontar_termo # lança N entregas de termo (sem NF/código)
delete :remover_apontamento # remove um apontamento manual (por id)
end
end
end
# Configurações (apenas admin/gerente)
namespace :admin do
resources :usuarios, except: [:show] do
member { patch :toggle_ativo }
end
resources :configuracoes, only: [:index, :edit, :update] do
collection { post :toggle_tema }
end
resources :auditoria_logs, only: [:index]
# Perfis de acesso: o ADM monta o conjunto de permissões e atribui ao
# usuário. Rota `perfis` (e não `perfis_acesso`) pelo mesmo motivo de
# `grupos`/`eventos` mais abaixo — nome de rota curto evita o sufixo `_index`
# que o Inflector cria quando singular == plural.
resources :perfis, except: [:show], controller: 'perfis_acesso'
# SMTP e WhatsApp (Twilio) gravados no banco — só admin.
# Sem rotas `testar_*`: os botões de teste são submits do próprio form
# (params[:acao]), para o teste usar exatamente o que está na tela.
resource :configuracao_notificacao, only: [:show, :update],
controller: 'configuracao_notificacoes'
# Edição de lançamento do SimpliRoute (correção de status/motivo/comentário)
# — só admin. Grava direto na API do SimpliRoute + AuditoriaLog.
resource :edicao_lancamento, only: [:show], controller: 'edicao_lancamentos' do
get :buscar # NF -> lançamentos daquela NF (JSON; pode haver + de um)
get :carregar # visit_id -> card de um lançamento escolhido (JSON)
patch :atualizar # aplica a alteração na API
get :historico # histórico da visita na API (JSON, best-effort)
end
# Geração da planilha de carga do SimpliRoute (download .xlsx a partir de uma
# operação vigente + lat/long do mês anterior).
resource :planilha_simpli_route, only: [:show], controller: 'planilhas_simpli_route' do
get :baixar
end
# Romaneio "CONTROLE DE ENTREGA": uma folha A4 paisagem por veículo, assinada
# pelo motorista na retirada. O plano vem do SimpliRoute (API ou espelho de
# rastreio); o .xlsx é o plano B para quando o plano do dia ainda não foi
# publicado. As bases externas continuam somente leitura — o que gravamos são
# as tabelas `romaneio*`, nossas.
resources :romaneios, only: %i[index show create destroy] do
collection do
post :importar_planilha # caminho B: upload do .xlsx do plano
post :atualizar_logo # troca o logo impresso no cabeçalho
end
member do
# ?veiculo=GADE_001 -> inline (é a prévia do editor); sem veiculo -> download
# do romaneio inteiro. Uma rota só porque é o mesmo documento.
get :pdf
post :reimportar
# Vincula a operação do mês DEPOIS da importação e preenche APARELHO com
# o que a gade_entregas_* sabe — sem depender do plano estar disponível
# de novo (ver Romaneios::VinculadorDeOperacao).
patch :vincular_operacao
patch :atualizar_linha # JSON — um campo de uma parada
patch :atualizar_veiculo # JSON — motorista da folha
patch :atualizar_rotulo # JSON — o texto "PLANO:" do cabeçalho
end
end
# ── Notificações: quem recebe, o quê e por qual canal ──────────────────
# Grupos e contatos são a lista de destinatários cadastrada à mão; eventos
# ligam um gatilho aos grupos; a sessão do WhatsApp é o pareamento por QR.
#
# ⚠️ Os nomes das rotas (`grupos`, `eventos`, `envios`) NÃO são os nomes dos
# controllers de propósito: `grupos_contato` e `eventos_notificacao` têm
# singular igual ao plural para o Inflector (que não fala português), e aí
# o Rails sufixa o helper de index com `_index` — pegadinha silenciosa.
resources :grupos, except: [:show], controller: 'grupos_contato'
resources :contatos, except: [:show] do
# Grupos do WhatsApp de que o número conectado participa (JSON). Carregado
# sob demanda pelo form: se fosse no render da tela, uma ponte fora do ar
# faria o cadastro de contato inteiro esperar o timeout.
collection { get :grupos_whatsapp }
end
# Variáveis {{assim}} criadas pelo ADM, usáveis em qualquer mensagem.
resources :variaveis, except: [:show], controller: 'variaveis_personalizadas'
resources :eventos, except: [:show], controller: 'eventos_notificacao' do
member do
post :disparar # gatilho `manual` — manda mensagem de verdade
# Editor de blocos. O template é identificado pelo CANAL, não por id:
# existe no máximo um por evento+canal (índice único), então uma URL com
# id seria um identificador a mais para o mesmo par.
get 'template/:canal', to: 'mensagem_templates#edit', as: :template
patch 'template/:canal', to: 'mensagem_templates#update'
post 'template/:canal/preview', to: 'mensagem_templates#preview', as: :preview_template
end
end
resources :envios, only: [:index], controller: 'notificacao_envios'
# Pareamento do WhatsApp por QR code (ponte Baileys). `show` faz polling do
# status via JSON enquanto o QR não é lido.
resource :whatsapp_sessao, only: [:show], controller: 'whatsapp_sessoes' do
get :status # JSON { conectado, numero, qr }
post :testar # envia uma mensagem de teste
delete :desconectar
end
end
# API interna — Dashboard métricas
namespace :api do
namespace :v1 do
get 'dashboard/metricas', to: 'dashboard#metricas'
end
end
# Health check (Docker)
get '/health', to: proc { [200, {}, ['OK']] }
end