modules/ai-guide/Write-AiGuide-Persistence.ps1
|
param( [string] $ProjectName, [string] $DbProvider = "MSSQL", [string] $OutputPath ) . (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "..\core\Utils.ps1") $guideDir = Join-Path $OutputPath "ai-guide" function Write-Guide($fileName, $content) { Write-CoreFile (Join-Path $guideDir $fileName) $content } $ormShort = "EF Core 8 (Code-First, LINQ)" $dbNote = switch ($DbProvider) { "Postgres" { "PostgreSQL (Npgsql)" } default { "MS SQL Server" } } $ormNote = "All data access is written using EF Core 8. DbContext is used to manage entities Code-First." $dbContextNote = @' ### AppDbContext Registration When adding a new entity (e.g. `Category`), add its `DbSet` and global query filter (for soft delete) in `AppDbContext.cs`: ```csharp // {P}-backend/src/{P}.Persistence/Context/AppDbContext.cs public DbSet<Category> Categories => Set<Category>(); // In OnModelCreating: builder.Entity<Category>().HasQueryFilter(e => !e.IsDeleted); ``` ### EF Core Value Object Property Conversion To map a Value Object (like `Email`) to a string database column, configure it in `AppDbContext.cs`: ```csharp builder.Entity<User>(entity => { entity.Property(u => u.Email) .HasConversion(email => email.Value, value => new Email(value)) .HasMaxLength(256); }); ``` '@.Replace("{P}", $ProjectName) $uowNote = @' ### Unit of Work Transaction Management Inject `IUnitOfWork` to orchestrate multiple transactions: ```csharp await _uow.BeginTransactionAsync(); try { await _categoryRepo.AddAsync(category); await _productRepo.AddAsync(product); await _uow.SaveChangesAsync(); await _uow.CommitTransactionAsync(); } catch { await _uow.RollbackTransactionAsync(); throw; } ``` '@ $migrationNote = @' ### EF Core Migrations Use the path-agnostic scripts inside `{P}-backend/scripts/` to manage migrations: ```powershell # Windows PowerShell: cd {P}-backend .\scripts\migrate.ps1 -MigrationName "AddCategoryTable" # Linux/Mac Bash: cd {P}-backend ./scripts/migrate.sh AddCategoryTable ``` '@.Replace("{P}", $ProjectName) $persistenceGuideContent = @' # Persistence Layer AI Developer Guide You are an AI assistant helping developers build the Persistence Layer of the {P} solution. This layer manages database connections, repository implementations, ORM configuration, and migrations. --- ## Technical Context - **ORM Strategy:** {O} - **Database Engine:** {D} - **Rule:** {R} --- ## Strict Persistence Rules 1. **Clean Interfaces:** Repositories must implement the repository interfaces defined in the Domain layer. 2. **Soft Delete enforcement:** All deletions (`DeleteAsync`) must call `entity.Delete()` domain method to mark the entity as deleted instead of running physical SQL deletes. 3. **Global Filtering:** Always apply global query filters (like `IgnoreQueryFilters()` in EF Core) if soft-deleted items must be explicitly loaded for administrative tasks. --- {C} {M} {U} {G} --- ## Service Registration Every new repository must be registered in the dependency injection container: ```csharp // {P}-backend/src/{P}.Persistence/PersistenceServiceRegistration.cs public static class PersistenceServiceRegistration { public static IServiceCollection AddPersistenceServices(this IServiceCollection services, IConfiguration configuration) { // AppDbContext and connection configuration... services.AddScoped<ICategoryRepository, CategoryRepository>(); return services; } } ``` '@.Replace("{P}", $ProjectName).Replace("{O}", $ormShort).Replace("{D}", $dbNote).Replace("{R}", $ormNote).Replace("{C}", $dbContextNote).Replace("{M}", "").Replace("{U}", $uowNote).Replace("{G}", $migrationNote) Write-Guide "persistence-guide.md" $persistenceGuideContent |