Create or review Rock RMS plugin migrations (hotfixes) in Rock/Plugin/HotFixes/. Plugin migrations are single .cs files with sequential numbering and a [MigrationNumber] attribute. Use when the user says "create a plugin migration", "plugin migration", "hotfix migration", "new hotfix", "write a hotfix", "review plugin migration", "check this hotfix", "audit hotfix migration", or needs to create a data fix, configuration change, attribute update, or stored procedure update that ships as a plugin migration. Also use when the user describes a fix or change that targets Rock/Plugin/HotFixes/. Do NOT use for EF migrations in Rock.Migrations/ — use /migration instead. Do NOT use for standalone SQL scripts — use /sql instead.
Create or review Rock RMS plugin migrations (hotfixes) in Rock/Plugin/HotFixes/. Plugin migrations are single .cs files with sequential numbering and a [MigrationNumber] attribute. Use when the user says "create a plugin migration", "plugin migration", "hotfix migration", "new hotfix", "write a hotfix", "review plugin migration", "check this hotfix", "audit hotfix migration", or needs to create a data fix, configuration change, attribute update, or stored procedure update that ships as a plugin migration. Also use when the user describes a fix or change that targets Rock/Plugin/HotFixes/. Do NOT use for EF migrations in Rock.Migrations/ — use /migration instead. Do NOT use for standalone SQL scripts — use /sql instead.
argument-hint
Describe what the plugin migration should do, or say 'review' to review an existing one (e.g., 'fix the HTML content for the SQL runner warning block')
compatibility
Requires Claude Code with access to the Rock RMS codebase.
metadata
{"version":"1.3","author":"Maxwell Eley"}
Rock RMS Plugin Migration Creator & Reviewer
You are creating or reviewing a plugin migration (hotfix) in the Rock RMS codebase. Plugin migrations are single .cs files in Rock/Plugin/HotFixes/ with sequential numbering and a [MigrationNumber] attribute. They inherit from and provide and methods.
Rock.Plugin.Migration
Up()
Down()
The user's request: $ARGUMENTS
Reference Routing Table
Load reference files progressively — only when needed.
Reference File
Load When
references/hotfix-patterns.md
Before writing migration logic (always in write mode)
references/methods-and-sql.md
When choosing methods, writing SQL, or working with stored procedures
references/common-pitfalls.md
Before finalizing any migration — both write and review modes
Do NOT read all files upfront. Read hotfix-patterns.md always for write mode; read others only when their trigger condition is met.
Step 1 — Understand the Request and Determine Mode
Parse what the migration needs to do and determine which mode to use:
Write mode — The user describes what the migration should accomplish, or says "create", "write", "new". Proceed to Step 2 (Write Mode).
Review mode — The user says "review", "check", "audit", or names an existing migration file. Proceed to Step 2 (Review Mode).
Migration categories (for write mode):
Data fix — UPDATE/INSERT/DELETE records to correct bad data
Configuration change — update page layouts, block settings, HTML content
Attribute update — add/modify block type attributes, person attributes, defined values
Stored procedure update — create or alter a stored procedure
Post-update job — add a run-once service job
Block type change — add/update/remove block types and entity types
If ambiguous, ask clarifying questions before proceeding.
Write Mode
Step 2 — Determine Migration Number and Version
Scan Rock/Plugin/HotFixes/ for the highest existing migration number:
Glob: Rock/Plugin/HotFixes/*.cs
Parse the leading number from each filename (e.g., 279_MigrationRollupsForV18_3_0_1.cs → 279).
Next number = highest + 1
Determine minimum Rock version:
If the user specifies a version, use it
If working on a specific release branch, use that version
Every entity inheriting Model<T> has: Id (identity), Guid (uniqueidentifier), IsSystem (bit), CreatedDateTime, ModifiedDateTime, CreatedByPersonAliasId, ModifiedByPersonAliasId
Audit FK columns (CreatedByPersonAliasId, ModifiedByPersonAliasId) reference [PersonAlias], NOT [Person]
Campus FK columns typically use ON DELETE SET NULL
[Order] columns should be calculated from existing max, not hardcoded
Check SystemGuid files:Rock/SystemGuid/{EntityType}.cs for well-known GUIDs
Check enum definitions:Rock.Enums/[Domain]/ for integer values of enum-typed columns
Load references:
Read references/hotfix-patterns.md for common patterns and complete examples
Read references/methods-and-sql.md if using RockMigrationHelper, stored procedures, or complex SQL
Step 4 — Write the Migration File
Use the following template. The copyright block, namespace, class structure, and XML doc comments must match exactly:
// <copyright>// Copyright by the Spark Development Network//// Licensed under the Rock Community License (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.rockrms.com/license//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// </copyright>using System;
namespaceRock.Plugin.HotFixes
{
///<summary>/// [Description of what this migration does]///</summary>///<seealso cref="Rock.Plugin.Migration" />
[MigrationNumber( {number}, "{minRockVersion}" )]
publicclass {ClassName} : Migration
{
///<summary>/// Operations to be performed during the upgrade process.///</summary>publicoverridevoidUp()
{
// Migration logic here
}
///<summary>/// Operations to be performed during the downgrade process.///</summary>publicoverridevoidDown()
{
// Down migrations are not yet supported in plug-in migrations.
}
}
}
For available methods (Sql(), SqlScalar(), RockMigrationHelper.*, EF wrappers), SQL formatting rules, string escaping, stored procedure patterns, and code organization conventions, consult references/methods-and-sql.md.
Step 5 — Validate
Read references/common-pitfalls.md and run through the pre-finalization checklist before presenting.
Output: Write the .cs file to Rock/Plugin/HotFixes/ and show the contents in conversation for review.
Review Mode
Step 2 (Review Mode) — Find the Migration
If $ARGUMENTS names a specific file or migration number, find it in Rock/Plugin/HotFixes/
Otherwise, find the most recently created .cs file (highest number prefix):
Glob: Rock/Plugin/HotFixes/*.cs
Read the full .cs file
Step 3 (Review Mode) — Research for Comparison
Before reviewing, gather the context needed to judge correctness:
Read the actual model files (Rock/Model/[Domain]/[Entity]/[Entity].cs) for every entity the migration touches — verify column types, [Required], [MaxLength], nullable, FK navigation properties
Check Rock/SystemGuid/ files if the migration references GUIDs
Check Rock.Enums/[Domain]/ if the migration uses enum integer values
Read references/hotfix-patterns.md for expected patterns
Read references/common-pitfalls.md for known failure modes
Step 4 (Review Mode) — Audit the Migration
Run through the pre-finalization checklist from references/common-pitfalls.md, plus these additional review-specific checks:
Structural checks
Class inherits Rock.Plugin.Migration
Copyright header and XML doc comments present
[MigrationNumber] attribute present with valid number and version
Cross-reference checks
If migration references SystemGuid constants, verify they exist
If migration uses RockMigrationHelper methods, verify parameter order matches method signatures
Check for potential conflicts with other recent migrations
Step 5 (Review Mode) — Report Findings
Present findings using severity levels:
Severity
Meaning
Examples
CRITICAL
Must fix — will cause errors or data loss
Wrong block type method, missing string escaping, SQL syntax error
WARNING
Should fix — could cause issues or violates conventions
Missing IF NOT EXISTS guard, magic string GUIDs, wrong GUID casing
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.
Examples
Example 1: Fix HTML content
User says: "Fix the SQL runner warning block HTML to use proper Bootstrap classes"
Actions:
Determine next migration number
Research the HtmlContent entity model
Write Sql() with UPDATE on [HtmlContent] by known Guid
Result: File written to Rock/Plugin/HotFixes/280_FixSqlRunnerWarningHtml.cs with a Sql() UPDATE on [HtmlContent] targeting the known Guid.
Example 2: Add a block type attribute
User says: "Add a 'ShowHeader' boolean attribute to the PersonBio block type"
Actions:
Look up PersonBio block type Guid in SystemGuid
Use RockMigrationHelper.AddOrUpdateBlockTypeAttribute()
Result: File written with RockMigrationHelper.AddOrUpdateBlockTypeAttribute() call using the PersonBio block type Guid from Rock/SystemGuid/BlockType.cs.
Example 3: Add a post-update service job
User says: "Add a run-once job to fix broken achievement types from the v18.0 bug"
Actions:
Add using Rock.Model; for typeof() reference
Use RockMigrationHelper.AddPostUpdateServiceJob() with job type, cron expression, and SystemGuid
Result: File written with AddPostUpdateServiceJob() using typeof(Rock.Jobs.PostUpdateJobs.PostV183UpdateAchievementTypes).FullName and the correct SystemGuid.
Example 4: Update a stored procedure
User says: "Update the SynchronizeListRecipients proc to exclude archived members"
Actions:
Read references/methods-and-sql.md for stored procedure pattern
Save/restore ANSI_NULLS and QUOTED_IDENTIFIER
Drop existing procedure if exists
Create updated procedure (inline or via HotFixMigrationResource)
Result: File written with the full stored procedure pattern including session setting save/restore and IF EXISTS guard.
Example 5: Review an existing plugin migration
User says: "review my plugin migration" or /plugin-migration review
Actions:
Find the most recent migration in Rock/Plugin/HotFixes/
Read the .cs file
Enter Review Mode: research models, audit against checklist + common pitfalls
Report findings by severity (CRITICAL/WARNING/NOTE) with go/no-go recommendation
Result: Severity-based findings report with actionable fix suggestions and a go/no-go recommendation.
Troubleshooting
Migration number conflict: Another developer may have used that number. Re-scan the directory for the latest number after pulling latest.
"Down migrations are not yet supported": This is the standard convention for plugin migrations. Keep the comment in Down() as-is unless the migration has a natural reverse (like stored procedure changes).
Large SQL won't fit inline: For stored procedures or large scripts, use HotFixMigrationResource embedded resources. Add the SQL to the .resx file and reference it as HotFixMigrationResource._NNN_Description_ProcedureName.
RockMigrationHelper method not found: Check Rock/Data/MigrationHelper.cs for the exact method signature and overloads.
String escaping errors at runtime: Single quotes must be doubled in SQL within C# strings ('O''Brien'). Curly braces must be doubled in $@"..." strings ({{, }}). See references/common-pitfalls.md for full examples.
Wrong block type method (data loss risk): Never use UpdateBlockTypeByGuid() for Obsidian or Mobile blocks — it can delete entity-based block types. Use AddOrUpdateEntityBlockType() instead. See references/common-pitfalls.md for details.
Missing using Rock.Model;: Required when using typeof() for job types or entity types. Without it, the type reference may not resolve correctly.