Files
acai-scaffold/CLAUDE.md
Dmielgo f2021361ec Add production rules discovered during real projects
- Correct hooks-and-api.md: file hooks vs module hooks param injection,
  FK naming not always _num, CmsApi.hook Promise pattern
- Add 9 new rules to hooks-and-api.md: reserved `tipo` var, ghost modules,
  cms_uploads schema, name vs title by menuType, menuOrder, localCache
  gotcha, slug generation, uploads from hooks, CocoEmail
- Add 5 rules to modular-system.md: minified/ dir, Docker workflow,
  debug tools (?compiletwig/?pruebas), general sections deploy, controlador
- Add 2 rules to css-js-conventions.md: Vue inline conflict, Vue mount delay
- Add testing section to quick-reference.md
- Create docs/deploy-and-sync.md for production deploy and sync rules
- Promote 3 critical rules to CLAUDE.md (rules 11-13)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:17:00 +00:00

6.7 KiB

Acai CMS — Project Instructions

This is an Acai CMS website project. Follow these instructions when working with the codebase.

Environment

  • The site runs in Docker, typically at http://localhost:8080
  • You can make HTTP requests to test pages, APIs, or form submissions
  • If you need to inspect the live site, use browser tools (Playwright MCP) or HTTP requests to localhost:8080

Project Structure

.
├── template/estandar/
│   ├── modulos/          # Builder modules (visual components)
│   │   └── <module-id>/
│   │       ├── index-base.tpl    # Twig template (source — EDIT THIS)
│   │       ├── style.css         # Module styles
│   │       └── script.js         # Module JavaScript
│   │       ├── index.tpl         # Compiled (auto-generated, do NOT edit)
│   │       ├── index-twig.tpl    # Compiled (auto-generated, do NOT edit)
│   │       └── builder.json      # Compiled builder vars (auto-generated, do NOT edit)
│   ├── css/              # Global CSS
│   └── js/               # Global JavaScript
├── hooks/                # PHP hooks (server-side logic)
├── cms/
│   ├── data/schema/      # Database table schemas (JSON)
│   ├── lib/plugins/      # CMS plugins
│   └── uploads/          # Uploaded media files
├── .acai                 # Project config (domain, tokens, DB credentials)
├── .docker/
│   ├── .env              # Docker environment (DB credentials)
│   ├── docker-compose.yml
│   ├── tunnel-url.txt    # Public tunnel URL (if active)
│   └── bore-db-url.txt   # Database tunnel URL (if active)
└── database.sql          # Database dump

Key Concepts

Modules (template/estandar/modulos/)

Visual components that the site builder uses. Each module is a self-contained unit with its own template (Twig + Acai attributes), CSS, and JS. Modules are placed on pages via the drag-and-drop builder. The editable file is always index-base.tpl.

  • Include other modules: <module_id :param1="value1"></module_id>
  • Each module instance gets a unique section_id variable for anchors/scoping
  • Use interno variable to detect CMS editor mode vs public view

See docs/modular-system.md for detailed rules.

General Sections

Database-backed templates (headers, footers, record views) that use the thisrecord variable to access record fields. They use the same Twig + Acai attribute engine as modules.

  • Upload fields return arrays: thisrecord.image[0].urlPath
  • Foreign keys use _num suffix: category_num

See docs/modular-system.md for details.

Hooks (hooks/)

PHP files that execute server-side logic. Triggered by:

  • Twig filter: 'hooks/module_id/' | hook({param: value})
  • HTML tag: <hook result="var" endpoint="/hooks/module_id/" :param="value"></hook>
  • JavaScript: CmsApi.hook('/hooks/module_id/', {param: value}, callback)
  • Form action: via c-form attribute

See docs/hooks-and-api.md for usage.

Database Access

When the site is running in Docker, you can connect to the database:

  • Host: 127.0.0.1
  • Port: Check .docker/docker-compose.yml for the mapped port (usually 3307+)
  • Credentials: Read from .docker/.env:
    • DB_USERNAME
    • DB_PASSWORD
    • DB_DATABASE
docker exec -it dw-<project-name>-db mysql -u root -p<password> <database>

Important: Table names in CmsApi/Twig do NOT use the cms_ prefix. The primary key is always num, never id.

Acai Core (web-base)

The project workspace contains only the customization layer (modules, hooks, schemas, uploads). The CMS core (routing, rendering engine, admin panel, APIs) lives in a separate directory called web-base that is mounted as a Docker volume.

The web-base path can be obtained via: GET http://localhost:9090/api/web-base-path

Do NOT modify web-base files — they are shared across all projects.

Critical Rules

  1. Before working with any area (hooks, modules, templates, CSS/JS, etc.), read the corresponding documentation in docs/ first. Do not guess or assume — always consult the docs before taking action.
  2. Only edit index-base.tpl in modules — index.tpl, index-twig.tpl, and builder.json are auto-generated
  3. After editing any index-base.tpl, ALWAYS call the compile_module MCP tool to compile the module/section. This is mandatory — without compilation, changes won't take effect in the CMS.
  4. Use Twig filters (with |), never Twig functions
  5. Table names without cms_ prefix everywhere
  6. Primary key is num, never id
  7. Upload fields are arrays — access with [0].urlPath
  8. Tailwind CSS as primary styling, custom CSS scoped with BEM when needed
  9. Twig concatenation uses ~ operator: 'value=' ~ variable
  10. enlace (link) fields already include slashes
  11. File hooks (hooks/*.php) do NOT inject variables. Always read params manually: $params = json_decode(file_get_contents('php://input'), true) ?: []; — Only module hooks (modulos/*/hook.php) receive variables directly.
  12. tipo is a reserved variable. The .htaccess injects tipo=barra on every request. Never use tipo as a hook parameter name — it gets overwritten, causing 404s. Use account_type, user_tipo, etc.
  13. Never pass html via save_module to modules with configured builder vars (banners, carousels, modules with images/colors set from admin). It corrupts the visual configuration. Only pass js and/or css. See docs/deploy-and-sync.md.

Documentation