# Lubricantes Petronas

## Propósito

Este módulo administra el catálogo de lubricantes que se muestra en la landing de Petronas.

El diseño actual prioriza:

- mantener el CRUD restringido a administradores root
- validar estrictamente título, estado e imagen
- exponer en web pública sólo lubricantes activos
- seleccionar columnas explícitas para evitar respuestas sobredimensionadas
- resolver imágenes en lote para evitar consultas por cada tarjeta

## Endpoints

### Admin

- `GET /api/admin/lubricantes`
- `POST /api/admin/lubricantes`
- `GET /api/admin/lubricantes/{id}/edit`
- `PUT /api/admin/lubricantes/{id}`
- `DELETE /api/admin/lubricantes/{id}`

### Público

- `GET /endpoint/lubricantes`

## Permisos y roles

Los endpoints administrativos requieren:

- `auth:sanctum`
- `abilities:admin`
- `uuid-check`
- `rootUser`

El endpoint público no requiere autenticación y sólo devuelve registros activos.

## Inputs

### Crear lubricante

`multipart/form-data`

- `titulo`: requerido, texto de 2 a 120 caracteres
- `estado`: requerido, `0` o `1`
- `imagen`: requerida, imagen `webp`, `jpg`, `jpeg` o `png`, mínimo `393x224`

### Actualizar lubricante

`multipart/form-data`

- `titulo`: requerido, texto de 2 a 120 caracteres
- `estado`: requerido, `0` o `1`
- `imagen`: opcional, imagen `webp`, `jpg`, `jpeg` o `png`, mínimo `393x224`

Si en edición el frontend envía la URL de imagen actual, el backend la descarta antes de validar. Sólo se procesa la imagen cuando llega como archivo o base64 válido.

### Listado admin

Parámetros soportados:

- `page[size]`: opcional, entero entre `1` y `100`
- `page[number]`: opcional, entero mayor o igual a `1`
- `sort`: opcional, una o más columnas entre `id`, `titulo`, `estado`, `created_at`; permite prefijo `-` para descendente
- `filter[id]`: opcional, entero
- `filter[titulo]`: opcional, texto
- `filter[estado]`: opcional, `0` o `1`

Filtros o columnas de orden no soportados responden `422`.

## Output público

```json
[
  {
    "id": 1,
    "titulo": "Petronas Syntium",
    "slug": "petronas-syntium",
    "estado": 1,
    "imagen": "https://dominio.test/storage/uploads/lubricantes/syntium@large.webp"
  }
]
```

## Comportamiento de negocio

1. Admin root crea o edita lubricantes desde el panel.
2. El backend normaliza espacios del título y deriva el slug desde ese título.
3. Las imágenes se almacenan bajo `uploads/lubricantes`.
4. El endpoint público lista únicamente lubricantes activos, ordenados del más nuevo al más antiguo.
5. La web de Petronas consume ese endpoint para renderizar las tarjetas públicas.

## Notas de seguridad

- El CRUD administrativo está protegido por `rootUser` para evitar IDOR entre admins sin privilegio root.
- `estado` es binario y no acepta números arbitrarios.
- El listado admin rechaza filtros y sorts desconocidos.
- El endpoint público no expone timestamps ni otros metadatos administrativos.
- Los errores de imagen y validación se devuelven por el flujo estándar de Laravel sin exponer detalles internos.

## Notas de performance

- Los listados usan columnas explícitas.
- La imagen pública se resuelve con una consulta a `image_settings` y una consulta a `images`, no por accessor por fila.
- El listado admin limita `page[size]` a `100`.
- La consulta pública no carga modelos Eloquent completos porque no necesita mutators ni relaciones.

## Cómo correr los tests relacionados

Desde `copetrol-api-and-public`:

```bash
php8.1 artisan test --filter=LubricantesAdminTest
php8.1 artisan test --filter=LubricantesEndpointTest
php8.1 artisan test --filter=LubricantePayloadServiceTest
```
