# 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.