Add nuxt-skills and update auto quotes to use new policy API structure

- Add nuxt-skills (vue, nuxt, nuxt-ui) to .claude/skills/
- Create useCustomerSelection() composable for managing insured/buyer selection
- Create usePolicyApi() composable for policy API operations
- Update auto quote components to use insured/buyer instead of client
- Update vehicle fields: remove valorVehiculo, add market_value, requested_value, rc_limits
- Make chassis_number and engine_number optional
- Update auto quote types and composables to match new API structure
- Update auto quote page to submit to policy API with new structure
This commit is contained in:
2026-04-27 14:56:53 -05:00
parent 67482f6629
commit a2eb1f3789
154 changed files with 10346 additions and 51 deletions

View File

@@ -0,0 +1,137 @@
/**
* Composable for managing customer selection in quote flows
* Handles insured and buyer selection with validation
*/
export function useCustomerSelection() {
const selectedCustomer = ref<any>(null) // Auto-generated type from useCustomer
const useSameForBuyer = ref(true)
const selectedBuyer = ref<any>(null)
/**
* Convert customer-service customer to policy-service insured/buyer
* Maps customer fields to policy-service structure
*/
const toPolicyPerson = (customer: any) => {
if (customer.customer_type === 'corporate') {
return {
type: 'corporate',
company_name: customer.legal_name,
ruc: customer.ruc,
legal_rep_name: customer.legal_rep_name,
legal_rep_document: customer.legal_rep_document_id,
email: customer.email,
phone: customer.phone,
address: customer.address
}
}
return {
type: 'individual',
name: `${customer.first_name} ${customer.last_name}`.trim(),
date_of_birth: customer.birth_date,
document_id: customer.document_id,
email: customer.email,
phone: customer.phone,
address: customer.address
}
}
/**
* Get insured person from selected customer
*/
const insured = computed(() => {
if (!selectedCustomer.value) return null
return toPolicyPerson(selectedCustomer.value)
})
/**
* Get buyer person (either same as insured or different)
*/
const buyer = computed(() => {
if (useSameForBuyer.value) {
return insured.value
}
if (!selectedBuyer.value) return null
return toPolicyPerson(selectedBuyer.value)
})
/**
* Validate customer has required fields for policy submission
*/
const validateCustomer = (customer: any) => {
const missing: string[] = []
if (customer.customer_type === 'corporate') {
if (!customer.legal_name) missing.push('legal_name')
if (!customer.ruc) missing.push('ruc')
if (!customer.legal_rep_name) missing.push('legal_rep_name')
if (!customer.legal_rep_document_id) missing.push('legal_rep_document_id')
} else {
if (!customer.first_name) missing.push('first_name')
if (!customer.last_name) missing.push('last_name')
if (!customer.birth_date) missing.push('birth_date')
if (!customer.document_id) missing.push('document_id')
}
return { valid: missing.length === 0, missing }
}
/**
* Check if insured is valid
*/
const isInsuredValid = computed(() => {
if (!selectedCustomer.value) return false
return validateCustomer(selectedCustomer.value).valid
})
/**
* Check if buyer is valid
*/
const isBuyerValid = computed(() => {
if (useSameForBuyer.value) {
return isInsuredValid.value
}
if (!selectedBuyer.value) return false
return validateCustomer(selectedBuyer.value).valid
})
/**
* Get validation errors
*/
const validationErrors = computed(() => {
const errors: { insured: string[]; buyer: string[] } = { insured: [], buyer: [] }
if (selectedCustomer.value) {
const validation = validateCustomer(selectedCustomer.value)
errors.insured = validation.missing
}
if (!useSameForBuyer.value && selectedBuyer.value) {
const validation = validateCustomer(selectedBuyer.value)
errors.buyer = validation.missing
}
return errors
})
/**
* Reset selection
*/
function reset() {
selectedCustomer.value = null
selectedBuyer.value = null
useSameForBuyer.value = true
}
return {
selectedCustomer,
selectedBuyer,
useSameForBuyer,
insured,
buyer,
isInsuredValid,
isBuyerValid,
validationErrors,
reset
}
}