Create Knex database migrations for the Benefriches API. Use when adding, modifying, or removing database columns/tables. Handles schema changes (create table, add/drop/rename columns), data migrations, and updates to tableTypes.d.ts.
설치
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
Create Knex database migrations for the Benefriches API. Use when adding, modifying, or removing database columns/tables. Handles schema changes (create table, add/drop/rename columns), data migrations, and updates to tableTypes.d.ts.
effort
low
allowed-tools
Bash, Read, Write
Create Database Migration
Generate timestamped Knex migrations following project conventions.
Quick Start
Create migration: pnpm --filter api knex:new-migration {description}
Example: pnpm --filter api knex:new-migration add-column-email-to-users-table
Creates timestamped file in apps/api/src/shared-kernel/adapters/sql-knex/migrations/
Implement up() and down() functions in the generated file
Update apps/api/src/shared-kernel/adapters/sql-knex/tableTypes.d.ts if schema changes
If new table created: add table name to tablesToCleanUp in apps/api/test/tablesToCleanUp.ts (child tables before parent tables)
Run: pnpm --filter api knex:migrate-latest
Transaction Handling
Knex automatically wraps each migration in a transaction — the knex parameter in up()/down() is already a transaction object. Do NOT call knex.transaction() inside migrations.
importtype { Knex } from"knex";
exportasyncfunctionup(knex: Knex): Promise<void> {
const rows = awaitknex("table_name")
.select("id", "json_column")
.whereRaw(`json_column::json->>'field' IS NOT NULL`);
for (const row of rows) {
const data = row.json_columnasRecord<string, unknown>;
const updated = { ...data, newField: transformValue(data.oldField) };
delete (updated asRecord<string, unknown>).oldField;
awaitknex("table_name").update({ json_column: updated }).where({ id: row.id });
}
}
exportasyncfunctiondown(): void {
return; // Data migration not reversible
}
Column Types Reference
Knex Method
PostgreSQL
TypeScript
table.uuid("id")
UUID
string
table.string("name")
VARCHAR(255)
string
table.text("desc")
TEXT
string
table.boolean("flag")
BOOLEAN
boolean
table.integer("count")
INTEGER
number
table.float("amount")
REAL
number
table.timestamp("at")
TIMESTAMP
Date
table.json("data")
JSON
Record<string, unknown>
tableTypes.d.ts Updates
After schema changes, update apps/api/src/shared-kernel/adapters/sql-knex/tableTypes.d.ts:
// Add new type for new tabletypeSqlNewTable = {
id: string;
name: string;
created_at: Date;
optional_col: string | null; // nullable columns use | null
};
// Register in Tables interfacedeclaremodule"knex/types/tables" {
interfaceTables {
new_table: SqlNewTable; // table_name: SqlType
}
}
Rules:
Use snake_case for column names (matches DB)
Use | null for nullable columns (not ?:)
Use Date for timestamps (Knex converts)
Register table in Tables interface
Checklist
Migration created with pnpm --filter api knex:new-migration {description}
up() implements forward migration
down() reverses migration (or returns void if not possible)
tableTypes.d.ts updated for schema changes (new table → add SqlXxx type + register in Tables interface)
If new table created: add table name to tablesToCleanUp array in apps/api/test/tablesToCleanUp.ts (respecting deletion order: child tables before parent tables)
Migration tested: pnpm --filter api knex:migrate-latest
Rollback tested: pnpm --filter api knex:migrate-rollback