Files
Reem-Notas/prompt_sistema_logistica_final.html

771 lines
38 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8">
<title>Prompt - Sistema de Controle de Custos Logística</title>
<style>
body { font-family: 'Segoe UI', Arial, sans-serif; max-width: 900px; margin: 40px auto; padding: 20px; background: #0f172a; color: #e2e8f0; line-height: 1.6; }
h1 { color: #f97316; border-bottom: 2px solid #f97316; padding-bottom: 10px; }
h2 { color: #fb923c; margin-top: 30px; }
h3 { color: #fdba74; }
.box { background: #1e293b; border-left: 4px solid #f97316; padding: 15px; margin: 15px 0; border-radius: 6px; }
.warning { background: #451a03; border-left-color: #fbbf24; }
.phase { background: #2a1810; border-left-color: #f97316; }
.improvement { background: #1e1b4b; border-left-color: #a78bfa; }
.security { background: #450a0a; border-left-color: #ef4444; }
.data { background: #0f172a; border-left-color: #22d3ee; border: 1px solid #1e293b; }
code { background: #334155; padding: 2px 6px; border-radius: 4px; font-family: 'Courier New', monospace; }
pre { background: #0f172a; padding: 15px; border-radius: 8px; overflow-x: auto; border: 1px solid #334155; }
table { width: 100%; border-collapse: collapse; margin: 15px 0; }
th, td { border: 1px solid #334155; padding: 10px; text-align: left; }
th { background: #1e293b; color: #f97316; }
tr:nth-child(even) { background: #1e293b; }
ul { margin: 8px 0; }
li { margin: 4px 0; }
.badge { display: inline-block; padding: 2px 8px; border-radius: 12px; font-size: 0.75em; font-weight: bold; margin-left: 8px; }
.badge-new { background: #f97316; color: #000; }
.badge-change { background: #fbbf24; color: #000; }
.badge-security { background: #ef4444; color: #fff; }
.badge-data { background: #22d3ee; color: #000; }
</style>
</head>
<body>
<h1>🚛 PROMPT: Sistema de Controle de Custos - Logística</h1>
<div class="box warning">
<strong>⚠️ INSTRUÇÃO INICIAL OBRIGATÓRIA:</strong><br>
Antes de começar, pergunte ao usuário: <em>"Qual fase devo executar? Informe o número da fase (1 a 8)."</em><br>
Se o usuário informar uma fase, execute APENAS essa fase. Se informar "TUDO", execute sequencialmente parando a cada fase para confirmação.<br>
Ao final de CADA fase, gere um <strong>CHECKPOINT</strong> com: (1) O que foi feito, (2) Próxima fase, (3) Arquivos criados/modificados.<br>
<strong>ATENÇÃO:</strong> O banco de dados EXISTE e tem dados reais. NUNCA execute DROP TABLE, TRUNCATE ou DELETE em massa nas tabelas existentes.
</div>
<h2>📋 RESUMO EXECUTIVO (Contexto)</h2>
<div class="box">
Empresa de logística <strong>Gade Hospitalar</strong> precisa controlar custos por operação (ex: UBS SUL, UBS LESTE, EMAD, STS, SAD).<br>
Sistema web em <strong>Ruby on Rails</strong> + <strong>PostgreSQL 15</strong> (banco JÁ EXISTE com dados reais) + <strong>Docker</strong>.<br>
Público: administradores, gerentes, motoristas e operadores (baixo nível tech).<br>
Design: moderno, minimalista, <strong>cores padrão PRETO + LARANJA + BRANCO</strong>, ícones grandes, poucos cliques, feedback visual claro.
</div>
<!-- ==================== DADOS REAIS DO BANCO ==================== -->
<h1>🗄️ DADOS REAIS DO BANCO EXISTENTE <span class="badge badge-data">REAL</span></h1>
<div class="box data">
<strong>📡 Tabela existente:</strong> <code>public.db_reem_simplerout_2026</code><br>
<strong>🔄 Atualização:</strong> Automática a cada 1 hora (dados sobem de outro sistema)<br>
<strong>🏢 Account:</strong> Gade Hospitalar (account_id: 95907)
<h3>📊 Estrutura da Tabela Existente (46 colunas)</h3>
<table>
<tr><th>Coluna</th><th>Tipo</th><th>Uso no Sistema</th></tr>
<tr><td>tracking_id</td><td>string</td><td>ID único da entrega (PK lógico)</td></tr>
<tr><td>reference_id</td><td>integer</td><td>Número da NF (Nota Fiscal)</td></tr>
<tr><td>planned_date</td><td>date</td><td>Data planejada da entrega</td></tr>
<tr><td>driver</td><td>string</td><td>Nome do motorista</td></tr>
<tr><td>codrivers</td><td>string</td><td>Ajudante (geralmente NULL)</td></tr>
<tr><td>vehicle</td><td>string</td><td>Placa/ID do veículo (ex: GADE_037)</td></tr>
<tr><td>title</td><td>string</td><td>Título da entrega (ex: "NF 46497 - ELISABETH ROCHA FERREIRA")</td></tr>
<tr><td>address</td><td>string</td><td>Endereço completo da entrega</td></tr>
<tr><td>eta</td><td>time</td><td>Hora estimada de chegada</td></tr>
<tr><td>etd</td><td>time</td><td>Hora estimada de saída</td></tr>
<tr><td>checkin</td><td>datetime</td><td>Horário real de chegada (pode ser NULL)</td></tr>
<tr><td>checkout</td><td>datetime</td><td>Horário real de saída</td></tr>
<tr><td>responsible_person</td><td>string</td><td>Quem fez a entrega (mesmo que driver)</td></tr>
<tr><td>estimated_service_time</td><td>interval</td><td>Tempo estimado de serviço (fixo 00:10:00)</td></tr>
<tr><td>real_service_time</td><td>interval</td><td>Tempo real de serviço (checkout - checkin)</td></tr>
<tr><td>advance</td><td>interval</td><td>Quanto chegou antes do planejado</td></tr>
<tr><td>delay</td><td>interval</td><td>Quanto atrasou (geralmente 00:00)</td></tr>
<tr><td>latitude / longitude</td><td>decimal</td><td>Coordenadas de chegada</td></tr>
<tr><td>checkout_latitude / checkout_longitude</td><td>decimal</td><td>Coordenadas de saída</td></tr>
<tr><td>load / load_2 / load_3</td><td>integer</td><td>Quantidade de cargas (geralmente 1/0/0)</td></tr>
<tr><td>status</td><td>string</td><td>Status da entrega (completed, pending, etc.)</td></tr>
<tr><td>comments</td><td>text</td><td>Comentários do motorista</td></tr>
<tr><td>observation</td><td>string</td><td>Observações internas</td></tr>
<tr><td>start_of_time_window_1 / end_of_time_window_1</td><td>time</td><td>Janela de horário 1 (08:00-18:00)</td></tr>
<tr><td>start_of_time_window_2 / end_of_time_window_2</td><td>time</td><td>Janela de horário 2 (23:59-23:59)</td></tr>
<tr><td>required_skills / optional_skills</td><td>string</td><td>Habilidades necessárias</td></tr>
<tr><td>notes</td><td>string</td><td>Complementos (ex: "COMPL: CASA 1", "TEL: (11) 99999-9999")</td></tr>
<tr><td>contact_name</td><td>string</td><td>Nome do local (ex: UBS SACOMA, EMAD VELEIROS, STS BUTANTA)</td></tr>
<tr><td>contact_phone</td><td>string</td><td>Telefone do local</td></tr>
<tr><td>contact_email</td><td>string</td><td>Email do local (geralmente NULL)</td></tr>
<tr><td>route_id</td><td>uuid</td><td>ID da rota/operacao (ex: UBS SUL, UBS LESTE)</td></tr>
<tr><td>account_id</td><td>integer</td><td>ID da conta (95907 = Gade Hospitalar)</td></tr>
<tr><td>account_name</td><td>string</td><td>Nome da conta</td></tr>
<tr><td>nota_fiscal</td><td>url</td><td>Foto da NF (URL S3)</td></tr>
<tr><td>protocolo_de_entrega</td><td>url</td><td>Foto do protocolo (URL S3)</td></tr>
<tr><td>termo_de_recebimento</td><td>url</td><td>Foto do termo (URL S3)</td></tr>
<tr><td>foto_da_fachada</td><td>url</td><td>Foto da fachada (URL S3)</td></tr>
<tr><td>relatorio_de_visita</td><td>url</td><td>Foto do relatório (URL S3)</td></tr>
<tr><td>numero_de_serie_da_base_aparelho</td><td>string</td><td>Número de série do equipamento</td></tr>
</table>
<h3>📈 Dados de Exemplo (Extraídos do Banco Real)</h3>
<ul>
<li><strong>Motoristas:</strong> Bruno Corgozinho, Carlos Matheus Pimentel, Edson Vinicius Pereira, Gregori Karenkvic, Steferson Lucas, Thiago Rabello Bittencourt, Henderson Estevam</li>
<li><strong>Veículos:</strong> GADE_001 a GADE_123 (14 veículos diferentes)</li>
<li><strong>Locais (contact_name):</strong> UBS SACOMA, UBS JD SELMA, EMAD SANTA CECILIA, EMAD VELEIROS, STS BUTANTA, EMAD GUARANI VARGAS, UBS JD ELIANE, SAD SANTO AMARO, UBS UNIAO DAS VLS DE TAIPAS, UBS ALMIRANTE DELLAMARE, UBS JD AEROPORTO, UBS JD PARANAPANEMA, UBS SANTA LUCIA</li>
<li><strong>Rotas (route_id):</strong> UUIDs que agrupam entregas por operação</li>
<li><strong>Status:</strong> completed (entregas concluídas), pode haver pending, cancelled, etc.</li>
<li><strong>Checkin:</strong> Pode ser NULL (entrega sem registro de chegada)</li>
<li><strong>Load:</strong> Geralmente 1 (uma carga por entrega)</li>
</ul>
<h3>🔑 Regras de Negócio Baseadas nos Dados Reais</h3>
<ul>
<li>Uma entrega = um <code>tracking_id</code> único</li>
<li>Cada entrega tem um <code>reference_id</code> = número da NF</li>
<li>O <code>driver</code> é o motorista principal (codrivers geralmente NULL)</li>
<li>O <code>contact_name</code> identifica o local/UBS de destino</li>
<li>O <code>route_id</code> agrupa entregas da mesma operação (ex: UBS SUL, UBS LESTE)</li>
<li><code>status = 'completed'</code> = entrega bem-sucedida (paga)</li>
<li><code>status != 'completed'</code> = pode ser desconto, pendente, cancelada</li>
<li><code>checkin IS NULL</code> = motorista não registrou chegada (possível desconto)</li>
<li><code>real_service_time = '00:00:00'</code> = chegou e saiu no mesmo minuto (possível problema)</li>
</ul>
</div>
<!-- ==================== MELHORIAS ==================== -->
<h1>🔧 MELHORIAS SUGERIDAS NO DESIGN E LÓGICA</h1>
<div class="box improvement">
<h3>✨ MELHORIA 1 — Cards Visuais Grandes no Dashboard <span class="badge badge-new">NOVO</span></h3>
<p>Cards com cores da marca (preto/laranja/branco):</p>
<ul>
<li>🟠 <strong>Card Entregas OK</strong> — laranja, contador grande e % de sucesso</li>
<li><strong>Card Pendentes</strong> — preto, entregas não consolidadas</li>
<li><strong>Card Descontos</strong> — branco com borda laranja, total de descontos</li>
<li>🟠 <strong>Card Bônus</strong> — laranja claro, total de bônus</li>
</ul>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 2 — Modo "Revisão Rápida" com Ações em Massa <span class="badge badge-new">NOVO</span></h3>
<p>Botões de ação em massa na consolidação:</p>
<ul>
<li><strong>"Marcar Todos como Entrega Normal"</strong></li>
<li><strong>"Marcar Selecionados como..."</strong> (Shift+click para selecionar múltiplas)</li>
<li><strong>Filtro:</strong> "Mostrar apenas não classificadas"</li>
<li><strong>Barra de progresso:</strong> "340 de 400 entregas classificadas (85%)"</li>
</ul>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 3 — Preview do Extrato Antes de Gerar PDF <span class="badge badge-new">NOVO</span></h3>
<p>Modal de preview HTML antes de gerar PDF — evita erros e re-trabalho.</p>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 4 — Notificações WhatsApp/E-mail <span class="badge badge-new">NOVO</span></h3>
<p>Ao finalizar consolidação, enviar para motoristas: "Sua consolidação [Período] está pronta. Valor: R$ [X]. Baixe: [link]"</p>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 5 — Comparativo Estimado vs Consolidado <span class="badge badge-new">NOVO</span></h3>
<p>Gráfico de barras lado a lado no Dashboard: Estimado (cinza) vs Consolidado (laranja) vs Diferença (preto).</p>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 6 — Filtro Avançado nas Consolidações <span class="badge badge-new">NOVO</span></h3>
<p>Busca por nome da operação, período, motorista, status, route_id.</p>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 7 — Soft Delete + Auditoria <span class="badge badge-new">NOVO</span></h3>
<p>Consolidações finalizadas NUNCA excluídas — apenas arquivadas. Log completo de quem fez o quê.</p>
</div>
<div class="box improvement">
<h3>✨ MELHORIA 8 — Tema Escuro/Claro <span class="badge badge-new">NOVO</span></h3>
<p>Toggle ☀️/🌙 no header. Tema escuro como padrão (preto + laranja fica incrível).</p>
</div>
<div class="box improvement">
<h3>🔁 MUDANÇA 1 — Checkboxes → Toggle Switches Visuais <span class="badge badge-change">MUDANÇA</span></h3>
<p>Toggle switches grandes coloridos: 🟠 laranja = Entrega Normal | ⚫ preto = Desconto | ⚪ branco = Bônus | 🟠 laranja escuro = Retirada</p>
</div>
<div class="box improvement">
<h3>🔁 MUDANÇA 2 — Validação em Wizard de 3 Passos <span class="badge badge-change">MUDANÇA</span></h3>
<p>Passo 1: Selecionar motorista | Passo 2: Classificar entregas com toggles + ações em massa | Passo 3: Revisar resumo → Próximo ou Finalizar</p>
</div>
<div class="box improvement">
<h3>🔁 MUDANÇA 3 — Job de 1h + Cálculo em Tempo Real <span class="badge badge-change">MUDANÇA</span></h3>
<p>Job persiste histórico, mas Dashboard calcula na hora ao abrir. Sem esperar 1h.</p>
</div>
<div class="box improvement">
<h3>🔁 MUDANÇA 4 — Login por PIN de 4 Dígitos + QR Code <span class="badge badge-change">MUDANÇA</span></h3>
<p>Motoristas usam PIN numérico ou escaneiam QR do extrato. Sem senha complexa.</p>
</div>
<!-- ==================== ARQUITETURA ==================== -->
<h2>🏗️ ARQUITETURA</h2>
<table>
<tr><th>Camada</th><th>Tecnologia</th></tr>
<tr><td>Backend</td><td>Ruby on Rails 7+ (API + Views)</td></tr>
<tr><td>Frontend</td><td>Rails Views + Hotwire (Turbo + Stimulus)</td></tr>
<tr><td>CSS</td><td>Tailwind CSS (tema customizado preto/laranja/branco)</td></tr>
<tr><td>Banco Existente</td><td>PostgreSQL 15 — tabela <code>db_reem_simplerout_2026</code> (apenas leitura)</td></tr>
<tr><td>Banco Novo</td><td>PostgreSQL 15 — tabelas do sistema (mesma instância, schema separado ou prefixo)</td></tr>
<tr><td>Auth</td><td>Devise + Pundit (roles: admin, gerente, operador, motorista)</td></tr>
<tr><td>PDF</td><td>Prawn (mais leve que WickedPDF)</td></tr>
<tr><td>Job/Cron</td><td>Whenever gem</td></tr>
<tr><td>Notificações</td><td>Twilio (WhatsApp) ou ActionMailer — opcional Fase 8</td></tr>
<tr><td>Docker</td><td>Docker + docker-compose.yml</td></tr>
<tr><td>Config</td><td>.env (NUNCA versionar)</td></tr>
<tr><td>Git</td><td>Servidor privado: <code>https://git.xenserver.com.br</code></td></tr>
</table>
<!-- ==================== REPOSITÓRIO GIT ==================== -->
<h2>🔒 REPOSITÓRIO GIT <span class="badge badge-security">SEGURANÇA</span></h2>
<div class="box security">
<strong>⚠️ AVISO DE SEGURANÇA:</strong><br>
NUNCA armazene credenciais de login (usuário/senha) em arquivos de código, prompts ou documentação.<br>
Sempre use variáveis de ambiente, CI/CD secrets ou gerenciadores de credenciais.
</div>
<div class="box">
<h3>📡 Servidor Git Privado</h3>
<p><strong>URL:</strong> <code>https://git.xenserver.com.br</code> (servidor próprio, privado)</p>
<p><strong>Repositório:</strong> <code>logistica-controle-custos</code> (criar como PRIVADO)</p>
<h3>🔐 Configuração Segura</h3>
<ol>
<li>Acesse <code>https://git.xenserver.com.br</code> e faça login com credenciais pessoais</li>
<li>Crie repositório privado: <code>logistica-controle-custos</code></li>
<li>Configure remote local (SEM credenciais no URL):</li>
</ol>
<pre>
git init
git add .
git commit -m "Initial commit - Fase 1"
# Adicionar remote sem credenciais
git remote add origin https://git.xenserver.com.br/[USUARIO]/logistica-controle-custos.git
# Cache de credenciais (pede senha uma vez)
git config --global credential.helper cache
git config --global credential.helper 'cache --timeout=3600'
# Primeiro push (digitar usuário/senha manualmente)
git push -u origin main
</pre>
<h3>📝 .gitignore Obrigatório</h3>
<pre>
# CREDENCIAIS — NUNCA versionar
.env
.env.local
.env.*.local
config/application.yml
config/database.yml
docker-compose.override.yml
*.pem
*.key
*.p12
# Rails
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
/storage/*
!/storage/.keep
/public/assets
/node_modules
/yarn-error.log
.byebug_history
/config/master.key
/config/credentials/*.key
# Docker
.env.docker
# IDEs
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
</pre>
<h3>📋 Checklist de Segurança do Repositório</h3>
<ul>
<li>✅ Repositório marcado como <strong>PRIVADO</strong></li>
<li>✅ Arquivo <code>.env</code> no <code>.gitignore</code></li>
<li>✅ Nenhuma senha, token ou chave em código</li>
<li><code>config/database.yml</code> usa variáveis de ambiente</li>
<li><code>docker-compose.yml</code> usa <code>env_file: .env</code></li>
<li>✅ Secret Key Base gerada via <code>rails secret</code> e armazenada em variável de ambiente</li>
</ul>
</div>
<h2>👥 PERFIL DE USUÁRIOS E PERMISSÕES</h2>
<table>
<tr><th>Perfil</th><th>Acesso</th></tr>
<tr><td>Admin</td><td>Tudo: Dashboard, Consolidação, Configurações, Motoristas, Auditoria</td></tr>
<tr><td>Gerente</td><td>Dashboard, Consolidação, gerar PDFs/extratos, visualizar arquivadas</td></tr>
<tr><td>Operador</td><td>Apenas Consolidação (criar, validar entregas, toggles), ver próprias consolidações</td></tr>
<tr><td>Motorista</td><td>Dashboard pessoal: valores estimados + consolidados validados, baixar próprio PDF</td></tr>
</table>
<h2>💰 PILARES DE PREÇO (Configuráveis na tela Configurações)</h2>
<table>
<tr><th>Pilar</th><th>Descrição</th><th>Tipo</th><th>Quando Aplicar</th></tr>
<tr><td>Entrega Bem-Sucedida</td><td>Valor pago por entrega concluída</td><td>Valor fixo (R$)</td><td>status = 'completed' E checkin IS NOT NULL</td></tr>
<tr><td>Retirada de Equipamento</td><td>Valor pago por retirada/devolução</td><td>Valor fixo (R$)</td><td>Quando o operador marcar como "Retirada" na consolidação</td></tr>
<tr><td>Bônus</td><td>Valor adicional por meta/critério</td><td>Valor fixo (R$)</td><td>Quando o operador marcar como "Bônus" na consolidação</td></tr>
<tr><td>Desconto</td><td>Valor descontado por problema</td><td>Valor fixo (R$)</td><td>Quando o operador marcar como "Desconto" na consolidação</td></tr>
</table>
<h2>📐 ESTRUTURA DE TELAS</h2>
<h3>🔐 TELA DE LOGIN</h3>
<ul>
<li>Campos: email, senha (admin/gerente/operador)</li>
<li>Alternativa motorista: <strong>PIN de 4 dígitos</strong> ou <strong>QR Code</strong></li>
<li>Botão grande "Entrar" com ícone</li>
<li>Esqueci minha senha → link mágico por email</li>
<li>Fundo preto, botão laranja, texto branco</li>
</ul>
<h3>🖥️ PAINEL ADMIN / GERENTE / OPERADOR</h3>
<h3>1. DASHBOARD</h3>
<ul>
<li><strong>Cards grandes (preto/laranja/branco):</strong>
<ul>
<li>🟠 <strong>Entregas OK</strong> — total de entregas completed no período</li>
<li><strong>Pendentes</strong> — entregas não consolidadas ainda</li>
<li><strong>Descontos</strong> — total de descontos aplicados</li>
<li>🟠 <strong>Bônus</strong> — total de bônus concedidos</li>
</ul>
</li>
<li><strong>Gráfico comparativo:</strong> barras lado a lado Estimado (cinza) vs Consolidado (laranja) por operação/route_id</li>
<li><strong>Lista últimas 5 consolidações</strong> com status e link</li>
<li><strong>Barra de progresso:</strong> "% do mês consolidado"</li>
<li>Atualização em tempo real ao carregar + job de 1h para histórico</li>
</ul>
<h3>2. CONSOLIDAÇÃO</h3>
<ul>
<li><strong>Lista de consolidações</strong> com filtros (nome, período, motorista, status, route_id)</li>
<li>Botão "Nova Consolidação" → modal:
<ul>
<li>Nome (ex: UBS SUL e LESTE Junho 2026)</li>
<li>Período (date range: planned_date)</li>
<li>Selecionar Motoristas (multi-select com busca — lista única de <code>driver</code> do banco)</li>
<li>Selecionar Rotas/Operações (multi-select de <code>route_id</code>)</li>
</ul>
</li>
<li><strong>Wizard de Validação (3 passos):</strong>
<ol>
<li><strong>Passo 1:</strong> Selecionar motorista da lista (com foto/nome e total de entregas no período)</li>
<li><strong>Passo 2:</strong> Classificar entregas com <strong>Toggle Switches coloridos</strong>:
<ul>
<li>🟠 Laranja = Entrega Normal (padrão)</li>
<li>⚫ Preto = Desconto</li>
<li>⚪ Branco = Bônus</li>
<li>🟠 Laranja Escuro = Retirada de Equipamento</li>
</ul>
+ Ações em massa + filtro "não classificadas"
</li>
<li><strong>Passo 3:</strong> Revisar resumo do motorista → "Próximo Motorista" ou "Finalizar Tudo"</li>
</ol>
</li>
<li><strong>Barra de progresso:</strong> "85% classificado — 340 de 400 entregas"</li>
<li><strong>Botões:</strong> "Salvar Rascunho" | "Finalizar Consolidação" (modal de confirmação)</li>
<li>Após finalizar: <strong>Preview do Extrato</strong> em modal HTML → "Gerar PDF"</li>
</ul>
<h3>3. CONFIGURAÇÕES</h3>
<ul>
<li><strong>Usuários:</strong> CRUD de logins com foto, role, status ativo/inativo</li>
<li><strong>Pilares de Preço:</strong> campos editáveis com máscara de moeda (R$), cores da marca</li>
<li><strong>Notificações:</strong> ligar/desligar WhatsApp/email, configurar Twilio</li>
<li><strong>Geral:</strong> nome da empresa, upload de logo, tema padrão</li>
<li><strong>Auditoria:</strong> log de quem criou/editou/finalizou o quê e quando</li>
</ul>
<h3>🛵 PAINEL MOTORISTA</h3>
<ul>
<li><strong>2 Cards grandes:</strong>
<ul>
<li>🟠 <strong>Valor Estimado</strong> (laranja) — cálculo ao vivo: entregas completed × preço_entrega</li>
<li><strong>Valor Consolidado</strong> (branco com borda laranja) — validado pelo operador</li>
</ul>
</li>
<li><strong>Lista de consolidações</strong> em que o motorista aparece (nome, período, valor, botão PDF)</li>
<li><strong>Botão de tema:</strong> ☀️/🌙 no canto superior</li>
<li>Design mobile-first: cards empilhados, fonte grande (min 18px), botões de dedo (min 48px)</li>
<li>Fundo preto, cards cinza escuro, destaques em laranja</li>
</ul>
<h2>🗄️ MODELO DE DADOS</h2>
<div class="box data">
<h3>📡 TABELAS EXISTENTES (APENAS LEITURA — NUNCA MODIFICAR)</h3>
<pre>
-- Já existe no PostgreSQL 15, atualizada a cada 1h
-- Nome: public.db_reem_simplerout_2026
-- Colunas principais usadas pelo sistema:
-- tracking_id (PK lógico)
-- reference_id (número da NF)
-- planned_date (data da entrega)
-- driver (nome do motorista)
-- vehicle (placa/ID veículo)
-- title (descrição da entrega)
-- checkin, checkout (horários reais)
-- status ('completed', 'pending', 'cancelled', etc.)
-- route_id (UUID da operação/rota)
-- contact_name (nome do local: UBS, EMAD, STS, SAD)
-- load, load_2, load_3 (quantidade de cargas)
-- nota_fiscal, relatorio_de_visita (URLs S3)
-- latitude, longitude, checkout_latitude, checkout_longitude
</pre>
<h3>🆕 TABELAS NOVAS DO SISTEMA (criar no mesmo PostgreSQL, schema separado ou prefixo)</h3>
<pre>
users (id, email, encrypted_password, pin_code, role, nome, telefone, ativo, tema_preferido, created_at, updated_at)
role: enum [admin, gerente, operador, motorista]
pin_code: string (4 dígitos, apenas motoristas)
configuracoes (id, chave, valor, descricao, updated_at, updated_by)
chaves: 'preco_entrega', 'preco_retirada', 'preco_bonus', 'preco_desconto',
'notificacao_whatsapp', 'notificacao_email', 'empresa_nome'
consolidacoes (id, nome, data_inicio, data_fim, status, valor_total,
created_by, finalizado_por, finalizado_em, created_at, updated_at, deleted_at)
status: enum [rascunho, finalizada, arquivada]
consolidacao_motoristas (id, consolidacao_id, motorista_nome, valor_total, created_at, updated_at)
-- motorista_nome = driver do banco existente
consolidacao_entregas (id, consolidacao_id, tracking_id, motorista_nome,
tipo, valor_aplicado, created_at, created_by)
tipo: enum [entrega_normal, retirada, bonus, desconto]
-- tracking_id referencia db_reem_simplerout_2026.tracking_id
historico_estimados (id, data_hora, valor_total_estimado, entregas_contadas, created_at)
-- atualizado a cada 1h pelo job
auditoria_logs (id, user_id, acao, entidade, entidade_id, dados_anteriores, dados_novos, created_at)
-- log de todas as ações críticas
</pre>
</div>
<h2>🐳 DOCKER + CONFIGURAÇÃO (YAML)</h2>
<pre>
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports: ["3000:3000"]
env_file: .env
environment:
DATABASE_URL: ${DATABASE_URL}
DB_HOST: ${DB_HOST}
DB_PORT: ${DB_PORT}
DB_NAME: ${DB_NAME}
DB_USER: ${DB_USER}
DB_PASSWORD: ${DB_PASSWORD}
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
REDIS_URL: ${REDIS_URL}
volumes: [".:/app"]
depends_on: [db, redis]
db:
image: postgres:15
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- "pg_data:/var/lib/postgresql/data"
# Se o banco existente estiver em outro servidor, remover esta seção
# e apontar DB_HOST para o servidor correto
redis:
image: redis:alpine
volumes:
pg_data:
# .env (NUNCA versionar — adicionar no .gitignore)
# ================================================
DATABASE_URL="postgresql://user:pass@host:5432/db"
DB_HOST="db" # ou IP do servidor PostgreSQL existente
DB_PORT="5432"
DB_NAME="logistica_db"
DB_USER="postgres"
DB_PASSWORD="senha_segura"
SECRET_KEY_BASE="gerar_com_rails_secret"
REDIS_URL="redis://redis:6379/0"
# Twilio (opcional — Fase 8)
TWILIO_ACCOUNT_SID=""
TWILIO_AUTH_TOKEN=""
TWILIO_WHATSAPP_FROM=""
# Configuração do banco existente
DB_EXISTING_TABLE="db_reem_simplerout_2026"
DB_EXISTING_SCHEMA="public"
</pre>
<h2>🎨 DIRETRIZES DE DESIGN (UX para baixo nível tech)</h2>
<div class="box">
<h3>🎨 Paleta de Cores da Marca</h3>
<table>
<tr><th>Elemento</th><th>Cor</th><th>Hex</th></tr>
<tr><td>Fundo principal (tema escuro)</td><td>Preto</td><td>#0a0a0a ou #111111</td></tr>
<tr><td>Fundo cards</td><td>Cinza escuro</td><td>#1a1a1a ou #1e1e1e</td></tr>
<tr><td>Cor primária (botões, destaques)</td><td>Laranja</td><td>#f97316 ou #ea580c</td></tr>
<tr><td>Cor secundária (textos, ícones)</td><td>Branco</td><td>#ffffff</td></tr>
<tr><td>Cor de alerta/sucesso</td><td>Verde</td><td>#22c55e</td></tr>
<tr><td>Cor de erro/desconto</td><td>Vermelho</td><td>#ef4444</td></tr>
<tr><td>Cor de info/bônus</td><td>Azul claro</td><td>#38bdf8</td></tr>
</table>
<h3>📐 Regras de UX</h3>
<ul>
<li><strong>Fonte mínima 18px</strong> no mobile, 16px no desktop</li>
<li><strong>Botões mínimo 48px</strong> de altura, cantos arredondados (rounded-lg)</li>
<li><strong>Toggle switches</strong> em vez de checkboxes — área maior, feedback visual</li>
<li><strong>Modais de confirmação</strong> para ações destrutivas (finalizar, arquivar)</li>
<li><strong>Toast notifications</strong> no canto superior direito, cor laranja para sucesso</li>
<li><strong>Wizard em passos</strong> — uma ação por tela, sem abas aninhadas</li>
<li><strong>Mobile-first</strong> — muitos motoristas acessarão pelo celular</li>
<li><strong>Tema escuro como padrão</strong> — preto + laranja é a identidade da marca</li>
<li><strong>Ícones + texto</strong> — nunca ícone sozinho</li>
<li><strong>Placeholders explicativos</strong> nos campos (ex: "Ex: UBS SUL e LESTE Junho 2026")</li>
<li><strong>Loading states</strong> — spinner laranja ao carregar dados</li>
<li><strong>Empty states</strong> — mensagem amigável quando não há dados (ex: "Nenhuma entrega neste período")</li>
</ul>
</div>
<h2>📊 JOB DE ATUALIZAÇÃO ESTIMADA (a cada 1h)</h2>
<pre>
# Gemfile: gem 'whenever', require: false
# config/schedule.rb
every 1.hour do
runner "HistoricoEstimado.atualizar!"
end
# app/models/historico_estimado.rb
class HistoricoEstimado < ApplicationRecord
def self.atualizar!
preco = Configuracao.valor('preco_entrega').to_f
# Buscar entregas do dia com status 'completed' e checkin IS NOT NULL
entregas = DbReemSimplerout2026
.where(status: 'completed')
.where.not(checkin: nil)
.where(planned_date: Date.current)
.count
total = entregas * preco
create!(
data_hora: Time.current,
valor_total_estimado: total,
entregas_contadas: entregas
)
end
end
# O Dashboard calcula em tempo real na hora do acesso:
# SELECT COUNT(*) FROM db_reem_simplerout_2026
# WHERE status = 'completed' AND checkin IS NOT NULL
# AND planned_date BETWEEN :inicio AND :fim
# O job serve apenas para manter histórico de gráficos.
</pre>
<h2>📄 GERADOR DE PDF (Extrato)</h2>
<ul>
<li><strong>Cabeçalho:</strong> logo da empresa (preto + laranja), nome da consolidação, período, data de geração</li>
<li><strong>Dados do motorista:</strong> nome, período trabalhado, total de entregas</li>
<li><strong>Corpo:</strong> tabela com entregas (data, NF, local/contact_name, tipo, valor unitário, valor total)</li>
<li><strong>Resumo:</strong> total de entregas normais, retiradas, bônus, descontos, valor final a pagar</li>
<li><strong>Rodapé:</strong> "Documento gerado automaticamente em [data]", QR code para validação</li>
<li><strong>Estilo:</strong> limpo, fonte legível, cores preto/laranja/branco</li>
</ul>
<!-- ==================== FASES DE IMPLEMENTAÇÃO ==================== -->
<h1>🔧 FASES DE IMPLEMENTAÇÃO (Checkpoint obrigatório ao final de cada uma)</h1>
<div class="box phase">
<h3>🟠 FASE 1 — Setup Inicial + Docker + Git</h3>
<ol>
<li>Criar estrutura Rails 7+ com <code>docker-compose.yml</code></li>
<li>Configurar conexão com PostgreSQL 15 existente (tabela <code>db_reem_simplerout_2026</code> — APENAS LEITURA)</li>
<li>Criar model <code>DbReemSimplerout2026</code> com <code>self.table_name = 'db_reem_simplerout_2026'</code> e <code>self.primary_key = 'tracking_id'</code></li>
<li>Criar tabelas novas: users, configuracoes, consolidacoes, consolidacao_motoristas, consolidacao_entregas, historico_estimados, auditoria_logs</li>
<li>Configurar gem Figaro ou dotenv para variáveis em <code>.env</code> (NUNCA versionar .env)</li>
<li>Instalar e configurar Devise + Pundit (roles: admin, gerente, operador, motorista)</li>
<li>Seed: criar usuário admin padrão (admin@gade.com / senha123)</li>
<li>Testar <code>docker-compose up</code> e acesso ao Rails</li>
<li>Inicializar repositório Git: <code>git init</code>, criar <code>.gitignore</code> completo, primeiro commit</li>
<li>Adicionar remote para servidor privado <code>git.xenserver.com.br</code></li>
<li>Push inicial para o servidor Git privado</li>
</ol>
<strong>CHECKPOINT FASE 1:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 2 — Autenticação + Perfis + Configurações</h3>
<ol>
<li>Implementar login com redirecionamento por role</li>
<li>Login por PIN de 4 dígitos para motoristas (alternativa a senha)</li>
<li>Criar tela de Configurações com CRUD de usuários (admin/gerente/operador/motorista)</li>
<li>Criar CRUD de Pilares de Preço (entrega, retirada, bônus, desconto) com máscara de moeda</li>
<li>Validar permissões: operador não vê config, motorista não vê admin</li>
<li>Layout base com navegação lateral responsiva (Tailwind + tema preto/laranja/branco)</li>
<li>Toggle tema claro/escuro no header</li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 2:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 3 — Dashboard Admin/Gerente</h3>
<ol>
<li>Criar controller Dashboard com métricas consolidadas</li>
<li>Cards coloridos grandes (preto/laranja/branco): Entregas OK, Pendentes, Descontos, Bônus</li>
<li>Gráfico comparativo Estimado vs Consolidado (Chart.js simples, cores da marca)</li>
<li>Lista últimas 5 consolidações com link para detalhe</li>
<li>Barra de progresso "% do mês consolidado"</li>
<li>Cálculo em tempo real (SQL rápido) ao carregar a página — buscar de <code>db_reem_simplerout_2026</code></li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 3:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 4 — Job de Atualização Automática (1h) + Auditoria</h3>
<ol>
<li>Implementar job com Whenever gem para rodar a cada 1 hora</li>
<li>Lógica: contar entregas <code>status='completed'</code> + <code>checkin IS NOT NULL</code> do dia, multiplicar por <code>preco_entrega</code>, salvar em <code>historico_estimados</code></li>
<li>Criar modelo <code>AuditoriaLog</code> para registrar ações críticas (criar, editar, finalizar, arquivar consolidação)</li>
<li>Expor valor na API interna para o Dashboard</li>
<li>Testar execução manual e confirmar persistência no banco</li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 4:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 5 — Consolidação (Criar + Selecionar + Wizard Passo 1)</h3>
<ol>
<li>Tela "Nova Consolidação": formulário com nome, período (2 date pickers), multi-select de motoristas (busca de <code>driver</code> do banco), multi-select de rotas (<code>route_id</code>)</li>
<li>Ao salvar: criar registro em <code>consolidacoes</code> (status: rascunho) + <code>consolidacao_motoristas</code></li>
<li>Listar consolidações com filtros (status, período, nome, motorista, route_id)</li>
<li>Wizard Passo 1: Selecionar motorista da lista (com total de entregas no período)</li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 5:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 6 — Validação de Entregas + Toggles + Ações em Massa</h3>
<ol>
<li>Wizard Passo 2: Buscar entregas do período para o motorista selecionado (de <code>db_reem_simplerout_2026</code>)</li>
<li>Toggle switches coloridos grandes (laranja=normal, preto=desconto, branco=bônus, laranja escuro=retirada)</li>
<li>Ações em massa: "Marcar todos como Normal", "Marcar selecionados como..."</li>
<li>Filtro "Mostrar apenas não classificadas"</li>
<li>Barra de progresso "X de Y entregas classificadas"</li>
<li>Resumo lateral com total por tipo (Stimulus para atualização em tempo real)</li>
<li>Wizard Passo 3: Revisar resumo do motorista → "Próximo Motorista" ou "Salvar Rascunho"</li>
<li>Validação: não permitir finalizar sem classificar todas as entregas</li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 6:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 7 — Geração de PDFs (Preview + Relatório + Extrato)</h3>
<ol>
<li>Instalar e configurar Prawn (mais leve que WickedPDF)</li>
<li>Layout de PDF: logo preto/laranja, nome consolidação, período, tabela de entregas, total</li>
<li>Modal de Preview HTML antes de gerar PDF (modal com botão Confirmar/Voltar)</li>
<li>Botão "Gerar Relatório Individual" por motorista (PDF com detalhe das entregas)</li>
<li>Botão "Gerar Extrato" (PDF resumido com valor total a pagar — estilo extrato)</li>
<li>QR code no extrato para login rápido do motorista</li>
<li>Soft delete: consolidações finalizadas vão para status "arquivada", nunca excluídas</li>
<li>Commit e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 7:</strong> Liste todos os arquivos criados/modificados. Pare. Aguarde próxima fase.
</div>
<div class="box phase">
<h3>🟠 FASE 8 — Painel do Motorista + Notificações + Finalização</h3>
<ol>
<li>Tela do motorista após login: 2 cards grandes (Valor Estimado laranja | Valor Consolidado branco)</li>
<li>Lista de consolidações em que ele aparece com link para baixar próprio PDF</li>
<li>Login por PIN ou QR Code (escaneia extrato para acessar)</li>
<li>Notificações: integração Twilio (WhatsApp) ou ActionMailer (email) — ao finalizar consolidação, enviar mensagem automática para motoristas</li>
<li>Ajustes finais de responsividade (mobile)</li>
<li>Revisar todas as permissões (Pundit)</li>
<li>Revisar textos/labels para clareza (público baixo nível tech)</li>
<li>README.md com instruções de deploy Docker e configuração do .env</li>
<li>Teste end-to-end: login → criar consolidação → validar → gerar PDF → notificar → logout → login motorista → ver valores</li>
<li>Commit final e push para o Git privado</li>
</ol>
<strong>CHECKPOINT FASE 8 (FINAL):</strong> Liste todos os arquivos do projeto. Status: ✅ COMPLETO.
</div>
<h2>💡 DICAS PARA O CLAUDE (Instruções de Otimização)</h2>
<div class="box">
<ul>
<li>Use <strong>Rails 7+ com importmap</strong> — evite Webpack para reduzir complexidade</li>
<li>Use <strong>Tailwind via CDN</strong> durante desenvolvimento, depois compile se necessário</li>
<li>Para o banco existente: use <code>self.table_name = 'db_reem_simplerout_2026'</code> e <code>self.primary_key = 'tracking_id'</code> — NUNCA crie migration para essa tabela</li>
<li>Para toggles: use <strong>Stimulus</strong> para atualizar totais em tempo real sem recarregar página</li>
<li>Para o job de 1h: use <strong>Whenever gem</strong> (mais simples que Sidekiq para cron)</li>
<li>Para PDF: <strong>Prawn</strong> é mais leve que WickedPDF (sem dependência de wkhtmltopdf)</li>
<li>Para mobile: use <strong>CSS Grid/Flexbox</strong> com breakpoints Tailwind (<code>md:</code>, <code>lg:</code>)</li>
<li>Para tema escuro: use <code>dark:</code> prefix do Tailwind + <code>class</code> strategy — tema escuro como padrão</li>
<li>Para cores da marca: configure no <code>tailwind.config.js</code> — preto <code>#0a0a0a</code>, laranja <code>#f97316</code>, branco <code>#ffffff</code></li>
<li>Seja verboso nos <strong>CHECKPOINTS</strong> — liste arquivo por arquivo para continuidade</li>
<li>A cada fase: <code>git add . && git commit -m "Fase X completa" && git push</code></li>
<li>Se o banco existente estiver em servidor separado, configure <code>DB_HOST</code> no .env apontando para o IP correto</li>
</ul>
</div>
<h2>📝 EXEMPLO DE COMANDO PARA INICIAR CADA FASE</h2>
<pre>
# No início de cada conversa com o Claude, cole:
"Execute a FASE [NÚMERO] do prompt de Sistema de Controle de Custos Logística.
A fase anterior foi concluída. Aqui está o CHECKPOINT da fase anterior: [COLE AQUI]"
# Comandos Git a cada fase:
git add .
git commit -m "Fase X - [descricao]"
git push origin main
</pre>
<div class="box warning">
<strong>⚠️ IMPORTANTE:</strong> Se em alguma fase o Claude atingir o limite de tokens/contexto, peça para ele gerar o CHECKPOINT incompleto e continue na próxima conta free com: <em>"Continue a FASE X a partir deste CHECKPOINT: [cole]"</em>.
</div>
<div class="box security">
<strong>🔐 LEMBRETE FINAL DE SEGURANÇA:</strong><br>
<ul>
<li>NUNCA commit arquivos .env, application.yml, ou qualquer arquivo com senha</li>
<li>NUNCA exponha SECRET_KEY_BASE, senhas de banco, ou tokens de API</li>
<li>Sempre use <code>ENV['VARIAVEL']</code> no código Rails</li>
<li>Configure o repositório Git como PRIVADO no servidor <code>git.xenserver.com.br</code></li>
<li>Use HTTPS com credential helper ou SSH keys para autenticação no Git</li>
<li>NUNCA execute DROP TABLE, TRUNCATE ou DELETE em massa na tabela <code>db_reem_simplerout_2026</code> existente</li>
</ul>
</div>
</body>
</html>