Scaffold a new Rock RMS entity model with all required files and conventions. Creates the entity class, EntityTypeConfiguration, SystemGuid entry, optional enum definitions, and optional service class. Use when the user says "create an entity", "new entity model", "scaffold entity", "add a new table", "new model class", or describes a new domain object that needs a database table. Also use when asked to "review entity model" or "check my entity". Do NOT use for ViewModels/Bags — use /bag-generator instead. Do NOT use for migrations — use /migration after scaffolding the entity.
You are scaffolding a new entity model in the Rock RMS codebase, or reviewing an existing one. Rock entities follow strict conventions — this skill enforces them.
The user's request: $ARGUMENTS
Load reference files progressively — only when needed.
| Reference File | Load When |
|---|---|
references/entity-patterns.md | Before writing any entity code (always in write mode) |
references/common-pitfalls.md | Before finalizing — both write and review modes |
Do NOT read all files upfront. Read entity-patterns.md always for write mode; read common-pitfalls.md before finalizing.
Write mode — The user describes a new entity or says "create", "scaffold", "add". Proceed to .
Review mode — The user says "review", "check", "audit", or names an existing entity file. Proceed to Step 2 (Review Mode).
For write mode, parse the user's intent:
CampusSchedule, not CampusSchedules)IOrdered), active flag (IHasActiveFlag), caching (ICacheable)?Model<T> (default — includes audit columns, security, attributes) or Entity<T> (simple entities without audit)If the user doesn't specify all of these, make reasonable decisions based on the entity's purpose, but ask about the domain if unclear.
Before writing any code:
references/entity-patterns.md for the complete entity template and conventionsRock/Model/**/{EntityName}.csRock/SystemGuid/EntityType.cs for naming conventions and to ensure no GUID conflictsRock.Enums/ if the entity needs new enum types — verify the domain folder existsEvery entity needs a unique GUID. There are two approaches used in the codebase:
Option A — SystemGuid constant (preferred for new entities):
Rock/SystemGuid/EntityType.cs in alphabetical order// In Rock/SystemGuid/EntityType.cs:
/// <summary>
/// The campus schedule entity type
/// </summary>
public const string CAMPUS_SCHEDULE = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
// In the entity class:
[Rock.SystemGuid.EntityTypeGuid( Rock.SystemGuid.EntityType.CAMPUS_SCHEDULE )]
Option B — Inline GUID string: Many entities (especially newer ones) use an inline GUID string directly in the attribute instead of a SystemGuid constant. This is acceptable but less refactorable:
[Rock.SystemGuid.EntityTypeGuid( "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" )]
Use Option A when the entity type GUID will be referenced in migrations, seed data, or other code. Use Option B for entities that are only referenced by type name.
File path: Rock/Model/[Domain]/[EntityName]/[EntityName].cs
Namespace: Rock.Model
The entity file contains both the entity class and its EntityTypeConfiguration in the same file. Read references/entity-patterns.md for the complete template and all annotation requirements.
Key structural requirements:
[RockDomain], [Table], [DataContract], [CodeGenerateRest], [Rock.SystemGuid.EntityTypeGuid]Model<T> (or Entity<T> for non-audited entities)#region Entity Properties / #region Navigation Properties / #region Public MethodsEntityTypeConfiguration class in #region Entity Configuration at the bottom of the fileIf the entity has enum-typed properties, create the enum file:
Rock.Enums/[Domain]/[EnumName].csRock.Model[Enums.EnumDomain( "Domain" )]Only create Rock/Model/[Domain]/[EntityName]/[EntityName]Service.cs if the entity needs custom query methods beyond standard CRUD. The base Service<T> class (auto-generated via CodeGeneration) provides standard operations.
If created:
partial class extending the auto-generated serviceRockContextGetByParentId())If a service method needs multiple behavior-modifying parameters, create an Options POCO:
Rock/Model/[Domain]/[EntityName]/Options/[PocoName].csRock.Model.[Domain].[EntityName].OptionsRead references/common-pitfalls.md and run through the checklist before presenting.
Output: Write the files and show their contents in conversation. Remind the user of next steps:
Rock.CodeGeneration (WPF app) to generate the [Entity]Service.CodeGenerated.cs file/migration to scaffold and write the EF migration that creates the table/bag-generator (if available) to create ViewModels/Bags for Obsidian blocks$ARGUMENTS names a specific entity, find it: Rock/Model/**/{EntityName}.csreferences/entity-patterns.md for expected patternsRock/SystemGuid/EntityType.cs — verify the GUID exists and matchesRock.Enums/[Domain]/ with correct attributesRead references/common-pitfalls.md and run through the checklist, plus:
Model<T> or Entity<T> (not raw DbContext entity)partial class keyword used#region Entity Configuration<summary> tags; older entities also have <value> tags)[DataMember] on entity properties (navigation properties may omit it — check if entity follows newer or older conventions)[DataMember( IsRequired = true )] on required properties[Required] on non-nullable value-type properties and required string properties[MaxLength] on string properties that need length constraintsint? for optional relationships, non-nullable int for requiredfalse; parent-child: depends)Present findings using severity levels:
| Severity | Meaning | Examples |
|---|---|---|
| CRITICAL | Must fix — will cause build errors, runtime failures, or data issues | Missing EntityTypeConfiguration, wrong base class, missing SystemGuid |
| WARNING | Should fix — violates conventions or could cause subtle bugs | Missing [DataMember], wrong cascade rule, missing XML docs |
| NOTE | Consider — minor improvement | Could implement IOrdered, property naming suggestion |
End with a summary: total findings by severity and a go/no-go recommendation.
If the entity is clean: Say so. Don't invent issues to fill a report.
User says: "Create a CampusSchedule entity in Core that links a Campus to a Schedule with an IsActive flag"
Actions:
Rock/SystemGuid/EntityType.csRock/Model/Core/CampusSchedule/CampusSchedule.cs with:
CampusId (required FK), ScheduleId (required FK), IsActive (bool)HasRequired for both FKs, cascade delete falseResult: Two files written — SystemGuid entry and entity file. User reminded to run CodeGeneration and /migration.
User says: "Create a NotificationPreference entity in Communication with a PreferenceType enum (Email, SMS, Push) and an Order property"
Actions:
Rock.Enums/Communication/NotificationPreferenceType.csRock/SystemGuid/EntityType.csIOrdered with PreferenceType enum property and Order int propertyResult: Three files written — enum definition, SystemGuid entry, and entity file with IOrdered interface.
User says: "Create a MembershipCard entity in Group with a PersonAliasId, GroupId, ExpirationDate, and a service method to get active cards for a person"
Actions:
MembershipCardService.cs partial class with GetActiveCardsForPerson(int personAliasId) methodResult: Three files written — SystemGuid entry, entity file, and custom service file.
User says: "review the AIAgent entity"
Actions:
Rock/Model/AI/AIAgent/AIAgent.csResult: Severity-based findings report with go/no-go recommendation.
"Entity not discovered by EF": Rock uses reflection to auto-discover IEntity implementations. Ensure the class inherits from Model<T> or Entity<T>, is public, is not abstract, and doesn't have [NotMapped]. No DbSet registration is needed.
"CodeGeneration didn't produce a service file": The CodeGeneration WPF app (Rock.CodeGeneration/) generates [Entity]Service.CodeGenerated.cs files. It must be run manually after creating a new entity. The generated file goes in Rock/Model/CodeGenerated/.
"Table name conflicts": The [Table] attribute value should match the entity name (singular, no prefix). Rock removes the pluralizing convention, so [Table("CampusSchedule")] maps to table [CampusSchedule].
"FK cascade delete causing issues": Default to WillCascadeOnDelete( false ) for most relationships. Only use true for true parent-child ownership where deleting the parent should delete all children. PersonAlias audit FKs must always be false.
"Enum not recognized in entity": Ensure the enum is in Rock.Enums/[Domain]/ with namespace Rock.Model and has the [Enums.EnumDomain("Domain")] attribute. The enum project must be referenced by the Rock project.
"Build error: 'EntityTypeConfiguration' not found": Add using System.Data.Entity.ModelConfiguration; to the entity file's using statements.