Files
feadulta/docs/plans/2026-07-16-subir-avatar-api-175.md

56 lines
3.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.