Skip to content

feat(utilities): Change Column — rename or change a type the safe way, as steps to review - #589

Merged
huyplb merged 1 commit into
mainfrom
feat/column-change-screen
Nov 2, 2026
Merged

huyplb merged 1 commit into
mainfrom
feat/column-change-screen

Conversation

@huyplb

@huyplb huyplb commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Step 2 of the safe column change design, for the board card safe-column-change: the screen over planColumnChange (#588, merged).

What it does

Utilities → Change Column (Maintenance group) works on the credential picked in the Utilities header:

  • Inputs: a table and column, plus a new name, a new type, or both. The schema's existing types are offered in the type field, next to a rows-per-batch field.
  • What it touches: indexes, foreign keys, and views or triggers that may use the column. When nothing does, it says so.
  • Warnings: a conversion that can lose data, or an engine without triggers.
  • Refusals, with the planner's reason.
  • Steps: numbered, each with its SQL, a safe to rerun badge, a note and Copy. Copy all and Open in editor take the whole script, each step under a -- Step n: … comment.
  • Open in editor opens a new tab named for the change, e.g. Change orders.status. That connection becomes the only destination, because the steps belong to one database and must never run on whatever else is checked. The editor's Safe mode then confirms each write.

Nothing runs from the screen.

planColumnChange reaches the browser through @foxschema/ui-shared and a shared/lib/column-change.ts facade, as the import rules require. utilities.columns joins the feature map (FEATURE_MAP.md, data.js, rebuilt page: 35 features).

Tests

ColumnChangePanel.test.tsx, run against the real editor store with a cached schema:

  • a type change shows its impact and 7 steps, and Open in editor creates the tab with the script and only this connection
  • a rename alone is 1 step
  • a refusal is explained
  • picking another column starts a fresh change

All 86 Utilities tests pass, and so do the feature-map drift test, the test-ID catalog (regenerated), ui-shared and the frontend architecture test. tsc and eslint are clean.

Live: on the seeded Postgres demo_a, picking orders.status with type varchar(30) showed idx_a_orders_status under impact and the seven steps with this schema's SQL. Open in editor gave a Change orders.status tab starting at Step 1, with only that connection checked.

🤖 Generated with Claude Code


Note

Medium Risk
The feature produces multi-step DDL/DML migration scripts for column renames and type changes; execution stays manual in the editor, but mistaken runs could still affect production data.

Overview
Adds Utilities → Change Column as a new Maintenance tool wired to the locked connection in the Utilities header. Users pick table/column, optional new name and/or type, and batch size; the UI calls planColumnChange (via @foxschema/ui-shared and a thin shared/lib/column-change re-export) to show impact (indexes, FKs, views/triggers), warnings, refusals, and numbered steps with per-step and full-script copy.

Open in editor creates a new SQL tab titled for the change, loads the commented multi-step script, restricts execution to only that connection, and switches to the SQL editor—nothing executes from the panel itself. Session password unlock and schema load mirror other utilities.

Also adds ColumnChangePanel.test.tsx, e2e column-change-* / utilities-change-column test IDs, and registers utilities.columns in the feature map (35 features).

Reviewed by Cursor Bugbot for commit 90a5feb. Bugbot is set up for automated code reviews on this repo. Configure here.

…, as steps to review

Step 2 of docs/plans/2026-11-01-safe-column-change.md (board card
safe-column-change): the screen over planColumnChange (#588).

Utilities → Change Column, for the credential picked in the header: pick a
table and column, give a new name, a new type (the schema's types are
offered), or both, and a batch size. It shows what the change touches
(indexes, foreign keys, views and triggers that may use it), any warning
(lossy conversion, no triggers on this engine), or why the change is
refused. The steps are numbered, each with its SQL, a rerun-safe badge, a
note and Copy; Copy all and Open in editor take the whole script.

Open in editor opens a new tab named for the change, with this connection
as the only destination: the steps belong to one database, never to
whatever else is checked. Nothing runs from the screen.

planColumnChange reaches the browser through @foxschema/ui-shared and the
shared/lib/column-change facade. utilities.columns joins the feature map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Test IDs

Added (19)

  • column-change-batch
  • column-change-column
  • column-change-copy-all
  • column-change-hint
  • column-change-impact
  • column-change-load-error
  • column-change-new-name
  • column-change-new-type
  • column-change-open-editor
  • column-change-panel
  • column-change-password
  • column-change-refused
  • column-change-step-{…}
  • column-change-step-{…}-copy
  • column-change-steps
  • column-change-table
  • column-change-unlock
  • column-change-warnings
  • utilities-change-column

{…} is a part filled in at run time. The full tree: docs/testing/TEST_IDS.md.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 90a5feb. Configure here.

void navigator.clipboard?.writeText(text).then(() => {
setDone(true);
setTimeout(() => setDone(false), 1500);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy throws without clipboard API

Medium Severity

CopyButton calls .then() on navigator.clipboard?.writeText(...). When clipboard is missing that expression is undefined and the click throws, so Copy all and per-step Copy do nothing. A rejected writeText is also left unhandled. Sibling utilities already go through writeClipboard, which covers both cases and only reports success after a real write.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 90a5feb. Configure here.

setLoadError(null);
try {
ensureConnectionSelected(lockedConnectionId);
await ensureSchema(lockedConnectionId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panel adds editor run destination

Medium Severity

load always calls ensureConnectionSelected, which is add-only: it checks the Utilities credential on the active SQL Editor tab. Opening Change Column can therefore attach that database to some other query. ensureSchema already loads by connection id and does not need the destination ticked. A later Run on the original tab can then hit this extra database.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 90a5feb. Configure here.

editor.setSql(script);
editor.renameTab(useSqlEditorStore.getState().activeTabId, `Change ${table?.name}.${column?.name}`);
editor.selectOnlyConnection(lockedConnectionId);
setActiveView('sqlEditor');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Editor open retargets every shared tab

Medium Severity

Open in editor creates a tab and then calls selectOnlyConnection. When destination sharing is on, that writes the shared list, so every tab switches to this one connection. Unrelated queries that were aimed at another database are silently retargeted, and a later Run can execute against the wrong server.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 90a5feb. Configure here.

@huyplb
huyplb merged commit 813b1e1 into main Nov 2, 2026
13 checks passed
@huyplb
huyplb deleted the feat/column-change-screen branch November 2, 2026 04:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant