DETALHES TÉCNICOS - Problemas de Compatibilidade
DETALHES TÉCNICOS - Problemas de Compatibilidade
PROBLEMA #1: Campo quantidade vs quantity em Step2
Localização 1: Interface Definition
Arquivo: /apps/producer/components/order/wizard/Step2Products.vueLinha: 21-25
interface ProdutoItem {
produto: Product | null
quantidade: number // ← INTERFACE DECLARA "quantidade"
aceita_similar: boolean
}
Localização 2: Template Usage
Arquivo: /apps/producer/components/order/wizard/Step2Products.vueLinha: 222
<input
id="quantidade-${index}"
v-model.number="item.quantity" <!-- ← TEMPLATE USA "quantity" -->
type="number"
min="1"
step="0.01"
class="form-control text-sm"
placeholder="Ex: 100"
/>
Localização 3: Synchronization Function
Arquivo: /apps/producer/components/order/wizard/Step2Products.vueLinha: 115-129
const sincronizarFormData = () => {
formData.value.produtos = produtos.value
.filter(item => item.produto !== null)
.map(item => ({
produtoId: item.produto!.id.toString(),
produtoNome: item.produto!.commercial_name,
quantidade: item.quantity, // ← TENTA ACESSAR "item.quantity"
unidade: item.produto!.measurement_unit?.sigla || '',
measurement_unit_id: item.produto!.measurement_unit_id || undefined,
aceita_similar: item.aceita_similar,
marca: item.produto!.brand?.description || '',
principio_ativo: item.produto!.active_ingredient?.description || '',
}))
}
Expected Flow
- Interface declara:
ProdutoItem.quantidade: number - Template deve usar:
v-model.number="item.quantidade" - Sync envia:
{ quantidade: item.quantidade }
Actual Flow
- Interface declara:
ProdutoItem.quantidade: number - Template usa:
v-model.number="item.quantity"← WRONG - Sync envia:
{ quantidade: item.quantity }← item.quantity is UNDEFINED
Fix Option A: Rename to "quantity"
// Step 1: Update interface
interface ProdutoItem {
quantidade: number // REMOVE
quantity: number // ADD
}
// Step 2: Template already correct
v-model.number="item.quantity" // OK
// Step 3: Sync already correct
quantidade: item.quantity, // OK
Fix Option B: Rename to "quantidade"
// Step 1: Interface already correct
interface ProdutoItem {
quantidade: number // KEEP
}
// Step 2: Update template
v-model.number="item.quantidade" // CHANGE from "quantity"
// Step 3: Sync already correct
quantidade: item.quantidade, // CHANGE from "item.quantity"
PROBLEMA #2: Missing API Validation
Affected Endpoint
File: /apps/api/app/Http/Controllers/Api/OrderController.phpMethod: saveDraft() (Line 576)
Current Request Validation
File: /apps/api/app/Http/Requests/StoreOrderRequest.php
public function rules(): array
{
return [
// These are validated
'description' => 'required|string|min:50|max:1000',
'data_limite_cotacao' => 'required|date|after:+2 days',
'raio_fornecimento' => 'required|integer|min:10|max:500',
'items' => 'required|array|min:1',
'items.*.product_id' => 'required|integer|exists:products,id',
'items.*.quantidade' => 'required|integer|min:1',
'items.*.measurement_unit_id' => 'required|integer|exists:measurement_units,id',
// These are NOT validated
// bidding_type
// customer_address_id
// freight_type
// deadline_mode
// condicao_pagamento
// prazo_entrega (delivery_deadline)
// payment_terms
];
}
Missing Validations Needed
1. bidding_type Validation
// Should validate but doesn't
'bidding_type' => 'required|in:open,closed',
Frontend sends: open or closed (Line 19, useWizardOrder.ts)
Database expects: Enum (OrderStatus or similar)
Current issue: No validation = invalid data could be saved
2. customer_address_id Validation
// Should validate but doesn't
'customer_address_id' => 'required|integer|exists:customer_addresses,id',
Frontend sends: Integer ID (Line 70, Step4Location.vue) Database expects: Must exist in customer_addresses table Current issue: No validation = orphaned addresses could be created
3. freight_type Validation
// Should validate but doesn't
'freight_type' => 'required|in:cif,fob',
Frontend sends: cif, fob, or empty string (Line 43, useWizardOrder.ts)
Database expects: Enum value
Current issue: Empty string could be saved as valid
4. deadline_mode Validation
// Should validate but doesn't
'deadline_mode' => 'in:general,specific',
Frontend sends: general or specific (Line 37, useWizardOrder.ts)
Database expects: Enum
Current issue: No validation = invalid mode could be saved
5. condicao_pagamento Validation
// Should validate but doesn't
'condicao_pagamento' => 'in:avista,parcelado,a_combinar',
Frontend sends: Valid values (Line 32-35, Step3Deadlines.vue) Database expects: Valid enum value Current issue: No validation = custom invalid values could be saved
6. prazo_entrega Validation
// Should validate when deadline_mode is 'general'
'prazo_entrega' => 'required_if:deadline_mode,general|integer|min:3|max:60',
Frontend sends: Number of days (Line 39, useWizardOrder.ts) Database expects: Valid days (3-60) Current issue: Frontend validates but API doesn't
Recommended Complete Validation
public function rules(): array
{
return [
// Original validations
'description' => 'nullable|string|min:50|max:1000', // Allow null (auto-filled)
'deadline_date' => 'required|date|after:+2 days', // FIELD NAME CHECK
'supply_radius' => 'required|integer|min:10|max:500',
// Items validation
'items' => 'array|min:0', // Allow empty for drafts
'items.*.product_id' => 'required|integer|exists:products,id',
'items.*.quantidade' => 'required|integer|min:1',
'items.*.measurement_unit_id' => 'required|integer|exists:measurement_units,id',
'items.*.aceita_similar' => 'boolean',
'items.*.delivery_date' => 'nullable|date|after:deadline_date',
// NEW: Missing validations
'bidding_type' => 'in:open,closed',
'customer_address_id' => 'integer|exists:customer_addresses,id',
'freight_type' => 'in:cif,fob',
'deadline_mode' => 'in:general,specific',
'condicao_pagamento' => 'in:avista,parcelado,a_combinar',
'prazo_entrega' => 'integer|min:3|max:60',
];
}
PROBLEMA #3: Fixed "description" Field
Location
File: /apps/producer/composables/useWizardOrder.tsLine: 393
const convertToApiFormat = (status: 'draft' | 'completed' = 'draft') => {
return {
description: 'Rascunho de licitação', // ← ALWAYS FIXED
// ... other fields
}
}
Problem
- User cannot customize description
- API validates:
min:50|max:1000 - Fixed text is always the same for all orders
Expected Behavior
Users should be able to write custom description like:
- "Herbicida para soja - safra 2024"
- "Adubo NPK para milho"
- "Sementes de arroz variedade BRS"
Solution
Add field to Step 1:
// WizardFormData interface (add)
export interface WizardFormData {
// ... existing fields
descricao: string // NEW FIELD
}
// useWizardOrder state (add)
formData.value = {
descricao: '', // NEW
// ... other fields
}
// convertToApiFormat (change)
const convertToApiFormat = () => {
return {
description: formData.value.descricao || 'Rascunho de licitação',
// ... other fields
}
}
// Step 1 validation (add)
const validateStep1 = (): boolean => {
const novosErros: WizardErros = {}
if (!formData.value.descricao || formData.value.descricao.length < 50) {
novosErros.descricao = 'Descrição deve ter no mínimo 50 caracteres'
}
if (formData.value.descricao.length > 1000) {
novosErros.descricao = 'Descrição deve ter no máximo 1000 caracteres'
}
// ... rest of validation
}
Step1BasicInfo.vue (add)
<!-- After product types selection -->
<div class="form-group">
<label for="descricao" class="form-label required">
Descrição da Licitação
</label>
<textarea
id="descricao"
v-model="formData.descricao"
class="form-control"
rows="4"
placeholder="Descreva o que você está solicitando..."
maxlength="1000"
></textarea>
<p class="text-xs text-agrsis-neutral-600 mt-1">
{{ formData.descricao?.length || 0 }}/1000 caracteres
</p>
<p v-if="erros.descricao" class="text-sm text-red-600 mt-1">
{{ erros.descricao }}
</p>
</div>
PROBLEMA #4: Inconsistent Field Names Between Endpoints
Issue
Frontend and API use different field naming conventions
StoreOrderRequest expects:
'data_limite_cotacao' // Snake case PT-BR
'raio_fornecimento' // Snake case PT-BR
saveDraft receives:
'deadline_date' // Snake case EN
'supply_radius' // Snake case EN
'bidding_type' // Snake case EN
'deadline_mode' // Snake case EN
'prazo_entrega' // Snake case PT-BR (mixed!)
'condicao_pagamento' // Snake case PT-BR (mixed!)
Order Model
// Database schema uses:
- bidding_type // EN
- customer_address_id // EN
- deadline_date // EN
- supply_radius // EN
- deadline_mode // EN
- delivery_deadline // EN
- payment_terms // EN
- freight_type // EN
Recommendation
Standardize on snake_case English throughout:
bidding_type✓customer_address_id✓deadline_date✓supply_radius✓deadline_mode✓delivery_deadline✓payment_terms✓freight_type✓
PROBLEMA #5: Status Field Handling
Issue
Frontend sends status, API ignores it
Frontend (useWizardOrder.ts, Line 572)
const apiData = convertToApiFormat('completed') // Sends status
return {
status: 'draft' | 'completed', // Explicitly in convertToApiFormat
// ... other fields
}
API (OrderController.php, Line 651)
'status' => $this->determineDraftStatus($request), // Ignores frontend's status!
determineDraftStatus Logic
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; // Auto-determined
}
return OrderStatus::DRAFT; // Auto-determined
}
Current Behavior
- Frontend sends: status = 'completed'
- API receives: status field
- API ignores: Calculates its own status
- Result: Frontend's status is discarded
Recommendation
Either:
Option A: Keep current behavior (auto-determine)
// Frontend shouldn't send status
const convertToApiFormat = () => {
return {
// DO NOT include status
description: 'Rascunho de licitação',
// ... other fields
}
}
Option B: Use frontend's status
// API should use frontend's status
'status' => $request->input('status', OrderStatus::DRAFT),
Current approach (A) is fine, just don't send status from frontend.
Testing Checklist
Unit Tests Needed
-
test_quantity_field_is_correctly_mapped()- Verify item.quantity syncs -
test_description_validation()- Min 50, max 1000 chars -
test_bidding_type_validation()- Only open/closed -
test_freight_type_validation()- Only cif/fob -
test_customer_address_exists()- Address ID must exist
Integration Tests Needed
-
test_complete_order_creation_flow()- All steps → API -
test_draft_saved_with_partial_data()- Only basic info -
test_draft_published_requires_complete_data()- All mandatory fields -
test_invalid_data_rejected()- API rejects invalid inputs
End-to-End Tests Needed
- Create order with 5 products → Verify quantities saved
- Submit invalid bidding_type → Verify validation error
- Create draft without address → Verify allowed
- Publish draft without items → Verify validation error
Last Updated: 2024-12-22