# Convenciones del Sistema VEX

Guía obligatoria para cualquiera que escriba código en este proyecto.

## 1. Idioma

Todo en español: nombres de clases, métodos, variables, rutas, vistas,
mensajes y comentarios. Las únicas excepciones son los nombres que impone
Laravel (`handle`, `boot`, `rules`, `authorize`, `up`, `down`, `casts`) y las
columnas heredadas de la base anterior que ya están en las migraciones.

## 2. Comentarios

El comentario explica **por qué**, no **qué**. Si dice lo mismo que el código,
sobra.

```php
// ❌ Suma los pagos
$total = array_sum($pagos);

// ✅ Se comparan montos redondeados: sin esto, una diferencia de 0.000001
//    dejaba órdenes marcadas como pendientes aunque estuvieran cobradas.
if (Dinero::cubre($abonado, $costo)) { … }
```

Cada clase abre con un bloque que explica su papel y, cuando corresponde, qué
problema del sistema anterior resuelve. Cada regla de negocio no evidente
lleva su explicación encima.

## 3. Formato

- Una etiqueta o instrucción por línea. Nada de amontonar varias cosas en una
  misma línea para ahorrar espacio.
- Al cerrar una etiqueta, la siguiente empieza en línea nueva.
- Indentación de 4 espacios en PHP y Blade; 4 en CSS y JS.
- Líneas de hasta ~110 caracteres.
- Separadores de sección en las clases largas:

```php
    /* ==================================================================
     | Título de la sección
     * ================================================================*/
```

## 4. Estructura

| Capa | Responsabilidad |
|---|---|
| `Http/Controllers` | Recibir la petición, autorizar, delegar, responder. **Nada de lógica de negocio.** |
| `Http/Requests` | Validar y normalizar la entrada. Mensajes en español, escritos para quien está en el mostrador. |
| `Services` | Toda la lógica de negocio y las transacciones. |
| `Models` | Relaciones, `scopes`, `casts` y cálculos sobre el propio registro. |
| `Policies` | Quién puede hacer qué sobre un registro concreto. |
| `Support` | Utilidades sin estado (`Dinero`, `Telefono`, `Ciclo`, `Codigo`, `Geo`). |

Un controlador que abra una transacción o escriba en `caja_movimientos` está
haciendo el trabajo de un servicio.

## 5. Dinero

- **Siempre** por `App\Support\Dinero`: `redondear()`, `formato()`, `cubre()`,
  `saldo()`, `desdeFormulario()`.
- Nunca comparar montos con `==` ni con `>=` directo.
- Nunca truncar centavos con `(int)`.

## 6. Movimientos de caja

- **Solo** `CajaService` los crea o los borra.
- Nunca deducir nada del texto del `concepto`: para eso están `orden_id`,
  `caja_maritima_id` y `origen`.
- Un movimiento con `cierre_id` está cuadrado y **no se toca**.

## 7. Permisos

- Puerta de pantalla: middleware `permiso:modulo,nivel` en la ruta.
- Permiso sobre un registro concreto: `$this->authorize('accion', $modelo)`.
- En las vistas: `@puede('modulo', 'nivel') … @endpuede` y `@admin … @endadmin`.
- Toda consulta que liste órdenes, bultos o clientes pasa por el alcance de
  oficina (`scopeDeOficinas`, `scopeSeleccionablesPor`).

Recordar los tres estados del alcance: `null` = ve todo, `[]` = no ve nada,
`[1,4]` = solo esas. Confundir el segundo con el primero abre todo el sistema.

## 8. Consultas

- `with()` siempre que la vista recorra relaciones. `Model::preventLazyLoading`
  está activo fuera de producción y hará fallar la pantalla si falta.
- Agregados con `withSum` / `withCount`, nunca dentro de un bucle.
- Paginar los listados largos (`config('vex.por_pagina')`).

## 9. Vistas Blade

```blade
<x-layouts.app>
    <x-slot:titulo>Título de la pantalla</x-slot:titulo>
    <x-slot:subtitulo>Contexto breve</x-slot:subtitulo>

    <x-slot:acciones>
        <a class="boton" href="…"><x-icono nombre="mas" /> Acción principal</a>
    </x-slot:acciones>

    …contenido…
</x-layouts.app>
```

- Clases del sistema de diseño (`resources/css/vex.css`): `.tarjeta`, `.kpi`,
  `.boton`, `.distintivo`, `.tabla`, `.aviso`, `.campo`, `.entrada`,
  `.rejilla--*`, `.pestanas`, `.modal`, `.progreso`, `.facil__*`.
- Iconos: `<x-icono nombre="paquete" />`. Nunca emojis en la interfaz.
- Dinero: `@dinero($monto)`. Peso: `@peso($libras)`.
- Fechas: `$fecha->translatedFormat('d M Y · h:i A')`.
- Toda tabla necesita su estado vacío (`.tabla__vacia` o `.vacio`).
- Toda acción destructiva lleva `data-confirmar="…"` en el formulario.

## 10. Pantallas de calle (ruteros y verificador)

Usan `layouts/facil.blade.php` y las clases `.facil*`. Las usan personas de
45 a 60 años, de pie, con el teléfono en una mano y un paquete en la otra.

- Nada de tablas ni de columnas: tarjetas grandes.
- Letra desde 1.15rem, botones de 62px de alto mínimo.
- Cada paso es una dirección propia, para que el botón "atrás" funcione.
- Icono **y** palabra en cada botón, nunca solo el icono.

## 11. Nombres de rutas

`modulo.accion` en español: `entregas.index`, `maritimo.caja.actualizar`,
`finanzas.corte`. Los parámetros usan el nombre del modelo en minúscula
(`{orden}`, `{caja}`, `{paquete}`).

## 12. Auditoría

Toda operación que cree, modifique o elimine algo relevante llama a
`AuditoriaService::registrar()` con acción, módulo, detalle legible y el
modelo afectado.
