Configuración
API de Configuración
Endpoints para gestionar la configuración a nivel de tenant, incluyendo información de la empresa, ajustes fiscales, personalización del PDF y logotipo.
Obtener Configuración
GET /api/settings
Permiso: config:manage (solo Owner)
Obtiene la configuración del tenant actual. El campo logoUrl se devuelve como una URL prefirmada de S3 (temporal, válida por tiempo limitado).
Respuesta 200 OK:
{
"data": {
"id": "clxyz...",
"companyName": "Acme Solutions S.A. de C.V.",
"email": "contacto@acme.mx",
"phone": "+52 55 1234 5678",
"address": "Av. Reforma 222, Col. Juárez, CDMX",
"logoUrl": "https://s3.amazonaws.com/...presigned...",
"bankInfo": {
"bankName": "BBVA México",
"clabe": "012345678901234567"
},
"defaultNotes": "Cotización válida por 15 días",
"taxRate": "0.16",
"quoteValidityDays": 15,
"currency": "MXN",
"pdfBranding": {
"primaryColor": "#1A56DB",
"accentColor": "#c96b3c",
"fontFamily": "Helvetica",
"headerLayout": "left",
"footerText": "Gracias por su preferencia"
},
"reminderDaysBefore": 3
}
}Errores:
| Status | Error | When |
|---|---|---|
| 403 | "Sin permisos" | El rol no tiene el permiso config:manage |
| 404 | "Negocio no encontrado" | No se encontró el tenant |
Actualizar Configuración
PUT /api/settings
Permiso: config:manage (solo Owner)
Actualiza una o más configuraciones del tenant. Todos los campos son opcionales; solo incluye los que quieras cambiar.
Cuerpo de la solicitud:
{
"companyName": "Acme Solutions S.A. de C.V.",
"phone": "+52 55 1234 5678",
"email": "nuevo@acme.mx",
"address": "Av. Reforma 222, Col. Juárez, CDMX",
"taxRate": 0.16,
"quoteValidityDays": 30,
"currency": "MXN",
"defaultNotes": "Precios sujetos a cambio sin previo aviso",
"bankInfo": {
"bankName": "BBVA México",
"clabe": "012345678901234567"
},
"pdfBranding": {
"primaryColor": "#1A56DB",
"accentColor": "#c96b3c",
"fontFamily": "Helvetica",
"headerLayout": "left",
"footerText": "Gracias por su preferencia"
},
"reminderDaysBefore": 5
}| Field | Type | Required | Description |
|---|---|---|---|
| companyName | string | No | Nombre de la empresa (mínimo 2 caracteres) |
| phone | string | No | Número de teléfono |
| string | No | Correo electrónico válido | |
| address | string | No | Dirección del negocio |
| taxRate | number | No | Tasa de impuesto entre 0 y 1 (ej. 0.16 = 16%) |
| quoteValidityDays | integer | No | Vigencia predeterminada de la cotización en días (1-365) |
| currency | string | No | Código de moneda de 3 letras (ej. MXN, USD, COP) |
| defaultNotes | string | No | Notas predeterminadas para cotizaciones nuevas |
| bankInfo | object | null | No | Datos bancarios (bankName, clabe). Envía null para eliminarlos. |
| pdfBranding | object | null | No | Opciones de estilo del PDF. Envía null para restablecer. |
| pdfBranding.primaryColor | string | No | Color hexadecimal (ej. #1A56DB) |
| pdfBranding.accentColor | string | No | Color hexadecimal (ej. #c96b3c) |
| pdfBranding.fontFamily | string | No | Helvetica, Times o Courier |
| pdfBranding.headerLayout | string | No | left, center o right |
| pdfBranding.footerText | string | No | Texto del pie de página (máximo 200 caracteres) |
| reminderDaysBefore | integer | No | Días antes del vencimiento para enviar recordatorio (1-30) |
Respuesta 200 OK:
{
"data": { ...configuración actualizada del tenant... }
}Efectos secundarios:
- Activa la finalización del paso de onboarding
company_info - Registra una entrada de auditoría con la acción
update
Subir Logotipo
POST /api/settings/logo
Permiso: config:manage (solo Owner)
Sube un logotipo de la empresa mediante datos multipart. La imagen se almacena en S3 y se actualiza el logoUrl del tenant.
Solicitud: multipart/form-data
| Field | Type | Required | Description |
|---|---|---|---|
| logo | File | Yes | Archivo de imagen (PNG, JPG, WebP o SVG). Máximo 2MB. |
Ejemplo con cURL:
curl -X POST "https://cotizera.com/api/settings/logo" \
-H "Cookie: next-auth.session-token=YOUR_TOKEN" \
-F "logo=@/path/to/logo.png"Respuesta 200 OK:
{
"logoUrl": "https://s3.amazonaws.com/...presigned...",
"s3Key": "logos/tenant-id/logo.png"
}Errores:
| Status | Error | When |
|---|---|---|
| 400 | "No se proporcionó un archivo" | Falta el campo logo |
| 400 | "Tipo de archivo no permitido. Use PNG, JPG, WebP o SVG." | Tipo de archivo no válido |
| 400 | "El archivo excede el tamaño máximo de 2MB" | El archivo es demasiado grande |