Categories
Agent Tooling (71)
- .agents/skills/agent-browser/references/authentication.md
- .agents/skills/agent-browser/references/commands.md
- .agents/skills/agent-browser/references/profiling.md
- .agents/skills/agent-browser/references/proxy-support.md
- .agents/skills/agent-browser/references/session-management.md
- .agents/skills/agent-browser/references/snapshot-refs.md
- .agents/skills/agent-browser/references/video-recording.md
- .agents/skills/agent-browser/SKILL.md
- .agents/skills/aspire-deployment/references/aws.md
- .agents/skills/aspire-deployment/references/azure.md
- .agents/skills/aspire-deployment/references/cicd.md
- .agents/skills/aspire-deployment/references/docker-compose.md
- .agents/skills/aspire-deployment/references/javascript.md
- .agents/skills/aspire-deployment/references/kubernetes.md
- .agents/skills/aspire-deployment/references/preflight.md
- .agents/skills/aspire-deployment/SKILL.md
- .agents/skills/aspire-monitoring/references/diagnostics-bridge.md
- .agents/skills/aspire-monitoring/references/monitoring.md
- .agents/skills/aspire-monitoring/references/playwright-handoff.md
- .agents/skills/aspire-monitoring/SKILL.md
- .agents/skills/aspire-orchestration/references/agent-workflows.md
- .agents/skills/aspire-orchestration/references/app-commands.md
- .agents/skills/aspire-orchestration/references/detection.md
- .agents/skills/aspire-orchestration/references/resource-management.md
- .agents/skills/aspire-orchestration/references/safety-guardrails.md
- .agents/skills/aspire-orchestration/SKILL.md
- .agents/skills/aspire/references/aspire-13-3-breaking-changes.md
- .agents/skills/aspire/SKILL.md
- .agents/skills/aspireify/references/apphost-wiring.md
- .agents/skills/aspireify/references/csharp-authoring.md
- .agents/skills/aspireify/references/docker-compose.md
- .agents/skills/aspireify/references/full-solution-apphosts.md
- .agents/skills/aspireify/references/javascript-apps.md
- .agents/skills/aspireify/references/opentelemetry.md
- .agents/skills/aspireify/references/scan-and-propose.md
- .agents/skills/aspireify/references/service-defaults.md
- .agents/skills/aspireify/references/typescript-authoring.md
- .agents/skills/aspireify/references/validation.md
- .agents/skills/aspireify/SKILL.md
- .agents/skills/caveman-compress/README.md
- .agents/skills/caveman-compress/SECURITY.md
- .agents/skills/caveman-compress/SKILL.md
- .agents/skills/caveman-help/README.md
- .agents/skills/caveman-help/SKILL.md
- .agents/skills/caveman-stats/README.md
- .agents/skills/caveman-stats/SKILL.md
- .agents/skills/caveman/README.md
- .agents/skills/caveman/SKILL.md
- .agents/skills/csharp-developer/SKILL.md
- .agents/skills/dotnet-inspect/SKILL.md
- .agents/skills/efcore-data-layer/SKILL.md
- .agents/skills/git/SKILL.md
- .agents/skills/microsoft-code-reference/SKILL.md
- .agents/skills/microsoft-docs/SKILL.md
- .agents/skills/microsoft-skill-creator/references/skill-templates.md
- .agents/skills/microsoft-skill-creator/SKILL.md
- .agents/skills/skill-creator/references/output-patterns.md
- .agents/skills/skill-creator/references/workflows.md
- .agents/skills/skill-creator/SKILL.md
- .agents/skills/tunit-testing/references/aspire-integration.md
- .agents/skills/tunit-testing/references/aspnetcore-integration.md
- .agents/skills/tunit-testing/references/assertions.md
- .agents/skills/tunit-testing/references/data-driven.md
- .agents/skills/tunit-testing/references/infrastructure-and-troubleshooting.md
- .agents/skills/tunit-testing/references/lifecycle-hooks.md
- .agents/skills/tunit-testing/SKILL.md
- AGENTS.md
- backend/AGENTS.md
- backend/tests/AGENTS.md
- Front/AGENT.md
- opencode.jsonc
name: efcore-data-layer description: This skill should be used by AI agents to assist with Entity Framework Core data layer development, including entity configuration, migrations, and database access patterns.
Entity Framework Core Data Layer Skill
Project Structure
- DbContext:
KdsAiDbContextinKds.Ai.Data - Entities:
Kds.Ai.Data/Entities/ - Configurations:
Kds.Ai.Data/Configurations/ - Migrations:
Kds.Ai.Data/Migrations/
Entity Configuration
Use Fluent API configuration instead of data annotations. Create separate configuration classes implementing IEntityTypeConfiguration<TEntity>:
public sealed class MonitorSpecConfiguration : IEntityTypeConfiguration<MonitorSpec>
{
public void Configure(EntityTypeBuilder<MonitorSpec> builder)
{
builder.HasKey(x => x.Id);
builder.Property(x => x.Name).HasMaxLength(200).IsRequired();
builder.HasIndex(x => x.RestaurantId);
builder.HasMany(x => x.Runs)
.WithOne(x => x.MonitorSpec)
.HasForeignKey(x => x.MonitorSpecId);
}
}Important: Configurations are automatically discovered and applied via ApplyConfigurationsFromAssembly in KdsAiDbContext.OnModelCreating. Do NOT manually register configurations - just create the configuration class in the Configurations/ folder and it will be auto-discovered.
Entity ID Convention
Use Guid as primary key type for all entities:
public sealed class MonitorSpec
{
public Guid Id { get; set; }
public Guid RestaurantId { get; set; }
public string Name { get; set; } = string.Empty;
// ...
}Ids are set by the application, not generated by the database.
Migration Commands
# Add new migration (run from /backend/Kds.Ai.Data directory)
cd ./backend/Kds.Ai.Data && ./Add-Migration.ps1 <MigrationName>
# Migrations are automatically applied at aspire host startupBest Practices
- Always use fluent configuration in
Configurations/folder - Never use
[Key],[Required],[MaxLength]or other data annotations on entities - Keep entities as POCOs without EF dependencies
- Use
sealedclasses for entities and configurations - Configure indexes explicitly for foreign keys and frequently queried columns
- Use navigation properties with explicit foreign key configuration
- Enums are automatically converted to strings via
ConfigureConventionsin DbContext - Configuration classes are auto-discovered - do NOT manually register them in OnModelCreating
- For explicit transactions under retrying providers, prefer
ExecuteInTransactionAsync/ExecuteInTransactiononCreateExecutionStrategy()and pass input as state to avoid closures. - When using
ExecuteInTransactionAsync, it can returnTResult, so use that result for atomic bulk operations instead of mutating outer variables.
Repository Conventions
IMPORTANT: All repositories must live in the Kds.Ai.Data project, not in feature-specific projects.
- Location:
backend/Kds.Ai.Data/Repositories/ - Namespace:
Kds.Ai.Data.Repositories - Registration: Register all repositories in
Kds.Ai.Data/DependencyInjectionExtensions.csusing theAddDataModule()method - Naming:
- Interface:
I{Entity}Repository(e.g.,IMonitorSpecRepository,IMonitorRunRepository) - Implementation:
Ef{Entity}Repository(e.g.,EfMonitorSpecRepository,EfMonitorRunRepository) - Access Modifier: Implementation classes should be
internal sealed(interfaces arepublic)
Example:
// In Kds.Ai.Data/Repositories/IMonitorRunRepository.cs
namespace Kds.Ai.Data.Repositories;
public interface IMonitorRunRepository
{
Task<MonitorRun?> GetByIdAsync(Guid id, CancellationToken ct = default);
// ...
}
// In Kds.Ai.Data/Repositories/EfMonitorRunRepository.cs
namespace Kds.Ai.Data.Repositories;
internal sealed class EfMonitorRunRepository(KdsAiDbContext dbContext) : IMonitorRunRepository
{
// Implementation
}
// In Kds.Ai.Data/DependencyInjectionExtensions.cs
builder.Services.AddScoped<IMonitorRunRepository, EfMonitorRunRepository>();Feature-specific projects (like Kds.Ai.AnomalyDetector) should only consume repositories via dependency injection, never define them.
Data Seeding Conventions
IMPORTANT: All data seeding logic must live in the Kds.Ai.Data project, not in feature-specific projects.
- Location:
backend/Kds.Ai.Data/Seeding/ - Namespace:
Kds.Ai.Data.Seeding - Registration: Seeding is configured in
Kds.Ai.Data/DependencyInjectionExtensions.csusing EF Core'sUseSeeding()andUseAsyncSeeding()callbacks - Naming:
{Entity}Seedingfor static seed classes (e.g.,MonitorSpecSeeding) - Access Modifier: Seed classes should be
public staticwithpublic staticmethods
Example:
// In Kds.Ai.Data/Seeding/MonitorSpecSeeding.cs
namespace Kds.Ai.Data.Seeding;
public static class MonitorSpecSeeding
{
public static void Seed(KdsAiDbContext context)
{
SeedAsync(context, CancellationToken.None).GetAwaiter().GetResult();
}
public static async Task SeedAsync(KdsAiDbContext context, CancellationToken cancellationToken)
{
// Seeding logic
}
}
// In Kds.Ai.Data/DependencyInjectionExtensions.cs
builder.Services.AddDbContext<KdsAiDbContext>(options =>
{
options
.UseSeeding((context, _) =>
{
if (context is KdsAiDbContext db)
MonitorSpecSeeding.Seed(db);
})
.UseAsyncSeeding(async (context, _, cancellationToken) =>
{
if (context is KdsAiDbContext db)
await MonitorSpecSeeding.SeedAsync(db, cancellationToken);
});
});Feature-specific projects should never define seeding logic. If you need seed data for a specific feature, add it to the appropriate seeding class in Kds.Ai.Data/Seeding/.