From 0dabba5442addd1375b2c0a7f05df5fe3271aad8 Mon Sep 17 00:00:00 2001 From: Jordan Diaz Date: Wed, 6 May 2026 07:20:48 +0000 Subject: [PATCH] ajustes en docs generales --- docs/03-modules-and-sections.md | 20 ++++++++++++++++++++ docs/04-pages-and-records.md | 1 + docs/06-hooks-and-cmsapi.md | 15 +++++++++++++++ docs/09-mcp-tools-reference.md | 30 ++++++++++++++++++++++++++++-- docs/11-quick-reference.md | 4 ++++ 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/docs/03-modules-and-sections.md b/docs/03-modules-and-sections.md index e941c85..7620c31 100644 --- a/docs/03-modules-and-sections.md +++ b/docs/03-modules-and-sections.md @@ -126,6 +126,26 @@ Particularidades: - Foreign keys con sufijo `_num`: `thisrecord.categoria_num` - Si la FK tiene relación cargada, también aparece como objeto: `thisrecord.categoria_bd[0].nombre` +### Gestionar la galería / uploads de un registro + +Cuando el usuario pide "cambia la imagen de la vacante 12", "borra la 2ª foto de la galería", "reordena las imágenes" — **NO uses `upload_record_image` para reemplazar**: eso añade un upload nuevo encima sin borrar el viejo y deja basura. Usa el flow de gestión: + +``` +list_record_uploads({ tableName, recordId, fieldName }) + → [{ uploadId, urlPath, info1, ... }, ...] +``` + +Y según el caso: + +| Acción del usuario | Tool a usar | +|---|---| +| Reemplazar una imagen concreta por otra | `replace_record_image({ tableName, recordId, fieldName, uploadId, imageUrl })` | +| Borrar una imagen | `delete_record_upload({ uploadId })` | +| Cambiar el orden | `reorder_record_uploads({ tableName, recordId, fieldName, uploadIds: [...] })` | +| Añadir una imagen NUEVA (sin tocar las existentes) | `upload_record_image({ tableName, recordId, fieldName, imageUrl })` | + +En modo producción todas estas tools sincronizan automáticamente con el servidor real. Si solo conoces el `recordId` y necesitas saber qué `fieldName` tiene uploads, llama antes a `get_table_schema({ minimal: true })` y filtra los campos `type: "upload"`. + ### Embeber formularios en el detalle Si un detalle necesita un formulario (postular, pedir info), **embebe el módulo del formulario dentro de la sección general** pasándole el `num` del registro actual: diff --git a/docs/04-pages-and-records.md b/docs/04-pages-and-records.md index 450b7da..3230b6c 100644 --- a/docs/04-pages-and-records.md +++ b/docs/04-pages-and-records.md @@ -122,6 +122,7 @@ Comprueba siempre qué campo tiene la tabla antes de cambiar visibilidad: 3. `set_module_config_vars` — actualizar valores. 4. O editar el template del módulo: `acai-view` + `acai-line-replace` sobre `index-base.tpl` (compila automáticamente). 5. `reorder_module` para mover módulos, `toggle_module_visibility` para ocultar/mostrar. +6. Para imágenes ya existentes en un campo `upload`: `list_record_uploads` para obtener `uploadId` → `replace_record_image` (sustituir), `delete_record_upload` (borrar) o `reorder_record_uploads` (reordenar). Para añadir uno nuevo, sigue siendo `upload_record_image`. ## Trabajar con páginas Standard diff --git a/docs/06-hooks-and-cmsapi.md b/docs/06-hooks-and-cmsapi.md index c9a2ddc..1eaf81c 100644 --- a/docs/06-hooks-and-cmsapi.md +++ b/docs/06-hooks-and-cmsapi.md @@ -287,6 +287,21 @@ set_hook_middleware({ - Crear el `.php` con `acai-write` **NO** activa middleware automáticamente — hay que llamar `set_hook_middleware` explícitamente. - Lee `get_hook_middleware` antes de modificar para no sobrescribir configuraciones existentes. +### Auto-registro en `layout.json` + +Cuando creas, renombras o borras un hook global con las tools de archivos, el backend mantiene `layout.json["hooks"]` sincronizado **automáticamente** — no necesitas tocarlo a mano: + +| Acción del agente | Efecto en `layout.json["hooks"]` | +|---|---| +| `acai-write hooks/hooks.X.php` (fichero nuevo) | Añade entry con `endPoint: /hooks/X/`, `middleWare: []`, `entryParams: [{variable: entryVariable}]` | +| `acai-write` sobre un hook existente | Sin cambios (se preserva `middleWare`, `entryParams`, etc.) | +| `acai-delete hooks/hooks.X.php` | Quita la entry huérfana | +| `acai-rename hooks/hooks.X.php → hooks.Y.php` | Quita la vieja + añade la nueva con defaults | + +**Implicación**: tras `acai-write` de un hook nuevo, ya está registrado. Si quieres que se ejecute como middleware (`["allurls"]` o records concretos), solo te falta `set_hook_middleware` para configurar ese campo. Para los hooks de módulo (`template/estandar/modulos//hook.php`) no hay registro en `layout.json` — se descubren por convención de path al ejecutar el módulo. + +**Nunca edites `layout.json` directamente** para gestionar hooks. Eso compite con el sync del backend y deja el fichero inconsistente. + ## Schemas y formato de datos al insertar Antes de un `CmsApi::insert`/`update` o de un `create_or_update_record` desde MCP, consulta el schema (`get_table_schema`). Tipos de campo y formato esperado: diff --git a/docs/09-mcp-tools-reference.md b/docs/09-mcp-tools-reference.md index eb51083..cd235d1 100644 --- a/docs/09-mcp-tools-reference.md +++ b/docs/09-mcp-tools-reference.md @@ -97,7 +97,11 @@ Ver `06-hooks-and-cmsapi.md` para uso. Crear/editar el `.php` del hook se hace c | Tool | Acción | Notas | |------|--------|-------| | `generate_image` | Genera imagen con IA y la guarda en `cms/uploads/generated/` | Devuelve `dockerUrl` y `uploadUrl`/`fullUrl`. **En Forge prefiere `uploadUrl`/`fullUrl`** sobre `dockerUrl` para `upload_record_image` | -| `upload_record_image` | Sube imagen a un campo de un registro | Necesita `tableName`, `recordId` (num), `fieldName` real (de relations o `uploadFields`) | +| `upload_record_image` | Sube imagen a un campo `upload` de un registro | Necesita `tableName`, `recordId` (num), `fieldName` real (de `uploadFields` o `get_table_schema`). Sincroniza a producción si el proyecto está en modo prod | +| `list_record_uploads` | Lista los uploads existentes de un campo de un registro | Devuelve cada upload con su `uploadId` (necesario para `replace`/`delete`/`reorder`) | +| `replace_record_image` | Reemplaza un upload existente por uno nuevo | Necesita `uploadId` (de `list_record_uploads`). Borra el viejo + sube el nuevo, ambos con sync a producción | +| `delete_record_upload` | Borra un upload concreto del campo | Necesita `uploadId`. Sincroniza el borrado a producción | +| `reorder_record_uploads` | Cambia el orden de los uploads de un campo | Lista de `uploadIds` en el orden deseado | | `upload_image_to_assets` | Sube imagen a `/images/` del template (assets globales) | Acepta base64, data URI, URL. Permite resize/quality/format | ### Navegación @@ -118,7 +122,8 @@ Ver `06-hooks-and-cmsapi.md` para uso. Crear/editar el `.php` del hook se hace c | Tool | Acción | |------|--------| | `list_git_log` | Lista los últimos commits para que el usuario elija un id de rollback | -| (rollback) | Tool de rescate; pide confirmación al usuario | +| `recover_previous_git` | Rollback rápido al commit anterior. Tool de rescate — pide confirmación al usuario antes de ejecutar | +| `recover_git` | Rollback a un commit específico (por id, obtenido vía `list_git_log`). Pide confirmación al usuario | ### Autenticación @@ -231,6 +236,27 @@ read_doc({ name: "05-tables-and-fields" }) // doc completo read_doc({ name: "06-hooks-and-cmsapi", section: "Hook middleware" }) // sección por heading H2 ``` +### 11. Gestionar uploads existentes de un registro + +Cuando el usuario pide "cambia la imagen de la vacante 12", "borra la foto X de la galería", "reordena las imágenes" — **NO uses `upload_record_image` para reemplazar**: eso añade un upload nuevo encima sin tocar el viejo y deja basura. Usa el flow de gestión: + +``` +list_record_uploads({ tableName, recordId, fieldName }) + → array de uploads, cada uno con su uploadId +``` + +Según lo que pida el usuario: + +- **Reemplazar** una imagen concreta: `replace_record_image({ tableName, recordId, fieldName, uploadId, imageUrl, alt? })` — borra el viejo + sube el nuevo, ambos con sync a producción. +- **Borrar** una imagen: `delete_record_upload({ uploadId, table? })` — sync de borrado a producción. +- **Reordenar**: `reorder_record_uploads({ tableName, recordId, fieldName, uploadIds: [...] })` con la lista en el orden deseado. + +Para AÑADIR un upload nuevo (sin reemplazar nada existente), usa `upload_record_image` directamente. + +Notas: +- En modo producción todas estas tools sincronizan automáticamente con el servidor real (no solo modifican local). +- Si solo tienes el `recordId` y necesitas saber qué `fieldName` tiene uploads, llama antes a `get_table_schema({ minimal: true })` y filtra los campos `type: "upload"`. + ## Reglas globales para todas las tools 1. **`tableName` siempre SIN prefijo `cms_`** (excepto en `queryDB` Twig y en el `middleWare` de `set_hook_middleware`). diff --git a/docs/11-quick-reference.md b/docs/11-quick-reference.md index e838404..81392dd 100644 --- a/docs/11-quick-reference.md +++ b/docs/11-quick-reference.md @@ -100,6 +100,9 @@ Este documento es un **resumen ejecutable** de las reglas críticas, los tipos d | Ver datos de un módulo en una página | `get_module_config_vars` | | Cambiar valores de un módulo | `set_module_config_vars` | | Subir imagen a un módulo | Usa `uploadFields` de `set_module_config_vars` → `upload_record_image` (`tableName: "builder_custom"`) | +| Reemplazar imagen existente de un registro | `list_record_uploads` → `replace_record_image({ uploadId, imageUrl })` | +| Borrar imagen de un registro | `list_record_uploads` → `delete_record_upload({ uploadId })` | +| Reordenar galería de un registro | `list_record_uploads` → `reorder_record_uploads({ uploadIds: [...] })` | | Crear tabla nueva | `create_table` (pregunta `enlace`/`seoMetas` antes) → `create_field` | | Crear detalle de registro | Sección general en `template/estandar/modulos/custom-{tableName}/` | | Editar header / footer | `get_layout_field` → `set_layout_field` (NUNCA edites los `.tpl` directamente) | @@ -111,6 +114,7 @@ Este documento es un **resumen ejecutable** de las reglas críticas, los tipos d | URL del proyecto | `get_web_url` (añade `?pruebas=1`) | | Navegar el preview del usuario | `navigate_browser` | | Token JWT expirado (403) | `refresh_acai_token` | +| Volver a una versión anterior del proyecto | `list_git_log` → `recover_git({ id })` (o `recover_previous_git` para el commit anterior) — pide confirmación al usuario | | Necesito un doc no cargado | `read_doc({ name: "..." })` | | Listado de docs | `list_docs()` |