Field group storage migration
Rename field-group tables and columns to their current names, per site, with a preview-first CLI. Includes a step-by-step runbook and rollback.
Field groups used to be called components, and the old name is still in the database even though it is gone from the API and the admin. Three things still carry it:
| What | Old name | New name |
|---|---|---|
| The registry table | dynamic_components | dynamic_field_groups |
| Each field group's data table | comp_<slug> | fg_<slug> |
| The column naming a stored row's field group | _component_type | _field_group_type |
nextly migrate:field-groups renames them.
You do not have to do this
Nextly reads whichever generation your database holds. A site that never runs this keeps working, and a site that runs it keeps working. There is no flag day, no coordinated release, and no window where half your fleet is broken.
That is deliberate: the migration is expand → migrate → contract, and the expand half already shipped. The application probes each database and serves whatever it finds.
So treat this as tidying up, done per site, at a time you choose.
It previews by default
Running the command with no flags writes nothing:
nextly migrate:field-groupsIt prints every storage object that would be renamed, by name, and stops.
Applying is explicit, and needs you to confirm a backup exists:
nextly migrate:field-groups --apply --backup-confirmed--backup-confirmed is not a formality and it is not defaulted. This rewrites stored content. The migration is resumable and reversible, but neither property helps against the failures that actually motivate a backup — a run on a database whose disk fills, a rollback whose recorded plan was lost, or discovering afterwards that you were pointed at the wrong database.
A preview takes no lock and issues no DDL, so it works with a read-only credential. That is the credential you should preview production with.
Reading the preview
Three things in the output matter, and each answers a different question.
The rename list names every object that changes. It is a list rather than a count on purpose: a run also rewrites stored rows and passes settlement gates, so any number derived from renames alone understates the work while looking authoritative. Your question when reading it is whether your table is there, which a total cannot answer.
Whether the plan was checked against your database. A preview takes no lock, so another run can be writing while it reads. When that happens the command says so:
This plan was NOT checked against your database.
That list is then the most that could change rather than what will — some of it may already have been applied by whoever is writing. Re-run the preview when nothing else is writing.
Whether a migration is already running. Three outcomes, and the third is not the first:
- No migration is currently running — nothing holds the lock.
- A migration is running right now — someone else is mid-flight; wait.
- The lock could not be read — your role cannot read the lock table. This is not the same as "nothing is running." Find out why before you write anything.
Runbook, per site
Do one site at a time and let each soak before starting the next. Suggested order: playground → your own sites → client sites last.
-
Upgrade the site to a Nextly release that includes this command.
-
Take a backup, and confirm you can restore it. Not that it exists — that it restores.
-
Preview, ideally with a read-only credential:
nextly migrate:field-groupsRead all three signals above. If the plan was not checked against the database, or the lock is held or unreadable, stop and resolve that first.
-
Apply:
nextly migrate:field-groups --apply --backup-confirmed -
Verify before moving on:
- the admin loads and lists your field groups;
- opening a field group in the Schema Builder works, and saving a trivial edit succeeds;
- an entry containing a field group reads and writes correctly.
-
Soak. Leave it running normally before starting the next site.
Rolling back
The migration is reversible. Preview the rollback first, exactly as you previewed the migration:
nextly migrate:field-groups --down
nextly migrate:field-groups --down --apply --backup-confirmedIf something goes wrong midway
The run is resumable — re-running continues rather than starting over, and a database already at the target reports that there is nothing to do rather than acting again.
If a field group ends up marked diverged — its tables changed and the record describing them did not — the admin will refuse further schema edits on it and offer a repair. Open that field group in the Schema Builder, review what the repair would change, and apply it. Nothing there moves data; it only makes the stored description match the tables.
Production migrations
Ship database schema changes to production safely with the Nextly migration CLI. Forward-only model, GitHub Actions, Vercel build step, and other-platform patterns.
Authentication
Custom email + password authentication with JWT sessions, API keys, RBAC, and the super-admin bootstrap flow.