Fases 4, 5 e 6 — Job 1h + Auditoria + Consolidação + Wizard de validação
This commit is contained in:
236
README.md
236
README.md
@@ -2,8 +2,8 @@
|
||||
|
||||
Sistema web para controle de custos de entregas hospitalares da **Gade Hospitalar**.
|
||||
|
||||
**Stack:** Ruby on Rails 7+ · PostgreSQL 15 · Docker · Tailwind CSS · Hotwire (Turbo + Stimulus)
|
||||
**Repositório:** <https://git.xenserver.com.br/victor/Reem-Notas>
|
||||
**Stack:** Ruby on Rails 7+ · PostgreSQL 15 · Docker · Tailwind CSS · Hotwire (Turbo + Stimulus)
|
||||
**Repositório:** https://git.xenserver.com.br/Cludio-code/logistica-controle-custos
|
||||
|
||||
---
|
||||
|
||||
@@ -13,7 +13,6 @@ A **Gade Hospitalar** precisa controlar o custo de cada operação de entrega
|
||||
(UBS SUL, UBS LESTE, EMAD, STS, SAD, etc.).
|
||||
|
||||
O banco **já existe** e é atualizado a cada 1 hora por outro sistema externo:
|
||||
|
||||
- Tabela: `public.db_reem_simplerout_2026`
|
||||
- Account: Gade Hospitalar (account_id: 95907)
|
||||
- **NUNCA** fazer `DROP TABLE`, `TRUNCATE`, `DELETE` ou migration nessa tabela.
|
||||
@@ -23,13 +22,13 @@ e lê a tabela existente apenas para exibir e consolidar entregas.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Estado atual — O que já foi feito
|
||||
## 🏗️ Estado atual — O que já foi feito (Fase 1 ✅)
|
||||
|
||||
```text
|
||||
```
|
||||
logistica-controle-custos/
|
||||
├── Gemfile # Todas as gems (Devise, Pundit, Prawn, Whenever, Tailwind…)
|
||||
├── Dockerfile # Ruby 3.2.2-slim
|
||||
├── docker-compose.yml # app (postgres externo via .env)
|
||||
├── docker-compose.yml # app + db (postgres:15)
|
||||
├── tailwind.config.js # Paleta preto #0a0a0a / laranja #f97316 / branco
|
||||
├── .env.example # Template de variáveis — copiar para .env
|
||||
├── .gitignore # Protege .env, master.key, credenciais
|
||||
@@ -40,44 +39,27 @@ logistica-controle-custos/
|
||||
│
|
||||
├── app/
|
||||
│ ├── models/
|
||||
│ │ ├── entrega.rb # ⚠️ READ-ONLY — tabela db_reem_simplerout_2026
|
||||
│ │ ├── entrega.rb # ⚠️ READ-ONLY — tabela existente db_reem_simplerout_2026
|
||||
│ │ ├── user.rb # Devise + roles (admin/gerente/operador/motorista) + PIN
|
||||
│ │ ├── configuracao.rb # Preços configuráveis + mapa_de_precos()
|
||||
│ │ ├── configuracao.rb # Preços configuráveis (entrega, retirada, bonus, desconto)
|
||||
│ │ ├── consolidacao.rb # Soft delete, enum status, cálculo de progresso
|
||||
│ │ ├── consolidacao_motorista.rb
|
||||
│ │ ├── consolidacao_entrega.rb # Enum tipo: normal/retirada/bonus/desconto
|
||||
│ │ ├── historico_estimado.rb # Job 1h + cálculo ao vivo
|
||||
│ │ └── auditoria_log.rb # Log de ações críticas + .registrar()
|
||||
│ │ └── auditoria_log.rb # Log de ações críticas
|
||||
│ │
|
||||
│ ├── controllers/
|
||||
│ │ ├── application_controller.rb # Auth + Pundit + tema
|
||||
│ │ ├── users/sessions_controller.rb # PIN login + redirect por role
|
||||
│ │ ├── dashboard_controller.rb # Cálculos ao vivo (Fase 3)
|
||||
│ │ ├── usuarios_controller.rb # CRUD usuários
|
||||
│ │ ├── configuracoes_controller.rb # Preços + toggle tema
|
||||
│ │ └── motorista_controller.rb # Painel do motorista
|
||||
│ │
|
||||
│ │ └── application_controller.rb # Auth + Pundit + tema
|
||||
│ ├── policies/
|
||||
│ │ ├── application_policy.rb # Base Pundit + helpers admin?/gerente?/operador?
|
||||
│ │ ├── user_policy.rb # Admin vê tudo; gerente não vê admins
|
||||
│ │ └── configuracao_policy.rb # Apenas admin edita preços
|
||||
│ │
|
||||
│ │ └── application_policy.rb # Base Pundit
|
||||
│ ├── helpers/
|
||||
│ │ └── application_helper.rb # moeda(), nav_link_to(), badge_status(), badge_role(), progress_bar()
|
||||
│ │
|
||||
│ └── views/
|
||||
│ ├── devise/sessions/new.html.erb # Login com teclado PIN + abas E-mail/PIN
|
||||
│ ├── layouts/
|
||||
│ │ ├── application.html.erb # Layout dark/light + sidebar responsiva
|
||||
│ │ └── _sidebar.html.erb # Navegação condicional por role
|
||||
│ ├── dashboard/index.html.erb # Cards grandes + Chart.js + ranking
|
||||
│ ├── usuarios/ # index, new, edit, _form
|
||||
│ ├── configuracoes/ # index (cards de preço), edit
|
||||
│ ├── motorista/index.html.erb # Painel simplificado do motorista
|
||||
│ └── shared/_flash.html.erb
|
||||
│ │ └── application_helper.rb # nav_link_to, moeda(), badge_status(), progress_bar()
|
||||
│ └── views/layouts/
|
||||
│ ├── application.html.erb # Layout base dark theme laranja/preto/branco
|
||||
│ └── _navbar.html.erb # Sidebar responsiva com hamburguer mobile
|
||||
│
|
||||
└── db/
|
||||
├── seeds.rb # Admin/Gerente/Operador + 3 motoristas com PIN
|
||||
├── seeds.rb # Admin: admin@gade.com / Gade@2026! + configs de preço
|
||||
└── migrate/
|
||||
├── ..._create_users.rb
|
||||
├── ..._create_configuracoes.rb
|
||||
@@ -85,8 +67,7 @@ logistica-controle-custos/
|
||||
├── ..._create_consolidacao_motoristas.rb
|
||||
├── ..._create_consolidacao_entregas.rb
|
||||
├── ..._create_historico_estimados.rb
|
||||
├── ..._create_auditoria_logs.rb
|
||||
└── ..._add_fase2_fields_to_users.rb # PIN + ativo + trackable + lockable
|
||||
└── ..._create_auditoria_logs.rb
|
||||
```
|
||||
|
||||
---
|
||||
@@ -94,41 +75,35 @@ logistica-controle-custos/
|
||||
## 🚀 Setup do zero (próximo dev)
|
||||
|
||||
### 1. Clone
|
||||
|
||||
```bash
|
||||
git clone https://git.xenserver.com.br/victor/Reem-Notas.git
|
||||
cd Reem-Notas
|
||||
git clone https://git.xenserver.com.br/Cludio-code/logistica-controle-custos.git
|
||||
cd logistica-controle-custos
|
||||
```
|
||||
|
||||
### 2. Configure o .env
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
nano .env # preencha DB_HOST, DB_PASSWORD, etc.
|
||||
```
|
||||
|
||||
### 3. Gere o SECRET_KEY_BASE
|
||||
|
||||
```bash
|
||||
docker run --rm ruby:3.2.2-slim bash -c "gem install rails --no-doc -q && rails secret"
|
||||
# Cole o resultado no .env → SECRET_KEY_BASE=...
|
||||
```
|
||||
|
||||
### 4. Suba os containers
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 5. Banco + seeds
|
||||
|
||||
```bash
|
||||
docker-compose exec app bundle exec rails db:create db:migrate db:seed
|
||||
```
|
||||
|
||||
### 6. Acesse
|
||||
|
||||
```text
|
||||
```
|
||||
http://localhost:3000
|
||||
Login: admin@gade.com
|
||||
Senha: Gade@2026! ← ALTERE NO PRIMEIRO ACESSO
|
||||
@@ -149,98 +124,99 @@ docker-compose down # parar tudo
|
||||
|
||||
## 🗺️ Fases de implementação
|
||||
|
||||
<<<<<<< HEAD
|
||||
| Fase | Status | O que fazer |
|
||||
|------|--------|-------------|
|
||||
| **1** | ✅ **CONCLUÍDA** | Setup + Docker + Models + Migrations + Seeds + Layout base |
|
||||
| **2** | ✅ **CONCLUÍDA** | Login por role + PIN motorista + CRUD usuários + pilares de preço + sidebar |
|
||||
| **3** | ✅ **CONCLUÍDA** | Dashboard: cards grandes laranja/preto/branco + gráfico Chart.js + cálculo ao vivo |
|
||||
| **4** | ⏳ Próxima | Job Whenever (1h) + HistoricoEstimado + AuditoriaLog |
|
||||
| **5** | ⏳ | Nova Consolidação + Wizard Passo 1 (selecionar motorista) |
|
||||
| **6** | ⏳ | Toggle switches coloridos + ações em massa + barra de progresso (Stimulus) |
|
||||
| **7** | ⏳ | PDFs com Prawn: relatório individual + holerite com QR code |
|
||||
| **8** | ⏳ | Painel motorista + notificações WhatsApp/email + responsividade final |
|
||||
=======
|
||||
| Fase | Status | O que foi feito / fazer |
|
||||
| ----- | ---------------- | ------------------------------------------------------------------------------------------- |
|
||||
| **1** | ✅ **CONCLUÍDA** | Setup + Docker + Models + Migrations + Seeds + Layout base |
|
||||
| **2** | ✅ **CONCLUÍDA** | Login por role + PIN motorista + CRUD usuários + pilares de preço + toggle tema + Pundit |
|
||||
| **3** | ✅ **CONCLUÍDA** | Dashboard: cards laranja/preto/branco + gráfico Chart.js + ranking motoristas + cálculo ao vivo |
|
||||
| **4** | ⏳ Próxima | Job Whenever (1h) + HistoricoEstimado + UI de AuditoriaLog |
|
||||
| **5** | ⏳ | Nova Consolidação + Wizard Passo 1 (selecionar motorista) |
|
||||
| **6** | ⏳ | Toggle switches coloridos + ações em massa + barra de progresso (Stimulus) |
|
||||
| **7** | ⏳ | PDFs com Prawn: relatório individual + holerite com QR code |
|
||||
| **8** | ⏳ | Painel motorista + notificações WhatsApp/email + responsividade final |
|
||||
>>>>>>> 63b7f4d (Atualização README - Fase 2 e 3)
|
||||
| **2** | ⏳ Pendente | Login por role + PIN motorista + CRUD usuários + pilares de preço + sidebar |
|
||||
| **3** | ⏳ Pendente | Dashboard: cards grandes laranja/preto/branco + gráfico Chart.js + cálculo ao vivo |
|
||||
| **4** | ✅ **CONCLUÍDA** | Job Whenever (1h) + HistoricoEstimado + AuditoriaLog + API métricas |
|
||||
| **5** | ✅ **CONCLUÍDA** | Nova Consolidação + filtros + Wizard Passo 1 (selecionar motorista) |
|
||||
| **6** | ✅ **CONCLUÍDA** | Toggles coloridos + ações em massa + barra progresso + Wizard Passos 2 e 3 (Stimulus) |
|
||||
| **7** | ⏳ Pendente | PDFs com Prawn: relatório individual + holerite com QR code |
|
||||
| **8** | ⏳ Pendente | Painel motorista + notificações WhatsApp/email + responsividade final |
|
||||
|
||||
---
|
||||
### 📂 Arquivos das Fases 4, 5 e 6
|
||||
|
||||
## 👥 Perfis de acesso
|
||||
**Fase 4 — Job 1h + Auditoria:**
|
||||
```
|
||||
config/schedule.rb # Whenever — roda a cada 1h
|
||||
lib/tasks/historico.rake # rake historico:atualizar
|
||||
app/jobs/application_job.rb
|
||||
app/jobs/atualizar_historico_estimado_job.rb # conta entregas pagas × preco_entrega
|
||||
app/controllers/api/v1/dashboard_controller.rb # GET /api/v1/dashboard/metricas
|
||||
app/controllers/concerns/auditavel.rb # auditar!(:acao, registro) nos controllers
|
||||
app/policies/dashboard_policy.rb
|
||||
```
|
||||
Ativar o cron no servidor: `bundle exec whenever --update-crontab`
|
||||
Testar manualmente: `docker-compose exec app bundle exec rake historico:atualizar`
|
||||
|
||||
| Perfil | Login | Acesso | Vai para |
|
||||
| --------- | ------------------- | ----------------------------------- | --------------- |
|
||||
| Admin | email + senha | Tudo | `/dashboard` |
|
||||
| Gerente | email + senha | Dashboard + Consolidações + PDFs | `/dashboard` |
|
||||
| Operador | email + senha | Consolidações (criar + validar) | `/dashboard` |
|
||||
| Motorista | PIN 4 dígitos | Painel pessoal + baixar próprio PDF | `/motorista` |
|
||||
**Fase 5 — Consolidação + Wizard Passo 1:**
|
||||
```
|
||||
db/migrate/20260101000008_add_route_ids_to_consolidacoes.rb # rodar db:migrate!
|
||||
app/controllers/consolidacoes_controller.rb # index/new/create/show/wizard/finalizar/arquivar
|
||||
app/policies/consolidacao_policy.rb
|
||||
app/views/consolidacoes/index.html.erb # lista com filtros (status/nome/período/motorista/rota)
|
||||
app/views/consolidacoes/new.html.erb # form: nome + 2 date pickers + multi-select motoristas/rotas
|
||||
app/views/consolidacoes/wizard.html.erb # Passo 1: lista motoristas com progresso
|
||||
```
|
||||
|
||||
### Credenciais de teste (seeds)
|
||||
**Fase 6 — Validação + Toggles + Massa:**
|
||||
```
|
||||
app/controllers/consolidacao_entregas_controller.rb # validar/classificar/classificar_em_massa/revisar
|
||||
app/views/consolidacao_entregas/validar.html.erb # Passo 2: toggles coloridos + checkbox massa + resumo lateral
|
||||
app/views/consolidacao_entregas/revisar.html.erb # Passo 3: resumo + próximo motorista / salvar rascunho
|
||||
app/javascript/controllers/validacao_controller.js # Stimulus: tempo real (progresso, resumo, toggles)
|
||||
config/routes.rb # ATUALIZADO — rotas do wizard
|
||||
```
|
||||
|
||||
| Usuário | Login | Senha / PIN |
|
||||
| ---------------- | ------------------ | ------------ |
|
||||
| Admin | admin@gade.com | Gade@2026! |
|
||||
| Gerente | gerente@gade.com | Gade@2026! |
|
||||
| Operador | operador@gade.com | Gade@2026! |
|
||||
| Motorista João | PIN | 1234 |
|
||||
| Motorista Maria | PIN | 5678 |
|
||||
| Motorista Carlos | PIN | 9012 |
|
||||
**Cores dos toggles (padrão do projeto):**
|
||||
🟧 Laranja = Entrega Normal · 🟫 Laranja escuro = Retirada · ⬜ Branco = Bônus · ⬛ Preto = Desconto
|
||||
|
||||
> ⚠️ **Altere todas as senhas no primeiro acesso em produção.**
|
||||
**Regras implementadas:**
|
||||
- Entregas elegíveis: `status='completed'` AND `checkin IS NOT NULL` (somente leitura da tabela existente)
|
||||
- Não permite finalizar consolidação com entregas não classificadas (botão desabilitado + validação server-side)
|
||||
- Consolidação finalizada não pode ser editada por operadores (Pundit)
|
||||
- Todas ações críticas registradas em `auditoria_logs`
|
||||
|
||||
---
|
||||
|
||||
### ▶️ Para continuar da Fase 4
|
||||
### ▶️ Para continuar (Fases 2, 3, 7 ou 8)
|
||||
|
||||
Cole este contexto no início da conversa com o Claude:
|
||||
|
||||
```text
|
||||
Execute a FASE 4 do Sistema de Controle de Custos Logística da Gade Hospitalar.
|
||||
```
|
||||
Continue o Sistema de Controle de Custos Logística da Gade Hospitalar.
|
||||
|
||||
CHECKPOINT FASES 1-3 (concluídas):
|
||||
- Rails 7+ com Docker, PostgreSQL 15, Tailwind (preto #0a0a0a / laranja #f97316)
|
||||
- Models: Entrega (read-only), User (Devise + roles + PIN), Configuracao,
|
||||
Consolidacao, ConsolidacaoMotorista, ConsolidacaoEntrega,
|
||||
HistoricoEstimado, AuditoriaLog
|
||||
- Devise com login por e-mail (admin/gerente/operador) e PIN 4 dígitos (motorista)
|
||||
- Pundit: UserPolicy, ConfiguracaoPolicy, ApplicationPolicy
|
||||
- Dashboard com Chart.js: cards KPI, gráfico diário, ranking motoristas, grid locais
|
||||
- CRUD de usuários com toggle ativo/inativo e formulário dinâmico por role
|
||||
- Configurações de preço (entrega, retirada, bonus, desconto) com cards editáveis
|
||||
- Toggle tema claro/escuro salvo na sessão
|
||||
- Sidebar responsiva (desktop fixa + drawer mobile) com navegação por role
|
||||
- Seeds: admin/gerente/operador com e-mail + 3 motoristas com PIN
|
||||
CHECKPOINT — FASES 1, 4, 5 e 6 CONCLUÍDAS:
|
||||
- Rails 7+ com Docker, PostgreSQL externo, Tailwind (preto #0a0a0a / laranja #f97316)
|
||||
- Models: Entrega (read-only db_reem_simplerout_2026), User (Devise+roles),
|
||||
Configuracao, Consolidacao (+route_ids jsonb), ConsolidacaoMotorista,
|
||||
ConsolidacaoEntrega, HistoricoEstimado, AuditoriaLog
|
||||
- 8 migrations criadas
|
||||
- Fase 4: Whenever (1h) + AtualizarHistoricoEstimadoJob + rake historico:atualizar
|
||||
+ API GET /api/v1/dashboard/metricas + concern Auditavel
|
||||
- Fase 5: ConsolidacoesController completo (filtros, multi-select motoristas/rotas)
|
||||
+ Wizard Passo 1 (wizard.html.erb)
|
||||
- Fase 6: ConsolidacaoEntregasController (validar/classificar/classificar_em_massa/revisar)
|
||||
+ toggles coloridos + ações em massa + Stimulus validacao_controller.js
|
||||
+ validação de finalização
|
||||
|
||||
FASE 4 deve implementar:
|
||||
1. Job com Whenever: rodar a cada 1h para calcular e salvar HistoricoEstimado
|
||||
2. Modelo HistoricoEstimado: snapshot do valor estimado por motorista por hora
|
||||
3. Controller + view de AuditoriaLog: tabela paginada com filtro por usuário/ação
|
||||
4. Indicador visual no Dashboard mostrando "última atualização" do histórico
|
||||
5. Rake task manual: rails historico:calcular (para rodar fora do cron)
|
||||
FALTAM: Fase 2 (auth/PIN/CRUD usuários/configurações), Fase 3 (Dashboard com
|
||||
gráficos), Fase 7 (PDFs Prawn + holerite + QR code), Fase 8 (painel motorista
|
||||
+ notificações). Consulte o README.md do repositório para detalhes.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Banco existente — referência rápida
|
||||
|
||||
| Campo | Uso |
|
||||
| -------------- | ------------------------------------------ |
|
||||
| `tracking_id` | PK lógico da entrega |
|
||||
| `reference_id` | Número da NF |
|
||||
| `planned_date` | Data da entrega (filtro principal) |
|
||||
| `driver` | Nome do motorista |
|
||||
| `status` | `'completed'` = entrega paga |
|
||||
| `checkin` | NULL = motorista não registrou chegada |
|
||||
| `route_id` | UUID da operação (UBS SUL, EMAD, etc.) |
|
||||
| Campo | Uso |
|
||||
|-------|-----|
|
||||
| `tracking_id` | PK lógico da entrega |
|
||||
| `reference_id` | Número da NF |
|
||||
| `planned_date` | Data da entrega (filtro principal) |
|
||||
| `driver` | Nome do motorista |
|
||||
| `status` | `'completed'` = entrega paga |
|
||||
| `checkin` | NULL = motorista não registrou chegada |
|
||||
| `route_id` | UUID da operação (UBS SUL, EMAD, etc.) |
|
||||
| `contact_name` | Nome do local (UBS SACOMA, EMAD VELEIROS…) |
|
||||
|
||||
**Regra de pagamento:** `status = 'completed'` AND `checkin IS NOT NULL`
|
||||
@@ -249,18 +225,29 @@ FASE 4 deve implementar:
|
||||
|
||||
## 🎨 Design — padrão da marca
|
||||
|
||||
| Elemento | Cor | Hex |
|
||||
| ----------------- | ------------ | --------- |
|
||||
| Fundo | Preto | `#0a0a0a` |
|
||||
| Cards | Cinza escuro | `#1a1a1a` |
|
||||
| Destaque / botões | Laranja | `#f97316` |
|
||||
| Textos | Branco | `#ffffff` |
|
||||
| Sucesso | Verde | `#22c55e` |
|
||||
| Erro/desconto | Vermelho | `#ef4444` |
|
||||
| Elemento | Cor | Hex |
|
||||
|----------|-----|-----|
|
||||
| Fundo | Preto | `#0a0a0a` |
|
||||
| Cards | Cinza escuro | `#1a1a1a` |
|
||||
| Destaque / botões | Laranja | `#f97316` |
|
||||
| Textos | Branco | `#ffffff` |
|
||||
| Sucesso | Verde | `#22c55e` |
|
||||
| Erro/desconto | Vermelho | `#ef4444` |
|
||||
|
||||
- Fonte mínima 16px desktop / 18px mobile
|
||||
- Botões mínimo 48px altura (acessibilidade touch)
|
||||
- Tema escuro como padrão (toggle disponível no header)
|
||||
- Tema escuro como padrão
|
||||
|
||||
---
|
||||
|
||||
## 👥 Perfis de acesso
|
||||
|
||||
| Perfil | Login | Acesso |
|
||||
|--------|-------|--------|
|
||||
| Admin | email + senha | Tudo |
|
||||
| Gerente | email + senha | Dashboard + Consolidações + PDFs |
|
||||
| Operador | email + senha | Consolidações (criar + validar) |
|
||||
| Motorista | PIN 4 dígitos ou QR | Painel pessoal + baixar próprio PDF |
|
||||
|
||||
---
|
||||
|
||||
@@ -269,4 +256,3 @@ FASE 4 deve implementar:
|
||||
- **NUNCA** versione `.env`, `config/master.key` ou qualquer arquivo com senha
|
||||
- Repositório **PRIVADO** em git.xenserver.com.br
|
||||
- Use sempre `ENV['VARIAVEL']` no código Ruby
|
||||
- Todas as actions protegidas por Pundit (`authorize` obrigatório)
|
||||
|
||||
Reference in New Issue
Block a user