# API de subida de avatar (#175) — Plan de implementación

> **For Hermes:** implementar por pasos pequeños, con prueba de integración local antes de tocar el código de producción.

**Objetivo:** permitir que Mixbot/Inma asigne o reemplace de forma segura la foto de un autor mediante `POST /wp-json/fea/v1/subir-avatar`, sin depender del wp-admin ni de Rafa.

**Arquitectura:** un mu-plugin nuevo y autónomo en `mu-plugins/`, paralelo a `fea-crear-autor-api.php`. Reutiliza el mismo modelo de autenticación (Application Password autenticada + capacidad `edit_others_posts`). Recibe un `multipart/form-data` con `user_id` exacto e imagen en el campo `avatar`; valida, normaliza a un cuadrado de 512 px, crea el attachment de WordPress y actualiza únicamente el meta ACF `foto_perfil`.

**Decisiones deliberadas de contrato:**
- **Multipart**, no base64: evita codificación innecesaria y usa el manejo seguro nativo de uploads de WordPress.
- **`user_id` obligatorio**, no slug: evita ambigüedades al asignar una imagen a una persona.
- **JPEG, PNG y WebP; máximo 5 MB; mínimo 512×512 px; máximo 4096 px por lado y 16 megapíxeles.**
- Se conserva el attachment previo; la respuesta devuelve `previous_attachment_id` para rollback manual. No se borra ningún avatar anterior.
- La imagen se recorta centrada y se normaliza a **512×512 px** en el servidor.

**Alcance de seguridad:** el endpoint no permite elegir meta, ruta de filesystem, MIME arbitrario ni otro usuario distinto del `user_id` explícito. Requiere autenticación y permiso de editor o superior.

---

### Task 1: Añadir prueba de integración local para el contrato vacío

**Files:**
- Create: `tests/integration/test_subir_avatar_api.sh`

**Step 1:** probar contra el WordPress Docker local que la ruta no está disponible antes de cargar el nuevo mu-plugin.

**Step 2:** el script debe cubrir, tras cargar el plugin: falta de autenticación (401), falta de `user_id` (400), usuario inexistente (404), falta de fichero (400) y una subida correcta a un usuario temporal.

**Step 3:** el caso correcto debe verificar respuesta, attachment creado, meta `foto_perfil` actualizado y que el attachment anterior no se elimina. Debe limpiar el usuario/attachment temporal al terminar.

### Task 2: Implementar el mu-plugin mínimo

**Files:**
- Create: `mu-plugins/fea-subir-avatar-api.php`

**Step 1:** registrar `POST /fea/v1/subir-avatar` y reutilizar una callback de autorización equivalente a la de `crear-autor`.

**Step 2:** validar `user_id` y el fichero `avatar` antes de persistir nada.

**Step 3:** procesar la imagen con APIs nativas de WordPress, normalizarla a 512×512 y crear su attachment con metadata.

**Step 4:** actualizar exclusivamente `foto_perfil` y devolver ID del usuario, attachment nuevo, attachment anterior y URL.

### Task 3: Ejecutar integración local y revisión de seguridad

**Files:**
- Modify only if a test demuestra una necesidad real.

**Step 1:** copiar temporalmente el mu-plugin y el script de prueba a la instalación WordPress Docker local. No tocar producción.

**Step 2:** ejecutar la prueba y verificar que falla de forma esperada antes de implementar, y pasa después.

**Step 3:** ejecutar `php -l` sobre el mu-plugin y revisar `git diff --check` / `git diff`.

**Step 4:** dejar los cambios solo en la rama aislada `feat/subir-avatar-175`; no hacer push, PR ni despliegue sin aprobación explícita de Rafa.
