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