prisma-migration-reviewer — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited prisma-migration-reviewer (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Before generating any output, read config/defaults.md and adapt all patterns, imports, and code examples to the user's configured stack.
migration.sql file (typically at prisma/migrations/<timestamp>_<name>/migration.sql).These operations destroy data. Block deployment until reviewed.
Column drop:
-- CRITICAL: Drops column and all its data
ALTER TABLE "User" DROP COLUMN "legacyId";Safe alternative: Rename to _deprecated_legacyId, drop in a later migration after confirming no code references it.
Table drop:
-- CRITICAL: Drops table and all rows
DROP TABLE "OldAuditLog";Safe alternative: Rename table to _archived_OldAuditLog. Drop after data is verified migrated or backed up.
Type change with data loss:
-- CRITICAL: Changing TEXT to VARCHAR(50) truncates values longer than 50 chars
ALTER TABLE "Post" ALTER COLUMN "title" TYPE VARCHAR(50);Safe alternative: First query SELECT MAX(LENGTH(title)) FROM "Post" to verify no data exceeds the new limit.
Enum value removal:
-- CRITICAL: Rows with removed value become invalid
-- Prisma recreates enum without the old value
CREATE TYPE "Role_new" AS ENUM ('USER', 'ADMIN');
ALTER TABLE "User" ALTER COLUMN "role" TYPE "Role_new" USING ("role"::text::"Role_new");
DROP TYPE "Role";
ALTER TYPE "Role_new" RENAME TO "Role";Safe alternative: First update all rows with the old value, then remove it.
NOT NULL on existing column without default:
-- WARNING: Fails if any existing rows have NULL in this column
ALTER TABLE "User" ALTER COLUMN "name" SET NOT NULL;Safe alternative:
UPDATE "User" SET "name" = 'Unknown' WHERE "name" IS NULL;ALTER TABLE "User" ALTER COLUMN "name" SET NOT NULL;Adding unique constraint on column with potential duplicates:
-- WARNING: Fails if duplicate values exist
ALTER TABLE "User" ADD CONSTRAINT "User_email_key" UNIQUE ("email");Safe alternative: First query SELECT email, COUNT(*) FROM "User" GROUP BY email HAVING COUNT(*) > 1 and resolve duplicates.
Renaming column (Prisma drops and recreates):
-- WARNING: Prisma may generate DROP + ADD instead of RENAME, losing data
ALTER TABLE "User" DROP COLUMN "name";
ALTER TABLE "User" ADD COLUMN "fullName" TEXT;Safe alternative: Use raw SQL migration with ALTER TABLE "User" RENAME COLUMN "name" TO "fullName".
Large table ALTER:
-- WARNING: On tables with millions of rows, this acquires an exclusive lock
ALTER TABLE "Event" ADD COLUMN "metadata" JSONB;For PostgreSQL, adding a nullable column with no default is fast (no table rewrite). But adding a column with a DEFAULT requires a table rewrite on PostgreSQL < 11.
Missing index on foreign key:
ALTER TABLE "Post" ADD COLUMN "authorId" TEXT NOT NULL;
ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey"
FOREIGN KEY ("authorId") REFERENCES "User"("id");
-- INFO: No index on "Post"."authorId" — queries filtering/joining on this FK will be slowRecommend: CREATE INDEX "Post_authorId_idx" ON "Post"("authorId");
Missing composite index for common query patterns:
-- INFO: If queries often filter by both status and createdAt, add a composite index
CREATE INDEX "Order_status_createdAt_idx" ON "Order"("status", "createdAt");schema.prisma, Prisma generates a column drop and add, not a rename. Always use npx prisma migrate --create-only and edit the SQL to use RENAME COLUMN.String? to String generates SET NOT NULL without a backfill. Always add a backfill step.Before approving any migration:
DROP COLUMN or DROP TABLE without confirmed backup or rename strategySET NOT NULL without backfill for existing NULL rowsUNIQUE constraint on columns with unverified uniquenessRENAME COLUMN, not drop + add## Migration Review: `<migration_name>`
### Summary
| Risk Level | Count |
|-----------|-------|
| 🔴 CRITICAL | N |
| 🟡 WARNING | N |
| 🔵 INFO | N |
### Findings
#### 🔴 CRITICAL: [Title]
**Statement**: `[SQL statement]`
**Risk**: [What can go wrong]
**Recommendation**: [Safer alternative with SQL]
#### 🟡 WARNING: [Title]
...
#### 🔵 INFO: [Title]
...
### Pre-Deploy Checklist
- [ ] [Actionable step based on findings]See references/migration-risks.md for the complete catalog of dangerous operations and zero-downtime patterns.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.