You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(cli): integrate cutover/drop with drizzle-kit; phase-aware status
Three issues from the spike's lifecycle smoke-test, all in the
encrypt CLI. Bundled into one commit because they touch adjacent
files.
Issue 1: `encrypt drop` wrote a self-named timestamped migration
(`20260504112456_drop_*.sql`) that drizzle-kit migrate refused to
pick up — no journal entry, wrong prefix. Same shape `db install
--drizzle` already gets right by shelling out to `drizzle-kit
generate --custom`.
Fix: detect drizzle and route through a new
`packages/cli/src/commands/encrypt/drizzle-helper.ts` that wraps
`drizzle-kit generate --custom --name=...`, locates the generated
file, and writes the drop SQL into it. The migration now lands
with a journal entry; `drizzle-kit migrate` applies it like any
other migration. Non-drizzle projects keep the timestamped-file
fallback (Prisma / raw-SQL paths planned).
Issue 2: `encrypt cutover` ran `eql_v2.rename_encrypted_columns()`
live and never told drizzle. Drizzle's `meta/_journal.json` and
snapshot stayed pinned to the pre-rename shape, so the next
`drizzle-kit generate` against the source produced a confused
diff trying to recreate the old layout.
Fix: after cutover succeeds (transaction committed), scaffold a
follow-up custom drizzle migration containing idempotent
`ALTER TABLE … RENAME COLUMN` statements wrapped in a `DO` block
that checks whether `<col>_encrypted` still exists. On the source
DB the rename already ran, so the block is a no-op and Drizzle's
journal still records the migration; on a fresh restore the block
performs the rename. Same file, both behaviours, reproducible.
Non-drizzle projects skip the resync step (logged-only warning if
scaffolding fails).
Issue 3: `encrypt status` rendered `rowsProcessed/rowsTotal (pct%)`
uniformly across every phase. The same fraction means different
things at different points in the lifecycle, and `0/0 (100%)` for
a `backfilled` column that needed no encrypting reads as
nonsense.
Fix: phase-aware framing for the PROGRESS column. `schema-added`
shows `—`. `dual-writing` shows `(awaiting backfill)`. `backfilling`
keeps the fraction. `backfilled` / `cut-over` / `dropped` show a
plain completion marker instead of a degenerate ratio. Same data,
phase-appropriate label.
Wire `--migrations-dir <path>` through to cutover for projects with
non-default drizzle out dirs.
166 tests pass; biome clean.
Coverage check during dual-writing (the bug report's bonus
suggestion — show "rows-with-both-columns / total" rather than
just "awaiting backfill") needs a live SELECT against the user's
table, not just the cs_migrations data we already have. Tracked
as a follow-up; today's status surfaces phase awareness without
new queries.
`Could not scaffold the Drizzle rename migration: ${reason}\nDrizzle's snapshot may be out of sync with the live schema. Run \`drizzle-kit pull\` to resync, or scaffold the rename migration manually.`,
@@ -54,41 +64,56 @@ export async function dropCommand(options: DropCommandOptions) {
54
64
process.exit(1)
55
65
}
56
66
57
-
constmigrationsDir=path.resolve(
58
-
process.cwd(),
59
-
options.migrationsDir??'drizzle',
60
-
)
61
-
fs.mkdirSync(migrationsDir,{recursive: true})
67
+
constdropSql=`-- Generated by stash encrypt drop\n-- Drops the plaintext column now that ${options.table}.${options.column} is encrypted.\n\nALTER TABLE "${options.table}" DROP COLUMN "${options.column}_plaintext";\n`
constsql=`-- Generated by @cipherstash/cli encrypt drop\n-- Drops the plaintext column now that ${options.table}.${options.column} is encrypted.\n\nALTER TABLE "${options.table}" DROP COLUMN "${options.column}_plaintext";\n`
71
-
fs.writeFileSync(filePath,sql,'utf-8')
75
+
if(isDrizzle){
76
+
// Scaffold via drizzle-kit so the migration is journaled + snapshotted.
77
+
// Without this, the file ships but `drizzle-kit migrate` never picks it
0 commit comments