# Customization code migration to CBX 4

> Task-oriented guides for realigning existing site customizations to the breaking changes introduced in CBX 4.

Source: CBX documentation, version 4.0 preview (unreleased). Canonical page: https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/. Last updated 2026-08-25.

---
**Task-oriented guides for realigning existing site customizations** (`data/customization/`) to the
breaking changes introduced in CBX 4.

CBX 4 is a deliberate, breaking refactor of the core. Because every deployment carries its own
customization code in `data/customization/` — **gitignored, out-of-tree, per-site** — a core change that
renames a model, drops a table column, or changes a convention will silently break that code. This area
is the running record of those breaks and the concrete before → after fixes for each.

> **Where these docs live.** This directory ships **inside the CBX component itself**
> (`<component>/docs/migration-to-cb4/`), so it travels with the code on every platform CBX runs on
> — Joomla (`components/com_configbox`), WordPress (`plugins/configbox/app`) and Magento 2 (`cb-lib`), all
> of which mount the same component repo — and it is included in the release package built by
> `tools/make_packages.sh`. Intended workflow: open a client project with its `data/customization/`,
> upgrade CBX, then point an AI at the customizations **and this directory** and ask it to *amend the
> customizations*. Everything an agent needs to do that is here; no platform-specific paths are assumed.

> **For AI agents amending customization code:** load **[CHEATSHEET.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/CHEATSHEET)** first — it is the
> flat old → new lookup for every identifier, with a grep pack to find the hits. Scan the customization for
> each **Old** token, apply the **New**, and heed the **Status** (shim = defer, manual = must edit,
> manual+data = also ship a data migration). Then, for anything non-mechanical (removed features, data
> migrations, judgement calls), read the matching *playbook* — the per-domain articles below carry the worked
> conversions and the per-file decision procedure. The **[breaking-changes log](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/breaking-changes-log)**
> summarises *what* changed and why.

> **CLI tooling for the migration.** CBX ships a CLI suite that carries most of the operational
> work of this upgrade — checking, applying and un-sticking migrations, clearing caches, and
> smoke-testing without a browser. On **Joomla** run `php cli/joomla.php configbox:<cmd>`; on
> **WordPress** the same commands are `wp configbox <cmd>` (hyphenated; `migrate --status` and
> `migrate:unblock` are not ported there yet); on **Magento 2** there is no CLI suite yet — migrations
> run via `bin/magento setup:upgrade`, and you check state with the SQL in the CHEATSHEET's sign-off.
>
> | During the upgrade you will want | Command (Joomla form) |
> |---|---|
> | "Did the migrations actually run?" — the host platform's own version/status reports say **nothing** about CBX's schema | `configbox:migrate --status` (read-only; non-zero exit while work is pending) |
> | Apply outstanding core + customization update scripts, by name | `configbox:migrate` (`-v` for full failure diagnostics) |
> | A script failed and updates are frozen | `configbox:migrate:unblock` (explains the block first; `--dry-run` to only look) |
> | Clear caches after amending customization code | `configbox:cache:clear` |
> | Smoke-test a configurator page headlessly, as a given user | `configbox:run-task configuratorpage display page_id=<id> --user=<email>` |
>
> Full reference: `../technical/com_configbox_cli_commands.md` in the developer docs (`docs/technical/`).

---

## How this area is organised

**The running record (read first)**
- **[CHEATSHEET.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/CHEATSHEET)** — the **consolidated old → new identifier lookup**: one flat table of
  every renamed/removed table, column, class, method, property, cache key, DSL token and string-key across all
  domains, each tagged shim / manual / manual+data / removed, with the stacked `element→answer→question`
  rename already resolved to its final target. Load this first when amending a customization; it points into
  the playbooks for the detail. Ends with a ready-to-run grep pack to prove a customization is clean.
- **[breaking-changes-log.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/breaking-changes-log)** — the **single running index** of every breaking
  change: what broke, why, blast radius, and a one-line pointer to the playbook that fixes it. Append a new
  dated entry here whenever core work introduces another break.

**Playbooks — how to fix customization code** (one per customization kind, with the mechanical transform +
the cases that need human/AI judgement)
- **[exceptions-and-validation.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/exceptions-and-validation)** — errors are **exceptions** now.
  A custom property type's `check()` should throw `KenedoValidationException` instead of returning
  `false`; callers of `validateData()`/`store()` move to try/catch. Returning `false` still works, but a
  custom type that returns it **without** setting an error reports a message nobody can act on.

- **[model-property-customizations.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/model-property-customizations)** — the mechanical recipe for
  `model_property_customization/` files bound to the removed option/answer models, and the auto-conversion
  the core does for you.
- **[answers-collapse-deep-dive.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/answers-collapse-deep-dive)** — the **exhaustive** reference for the
  option/answer (xref → answer) collapse: the full mental model, every DB/SQL/cache/order/string/pricing
  touch-point, a per-file decision procedure, worked conversions, and the external-append data migration
  you owe. **Start here for any customization that touches the data model, not just property defs** — this
  is the one written for a heavily-customized site where an AI is asked to make the custom code compatible.
- **[assignments-lookups.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/assignments-lookups)** — reading the assignment relations through
  **`ConfigboxAssignmentsHelper`** instead of `ConfigboxCacheHelper::getAssignments()`: the full old-key →
  new-method table, why the undefined-key guards disappear, the two shapes that deliberately differ, and the
  `city_to_country` / `county_to_country` correction. `getAssignments()` still works — this is the better way
  to ask, and core no longer reads the array itself.
- **[element-question-rename.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/element-question-rename)** — the **exhaustive** before → after reference
  for the element → question rename: DB table/columns, admin model/controller/views, pricing API, the
  assignment/pricing cache keys, the ionCube rules/calc engine + stored JSON, and the calc-formula DSL
  tokens. Full before → after tables per layer, the per-file decision procedure, worked conversions, and the
  shim inventory. **Read this for any customization that touches the question entity.**
- **[customer-field-rename.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/customer-field-rename)** — the **exhaustive** before → after reference
  for the customer field rename: `#__configbox_users` + `#__cbcheckout_order_users` columns
  (`billing_*` / `shipping_*` snake_case, `vat_number`, `shipping_same_as_billing`), the augmented keys,
  the Customer Fields configuration rows, form/DOM/JS contracts, and the operator-facing template
  placeholders. **Read this for any customization that touches customer data, the customerform, order
  addresses or invoice/notification texts.**

**Orientation — what changed, per audience** (not fixes; context for people)
- **[whats-new-for-devs.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/whats-new-for-devs)** — new and changed capabilities for developers.
- **[whats-new-for-operators.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/whats-new-for-operators)** — UI/workflow changes shop staff will see.
- **[operators-what-changed.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/operators-what-changed)** — a focused **retraining** brief: the concrete
  screen/label/behaviour changes affected staff need to be walked through.
- **[whats-new-for-decision-makers.md](https://docs.configbox.at/docs/4.0-preview/migration-to-cb4/whats-new-for-decision-makers)** — the upgrade case: advantages
  and risks, aimed especially at sites still on the one-off-priced CBX 2.

> **Those three pages are about the jump to 4.0.** What the 4.0 line has gained *since* is a separate
> track, cut by surface rather than by audience: **[Latest features](https://docs.configbox.at/docs/4.0-preview/features/latest/)** —
> the storefront, the admin, the HTTP API, the CLI, the MCP server, the AI assistant, payments, catalog
> operations and the extension layer.

More playbooks get added here as further CBX 4 slices ship (overridden controllers/models,
custom properties, engine/calc code, template overrides, DB-schema-dependent customizations, …).

---

## The two kinds of fix

Every break falls into one of two buckets; each playbook labels its cases accordingly:

1. **Auto-converted by the core** — CBX 4 ships compatibility shims (legacy `getModel()` aliases,
   legacy customization-file loading, key remaps) so *cleanly-written* customizations keep working with **no
   code change**. You still get a deprecation line in the log telling you to update. These are called out
   so you know what you can safely defer.
2. **Needs a manual edit** — customizations that reference something genuinely *removed* (a dropped column,
   a deleted property, a table that no longer exists) cannot be shimmed. The core degrades gracefully
   (logs and skips rather than white-screening), but the feature stays broken until you apply the fix the
   playbook describes.

## Rules for documenting a breaking change

When our work on the CBX core introduces a breaking change, follow this — it is the standing process,
not just a style guide. The goal is that a future reader (human or AI) can, from these docs alone, both
**understand what changed** and **make custom code compatible** without re-deriving it from the diff.

**1. Log it first, in the right bucket.**
Every breaking change gets a **dated entry at the top of** `breaking-changes-log.md` before anything else,
tagged with the status legend (🟢 auto-converted · 🟡 partial · 🔴 manual). The log is the index; detail
lives in a playbook it links to.

**2. Classify every affected case as one of two kinds** (and label it):
- **Auto-converted by the core** — a shim keeps cleanly-written customizations working with no code change
  (a deprecation is logged). Say what the shim is and where it lives, and what the log line looks like, so a
  reader can *verify* it and know what they can safely defer.
- **Needs a manual edit** — something was genuinely removed; no shim is possible. Give the exact before →
  after. State whether the core **degrades gracefully** (logs & skips) or **fatals** if left unfixed —
  operators need to know which breaks are silent-but-degraded vs hard.

**3. Be concrete and greppable.** Name the exact file, function, class, table, column, cache key. Give the
literal identifiers a reader will grep for (old → new). Include the *hard-to-grep* variants too
(hard-coded table prefixes, `::class` string uses, minified twins).

**4. Separate "code fix" from "data migration".** A code-level shim (e.g. a remapped key) does **not** move
data. Whenever a change needs both, say so explicitly and point at how to ship the DB half (a
`data/customization/updates/` migration; see `../technical/com_configbox_migrations.md`). This is the most commonly
missed half on customized sites.

**5. Give a decision procedure for scale.** On a site with extensive customizations, a reader needs more
than a list — give a per-file procedure: how to tell if a file is even loaded on this install, which bucket
it falls in, what to do, and **a final grep list of removed identifiers** to prove the file is clean.

**6. Cover all three audiences, not just developers.** A breaking change usually has a human side. Note
whether operators/shop staff see a changed screen, label, or workflow (feed it into
`operators-what-changed.md`), and whether it's material to an upgrade decision
(`whats-new-for-decision-makers.md`). Don't leave retraining implicit.

**7. Record *why*.** One or two sentences on the motivation. Judgement calls during conversion resolve
better when the reader knows the direction the model is moving in.

**8. Verify claims before publishing.** Check identifiers against the actual code, not memory. Don't state
a shim exists unless you can name the method that implements it. Don't invent commercial/licensing facts in
the decision-maker doc — flag them as "confirm with Rovexo" instead.
