Skip to main content
Version: 4.0 preview

Latest features: catalog operations

Version
4.0 preview
Updated
View markdown

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


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.

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.

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.

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.

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.

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 · the commands · the dashboard health check

Building the catalog in the first place


Next: platform & extensibility · back to Latest features