RELATÓRIO DE COMPATIBILIDADE: FRONTEND PRODUTOR vs API - AgrSis
RELATÓRIO DE COMPATIBILIDADE: FRONTEND PRODUTOR vs API - AgrSis
RESUMO EXECUTIVO
Verificação completa da compatibilidade entre os componentes do wizard do frontend (Nuxt 3) e o controlador da API (Laravel 11) para o sistema de criação de licitações do AgrSis.
Status Geral: ⚠️ INCOMPATIBILIDADES IDENTIFICADAS - Requer correções
1. ANÁLISE POR STEP
STEP 1: BasicInfo - Tipo de Licitação
Frontend Captura:
bidding_type: 'open' | 'closed' ✅product_type_ids: number ✅
API Espera (saveDraft):
bidding_type: string ✅product_type_ids: NÃO RECEBE (campo ignorado)
Função convertToApiFormat:
bidding_type: formData.value.bidding_type, // ✅ Correto
// product_type_ids NÃO É ENVIADO PARA A API
Compatibilidade: ✅ PARCIAL
bidding_typeé mapeado corretamenteproduct_type_idsé capturado no frontend mas NUNCA enviado à API- Impacto: Sem impacto crítico - é apenas filtro de UI, não é armazenado no banco
STEP 2: Products - Lista de Produtos
Frontend Captura (array de produtos):
produtos: Array<{
produtoId: string // ID do produto
produtoNome: string // Nome comercial
quantidade: number // Quantidade
unidade: string // Sigla (ex: kg, L)
measurement_unit_id?: number // ID da unidade
aceita_similar: boolean // Aceita similar
delivery_date?: string // Data de entrega (específica)
marca?: string // Brand (opcional)
principio_ativo?: string // Active ingredient (opcional)
}>
API Espera (convertToApiFormat → saveDraft):
items: Array<{
product_id: number // parseInt(p.produtoId) ✅
quantidade: number // p.quantidade ✅
measurement_unit_id: number // p.measurement_unit_id || 1 ✅
aceita_similar: boolean // p.aceita_similar || false ✅
delivery_date?: string // p.delivery_date ✅
}>
ERRO IDENTIFICADO - Step2Products.vue (linha 121):
quantidade: item.quantity, // ERRO: frontend usa "quantity"
// mas campo no form é "quantidade"
Frontend possui:
interface ProdutoItem {
quantidade: number // Linha 23
...
v-model.number="item.quantity" // Template usa "quantity"!
}
Problema: Inconsistência interna - Template usa item.quantity mas interface declara quantidade
Compatibilidade: 🔴 CRÍTICO
- Frontend envia
quantity(campo inconsistente) - API espera
quantidade - Convertendo para
quantidadeantes de enviar à API - Impacto: Os produtos chegam na API com undefined/0
STEP 3: Deadlines - Prazos e Condições
Frontend Captura:
dataLimite: string // Data ISO (YYYY-MM-DD)
deadlineMode: 'general' | 'specific'
prazoEntrega: number // Dias (se general)
condicaoPagamento: string // avista|parcelado|a_combinar
produtos[].delivery_date: string // Se specific (YYYY-MM-DD)
API Espera (convertToApiFormat):
deadline_date: formData.value.dataLimite // ✅
deadline_mode: formData.value.deadlineMode // ✅
prazo_entrega: formData.value.prazoEntrega // ✅
condicao_pagamento: formData.value.condicaoPagamento // ✅
items[].delivery_date: p.delivery_date // ✅
Validações Frontend (useWizardOrder.ts):
dataLimite:
- Mínimo: 3 dias no futuro ✅
- Máximo: 60 dias ✅
prazoEntrega (general mode):
- Mínimo: 3 dias ✅
- Máximo: 60 dias ✅
delivery_date (specific mode):
- Mínimo: 3 dias ✅
- Máximo: 60 dias ✅
condicaoPagamento:
- Obrigatório ✅
- Valores: avista, parcelado, a_combinar ✅
API Validation (StoreOrderRequest.php):
data_limite_cotacao(CAMPO DIFERENTE!) - espera after:+2 days (3 dias) ✅raio_fornecimento- não vem do Step 3 ❌- Nenhuma validação para deadline_mode, prazo_entrega, condicao_pagamento
ERRO IDENTIFICADO - Mapeamento de Campo:
Frontend envia: deadline_date
StoreOrderRequest espera: data_limite_cotacao
Incompatibilidade detectada no Controller:
'delivery_deadline' => $request->prazo_entrega, // Campo correto ✅
'payment_terms' => $request->condicao_pagamento, // Campo correto ✅
Compatibilidade: 🟡 PARCIAL
- Nomes dos campos estão inconsistentes com o nome esperado
- Validações não cobrem todos os campos
- Impacto: Alguns campos podem ser ignorados ou falhar na validação
STEP 4: Location - Localização e Entrega
Frontend Captura:
freight_type: 'cif' | 'fob' | '' // Modalidade frete
enderecoId: number | null // ID do endereço
raioFornecimento: number // Raio em km
API Espera (convertToApiFormat):
freight_type: formData.value.freight_type // ✅
customer_address_id: formData.value.enderecoId // ✅
supply_radius: formData.value.raioFornecimento // ✅
Validações Frontend:
freight_type: Obrigatório (cif ou fob) ✅enderecoId: Obrigatório ✅raioFornecimento: 10-500 km ✅
API Validation (StoreOrderRequest.php):
raio_fornecimento: required|integer|min:10|max:500 ✅- Faltam validações: freight_type, customer_address_id
Controller (saveDraft):
'customer_address_id' => $request->customer_address_id, // ✅
'supply_radius' => $request->supply_radius, // ✅
'freight_type' => $request->freight_type, // ✅
Compatibilidade: ✅ COMPLETO
- Mapeamento correto
- Validações adequadas
- Campos casam perfeitamente
STEP 5: Review - Revisão Final
Step 5 é apenas visualização. Não envia dados novos.
Compatibilidade: ✅ OK
2. ANÁLISE DA FUNÇÃO convertToApiFormat
convertToApiFormat(status: 'draft' | 'completed' = 'draft')
Campos Enviados:
{
draft_uuid: savedDraftUuid || undefined,
description: 'Rascunho de licitação',
status: status,
bidding_type: formData.value.bidding_type,
customer_address_id: formData.value.enderecoId || undefined,
deadline_date: formData.value.dataLimite || undefined,
supply_radius: formData.value.raioFornecimento || undefined,
deadline_mode: formData.value.deadlineMode || undefined,
prazo_entrega: formData.value.prazoEntrega || undefined,
condicao_pagamento: formData.value.condicaoPagamento || undefined,
freight_type: formData.value.freight_type || undefined,
items: [...] // Produtos
}
Campos que a API RECEBE mas NÃO PROCESSA:
product_type_ids- NÃO ENVIADO (não critica)status- Enviado mas API pode ignorar (usadetermineDraftStatus)description- Enviado como "Rascunho de licitação" (fixo)
Campos OBRIGATÓRIOS na API que podem vir UNDEFINED:
deadline_date- Pode ser undefined ❌items- Array vazio é permitido ✅
3. ANÁLISE DO CONTROLLER (OrderController.php)
Endpoint saveDraft (POST /orders/draft)
Função determineDraftStatus:
private function determineDraftStatus(Request $request): OrderStatus
{
$hasDataLimite = !empty($request->deadline_date);
$hasItems = $request->has('items') && is_array($request->items) && count($request->items) > 0;
if ($hasDataLimite && $hasItems) {
return OrderStatus::PENDING; // Pronto para publicar
}
return OrderStatus::DRAFT; // Incompleto
}
Processamento de Items:
if ($request->has('items') && is_array($request->items) && count($request->items) > 0) {
foreach ($request->items as $item) {
if (isset($item['product_id']) && $item['product_id'] !== null && isset($item['quantidade'])) {
// Cria item
}
}
}
PROBLEMA: Espera campo quantidade mas frontend envia (através de sincronizarFormData):
quantidade: item.quantity, // item.quantity é undefined!
4. PROBLEMAS CRÍTICOS ENCONTRADOS
🔴 CRÍTICO #1: Inconsistência de Campo de Quantidade em Step2
Localização: /apps/producer/components/order/wizard/Step2Products.vue
Problema:
// Interface declara
interface ProdutoItem {
quantidade: number; // Linha 23
}
// Mas template usa
v-model.number="item.quantity" // Linha 222
// E sincronização espera
map(item => ({
quantidade: item.quantity, // UNDEFINED!
}))
Impacto: Quantidade dos produtos chega como undefined/0 na API
Solução:
// Opção 1: Padronizar como "quantidade"
v-model.number="item.quantidade"
// Opção 2: Padronizar como "quantity"
interface ProdutoItem {
quantity: number; // Renomear
}
🔴 CRÍTICO #2: Falta de Validação de Campos no Request
Localização: /apps/api/app/Http/Requests/StoreOrderRequest.php
Problema: StoreOrderRequest não valida:
bidding_typecustomer_address_idfreight_typedeadline_modecondicao_pagamentoproduct_type_ids(se fosse enviado)
Impacto: Dados inválidos podem ser salvos no banco
Solução: Adicionar regras de validação para todos os campos
🟡 CRÍTICO #3: Inconsistência entre StoreOrderRequest e saveDraft
Localização: /apps/api/app/Http/Controllers/Api/OrderController.php (linha 641-679)
Problema:
// StoreOrderRequest espera:
'data_limite_cotacao' // Nome diferente!
// saveDraft recebe:
'deadline_date' // Nome diferente!
Impacto: Os dois endpoints usam convenções de nomes diferentes
Solução: Padronizar nomes de campos em toda a API
🟡 CRÍTICO #4: Campo "description" Fixo no Frontend
Localização: /apps/producer/composables/useWizardOrder.ts (linha 393)
Problema:
description: 'Rascunho de licitação', // Sempre fixo!
Validação: StoreOrderRequest exige:
'description' => 'required|string|min:50|max:1000'
Impacto: Descrição não customizável pelo usuário
Solução: Adicionar campo de descrição no Step 1
🟡 CRÍTICO #5: API Ignora Status Enviado pelo Frontend
Localização: /apps/api/app/Http/Controllers/Api/OrderController.php (linha 651)
Problema:
// Frontend envia
status: 'draft' | 'completed'
// API ignora e calcula automaticamente
'status' => $this->determineDraftStatus($request)
Impacto: Status enviado é completamente ignorado (design questionável)
Solução: Usar determineDraftStatus corretamente (OK) ou validar que frontend não envie status inválido
5. PROBLEMAS DE DESIGN
🔶 DESIGN #1: Validações Duplicadas
Frontend valida em validateStep3(), validateStep4(), etc.
API valida em StoreOrderRequest e determineDraftStatus().
Impacto: Lógica duplicada, difícil de manter
🔶 DESIGN #2: Conversão de Tipos em convertToApiFormat
items: formData.value.produtos.length > 0 ? formData.value.produtos.map(p => ({
product_id: parseInt(p.produtoId), // Conversão aqui
})) : []
Frontend armazena IDs como string, converte para number antes de enviar.
Impacto: Unnecessary conversions, tipo fraco
6. MATRIZ DE COMPATIBILIDADE
| Campo | Frontend | API Espera | Convertido? | Status |
|---|---|---|---|---|
| bidding_type | string | string | ✅ | ✅ OK |
| product_type_ids | number | - | ❌ NÃO ENVIADO | ⚠️ OK |
| produtos.produtoId | string | product_id | ✅ parseInt | ✅ OK |
| produtos.quantidade | - | - | ❌ UNDEFINED | 🔴 ERRO |
| produtos.quantity | number | - | ❌ NÃO MAPEADO | 🔴 ERRO |
| produtos.measurement_unit_id | number | measurement_unit_id | ✅ | ✅ OK |
| produtos.aceita_similar | boolean | aceita_similar | ✅ | ✅ OK |
| produtos.delivery_date | string | delivery_date | ✅ | ✅ OK |
| dataLimite | string | deadline_date | ✅ | ✅ OK |
| deadlineMode | string | deadline_mode | ✅ | ✅ OK |
| prazoEntrega | number | prazo_entrega | ✅ | ✅ OK |
| condicaoPagamento | string | condicao_pagamento | ✅ | ✅ OK |
| freight_type | string | freight_type | ✅ | ✅ OK |
| enderecoId | number | customer_address_id | ✅ | ✅ OK |
| raioFornecimento | number | supply_radius | ✅ | ✅ OK |
| description | string (fixo) | description | ❌ FIXO | 🟡 AVISO |
7. LISTA DE CORREÇÕES NECESSÁRIAS
PRIORIDADE ALTA (Impede funcionamento):
- Frontend Step2Products.vue - Linha 222
- Trocar
item.quantityporitem.quantidade - OU renomear interface e uso consistente
- Trocar
- Frontend Step2Products.vue - Linha 116-129
- Sincronizar nomenclatura de campos
- Backend StoreOrderRequest.php
- Adicionar regras para validar todos os campos
- Especialmente: bidding_type, freight_type, customer_address_id
- Backend OrderController::saveDraft
- Adicionar validação de request (usar Form Request)
- OU aceitar e validar os campos manualmente
PRIORIDADE MÉDIA (Afeta UX/dados):
- Frontend useWizardOrder.ts - Linha 393
- Permitir que usuário customize "description"
- Adicionar campo no Step 1
- Frontend Step2Products.vue - Interface ProdutoItem
- Adicionar interface tipada para evitar erros
- Usar tipos genéricos corretamente
- Backend OrderController
- Padronizar nomes de campos entre endpoints
data_limite_cotacaovsdeadline_date
PRIORIDADE BAIXA (Melhorias):
- Ambos Validação de dados
- Considerar single source of truth para regras
- Usar JSON Schema ou similar
- Backend determineDraftStatus
- Adicionar mais lógica de validação
- Considerar validar relationship (endereço existe?)
- Frontend convertToApiFormat
- Adicionar tipo explícito para return
- Documentar transformações
8. RECOMENDAÇÕES
Curto Prazo (Corrigir erros):
- Corrigir inconsistência de
quantidadevsquantity - Adicionar validações faltantes na API
- Padronizar nomes de campos
Médio Prazo (Melhorar design):
- Usar TypeScript mais rigorosamente (strict mode)
- Criar interfaces compartilhadas frontend-backend
- Documentar contrato API
Longo Prazo (Arquitetura):
- Considerar geração automática de tipos (OpenAPI)
- Implementar validação schema única (JSON Schema)
- Adicionar testes E2E que validem frontend-backend
9. CONCLUSÃO
Status Geral: 🔴 CRÍTICO - NÃO RECOMENDADO PARA PRODUÇÃO
O sistema possui 2 erros críticos que impedem o funcionamento correto:
- Campo quantidade não é mapeado corretamente
- Falta validação completa na API
Recomenda-se corrigir antes de qualquer deploy em produção.
Tempo estimado para correção: 2-3 horas de desenvolvimento