Add entity
Skill makigjuro/cloudstack-ai-plugins/plugins/dotnet-architect/skills/add-entity
Claude Code plugin marketplace — AI-powered full-stack cloud engineer for .NET 10 + React 19 + Azure/Terraform/Helm projects. 29 skills, 6 agents, 14 rules.
npx -y skills add makigjuro/cloudstack-ai-plugins --skill add-entityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Scaffold a new domain entity with value object ID, aggregate root, factory method, and domain event. Use whenever the user wants to add a new domain concept, database table, persisted object, or aggregate root to the system.
SKILL.md
7.7 KB, as published. Nobody here has run it
Add Domain Entity
When the user asks to add a new entity, scaffold following the project's domain-driven design patterns.
If the entity involves non-trivial EF Core configuration (owned types, complex value conversions, table splitting), use context7 to look up the current EF Core docs for the specific pattern before writing the configuration.
Arguments
{Entity}-- Entity name in PascalCase (e.g.,Customer,Order){Service}-- Target microservice that owns this entity. Ask if ambiguous.
Configuration
Read cloudstack.json from the project root at the start of execution. Extract:
NAMESPACE=project.namespace(default: detect from*.slnname or first*.csprojroot namespace)DOMAIN_PATH=backend.sharedDomainPath(default: find directory matching**/Domain/containingEntities/)INFRA_PATH=backend.sharedInfraPath(default: find directory matching**/Shared.*Infrastructure/)SERVICES=backend.services[](default: discover fromsrc/*/directories containing.Application/subfolders)SOLUTION=backend.solutionPath(default: find*.slninsrc/)
If cloudstack.json does not exist, auto-detect by scanning the project structure.
Prerequisites
- The target microservice must exist under
src/with Infrastructure and Host projects - The shared Domain project must exist at
{DOMAIN_PATH} - EF Core tools must be installed (
dotnet tool list -g | grep ef)
1. Value Object ID ({DOMAIN_PATH}/ValueObjects/{Entity}Id.cs)
namespace {Namespace}.Domain.ValueObjects;
public class {Entity}Id : ValueObject
{
public Guid Value { get; init; }
public {Entity}Id(Guid value)
{
if (value == Guid.Empty)
throw new ArgumentException("{Entity}Id cannot be empty.", nameof(value));
Value = value;
}
public static {Entity}Id New() => new(Guid.NewGuid());
protected override IEnumerable<object?> GetEqualityComponents()
{
yield return Value;
}
}
2. Entity / Aggregate Root ({DOMAIN_PATH}/Entities/{Entity}.cs)
namespace {Namespace}.Domain.Entities;
public class {Entity} : AggregateRoot<{Entity}Id>
{
public TenantId TenantId { get; private set; }
// Add properties with private setters
// EF Core constructor
protected {Entity}() : base(default!) { }
// Private constructor called by factory method
private {Entity}({Entity}Id id, TenantId tenantId, ...) : base(id)
{
TenantId = tenantId;
// Set properties
}
// Factory method - the ONLY way to create instances
public static {Entity} Create(TenantId tenantId, ...)
{
var id = {Entity}Id.New();
var entity = new {Entity}(id, tenantId, ...);
entity.RaiseDomainEvent(new {Entity}CreatedEvent(id, tenantId, DateTimeOffset.UtcNow));
return entity;
}
// State-changing methods raise domain events
public void Update(...)
{
// Modify state
RaiseDomainEvent(new {Entity}UpdatedEvent(Id, ...));
}
}
3. Domain Event ({DOMAIN_PATH}/Events/{Entity}CreatedEvent.cs)
namespace {Namespace}.Domain.Events;
public class {Entity}CreatedEvent : DomainEvent
{
public {Entity}Id {Entity}Id { get; }
public TenantId TenantId { get; }
public DateTimeOffset OccurredAt { get; }
public {Entity}CreatedEvent({Entity}Id entityId, TenantId tenantId, DateTimeOffset occurredAt)
{
{Entity}Id = entityId;
TenantId = tenantId;
OccurredAt = occurredAt;
}
}
4. Repository Interface (Domain/ or Application/)
public interface I{Entity}Repository
{
Task<{Entity}?> GetByIdAsync({Entity}Id id, CancellationToken cancellationToken = default);
Task AddAsync({Entity} entity, CancellationToken cancellationToken = default);
Task SaveChangesAsync(CancellationToken cancellationToken = default);
}
public interface I{Entity}QueryRepository
{
Task<{Entity}?> GetByIdAsync({Entity}Id id, CancellationToken cancellationToken = default);
Task<(IReadOnlyCollection<{Entity}> Items, int TotalCount)> ListAsync(TenantId tenantId, int page, int pageSize, CancellationToken cancellationToken = default);
}
5. EF Core Configuration (Infrastructure/Persistence/Configurations/{Entity}Configuration.cs)
public class {Entity}Configuration : IEntityTypeConfiguration<{Entity}>
{
public void Configure(EntityTypeBuilder<{Entity}> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Id)
.HasConversion(id => id.Value, value => new {Entity}Id(value));
builder.Property(x => x.TenantId)
.HasConversion(id => id.Value, value => new TenantId(value));
// Configure other properties
}
}
6. Add DbSet to DbContext
public DbSet<{Entity}> {Entity}s => Set<{Entity}>();
7. EF Core Migration (MANDATORY)
After adding the DbSet and entity configuration, always create a migration immediately:
dotnet ef migrations add Add{Entity} \
--project src/{Service}/{Service}.Infrastructure \
--startup-project src/{Service}/{Service}.Host
Review the generated migration to verify only expected changes are included. This step is not optional -- skipping it causes PendingModelChangesWarning errors at startup.
Checklist
- Value object ID with validation and
GetEqualityComponents() - Entity inherits
AggregateRoot<TId>with protected parameterless constructor - Factory method is the only creation path
- Domain events raised in factory and state-change methods
- Past-tense event names:
{Entity}CreatedEvent,{Entity}UpdatedEvent - Separate command and query repository interfaces
- EF Core configuration with value object conversions
- DbSet added to DbContext
- EF Core migration created for the new table
- No framework dependencies in Domain layer
Output
After scaffolding, report:
## Scaffolded: {Entity}
Files created/modified:
- `{DOMAIN_PATH}/ValueObjects/{Entity}Id.cs`
- `{DOMAIN_PATH}/Entities/{Entity}.cs`
- `{DOMAIN_PATH}/Events/{Entity}CreatedEvent.cs`
- `src/{Service}/{Service}.Application/` -- Repository interfaces
- `src/{Service}/{Service}.Infrastructure/Persistence/Configurations/{Entity}Configuration.cs`
- `src/{Service}/{Service}.Infrastructure/Persistence/{Service}DbContext.cs` (modified)
- Migration: `src/{Service}/{Service}.Infrastructure/Persistence/Migrations/{timestamp}_Add{Entity}.cs`
Next: Run `/add-command` or `/add-query` to create endpoints for this entity.
Error Handling
- DbContext not found: Search for
*DbContext.csin the Infrastructure project. If none exists, the service may not have persistence set up yet -- warn the user. - EF Core tools not installed: Run
dotnet tool install --global dotnet-efand retry. - Migration fails: Check that the entity configuration is correct and the DbSet was added. Read the error output for hints.
- Value object ID already exists: The entity name may conflict with an existing one. Check
{DOMAIN_PATH}/ValueObjects/before creating.
Related Skills
/add-commandto create commands that operate on this entity/add-queryto create queries that read this entity/add-event-handlerto handle the domain events raised by this entity/add-migrationto create the EF Core migration for the new table