main local y origin/main son dos historias sin ancestro comun (ver #194). Analisis del agente: de las 46 commits solo-en-local, el unico contenido que no esta ya reflejado en origin/main via el snapshot de julio (PR #179) son estos 10 ficheros de docs/ (guias, handoffs, planes, benchmark, revisiones de issues). Copiados tal cual desde main con "git show main:docs/X > docs/X". Redactada una password SSH y una password cPanel/FTP en texto plano que tenia handoff-carta-46956-2026-06-17.md (servidor CDMON antiguo) antes de subirlo -- ver .env, nunca en docs versionados. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
6.2 KiB
Handoff técnico para Rafa — issues #174 y #175
Alcance
Preparación técnica solamente. No aplicar en producción desde aquí.
Issue #174 — cierre autónomo de la carta (publicar + rotar)
Regla funcional confirmada por Inma/Mixbot
La rotación que ya funcionó hoy manualmente por WP REST API para la carta 735 es esta, y solo para el post ES:
- nueva carta → añadir cat 6 (
carta actual) - la que estaba en cat 6 → quitar cat 6, añadir cat 22 (
semana pasada), manteniendo cat 21 (archivo acumulativo) - la que estaba en cat 22 → quitar cat 22, dejar solo cat 21
- no tocar traducciones en este paso
Decisión pendiente para Rafa
Hay dos caminos válidos:
Opción A — adaptar rotate_cartas.php a ES-only
Pros:
- reutiliza lógica ya existente y conocida en el repo
- más coherente con el toolkit actual de scripts
- fácil dejar
DRY-RUN+APPLY=1
Contras:
- hay que modificar el script actual porque hoy rota todos los idiomas
- si Mixbot publica por REST y la rotación la hace otro script aparte, el flujo queda repartido en dos piezas
Opción B — que Mixbot haga la rotación por WP REST API
Pros:
- ya está validado en vivo hoy
- mantiene toda la operación editorial en el mismo sitio donde ya se publica la carta
- evita acoplar la decisión editorial a un script server-side adicional
Contras:
- la lógica queda fuera del repo de scripts PHP si no se documenta bien
- conviene dejarla muy explícita para no divergirse del comportamiento esperado
Recomendación técnica
Mi lectura: cualquiera vale, pero elegiría según quién vaya a mantenerlo:
- si Rafa quiere la lógica versionada y centralizada en el repo, mejor A:
rotate_cartas.phpES-only - si Inma/Mixbot ya tienen el flujo sólido y prefieren autonomía total desde su lado, mejor B: REST API desde Mixbot, con la lógica documentada en el issue/runbook
Si Rafa elige A (script ES-only), propuesta concreta
Crear una variante mínima o adaptar rotate_cartas.php con estas reglas:
- entrada:
CARTA=<es_id> - lookup solo en idioma
es - localizar:
actual_es= post con cat 6pasada_es= post con cat 22nueva_es=CARTA
- operaciones:
pasada_espierde 22, conserva 21actual_espierde 6, gana 22, conserva 21nueva_esgana 6 y conserva/gana 21
- nunca tocar posts EN/FR/IT/PT
- mantener modo
DRY-RUN
Dry-run deseable para Rafa
Salida ideal del dry-run:
nueva_es=#54495 -> +6 (+21 si faltaba)actual_es=#54254 -> -6 +22 (mantiene 21)pasada_es=#53984 -> -22 (mantiene 21)translations untouched
Decisión funcional que conviene dejar escrita
Para evitar ambigüedad futura, dejar explícito en el issue o en el script:
21es acumulativa y la conservan todas las cartas archivables6y22son mutuamente excluyentes- la rotación editorial inicial afecta solo al ES
- las traducciones rotan/publican en un paso posterior independiente
Issue #175 — endpoint subir-avatar
Base ya existente
El sistema actual ya tiene casi todo:
- frontend lee
user_meta('foto_perfil') face_crop_avatar.pyya resuelve recorte/centrado de cararegen_avatars.phpya existe para regeneración/ajustes- caso real listo para probar: Silvia Martínez Cano,
user_id=1112,slug=silvia-mtnz
Contrato recomendado
Yo le propondría a Rafa este contrato por simplicidad operativa:
Endpoint
POST /wp-json/fea/v1/subir-avatar
Auth
La misma Application Password que ya usa crear-autor (#166), con el mismo criterio de permisos.
Identificador
user_id mejor que slug.
Motivo:
- Mixbot ya lo tiene en el roster
- evita ambigüedades por slug cambiado / transliteraciones / colisiones
- simplifica el lookup
Formato de entrada
multipart/form-data mejor que base64.
Motivo:
- más natural para subir imágenes
- menos overhead
- encaja mejor con
media_handle_sideload/ manejo típico WP - más fácil de depurar que base64
Campo esperado
user_id(obligatorio)file(obligatorio)
Opcionalmente:
crop=server|clientsi Rafa quiere dejar ambas puertas abiertas, aunque probablemente es overkill de entrada
Recomendación de procesamiento
Mi recomendación clara: que el endpoint NO haga face-crop complejo en la primera versión.
Mejor v1:
- Mixbot/Inma mandan la imagen ya cuadrada
- estándar objetivo: 1254x1254 (el que ya usáis)
- el endpoint solo:
- valida usuario
- guarda attachment
- actualiza
foto_perfil - devuelve
attachment_id,user_id,url
Pros:
- mucho menos riesgo y menos dependencias server-side
- evita meter OpenCV/Pillow/lógica pesada dentro del endpoint
- más fácil de testear e idempotente
- si mañana queréis face-crop automático, se añade en v2
Comportamiento recomendado del endpoint
- requiere login + permiso tipo
edit_others_posts(igual filosofía quecrear-autor) - valida que
user_idexista - acepta solo imagen (
jpg,jpeg,png,webpsi WP lo admite ahí) - crea attachment en Media Library
- hace
update_user_meta($user_id, 'foto_perfil', $attachment_id) - respuesta JSON:
user_iddisplay_nameattachment_idurlupdated: true
Idempotencia mínima útil
No hace falta obsesionarse en v1, pero sí conviene:
- si se vuelve a subir otra foto para el mismo
user_id, simplemente reemplazar elfoto_perfilal nuevo attachment - opcional: si el hash del fichero coincide con el ya asignado, devolver
updated:false
Caso piloto sugerido
Primera prueba con:
user_id=1112slug=silvia-mtnz- imagen ya recortada por Inma/Mixbot a 1254x1254
Así la prueba valida solo el endpoint, no el pipeline de crop.
Cierres administrativos
Por estado funcional, salvo sorpresa:
#166→ cerrable#168→ cerrable#170→ cerrable
Recomendación final para Rafa
Si quiere minimizar trabajo y riesgo:
- #174: usar la lógica que ya validó Mixbot hoy, y solo portar al repo si él prefiere centralizar
- #175: endpoint mínimo con
user_id+ multipart + imagen ya cuadrada a 1254x1254
Eso deja la autonomía mucho más cerca sin meterse en una refactor rara.