<# .SYNOPSIS Scaffolds EF Core DbContext, entities, and compiled models from PostgreSQL schema. .DESCRIPTION This script performs database-first scaffolding for a StellaOps module: 1. Cleans existing generated files (Entities, CompiledModels, DbContext) 2. Scaffolds DbContext and entities from live PostgreSQL schema 3. Generates compiled models for startup performance .PARAMETER Module The module name (e.g., Unknowns, PacksRegistry, Authority) .PARAMETER Schema The PostgreSQL schema name (defaults to lowercase module name) .PARAMETER ConnectionString PostgreSQL connection string. If not provided, uses default dev connection. .PARAMETER ProjectPath Optional custom project path. Defaults to src/{Module}/__Libraries/StellaOps.{Module}.Persistence.EfCore .EXAMPLE .\Scaffold-Module.ps1 -Module Unknowns .EXAMPLE .\Scaffold-Module.ps1 -Module Unknowns -Schema unknowns -ConnectionString "Host=localhost;Database=stellaops_platform;Username=unknowns_user;Password=unknowns_dev" .EXAMPLE .\Scaffold-Module.ps1 -Module PacksRegistry -Schema packs #> param( [Parameter(Mandatory=$true)] [string]$Module, [string]$Schema, [string]$ConnectionString, [string]$ProjectPath ) $ErrorActionPreference = "Stop" # Resolve repository root $RepoRoot = (Get-Item $PSScriptRoot).Parent.Parent.Parent.FullName # Default schema to lowercase module name if (-not $Schema) { $Schema = $Module.ToLower() } # Default connection string if (-not $ConnectionString) { $user = "${Schema}_user" $password = "${Schema}_dev" $ConnectionString = "Host=localhost;Port=5432;Database=stellaops_platform;Username=$user;Password=$password;SearchPath=$Schema" } # Default project path if (-not $ProjectPath) { $ProjectPath = Join-Path $RepoRoot "src" $Module "__Libraries" "StellaOps.$Module.Persistence.EfCore" } $ContextDir = "Context" $EntitiesDir = "Entities" $CompiledModelsDir = "CompiledModels" Write-Host "" Write-Host "============================================================================" -ForegroundColor Cyan Write-Host " EF Core Scaffolding for Module: $Module" -ForegroundColor Cyan Write-Host "============================================================================" -ForegroundColor Cyan Write-Host " Schema: $Schema" Write-Host " Project: $ProjectPath" Write-Host " Connection: Host=localhost;Database=stellaops_platform;Username=${Schema}_user;..." Write-Host "" # Verify project exists if (-not (Test-Path "$ProjectPath\*.csproj")) { Write-Error "Project not found at: $ProjectPath" Write-Host "Create the project first with: dotnet new classlib -n StellaOps.$Module.Persistence.EfCore" exit 1 } # Step 1: Clean existing generated files Write-Host "[1/4] Cleaning existing generated files..." -ForegroundColor Yellow $paths = @( (Join-Path $ProjectPath $EntitiesDir), (Join-Path $ProjectPath $CompiledModelsDir), (Join-Path $ProjectPath $ContextDir "${Module}DbContext.cs") ) foreach ($path in $paths) { if (Test-Path $path) { Remove-Item -Recurse -Force $path Write-Host " Removed: $path" -ForegroundColor DarkGray } } # Recreate directories New-Item -ItemType Directory -Force -Path (Join-Path $ProjectPath $EntitiesDir) | Out-Null New-Item -ItemType Directory -Force -Path (Join-Path $ProjectPath $CompiledModelsDir) | Out-Null New-Item -ItemType Directory -Force -Path (Join-Path $ProjectPath $ContextDir) | Out-Null # Step 2: Scaffold DbContext and entities Write-Host "[2/4] Scaffolding DbContext and entities from schema '$Schema'..." -ForegroundColor Yellow $scaffoldArgs = @( "ef", "dbcontext", "scaffold", "`"$ConnectionString`"", "Npgsql.EntityFrameworkCore.PostgreSQL", "--project", "`"$ProjectPath`"", "--schema", $Schema, "--context", "${Module}DbContext", "--context-dir", $ContextDir, "--output-dir", $EntitiesDir, "--namespace", "StellaOps.$Module.Persistence.EfCore.Entities", "--context-namespace", "StellaOps.$Module.Persistence.EfCore.Context", "--data-annotations", "--no-onconfiguring", "--force" ) $process = Start-Process -FilePath "dotnet" -ArgumentList $scaffoldArgs -Wait -PassThru -NoNewWindow if ($process.ExitCode -ne 0) { Write-Error "Scaffold failed with exit code: $($process.ExitCode)" exit 1 } Write-Host " Scaffolded entities to: $EntitiesDir" -ForegroundColor DarkGray # Step 3: Generate compiled models Write-Host "[3/4] Generating compiled models..." -ForegroundColor Yellow $optimizeArgs = @( "ef", "dbcontext", "optimize", "--project", "`"$ProjectPath`"", "--context", "StellaOps.$Module.Persistence.EfCore.Context.${Module}DbContext", "--output-dir", $CompiledModelsDir, "--namespace", "StellaOps.$Module.Persistence.EfCore.CompiledModels" ) $process = Start-Process -FilePath "dotnet" -ArgumentList $optimizeArgs -Wait -PassThru -NoNewWindow if ($process.ExitCode -ne 0) { Write-Error "Compiled model generation failed with exit code: $($process.ExitCode)" exit 1 } Write-Host " Generated compiled models to: $CompiledModelsDir" -ForegroundColor DarkGray # Step 4: Summary Write-Host "[4/4] Scaffolding complete!" -ForegroundColor Green Write-Host "" Write-Host "Generated files:" -ForegroundColor Cyan $contextFile = Join-Path $ProjectPath $ContextDir "${Module}DbContext.cs" $entityFiles = Get-ChildItem -Path (Join-Path $ProjectPath $EntitiesDir) -Filter "*.cs" -ErrorAction SilentlyContinue $compiledFiles = Get-ChildItem -Path (Join-Path $ProjectPath $CompiledModelsDir) -Filter "*.cs" -ErrorAction SilentlyContinue Write-Host " Context: $(if (Test-Path $contextFile) { $contextFile } else { 'Not found' })" Write-Host " Entities: $($entityFiles.Count) files" Write-Host " Compiled Models: $($compiledFiles.Count) files" Write-Host "" Write-Host "Next steps:" -ForegroundColor Yellow Write-Host " 1. Review generated entities for any customization needs" Write-Host " 2. Create repository implementations in Repositories/" Write-Host " 3. Add DI registration in Extensions/" Write-Host ""