# Latest features: catalog operations

> What's new for catalog work — move a product between installs, delete one and its whole graph, and control per property what travels on a copy, a delete and an export.

Source: CBX documentation, version 4.0 preview (unreleased). Canonical page: https://docs.configbox.at/docs/4.0-preview/features/latest/catalog-operations. Last updated 2026-08-25.

---
**A configured product is a graph, and it can finally be handled as one.** Move it to another install,
copy it, delete it, and in each case control exactly what travels with it — decided by the models'
own property definitions rather than by a hardcoded list somebody has to remember to extend.

← [Back to Latest features](https://docs.configbox.at/docs/4.0-preview/features/latest/)

---

## Move a product between installs

A product is not one record. It is the product row, its configurator pages, their questions, those
questions' answers, the detail panes, every calculation any of it uses, the rules wired through all of
it, and the images and files hanging off any of those. **Product transfer** packages all of that as a
zip and imports it into another CBX install — build on staging and push to live, or lift a product from
one client's site to another.

- [Admin Guide: move products between sites](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/move-products-between-sites)
- [The package format, the import modes, and what is validated](https://docs.configbox.at/docs/4.0-preview/technical/product_transfer#1-the-package)

### The part that is actually hard: three kinds of reference

Conflating these is how a transfer goes subtly wrong, so the design names them:

1. **Into the package** — a page names its product, an answer names its question, a rule names an
   answer. On import these are **re-aimed** at the records the import just created. A rule that named
   answer 412 on the source names the right answer here.
2. **Out of the package** — a tax class, a customer group, a shipping method. These are **never created
   by an import**: the target install's own records are used, matched by a display name the two installs
   can agree on, and an unmatched one is *reported* rather than guessed at. Importing a product must not
   invent a tax class, because the package cannot know the rate is right.
3. **Not a reference at all** — an option's own string key, like a template folder name. Either it
   exists on the target or it does not.

Which kind a reference is depends on **whether the referenced record is in the package**, not on which
model it is — a product referencing another product as an add-on is referencing something outside.

- [Three kinds of reference](https://docs.configbox.at/docs/4.0-preview/technical/product_transfer#3-three-kinds-of-reference--the-actual-difficulty)

### Checked before anything is written

Validation runs against the package **before** the first row is written: findings are graded blocker /
warning / notice, blockers stop the import, warnings are shown for the operator to acknowledge, and the
result carries a plain next-step sentence. Two import modes — fresh products alongside what is there,
or under the original IDs, overwriting.

Both halves have a command-line equivalent, so a staging → live promotion drops into a deploy script,
and both are also MCP tools, so an assistant can check a package before importing it.

- [Validation, and what a failure tells you](https://docs.configbox.at/docs/4.0-preview/technical/product_transfer#5-validation-runs-before-anything-is-written)
- [`configbox:product:export` / `:import`](https://docs.configbox.at/docs/4.0-preview/features/latest/cli) ·
  [`cbx_check_product_package` and friends](https://docs.configbox.at/docs/4.0-preview/features/latest/mcp-server)

## Delete a product, and everything that was only its

The same graph in reverse: the product plus its pages, questions, answers, detail panes, examples, its
own calculations and their translations and files — **including any child list a customization added to
the product form**, because the walk reads the models, not a list. Behind a typed confirmation, and
**refused if anything outside the product still needs one of those records**. A calculation belonging
to no product, or used by another one, is left alone.

It is deliberately a separate operation from an ordinary delete: an ordinary delete is refused the
moment anything references the record, so a product can never be destroyed by a call that looked
routine. There is no undo — which is why the tool form has a dry run that reports the same plan and the
same blockers and changes nothing.

- [Admin Guide: copy and retire products](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/copy-and-retire-products)
- [`cbx_delete_product_deep`](https://docs.configbox.at/docs/4.0-preview/features/latest/mcp-server) ·
  [the refusal an ordinary delete gives instead](https://docs.configbox.at/docs/4.0-preview/technical/kenedo_controller#6-the-rest-of-the-task-catalog)

## What travels, decided per property

A child list on a form declares, independently, what happens to its records in each of the three walks:
copied with the parent, deleted with the parent, exported with the parent. Three settings, three
questions, no shared answer — because they genuinely differ: examples belong to a product on a copy but
have no business travelling in a transfer package.

The settings were renamed from an "ignore" pair and inverted, because a name that says *ignore* without
saying ignore-in-which-walk is the kind of thing that reads correctly and is understood wrongly.

- [`childentries` — the three walks and their settings](https://docs.configbox.at/docs/4.0-preview/technical/property-types/childentries)
- [Copying a record, recursively](https://docs.configbox.at/docs/4.0-preview/technical/mvc_tasks)

## Keeping the catalog tidy

- **Orphaned translation strings.** CBX stores translatable text in its own table; deleting records
  used to leave their strings behind. `configbox:strings:purge` reports and removes them
  (`--status` counts without deleting).
- **Charset drift.** Every CBX table and text column belongs on one charset and collation; a
  half-specified `CREATE TABLE` silently takes the server's default instead and the mismatch only
  surfaces months later on a join. `configbox:charset` reports and repairs, the dashboard health check
  flags it, and there is an admin fixer.
- **Migrations that freeze on failure.** Schema changes are versioned, idempotent scripts. A failure
  sets a flag that stops further updates rather than limping onward, and the way out is
  `configbox:migrate:unblock`.

- [Database migrations](https://docs.configbox.at/docs/4.0-preview/technical/migrations) ·
  [the commands](https://docs.configbox.at/docs/4.0-preview/features/latest/cli) ·
  [the dashboard health check](https://docs.configbox.at/docs/4.0-preview/admin-guide/getting-started/check-the-dashboard)

## Building the catalog in the first place

- [How a product fits together](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/how-a-product-fits-together) ·
  [add a product](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/add-a-product) ·
  [pages and questions](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/add-pages-and-questions) ·
  [answers](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/add-answers)
- [Product lists](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/manage-product-lists) ·
  [detail panes](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/product-detail-panes) ·
  [the visual preview](https://docs.configbox.at/docs/4.0-preview/admin-guide/products/set-up-the-visual-preview)
- [Building a product, exhaustively](https://docs.configbox.at/docs/4.0-preview/functional/configurator_building)

---

*Next: [platform & extensibility](https://docs.configbox.at/docs/4.0-preview/features/latest/platform-and-extensibility) ·
[back to Latest features](https://docs.configbox.at/docs/4.0-preview/features/latest/)*
