Write or review Up() and Down() method bodies for Rock RMS Entity Framework migrations in Rock.Migrations/Migrations/. The developer must first scaffold files via 'Add-Migration'. Use when the user says "write the migration", "EF migration", "review the migration", "check my migration", or describes schema changes, data migrations, or platform entity changes for an EF migration. Do NOT use for plugin/hotfix migrations — use /plugin-migration instead. Do NOT use for standalone SQL scripts — use /sql instead.
You are writing or reviewing the Up() and Down() method bodies for an Entity Framework migration in the Rock RMS codebase. The developer has already scaffolded the migration files via Add-Migration in Package Manager Console — your job is to either write the migration logic or review what's already been written.
The user's request: $ARGUMENTS
Load reference files progressively — only when needed.
| Reference File | Load When |
|---|---|
references/ef-patterns.md | Before writing any migration logic (always in write mode) |
references/migration-helper-methods.md | When using RockMigrationHelper for pages, blocks, attributes, etc. |
references/common-pitfalls.md | Before finalizing any migration — both write and review modes |
Do NOT read all files upfront. Read ef-patterns.md always for write mode; read others only when their trigger condition is met.
This is a hard gate. Before doing anything else:
$ARGUMENTS includes a migration name, search for it in Rock.Migrations/Migrations/Glob: Rock.Migrations/Migrations/*.cs (exclude *.Designer.cs)
If files are NOT found, stop immediately and tell the user:
I couldn't find scaffolded migration files. Before using this skill, you need to run
Add-Migration YourMigrationNamein the Package Manager Console (targeting the Rock.Migrations project). This generates the .cs, .Designer.cs, and .resx files. Once that's done, invoke/migrationagain.
Do NOT proceed past this step without confirmed migration files.
public partial class {Name} : Rock.Migrations.RockMigrationNow determine which mode to use:
/migration without describing what to write. Proceed to Step 3 (Review Mode).If you can't tell which mode, look at the user's $ARGUMENTS. If they describe what the migration should do, it's write mode. If they ask to review, check, or validate, it's review mode. When in doubt, ask.
Parse what the migration needs to accomplish from $ARGUMENTS and conversation context:
If the intent is unclear, ask clarifying questions before proceeding.
Before writing migration logic, you must understand the actual database schema. Do not guess column names, types, or relationships.
Read the model files:
Rock/Model/[Domain]/[Entity]/[Entity].csRock/Model/**/{EntityName}.cs[Required] (NOT NULL), [MaxLength(N)] (string limits), FK navigation properties, enum-typed properties, default valuesUnderstand Rock's standard column patterns:
Model<T> has: Id, Guid, IsSystem, CreatedDateTime, ModifiedDateTime, CreatedByPersonAliasId, ModifiedByPersonAliasId[PersonAlias], NOT [Person] — no cascade deleteON DELETE SET NULL[Order] columns should be calculated from existing max, not hardcoded to 0Check SystemGuid files if referencing well-known entities: Rock/SystemGuid/{EntityType}.cs
Check enum definitions if a column uses an enum type: Rock.Enums/[Domain]/
Load references:
references/ef-patterns.md for EF methods and correct migration patternsreferences/migration-helper-methods.md if using RockMigrationHelperBuild the Up() body following this order of operations:
For the full list of available EF methods and their signatures, consult references/ef-patterns.md. For RockMigrationHelper method signatures, consult references/migration-helper-methods.md.
/sql skill (UPPERCASE keywords, bracketed identifiers)$@"..." for multi-line SQL with embedded constantsEvery non-trivial migration should break its logic into private methods — one per logical operation, with matching Up/Down pairs. The Up() and Down() methods themselves should read like a table of contents:
public override void Up()
{
AddConnectionsPages_Up();
AddConnectionNavigationViewBlocks_Up();
AddConnectionRequestNoteType_Up();
UpdateConnectionProperties();
}
public override void Down()
{
AddConnectionNavigationViewBlocks_Down();
AddConnectionsPages_Down();
}
Naming convention: Developer initials prefix (optional) + descriptive name + _Up()/_Down() suffix.
When to use: Any migration with more than one logical operation, always for rollups, or when logic is complex enough to benefit from a named method.
Additional organization:
private const string at class level for GUIDs referenced multiple times#region Private Methods / #endregion in complex migrationsBuild the Down() body as the exact reverse of Up():
Edge cases:
Read references/common-pitfalls.md and run through this checklist before presenting:
AddColumn types match the model's [Required], [MaxLength], nullable attributesdefaultValue or defaultValueSqlRock.SystemGuid constants used instead of magic string GUIDs where available$@"..." stringsIX_TableName_ColumnName)partial class keyword are presentAddOrUpdateEntityBlockType() for Obsidian/Mobile blocks, UpdateBlockType()/UpdateBlockTypeByGuid() for WebForms onlydbo. prefixUpdateEntityType() use the correct version number for the current branchOutput: Edit the existing .cs migration file in place with the completed Up() and Down() bodies. Also show the complete file in conversation for review.
Before reviewing, gather the context needed to judge correctness:
Rock/Model/[Domain]/[Entity]/[Entity].cs) for every entity the migration touches — verify column types, [Required], [MaxLength], nullable, FK navigation propertiesRock/SystemGuid/ files if the migration references GUIDsRock.Enums/[Domain]/ if the migration uses enum integer valuesreferences/ef-patterns.md for the expected patternsreferences/common-pitfalls.md for known failure modesRun through the same 14-point validation checklist from Step 7 above, plus these additional review-specific checks:
Rock.Migrations.RockMigrationPresent findings using severity levels:
| Severity | Meaning | Examples |
|---|---|---|
| CRITICAL | Must fix before merging — will cause errors or data loss | Missing Down() reversal for schema change, wrong FK cascade, wrong column type |
| WARNING | Should fix — could cause issues or violates conventions | Missing IF NOT EXISTS guard, magic string GUIDs instead of SystemGuid, inconsistent ordering |
| NOTE | Consider — minor improvement or style suggestion | Missing XML doc comment, could use private const string for repeated GUIDs |
Format each finding as:
[SEVERITY-N] Short title
Description of the issue and what to change.
Line/area: [where in the file]
End with a summary: total findings by severity and a go/no-go recommendation.
If the migration is clean: Say so. Don't invent issues to fill a report.
User says: "I added an AreDuplicateRegistrantsPrevented bool to RegistrationTemplate"
Actions:
AddColumn("dbo.RegistrationTemplate", "AreDuplicateRegistrantsPrevented", c => c.Boolean(nullable: false)); in Up()DropColumn("dbo.RegistrationTemplate", "AreDuplicateRegistrantsPrevented"); in Down()User says: "Add a new page for MCP Server configuration with an Obsidian block"
Actions:
User says: "review my migration" or /migration review
Actions:
User says: "Make BlockId nullable on HtmlContent with ON DELETE SET NULL"
Actions:
"Migration files not found": User needs to run Add-Migration YourName in Package Manager Console first.
Auto-scaffolded content looks wrong: EF sometimes misdetects model changes. Read the actual model file to verify what columns/types changed.
MigrationHelper method signature mismatch: Check Rock/Data/MigrationHelper.cs (~9,500 lines) for the exact overload and parameter order.
Down() data loss concern: If Down() can't safely reverse a data migration, add a comment explaining why and leave that portion empty.
Conflict with existing migration: If another migration in the same release touches the same table, coordinate the order of operations carefully.