Files
Reem-Notas/CLAUDE.md
victor 19b7cc838f Pagamento por checkout + consolidação por veículo (em vez de rota)
Regra de pagamento:
- Entrega.pagas agora exige status='completed' E checkout preenchido
  (antes era checkin). Afeta dashboard, painel do motorista, job 1h e
  elegibilidade das consolidações de forma consistente.

Veículo no lugar de rota na consolidação:
- migration troca consolidacoes.route_ids por vehicle_ids (jsonb + gin)
- Entrega: da_veiculo/veiculos_unicos; contar_pagas usa vehicle
- new.html.erb: filtro "Veículos" (multi-select por vehicle)
- validar.html.erb: mostra o veículo em vez do código da rota
- filtros/elegibilidade do controller passam a usar vehicle_ids

Docs/diagnóstico atualizados.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 02:17:25 -03:00

6.3 KiB

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).

# 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

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 checkout IS NOT NULL), which defines payment eligibility. Consolidations filter eligible deliveries by vehicle (vehicle column → Consolidacao#vehicle_ids), not by route.

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)