From 146aa3e762a08670ec6cfb31ef50170e6219e1d24cab257b38d0daadd5fa8fbf Mon Sep 17 00:00:00 2001 From: victor Date: Mon, 15 Jun 2026 21:17:14 -0300 Subject: [PATCH] =?UTF-8?q?Corre=C3=A7=C3=B5es=20para=20funcionamento=20do?= =?UTF-8?q?=20login=20adm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 2 +- CLAUDE.md | 125 ++++++++++++++++++ README.md | 2 +- Rakefile | 2 + app/controllers/admin/usuarios_controller.rb | 2 +- app/controllers/dashboard_controller.rb | 7 +- app/controllers/users/sessions_controller.rb | 8 +- app/models/application_record.rb | 3 + app/models/entrega.rb | 2 +- app/models/user.rb | 2 +- app/services/pdf/base_pdf.rb | 4 +- app/views/admin/configuracoes/index.html.erb | 2 +- .../pagamento_fechado.html.erb | 2 +- .../consolidacoes/preview_holerite.html.erb | 2 +- app/views/devise/passwords/edit.html.erb | 44 ++++++ app/views/devise/passwords/new.html.erb | 47 +++++++ app/views/devise/sessions/new.html.erb | 8 +- app/views/layouts/_navbar.html.erb | 4 +- app/views/layouts/application.html.erb | 2 +- app/views/motorista/sessoes/new.html.erb | 2 +- config/application.rb | 2 +- config/initializers/devise.rb | 2 - config/initializers/inflections.rb | 6 + ...01000004_create_consolidacao_motoristas.rb | 2 +- ...0101000005_create_consolidacao_entregas.rb | 2 +- db/seeds.rb | 12 +- 26 files changed, 262 insertions(+), 36 deletions(-) create mode 100644 CLAUDE.md create mode 100644 Rakefile create mode 100644 app/models/application_record.rb create mode 100644 app/views/devise/passwords/edit.html.erb create mode 100644 app/views/devise/passwords/new.html.erb create mode 100644 config/initializers/inflections.rb diff --git a/.env.example b/.env.example index f109ba6..62f8f4d 100644 --- a/.env.example +++ b/.env.example @@ -38,4 +38,4 @@ SMTP_DOMAIN=gade.com.br # ── App ─────────────────────────────────────────────────────── APP_HOST=localhost:3000 -APP_NAME=Gade Logística +APP_NAME=Reem Logística diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..de05f33 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,125 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project overview + +**Reem Logística** is a Rails 7 web application for controlling delivery costs for **Gade Hospitalar** (account_id: 95907). It manages consolidations of driver payments across delivery routes (UBS SUL, UBS LESTE, EMAD, STS, SAD, etc.). + +## Commands + +All commands run inside Docker. The PostgreSQL database lives externally (not in docker-compose). + +```bash +# Start +docker-compose up -d + +# Rails console +docker-compose exec app bundle exec rails console + +# Run migrations +docker-compose exec app bundle exec rails db:migrate + +# Seed (creates admin + test drivers) +docker-compose exec app bundle exec rails db:seed + +# Logs +docker-compose logs -f app + +# Tests (RSpec) +docker-compose exec app bundle exec rspec +docker-compose exec app bundle exec rspec spec/models/consolidacao_spec.rb # single file + +# Rake task (runs manually what the cron job runs hourly) +docker-compose exec app bundle exec rake historico:atualizar + +# Activate the hourly cron job on the server +docker-compose exec app bundle exec whenever --update-crontab +``` + +## Setup from scratch + +```bash +cp .env.example .env +# Edit .env: set DB_HOST, DB_PASSWORD, and generate SECRET_KEY_BASE with: +# openssl rand -hex 64 +docker-compose build --no-cache +docker-compose up -d +docker-compose exec app bundle exec rails db:create db:migrate db:seed +``` + +Default credentials (change in production): `admin@gade.com` / `Gade@2026!` + +## Critical constraint: read-only external table + +The table `public.db_reem_simplerout_2026` is owned by an external system (SimpleRoute) that updates it every hour. **NEVER** create migrations for it, and never run INSERT/UPDATE/DELETE/DROP/TRUNCATE on it. + +`Entrega` (app/models/entrega.rb) maps to this table and enforces `readonly? = true`. All queries go through its scopes — the most important being `.pagas` (`status='completed' AND checkin IS NOT NULL`), which defines payment eligibility. + +## Architecture + +### Data flow + +1. External system writes to `db_reem_simplerout_2026` hourly +2. `Atualizar HistoricoEstimadoJob` (triggered by Whenever cron every hour) counts paid deliveries per driver and writes to `historico_estimados` +3. Admins/managers create **Consolidações** (payment batches) covering a date range + list of drivers +4. A 3-step wizard classifies each delivery per driver (Normal/Retirada/Bônus/Desconto toggles) +5. Finalizing a consolidation sends WhatsApp (Twilio) and email notifications to drivers +6. Drivers view their own panel at `/motorista` using a 4-digit PIN or QR code from their printed payslip + +### Key models + +| Model | Table | Notes | +|---|---|---| +| `Entrega` | `db_reem_simplerout_2026` | Read-only. External data. | +| `Consolidacao` | `consolidacoes` | Payment batch. Enum status: `rascunho/finalizada/arquivada`. Soft-delete via `deleted_at`. | +| `ConsolidacaoMotorista` | `consolidacao_motoristas` | Join: which drivers are in a consolidation. | +| `ConsolidacaoEntrega` | `consolidacao_entregas` | Each classified delivery. Enum tipo: `normal/retirada/bonus/desconto`. | +| `HistoricoEstimado` | `historico_estimados` | Snapshot of hourly estimated values per driver. | +| `Configuracao` | `configuracoes` | Key-value store for prices and feature flags. Access via `Configuracao.valor('chave')`. | +| `AuditoriaLog` | `auditoria_logs` | Audit trail. Controllers include `Auditavel` concern and call `auditar!(:acao, registro)`. | +| `User` | `users` | Devise auth. Roles: `admin/gerente/operador/motorista`. Drivers may have no email — they log in via `pin_code` (4 digits, unique per driver) or `login_token` (QR). | + +### Authorization + +Pundit policies in `app/policies/`. `ApplicationController` includes `Pundit::Authorization` and calls `authenticate_user!` on every action. The motorista panel (`/motorista/**`) uses a separate session mechanism (`motorista/sessoes_controller.rb`) — drivers are NOT authenticated via Devise. + +### Two login flows for drivers + +- `/auth/login` (Devise, Fase 2) — PIN tab on the standard login page +- `/motorista/login` (Fase 8) — dedicated numeric keypad, used by QR codes printed on payslips. Prefer this for mobile. Both use `pin_code`. + +### PDF generation + +`app/services/pdf/` contains three classes: +- `BasePdf` — shared black/orange header and footer layout +- `RelatorioMotoristaPdf` — detailed delivery table per driver +- `HoleritePdf` — payslip style + embedded QR code (via `rqrcode`/`chunky_png`) linking to `/motorista/acesso/:token` + +### The consolidation wizard + +`/consolidacoes/:id/wizard` → `/consolidacao_entregas/validar` → `/consolidacao_entregas/revisar` + +- **Passo 1** (wizard): pick a driver. Shows progress per driver. +- **Passo 2** (validar): color-coded toggle buttons per delivery (orange=Normal, dark orange=Retirada, white=Bônus, black=Desconto). Toggle individual or mass-classify. Stimulus controller (`validacao_controller.js`) handles real-time totals and progress. +- **Passo 3** (revisar): summary for the selected driver, then move to the next driver or save as draft. + +Finalizing is blocked (server-side + UI) until all drivers have all eligible deliveries classified. + +### Notifications (NotificacaoService) + +Controlled by `Configuracao` flags `notificacao_whatsapp` and `notificacao_email`. Failures are rescued and logged — they never abort the finalization. WhatsApp requires Twilio ENV vars + driver `telefone` field in `+5511999998888` format. + +## Design system + +Dark theme (default). Colors: background `#0a0a0a`, cards `#1a1a1a`, accent/buttons `#f97316` (orange), text `#ffffff`, success `#22c55e`, error `#ef4444`. Minimum font 16px desktop / 18px mobile. Touch targets minimum 48px height. + +## Environment variables + +All config comes from `.env` (never hardcoded). Key variables: +- `DB_HOST` / `DB_NAME` / `DB_USER` / `DB_PASSWORD` — PostgreSQL connection +- `DB_EXISTING_ACCOUNT_ID` — filters `db_reem_simplerout_2026` to Gade's account (default: 95907) +- `SECRET_KEY_BASE` — generate with `openssl rand -hex 64` +- `APP_HOST` — used in QR code URLs and notification links +- `TWILIO_*` — WhatsApp notifications (optional) +- `SMTP_*` — Email notifications (optional, only activates if `SMTP_USERNAME` is set) diff --git a/README.md b/README.md index e0d5ad1..c6090b8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 🚛 Gade Logística — Sistema de Controle de Custos +# 🚛 Reem Logística — Sistema de Controle de Custos Sistema web para controle de custos de entregas hospitalares da **Gade Hospitalar**. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..2c151ac --- /dev/null +++ b/Rakefile @@ -0,0 +1,2 @@ +require_relative "config/application" +Rails.application.load_tasks diff --git a/app/controllers/admin/usuarios_controller.rb b/app/controllers/admin/usuarios_controller.rb index 1de528c..08041e0 100644 --- a/app/controllers/admin/usuarios_controller.rb +++ b/app/controllers/admin/usuarios_controller.rb @@ -4,7 +4,7 @@ class Admin::UsuariosController < ApplicationController def index authorize User - @usuarios = policy_scope(User).order(:nome).page(params[:page]).per(20) + @usuarios = policy_scope(User).order(:nome).limit(200) @roles = User.roles.keys end diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index c05c87a..2e46eda 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -47,14 +47,15 @@ class DashboardController < ApplicationController .count .sort_by { |_, v| -v } .first(6) + .to_h # Evolução diária do mês (para Chart.js) @grafico_diario = build_grafico_diario(entregas_mes, config[:entrega]) # Consolidações do mês - @consolidacoes_mes = Consolidacao.do_mes(@data_referencia) - @consolidacoes_abertas = @consolidacoes_mes.where(status: :aberta).count - @consolidacoes_fechadas = @consolidacoes_mes.where(status: :fechada).count + @consolidacoes_mes = Consolidacao.ativas.where(created_at: @mes_inicio.beginning_of_day..@mes_fim.end_of_day) + @consolidacoes_abertas = @consolidacoes_mes.where(status: :rascunho).count + @consolidacoes_fechadas = @consolidacoes_mes.where(status: :finalizada).count # Histórico estimado mais recente @historico_recente = HistoricoEstimado.order(created_at: :desc).limit(5) diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index edf3e97..489dfc9 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -23,7 +23,7 @@ class Users::SessionsController < Devise::SessionsController def after_sign_in_path_for(resource) case resource.role when 'motorista' - motorista_path + motorista_dashboard_path else dashboard_path end @@ -40,13 +40,13 @@ class Users::SessionsController < Devise::SessionsController private def handle_pin_login - pin = params[:user][:pin].to_s.strip + pin = params[:pin].to_s.strip user = User.find_by(pin_code: pin, role: 'motorista') - if user&.active? + if user&.ativo? sign_in(user) AuditoriaLog.registrar(user: user, acao: 'login_pin', entidade: 'User', dados_novos: { detalhes: "" }, request: request) - redirect_to motorista_path, notice: "Bem-vindo, #{user.nome_display}!" + redirect_to motorista_dashboard_path, notice: "Bem-vindo, #{user.nome_display}!" else flash.now[:alert] = 'PIN inválido ou motorista inativo.' @pin_login = true diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000..b440b80 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/app/models/entrega.rb b/app/models/entrega.rb index 1c4ed77..fd6f5f0 100644 --- a/app/models/entrega.rb +++ b/app/models/entrega.rb @@ -1,6 +1,6 @@ # app/models/entrega.rb # -# Model de LEITURA para a tabela existente da Gade Hospitalar. +# Model de LEITURA para a tabela existente da Reem Transporte. # NUNCA criar migration para esta tabela. # NUNCA executar INSERT, UPDATE, DELETE ou DROP nesta tabela. # diff --git a/app/models/user.rb b/app/models/user.rb index e6dedaf..74f623f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,7 +1,7 @@ # app/models/user.rb class User < ApplicationRecord devise :database_authenticatable, - :registerable, + :recoverable, :rememberable, :validatable diff --git a/app/services/pdf/base_pdf.rb b/app/services/pdf/base_pdf.rb index 4ce267e..e957dc1 100644 --- a/app/services/pdf/base_pdf.rb +++ b/app/services/pdf/base_pdf.rb @@ -30,7 +30,7 @@ module Pdf @pdf.fill_rectangle [-40 + 0, @pdf.cursor + 40], 8, 70 # faixa laranja lateral @pdf.fill_color 'FFFFFF' - @pdf.text_box 'GADE HOSPITALAR', + @pdf.text_box 'REEM TRANSPORTE', at: [10, @pdf.cursor + 20], size: 20, style: :bold @pdf.fill_color LARANJA @pdf.text_box 'Sistema de Controle de Custos Logísticos', @@ -44,7 +44,7 @@ module Pdf @pdf.repeat(:all) do @pdf.bounding_box [0, 20], width: @pdf.bounds.width do @pdf.fill_color CINZA - @pdf.text "Gerado em #{Time.current.strftime('%d/%m/%Y %H:%M')} · Gade Hospitalar — documento interno", + @pdf.text "Gerado em #{Time.current.strftime('%d/%m/%Y %H:%M')} · Reem Transporte — documento interno", size: 8, align: :center @pdf.fill_color '000000' end diff --git a/app/views/admin/configuracoes/index.html.erb b/app/views/admin/configuracoes/index.html.erb index 2e184cb..4661a99 100644 --- a/app/views/admin/configuracoes/index.html.erb +++ b/app/views/admin/configuracoes/index.html.erb @@ -47,7 +47,7 @@

Account ID

-

95907 (Gade Hospitalar)

+

95907 (Reem Transporte)

Atualização

diff --git a/app/views/consolidacao_mailer/pagamento_fechado.html.erb b/app/views/consolidacao_mailer/pagamento_fechado.html.erb index a4ed83d..e663777 100644 --- a/app/views/consolidacao_mailer/pagamento_fechado.html.erb +++ b/app/views/consolidacao_mailer/pagamento_fechado.html.erb @@ -2,7 +2,7 @@
-

GADE HOSPITALAR

+

REEM TRANSPORTE

Sistema de Logística

diff --git a/app/views/consolidacoes/preview_holerite.html.erb b/app/views/consolidacoes/preview_holerite.html.erb index 5a22669..fcdf70b 100644 --- a/app/views/consolidacoes/preview_holerite.html.erb +++ b/app/views/consolidacoes/preview_holerite.html.erb @@ -5,7 +5,7 @@
-

GADE HOSPITALAR

+

REEM TRANSPORTE

Holerite de Pagamento — Entregas

diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb new file mode 100644 index 0000000..bc5f0df --- /dev/null +++ b/app/views/devise/passwords/edit.html.erb @@ -0,0 +1,44 @@ +<%# app/views/devise/passwords/edit.html.erb — Redefinir senha (link do e-mail) %> +<% content_for :title, 'Nova senha' %> + +
+
+ +
+
+ 🔒 +
+

Definir nova senha

+
+ +
+ <%= form_with(url: user_password_path, scope: :user, method: :put, data: { turbo: false }) do |f| %> + <%= f.hidden_field :reset_password_token, value: params[:reset_password_token] %> +
+
+ <%= f.label :password, 'Nova senha', class: 'block text-sm font-medium text-gray-300 mb-1.5' %> + <%= f.password_field :password, autofocus: true, autocomplete: 'new-password', + class: 'w-full px-4 py-3 bg-[#0a0a0a] border border-white/10 rounded-xl text-white + focus:outline-none focus:border-[#f97316] focus:ring-1 focus:ring-[#f97316] text-base' %> +

Mínimo de 6 caracteres

+
+
+ <%= f.label :password_confirmation, 'Confirmar nova senha', class: 'block text-sm font-medium text-gray-300 mb-1.5' %> + <%= f.password_field :password_confirmation, autocomplete: 'new-password', + class: 'w-full px-4 py-3 bg-[#0a0a0a] border border-white/10 rounded-xl text-white + focus:outline-none focus:border-[#f97316] focus:ring-1 focus:ring-[#f97316] text-base' %> +
+ + <%= f.submit 'Salvar nova senha', + class: 'w-full py-3.5 bg-[#f97316] hover:bg-orange-500 text-white font-semibold + rounded-xl transition-colors cursor-pointer text-base min-h-[48px]' %> +
+ <% end %> + +

+ <%= link_to '← Voltar para o login', new_user_session_path, + class: 'text-sm text-[#f97316] hover:text-orange-400 transition-colors' %> +

+
+
+
diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb new file mode 100644 index 0000000..b4083c1 --- /dev/null +++ b/app/views/devise/passwords/new.html.erb @@ -0,0 +1,47 @@ +<%# app/views/devise/passwords/new.html.erb — Esqueci a senha (estilizada) %> +<% content_for :title, 'Recuperar senha' %> + +
+
+ +
+
+ 🔑 +
+

Recuperar senha

+

Informe seu e-mail para receber as instruções

+
+ +
+ <%= form_with(url: user_password_path, scope: :user, method: :post, data: { turbo: false }) do |f| %> +
+
+ <%= f.label :email, 'E-mail', class: 'block text-sm font-medium text-gray-300 mb-1.5' %> + <%= f.email_field :email, + autofocus: true, autocomplete: 'email', + class: 'w-full px-4 py-3 bg-[#0a0a0a] border border-white/10 rounded-xl text-white + placeholder-gray-600 focus:outline-none focus:border-[#f97316] focus:ring-1 + focus:ring-[#f97316] transition-colors text-base', + placeholder: 'seu@email.com' %> +
+ + <%= f.submit 'Enviar instruções', + class: 'w-full py-3.5 bg-[#f97316] hover:bg-orange-500 text-white font-semibold + rounded-xl transition-colors cursor-pointer text-base min-h-[48px]' %> +
+ <% end %> + +

+ <%= link_to '← Voltar para o login', new_user_session_path, + class: 'text-sm text-[#f97316] hover:text-orange-400 transition-colors' %> +

+
+ +

+ ⚠️ O envio de e-mail depende da configuração SMTP no servidor.
+ Sem SMTP, peça ao administrador para redefinir sua senha. +

+ +

Reem Transporte © <%= Date.today.year %>

+
+
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 4b36eb8..df1c2b3 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -10,7 +10,7 @@ d="M13 16V6a1 1 0 00-1-1H4a1 1 0 00-1 1v10a1 1 0 001 1h1m8-1a1 1 0 01-1 1H9m4-1V8a1 1 0 011-1h2.586a1 1 0 01.707.293l3.414 3.414a1 1 0 01.293.707V16a1 1 0 01-1 1h-1m-6-1a1 1 0 001 1h1M5 17a2 2 0 104 0m-4 0a2 2 0 114 0m6 0a2 2 0 104 0m-4 0a2 2 0 114 0"/>
-

Gade Logística

+

Reem Logística

Sistema de Controle de Custos

@@ -40,7 +40,7 @@ <%# Login por e-mail %>
- <%= form_with(url: user_session_path, method: :post) do |f| %> + <%= form_with(url: user_session_path, scope: :user, method: :post, data: { turbo: false }) do |f| %>
<%= f.label :email, 'E-mail', class: 'block text-sm font-medium text-gray-300 mb-1.5' %> @@ -82,7 +82,7 @@ <%# Login por PIN %>
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb index b77e638..f3ff62d 100644 --- a/app/views/layouts/_navbar.html.erb +++ b/app/views/layouts/_navbar.html.erb @@ -15,7 +15,7 @@
G
-

Gade Hospitalar

+

Reem Transporte

Logística

@@ -75,7 +75,7 @@
G
- Gade Logística + Reem Logística
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index ac28d0d..8b6ffe7 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -5,7 +5,7 @@ - <%= content_for?(:title) ? "#{yield(:title)} | Gade Logística" : "Gade Logística" %> + <%= content_for?(:title) ? "#{yield(:title)} | Reem Logística" : "Reem Logística" %> <%# Tailwind via CDN em desenvolvimento — compilar em produção %> diff --git a/app/views/motorista/sessoes/new.html.erb b/app/views/motorista/sessoes/new.html.erb index 1b646dd..f50c42b 100644 --- a/app/views/motorista/sessoes/new.html.erb +++ b/app/views/motorista/sessoes/new.html.erb @@ -7,7 +7,7 @@ <%# Logo %>
G
-

Gade Logística

+

Reem Logística

Digite seu PIN de 4 números

diff --git a/config/application.rb b/config/application.rb index 1b1fa42..ce91ec5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -4,7 +4,7 @@ require "rails/all" Bundler.require(*Rails.groups) require "dotenv/load" if defined?(Dotenv) -module GadeLogistica +module ReemLogistica class Application < Rails::Application config.load_defaults 7.1 diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 3c7f29e..93e0ff2 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -11,6 +11,4 @@ Devise.setup do |config| config.email_regexp = /\A[^@\s]+@[^@\s]+\z/ config.reset_password_within = 6.hours config.sign_out_via = :delete - config.responder.error_status = :unprocessable_entity - config.responder.redirect_status = :see_other end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 0000000..c9f330a --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,6 @@ +# Ensina ao Rails os plurais corretos em português. +# Sem isso: consolidacao → "consolidacaos" e configuracao → "configuracaos" +ActiveSupport::Inflector.inflections(:en) do |inflect| + inflect.irregular 'consolidacao', 'consolidacoes' + inflect.irregular 'configuracao', 'configuracoes' +end diff --git a/db/migrate/20260101000004_create_consolidacao_motoristas.rb b/db/migrate/20260101000004_create_consolidacao_motoristas.rb index 0387f7c..18c8298 100644 --- a/db/migrate/20260101000004_create_consolidacao_motoristas.rb +++ b/db/migrate/20260101000004_create_consolidacao_motoristas.rb @@ -1,7 +1,7 @@ class CreateConsolidacaoMotoristas < ActiveRecord::Migration[7.1] def change create_table :consolidacao_motoristas do |t| - t.references :consolidacao, null: false, foreign_key: true + t.references :consolidacao, null: false, foreign_key: { to_table: :consolidacoes } t.string :motorista_nome, null: false # driver da tabela existente t.decimal :valor_total, precision: 10, scale: 2, default: 0 diff --git a/db/migrate/20260101000005_create_consolidacao_entregas.rb b/db/migrate/20260101000005_create_consolidacao_entregas.rb index 56476d6..04fff5a 100644 --- a/db/migrate/20260101000005_create_consolidacao_entregas.rb +++ b/db/migrate/20260101000005_create_consolidacao_entregas.rb @@ -1,7 +1,7 @@ class CreateConsolidacaoEntregas < ActiveRecord::Migration[7.1] def change create_table :consolidacao_entregas do |t| - t.references :consolidacao, null: false, foreign_key: true + t.references :consolidacao, null: false, foreign_key: { to_table: :consolidacoes } t.string :tracking_id, null: false # FK lógico para db_reem_simplerout_2026 t.string :motorista_nome, null: false t.integer :tipo, null: false, default: 0 diff --git a/db/seeds.rb b/db/seeds.rb index fed4106..42b7981 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,5 +1,5 @@ # db/seeds.rb -# Dados iniciais do sistema Gade Hospitalar +# Dados iniciais do sistema Reem Transporte # Execute com: bundle exec rails db:seed puts "🌱 Criando dados iniciais..." @@ -30,7 +30,7 @@ configs = [ { chave: 'preco_desconto', valor: '15.00', descricao: 'Valor descontado por problema (R$)' }, { chave: 'notificacao_whatsapp', valor: 'false', descricao: 'Notificações via WhatsApp (true/false)' }, { chave: 'notificacao_email', valor: 'false', descricao: 'Notificações via e-mail (true/false)' }, - { chave: 'empresa_nome', valor: 'Gade Hospitalar', descricao: 'Nome da empresa exibido no sistema' }, + { chave: 'empresa_nome', valor: 'Reem Transporte', descricao: 'Nome da empresa exibido no sistema' }, ] configs.each do |cfg| @@ -52,9 +52,9 @@ puts " ⚠️ ALTERE A SENHA DO ADMIN NO PRIMEIRO ACESSO!" { nome: 'Maria Santos', pin: '5678' }, { nome: 'Carlos Souza', pin: '9012' }, ].each do |m| - User.find_or_create_by!(nome: m[:nome], role: :motorista) do |u| - u.pin_code = m[:pin] - u.ativo = true - end + u = User.find_or_initialize_by(nome: m[:nome], role: :motorista) + u.pin_code = m[:pin] + u.ativo = true + u.save!(validate: false) puts " ✅ Motorista: #{m[:nome]} / PIN: #{m[:pin]}" end