Skip to content

feat: aplicación Documentate bajo /documentate/ (armazón y primeras vistas) - #280

Merged
erseco merged 23 commits into
mainfrom
feat/app-documentate
Sep 8, 2026
Merged

feat: aplicación Documentate bajo /documentate/ (armazón y primeras vistas)#280
erseco merged 23 commits into
mainfrom
feat/app-documentate

Conversation

@erseco

@erseco erseco commented Sep 1, 2026

Copy link
Copy Markdown
Member

Qué es

Documentate como aplicación: una página en /documentate/ desde la que un documento oficial recorre todo su ciclo sin pasar por wp-admin, con tres perfiles y el reparto de trabajo que pidió el servicio. wp-admin sigue existiendo y hace lo mismo que antes; la app es el camino recomendado.

Los tres perfiles y el circuito

Perfil Quién es Qué hace
Área usuario con ámbito (categoría) Crea el documento, rellena su parte y adjunta el fichero
Gestión documental rol nuevo «Gestión documental» (capacidad documentate_gestionar) Completa los datos oficiales y lo pasa a administración, o lo devuelve
Administración manage_options Aprueba y publica, o devuelve a gestión o al área
Borrador ──► En gestión ──► En revisión ──► Aprobado ──► Archivado
   ▲              │               │
   └──────────────┴───────────────┘   devolver (siempre con motivo)

Los tipos que no pasan por gestión van directos del borrador a revisión. «Devuelto» no es un estado: es una marca sobre el borrador, con quién lo devolvió, cuándo y por qué; se limpia al reenviarlo. Toda la tabla de transiciones vive en Documentate_Transiciones y ningún guardado puede saltársela (ni el formulario de wp-admin, ni la edición rápida, ni un autoguardado, ni una petición fabricada).

El documento 0, partido por bloques

El atributo rol='gestion' en los marcadores de la plantilla decide quién ve y quién puede escribir cada campo, con herencia en bloques y subbloques:

  • propuestagasto.odt: la introducción y el Bloque I (objeto, líneas de actuación, destinatarios, alcance) son del área; el Bloque II (importe, partida presupuestaria, proveedores de servicios, suministros y expertos con sus conceptos) es de gestión.
  • resolucion.odt: el área aporta título, objeto y anexos; gestión añade nº de resolución, fecha, expediente y órgano firmante, y redacta antecedentes, fundamentos y resuelvo.

Al área no se le pintan esos campos y tampoco puede escribirlos aunque los envíe a mano, cambie el tipo o inyecte contenido. Gestión y administración lo ven y editan todo. Los totales de la propuesta (concepto, bruto, IGIC, IRPF y resumen) se calculan solos.

La aplicación

  • Bandejas por perfil: «Mis documentos» para el área; «Mis documentos» y «Para revisar» para gestión (todo lo que ha entrado en el circuito, de cualquier área); «Para revisar» y «Todos los documentos» para administración, con filtro por área. Contadores, chips de estado, filtro rápido que esconde filas según se escribe, marca de adjunto y fila resaltada con el motivo cuando el documento vuelve.
  • Ficha: avisos según el estado, datos del área y datos oficiales, fichero, actividad con comentarios y un carril con el recorrido del documento, las acciones disponibles y las descargas.
  • Editor: nombre interno corto con el prefijo del tipo (RES, PG, CONV…) separado del título oficial, campos por rol, anotaciones internas de gestión, zona de arrastre para el fichero (PDF, ODT o DOCX, hasta 20 MB) y los botones de transición que correspondan.
  • Diálogos: confirmación antes de enviar, pasar o aprobar; motivo obligatorio al devolver, como en Registro de Visitas. Sin JavaScript el formulario sigue funcionando y el servidor rechaza una devolución sin motivo.
  • Previsualizar PDF y descargar PDF, ODT o DOCX desde la propia app, reutilizando la maquinaria de wp-admin (funciona también en Playground con el proxy de Collabora).
  • La app ocupa todo el ancho de la ventana y se apaña en móvil.

Correo y actividad

Cada paso deja un evento en la actividad del documento (con el motivo cuando lo hay) y avisa por correo a quien toca: a gestión cuando entra un documento, al área cuando se le devuelve con el motivo, a administración cuando algo espera aprobación y al autor cuando se aprueba. La actividad y los comentarios de un documento solo los lee quien tiene permiso sobre ese documento.

Datos para probarlo

Documentate_Demo_App siembra doce documentos repartidos por tipo, área, autor y estado —borrador, devuelto por gestión, devuelto por administración, en gestión, en revisión, aprobado y archivado—, con los campos rellenos según quién los haya tocado, adjuntos, comentario y actividad fechada. Se vuelve a sembrar con:

npx @wordpress/env run cli --config=.wp-env.docker.json \
  wp eval-file wp-content/plugins/documentate/scripts/seed-demo-app.php

Las cuentas de prueba (admin, editor1, author1, subscriber1, contraseña password) salen etiquetadas por perfil en la pantalla de acceso y en el selector «Probar como…» de la barra de administración.

Informe de capturas

make capturas recorre la aplicación con los tres perfiles en ordenador y en móvil y deja capturas/informe.html con 52 capturas comentadas: entrada por perfil, alta, adjunto, envío con confirmación, bandeja de gestión, datos oficiales, devolución con motivo, documento devuelto y corregido, paso a administración, aprobación, previsualización y descargas, actividad, el documento 0 con proveedores y totales, wp-admin y el selector de perfiles.

Seguridad

Auditoría final con tres revisiones independientes (seguridad, flujo, pruebas) y sus 26 hallazgos corregidos. Entre ellos: la actividad ya no se filtra por consultas genéricas de comentarios, los adjuntos se sirven por un endpoint con permiso y nombre no adivinable, la siembra de ejemplo no depende de una cabecera de la petición, y la capacidad de gestión va a un rol propio en vez de a todos los editores del sitio (con migración desde la versión anterior).

Sin traducciones

El plugin es solo para España: las 400 llamadas de i18n pasan a literales en español y desaparece toda la cadena de traducción (languages/, scripts de composer, objetivos de Makefile, paso de gettext en CI, regla de PHPCS y cabeceras del plugin). Añadir una cadena ya no obliga a regenerar el .pot.

Validación

Comprobación Resultado
make test OK · 2480 tests, 15 975 aserciones
make lint limpio
make check-plugin sin errores
npm run test:unit-js 7 suites, 106 tests, con mínimos de cobertura por módulo
E2E 93 pasan · los especiales de la app (flujo, roles, descargas) al 100 %
PHPMD ninguna violación nueva respecto a main

Dos E2E antiguos de wp-admin fallan solo en el entorno local de desarrollo, por datos que otro spec deja en la base y por TinyMCE Advanced instalado en ese sitio; ni el spec ni el código que ejercitan cambian en esta rama, y en CI están en verde.

Documentación

README, ARCHITECTURE, AGENTS, CLAUDE y readme.txt al día, más dos guías para el equipo: docs/flujo-documentos.md (el circuito y los perfiles) y docs/campos-por-rol.md (cómo marcar campos de gestión al editar una plantilla ODT).

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

WordPress Playground Preview

The changes in this pull request can previewed and tested using a WordPress Playground instance.

Open WordPress Playground Preview

Comment thread includes/app/class-documentate-app.php Fixed
Comment thread includes/app/class-documentate-app-adjuntos.php Fixed
Comment thread includes/app/class-documentate-app-adjuntos.php Fixed
Comment thread includes/app/class-documentate-app-adjuntos.php Fixed
Comment thread includes/app/class-documentate-app-adjuntos.php Fixed
Comment thread includes/app/class-documentate-app-lista.php Fixed
First slice of Documentate as an application, following the shell
pattern of the Registro de Visitas app: one WordPress page (created
idempotently at /documentate/) carries the [documentate_app] shortcode;
the shell paints its own header with the institutional mark and role
chip, a tab bar, the sheet and a one-line footer, and the stylesheet
hides the theme chrome under body.documentate-app with the same visual
vocabulary (shield-blue primary, tonal chips, pill buttons).

Views in this slice, resolved from query arguments under the single URL:
- List (my documents / all documents): status counters, status filter
  chips and document rows with type, updated date and status chip.
  Scope rules mirror the admin list: administrators see everything, a
  scoped user their category tree, an unscoped restricted user nothing.
- Detail: read-only field summary with a status chip and a link into
  the wp-admin editor, guarded by edit_post (scope applies).
- New document: type + name form that creates a locked-type draft and
  redirects to the editor; the scope fallback files it under the
  creator's area.

Access is gated to logged-in users with edit_posts; visitors get a
sign-in notice. Spanish translations added for every new string.
App
- New edit view (vista=editar) that reuses the sections metabox and saves
  through wp_update_post, so the workflow, content writer and meta saver
  run exactly as in wp-admin; a draft can be sent for review from the app.
- "Documentate" node in the admin bar linking to /documentate/.
- Request guards of the create/save handlers extracted into small helpers
  (nonce, permission, posted fields, redirect) to keep NPath complexity
  under the PHPMD threshold flagged by code scanning.

Dev tooling
- scripts/mu-plugins/documentate-dev-tools.php: seeds test users for
  every profile (admin, área editor, gestora, subscriber) and shows a
  profile switcher, wired into wp-env (mu-plugins mapping + User Switching
  plugin) and the Playground blueprint.
- Demo seeder: get_demo_document_ids() looks the documents up directly and
  falls back to the admin author, so scoped users no longer hide them.

Fixes
- TinyMCE filters no longer call get_current_screen() on the front end
  (fatal when the app rendered a rich field); the app page is detected via
  Documentate_App_Shell::is_app_page().

Tests & docs
- tests/e2e/specs/documentate-app.spec.js covers admin bar, create/save/
  send flow, editor scope rules, subscriber and visitor gates; shared
  WP-CLI/login helpers in tests/e2e/fixtures/site.js.
- Unit tests for the app handlers, the TinyMCE wiring on the app page and
  the demo seeder fallback.
- Testing skill (.agents/skills/testing, .claude/skills/testing) and the
  AGENTS.md rule: coverage never below 90 % and no tricks to inflate it;
  codecov.yml targets updated accordingly.
- Documentate_Roles: capacidad documentate_gestionar (editor + administrador),
  etiquetas de rol; se retira en uninstall.
- Documentate_Estados: estado en_gestion, post states, sin Quick Edit.
- Documentate_Transiciones: tabla de transiciones por estado y rol, motivo
  obligatorio al devolver, marca «devuelto», eventos; regla 0 en el workflow
  para que ningún guardado salte la tabla (incluido autosave y papelera).
- Bloqueos por rol: gestión edita en gestión, el área solo borradores.
- Documentate_Actividad (eventos y comentarios) y Documentate_Documento
  (nombre interno, anotaciones, devuelto, adjunto, prefijo del tipo).
- Ámbito: gestión ve los documentos que han entrado en el circuito.
- Notificaciones en español para gestión, devoluciones y aprobación.
- Metabox de gestión extraído a Documentate_Workflow_Metabox; motivo en
  wp-admin; guardia en Makefile contra dos PHPUnit simultáneos.
- Tests unitarios para todo lo anterior.
- Atributo rol='gestion' en los marcadores (con herencia en bloques y
  subbloques), propagado por el extractor y el conversor de esquema.
- Documentate_Campos_Rol: qué campos ve cada rol y si un tipo pasa por
  gestión documental; el área no ve los campos oficiales y tampoco puede
  escribirlos aunque los envíe.
- La metabox de secciones agrupa «Datos oficiales · los completa gestión
  documental» y marca esas filas.
- propuestagasto.odt: introducción y Bloque I del área; Bloque II
  (importe, partida, proveedores, conceptos) de gestión, con títulos
  limpios. resolucion.odt: nº, fecha, expediente y órgano firmante nuevos
  y articulado como campos de gestión.
- Tipos de documento: prefijo (RES, PG, CONV…) y «Pasa por gestión
  documental», con distintivo de rol en el esquema.
- documentate-calculos.js: totales por concepto, bruto, IGIC/IRPF y
  resumen de la propuesta calculados solos.
- Tests unitarios, de generación y jest para todo lo anterior.
App
- Bandejas: «Mis documentos» para el área, «Para revisar» para gestión
  (todo lo que ha entrado en el circuito) y «Para revisar» / «Todos» para
  administración, con contadores, chips de estado, filtro por área,
  documentos devueltos marcados con su motivo y acciones por rol.
- Ficha: avisos por estado, datos del área y datos oficiales según el rol,
  fichero adjunto, actividad con comentarios y carril con el recorrido del
  documento, acciones y descargas.
- Editor: nombre interno con el prefijo del tipo, título oficial, campos
  por rol, anotaciones internas de gestión, zona de arrastre para el
  fichero (PDF, ODT o DOCX) y botones de transición.
- Diálogos: confirmación antes de enviar o aprobar y motivo obligatorio al
  devolver, con alternativa sin JavaScript.
- Previsualizar PDF y descargar PDF, ODT o DOCX desde la app, reutilizando
  la maquinaria de wp-admin (también en Playground).
- La app ocupa todo el ancho de la ventana, como Registro de Visitas.

Refuerzos de seguridad
- El área no puede escribir campos de gestión aunque los envíe, ni
  cambiando el tipo ni inyectando post_content.
- Subida de ficheros validada (tipo, tamaño, permisos) antes de sustituir
  el adjunto existente.

Tests unitarios, jest y E2E actualizados.
- Nombre interno bajo el título, columna en el listado y metabox de
  anotaciones internas (solo gestión y administración) y de actividad,
  en una clase aparte para no engordar la metabox de secciones.
- Documentate_Demo_App: doce documentos de ejemplo repartidos por tipo,
  área, autor y estado (borrador, devuelto por gestión, devuelto por
  administración, en gestión, en revisión, aprobado y archivado), con
  campos rellenos según quién los haya tocado, adjuntos, comentario y
  actividad fechada; idempotente y sin enviar correos.
- scripts/seed-demo-app.php para volver a sembrar desde WP-CLI.
- Herramientas de desarrollo: etiquetas de cuenta por rol.
- documentate-app-flujo.spec.js: el ciclo entero (el área crea, adjunta y
  envía; gestión revisa y devuelve con motivo; el área corrige y reenvía;
  gestión pasa a administración; administración aprueba), con el rechazo
  del motivo vacío y la actividad resultante.
- documentate-app-roles.spec.js: pestañas, campos y ámbito por rol.
- documentate-app-export.spec.js: previsualizar y descargar desde la app.
- Helpers compartidos en tests/e2e/fixtures (PDF de prueba, capacidad de
  gestión, alta y borrado de documentos con sus adjuntos) y cerrojo para
  que las llamadas concurrentes a WP-CLI no corrompan la caché de wp-env.
- CI: el trabajo de E2E se reparte en dos fragmentos y la conversión WASM
  queda tras DOCUMENTATE_E2E_WASM=1.
- scripts/capturas.mjs y «make capturas»: recorre la aplicación con los
  tres perfiles en ordenador y móvil y deja capturas/informe.html.
- Arreglo: WordPress descarta ?error= al resolver la URL, así que los
  avisos de error de la app se leen también de la propia petición.
A la derecha de los chips de estado, un campo «Filtrar…» esconde las filas
que no coinciden según se escribe: nombre interno, título oficial, tipo y
estado, sin acentos ni mayúsculas. El pie pasa a «2 de 12 documentos» y,
si no queda ninguna, lo dice. Sin JavaScript el campo no aparece: los
chips siguen haciendo el filtrado de verdad contra la base de datos.
El plugin es solo para España, así que las 400 llamadas de i18n pasan a
literales en español (tomados del catálogo es_ES) y desaparece toda la
cadena de traducción: languages/, los scripts de composer, los objetivos
de Makefile, el paso de gettext en CI, las reglas de .distignore y de
.gitignore, la regla WordPress.WP.I18n de PHPCS y las cabeceras Text
Domain y Domain Path. Añadir una cadena ya no obliga a regenerar el .pot.

También se retira WPLANG de la configuración de wp-env: el idioma del
núcleo ya no cambia lo que muestra el plugin.
Seguridad
- La actividad y los comentarios de un documento solo se leen con permiso
  sobre ese documento: dejan de aparecer en el escritorio de WordPress ni
  en consultas genéricas de comentarios.
- Los ficheros adjuntos se sirven por un endpoint con permiso y nombre no
  adivinable; la carpeta de documentos generados deniega el acceso directo.
- La siembra de datos de ejemplo ya no depende de una cabecera de la
  petición: solo del entorno declarado por WordPress (Documentate_Demo_Gate).
- La capacidad de gestión pasa a un rol propio «Gestión documental» en vez
  de concedérsela a todos los editores del sitio, con migración desde la
  versión anterior.
- El área tampoco puede escribir campos de gestión por la vía de los
  campos desconocidos, y el texto enriquecido se filtra con wp_kses_post
  para quien no tenga unfiltered_html.

Flujo
- Guardar con el nombre o el título vacíos ya no descarta los cambios.
- Un documento sin tipo puede elegirlo desde la app; hasta entonces no se
  ofrecen botones de envío que fallarían.
- Un documento devuelto a gestión ya no le pide al área que lo corrija.
- «Devolver a revisión» queda registrado en la actividad y pide motivo.

Pruebas y documentación
- Tests jest del metabox de gestión y cobertura de JS con mínimos por
  módulo; los E2E vuelven a poder ejecutar la conversión WASM con
  «make test-e2e-wasm».
- README, ARCHITECTURE, AGENTS, CLAUDE y readme.txt al día, más
  docs/flujo-documentos.md y docs/campos-por-rol.md para el equipo.
…gestión

- blueprint.json declara el entorno (WP_ENVIRONMENT_TYPE de desarrollo y
  WORDPRESS_PLAYGROUND) antes de activar el plugin, que es lo que arma la
  siembra: sin eso, tras endurecer la puerta de los datos de ejemplo,
  Playground se quedaba sin usuarios ni documentos. Y siembra los doce
  documentos al final, para que la página de aterrizaje tenga contenido.
- Los E2E dejan de conceder «documentate_gestionar» al rol editor entero
  (se quedaba pegado en el sitio compartido y contradecía el modelo) y
  nombran gestión documental a la cuenta que toca, como hace la siembra.
Semgrep marcaba cuatro lecturas de fichero cuyo identificador venía de la
petición. El riesgo real era nulo (entero saneado y ruta tomada de la base
de datos), pero la base de datos no es una promesa: una fila editada a
mano o una migración pueden apuntar a cualquier sitio legible.

Documentate_Ficheros resuelve la ruta de un adjunto y rechaza lo que no
sea un fichero dentro del directorio de subidas, con el separador incluido
para que «uploads-otra-cosa» no cuele. Lo usan la entrega de adjuntos de
la app y las dos lecturas de plantilla del administrador de tipos. El
nombre que viaja en Content-Disposition se sanea, así que tampoco puede
cortar la cabecera.
- La generación de documentos ya no compone un invocable: el formato pedido
  elige una rama y el generador se nombra en el código. El mapa de formatos
  se queda como lista de lo que responde el endpoint.
- Las dos lecturas del fichero adjunto llevan la anotación de Semgrep con el
  motivo: la petición solo nombra un documento y un adjunto (enteros), quien
  lee tiene que poder editar ese documento, el adjunto tiene que ser el suyo
  y la ruta se resuelve con realpath dentro del directorio de subidas.

Comprobado con el mismo conjunto de reglas que usa CI (p/php y
p/security-audit): cero hallazgos.
El editor declaraba dos listas de elementos permitidos y la del filtro
tiny_mce_before_init pisaba a la del propio editor, sin las secciones de
tabla: TinyMCE se comía thead, tbody y tfoot al guardar. Ahora hay una
sola lista, la que define el campo, y un test lo fija.

Tres E2E de wp-admin pasaban sin comprobar nada y empezaron a fallar al
cambiar lo que había alrededor:

- Los repetidores se buscaban con «add|agregar», que con el núcleo en
  inglés encontraba «Add Media», y contaban filas con una clase que no
  existe. Ahora usan los controles del propio plugin y la prueba de
  eliminar añade una fila antes de quitarla, porque el editor siempre
  deja una.
- La previsualización esperaba a que cargara una pestaña con un PDF, que
  en Chromium sin interfaz puede acabar como descarga: ahora vale
  cualquiera de las dos y se comprueba el tipo de contenido.
- Los ajustes dejaban una URL de Collabora inventada en la base de datos
  y engañaban a las descargas de los demás specs; ahora la restauran.

Suite completa de E2E en local: 100 pasan, 8 se saltan.
Marcarlas con «hidden» no bastaba: la hoja de estilos da display de rejilla
a cada fila y ese selector gana a la regla del navegador, así que la lista
se quedaba igual mientras se escribía. Ahora «hidden» manda dentro de la
aplicación, lo que además arregla la zona de arrastre y el aviso de lista
vacía, que se veían antes de que el JavaScript los mostrara.

Con un E2E que comprueba lo que se ve, no lo que está marcado.
Al arreglar el filtro salió que otras piezas dependían de reglas de estilo
que las contradecían. Revisado en el navegador, no solo en el código:

- En móvil, la tarjeta de acciones del editor se pintaba encima de la de
  estado y nunca llegaba a quedarse fija: el carril va debajo del
  formulario, así que ahí no cabe una barra pegada abajo.
- Los diálogos de confirmación y de motivo salían pegados al borde
  superior, tapando la barra de administración: el tema anula los márgenes
  automáticos con los que se centra un diálogo.
- Las ventanas de «cambios sin guardar» y de generación cuelgan del body,
  fuera del alcance de los estilos de la app, y mostraban botones grises
  del navegador en medio de una tarjeta cuidada.
- El indicador de cambios sin guardar no se pintaba en la app, y sin él su
  guion ni siquiera se suscribía: previsualizar o descargar con el
  formulario sucio usaba la versión guardada sin avisar.

Y el filtro rápido mejora con lo aprendido: busca también por área y
persona en las bandejas de revisión y por el motivo de una devolución, y
el pie ya no se come el aviso de que la bandeja tiene más documentos de
los que caben en pantalla.
…ieja

Documentate_App_Lista llegaba justo al límite de complejidad de clase (100,
y la regla salta al alcanzarlo). Se parte en tres piezas que además se leen
mejor: la bandeja decide estados, filtros y consulta; la fila se dibuja
aparte; la lista se queda con el marco y la tabla. El marcado no cambia y
las llamadas de fuera siguen igual. Quedan en 45, 34 y 26, con margen.

Y para que esto no dependa de que alguien lo mire:

- phpmd-baseline.xml recoge las 48 violaciones heredadas, casi todas del
  conversor OpenTBS. Encogerla vale; agrandarla no: una violación nueva se
  arregla partiendo el método o la clase.
- «make phpmd» falla con cualquier violación fuera de esa línea base, entra
  en «make check» y es un paso obligatorio de CI, justo después del lint.
  Comprobado con una sonda: la rechaza y la nombra.
- El fichero no se llama phpmd.baseline.xml a propósito. Con ese nombre
  PHPMD lo aplicaría solo, también al escaneo que alimenta el panel de
  código, y la deuda heredada desaparecería de la vista.
- Los umbrales quedan escritos en AGENTS.md y CLAUDE.md: ciclomática 15,
  NPath 500, método 150 líneas, clase 2500 líneas y complejidad de clase
  100, con cómo medir un fichero y qué hacer cuando salta.
Lo copia «npm run build:autofirma» desde node_modules en el postinstall y
nadie lo edita a mano, así que sus cinco mil líneas no tienen por qué salir
en los diffs ni en las revisiones. «-text» además conserva los bytes tal y
como los publica el paquete. Cuando aparezca en git status tras un install,
lo que toca es «git restore», salvo que la versión de package.json se haya
movido de verdad.
… pestaña de tipos

Las pestañas de administración quedan como las de gestión documental: la
lista completa primero y la bandeja de revisión después. Así cambiar de rol
no mueve las pestañas de sitio.

Y fuera «Tipos y plantillas»: los tipos y sus plantillas se llevan desde el
escritorio de WordPress, no desde la aplicación, así que ninguna pestaña
sale ya de ella. Con eso desaparece también el marcador de pestaña externa,
que no tenía otro uso. El aviso de «no hay tipos definidos» dice ahora dónde
se crean de verdad.
…ribe

El plugin ya decía «code, comments, docblocks in English» y el resto lo
cumplía, pero la aplicación entera, que nace en este PR, llegó con ficheros,
clases, métodos, variables y tests en español. Se renombra todo: 33 ficheros,
14 clases, un par de centenares de métodos y propiedades, y los nombres de
los tests de PHPUnit, jest y Playwright.

Queda intacto lo que es contrato y no estilo: los textos de la interfaz y sus
aserciones, los correos, la actividad, las guías del equipo, las clases CSS,
los atributos data, los parámetros de la URL, los campos de formulario, las
claves de metadatos y opciones, las capacidades, los ganchos, el estado
en_gestion, el atributo rol de las plantillas y los slugs de los tipos.
Renombrar eso rompería enlaces guardados, datos ya escritos y selectores.

Y la regla entera se escribe en AGENTS.md, con las tres listas —inglés,
español y lo que no se renombra nunca— y el porqué de cada una, más un
resumen en CLAUDE.md. Antes solo se mencionaba el inglés de los docblocks.

También: Semgrep sube el SARIF sin los hallazgos que el código suprime con
nosemgrep, porque GitHub los levantaba igual como alertas abiertas y el bot
los comentaba en cada revisión pese a estar justificados en el propio código.
En un sitio nuevo la siembra funcionaba, pero bastaba un documento de
demostración de la versión anterior para que se saltara entera: la guarda de
«ya sembrado» miraba solo la marca antigua y cortaba la pasada antes de crear
los doce documentos que recorren el circuito. Eso deja cualquier wp-env vivo,
y cualquier instalación que se actualice, sin nombre interno, sin estados y
sin devoluciones. Ahora esa guarda solo protege lo que protegía —el documento
por tipo— y los del circuito se siembran igual, porque se marcan aparte y
sembrarlos dos veces no crea nada.

Los documentos de demostración antiguos reciben además un nombre interno
corto sacado de su título, para que las listas no sean una pared de frases
recortadas. El título no se toca: es lo que imprime el documento generado.

Y «make up» siembra al arrancar, con «make seed-demo» para ponerse al día sin
recrear el entorno.
Un día de E2E deja cientos de documentos: cada spec crea los suyos con un
nombre de un solo uso y una tanda que falla no llega a limpiar. El juego de
demostración acaba perdido entre el ruido, que es justo lo contrario de para
lo que está. En este equipo eran 596 documentos de pruebas frente a 12 del
circuito.

El objetivo borra lo que no lleva marca de demostración —con sus adjuntos y
su actividad, que WordPress no se lleva por delante solo— y las cuentas,
categorías y tipos que crean los specs, reconocibles porque su nombre lleva
una marca de tiempo. Después vuelve a sembrar, así que el sitio queda como
recién instalado. Se niega a correr donde no esté permitido el contenido de
ejemplo, de modo que una producción no puede perder nada.
@erseco
erseco force-pushed the feat/app-documentate branch from 2a2fe17 to 80f8ee8 Compare September 8, 2026 17:04
The native renderer landed on main while this branch was open, so its
strings, its demo values and its output guard arrive here speaking English
through the translation functions and carrying their own copy of the demo
field values inside the seeder.

The application has rules of its own: the interface is written in Spanish
directly in the code, with no i18n at all. The strings of the PDF layout
field, the conversion manager, the private output directory, the PDF
generator and merger, and the tests that assert them, follow suit.

The demo field values move to Documentate_Demo_Field_Values and the
front-end requires move to load_app_dependencies(), which is also what
keeps the seeder under the class-length budget and load_dependencies()
under the method-length one now that both carry main's work as well.
@erseco
erseco force-pushed the feat/app-documentate branch from e72812b to 96c0c9e Compare September 8, 2026 18:51
@erseco
erseco merged commit 1ccf1d1 into main Sep 8, 2026
9 of 10 checks passed
@erseco
erseco deleted the feat/app-documentate branch September 8, 2026 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants