modules/ai-guide/Write-AiGuide-Core.ps1
|
param( [string] $ProjectName, [string] $OrmMode, [string] $DbProvider = "MSSQL", [string] $FrontendMode = "ReactTS", [string[]] $Entities = @("User", "Product"), [string] $OutputPath, [bool] $SkipTests = $false, [bool] $SkipCi = $false, [bool] $SkipFrontend = $false, [bool] $Observability = $false, [string] $IdeConfig = "VSCode", [string] $Platform = "Both" ) . (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 } $allEntitiesStr = $Entities -join ", " $generatorVersion = Get-MinVer "version" "?" $ormShort = switch ($OrmMode) { "Dapper" { "Dapper (raw SQL, micro-ORM)" } "EFCore" { "EF Core 10 (Code-First, LINQ)" } "Hybrid" { "Hybrid - Write: Dapper | Read: EF Core" } } $dbNote = switch ($DbProvider) { "Postgres" { "PostgreSQL (Npgsql)" } default { "MS SQL Server" } } $dbConnectionNote = switch ($DbProvider) { "Postgres" { "Host=db;Port=5432;Database=${ProjectName}Db;Username=postgres;Password=postgres" } default { "Server=db;Database=${ProjectName}Db;User Id=sa;Password=YourStrong@Passw0rd;TrustServerCertificate=True" } } $feSection = if ($SkipFrontend) { "Frontend: None" } else { "Frontend: ReactTS" } $testSection = if ($SkipTests) { "Test Layer: Skipped" } else { "Test Layer: xUnit + Moq + FluentAssertions" } $ciSection = if ($SkipCi) { "CI/CD: Skipped" } else { "CI/CD: GitHub Actions (ci.yml + docker.yml)" } $obsSection = if ($Observability){ "Observability: Serilog + OpenTelemetry" } else { "Observability: None" } $ideSection = if ($IdeConfig -ne "None") { "IDE: $IdeConfig" } else { "IDE: Unconfigured" } $uiRow = if ($Platform -match "Web|Both" -and -not $SkipFrontend) { "| UI | http://localhost:3000 |`n" } else { "" } $webRow = if ($Platform -match "Web|Both" -and -not $SkipFrontend) { "5. **[web-guide.md](web-guide.md)** - React TypeScript, React Query, UI routing.`n" } else { "" } $mobileRow = if ($Platform -match "Mobile|Both" -and -not $SkipFrontend) { "6. **[mobile-guide.md](mobile-guide.md)** - Expo React Native, SecureStore, local ApiClient.`n" } else { "" } # ─── README.md ──────────────────────────────────────────── $readmeContent = @' # {ProjectName} - AI Developer Guides Welcome to the AI developer guides for **{ProjectName}**. This directory contains modular instructions, architecture patterns, and coding rules designed specifically for AI coding assistants (like Cursor, Claude, ChatGPT, etc.) working on this codebase. --- ## Technical Overview | Category | Selected Option | |-------------------|---------------------------------------------| | Project Name | {ProjectName} | | ORM Mode | {OrmMode} | | Database | {DbProvider} | | {FrontendSection} | | | Active Entities | {Entities} | | {TestSection} | | | {CiSection} | | | {ObsSection} | | | {IdeSection} | | --- ## Guide Index Click on the guides below to read strict rules and step-by-step instructions for each layer: 1. **[domain-guide.md](domain-guide.md)** - Invariants, BaseEntity, Value Objects, Aggregates. 2. **[application-guide.md](application-guide.md)** - CQRS Commands/Queries, MediatR, Validation, DTOs. 3. **[persistence-guide.md](persistence-guide.md)** - EF Core configurations, Dapper type mapping, Soft Delete, Unit of Work. 4. **[webapi-guide.md](webapi-guide.md)** - Controller routing, Authorization, Global Exceptions, ApiResponse. {WebGuideRow}{MobileGuideRow}5. **[devlog.md](devlog.md)** - Architectural decision log and chronological history. --- ## Quick Start ```bash # Run the entire solution stack (API, DB, UI) via Docker docker-compose up --build ``` | Service | URL | |---------|-----------------------------------------------| | Swagger | http://localhost:8080/swagger | | API | http://localhost:8080/api | {UiRow}| Database| {DbConnectionNote} | *Default Credentials:* `admin` / `Admin123!` (Role: `Admin`) --- ## AI Core Directives (Must Obey) 1. **Keep WebApi Slim:** Controllers must do nothing except delegate requests to Mediator (`_mediator.Send`). 2. **Strict Layers:** Alt katman üst katmanı referans edemez (e.g. Domain has zero dependencies). 3. **Use FluentValidation:** Never write business validations directly in controllers or using DataAnnotations. 4. **Soft Delete Always:** Never write SQL physical `DELETE` statements. Call `entity.Delete()` to perform a soft delete. '@ $readmeContent = $readmeContent ` -replace '\{ProjectName\}', $ProjectName ` -replace '\{OrmMode\}', $ormShort ` -replace '\{DbProvider\}', $dbNote ` -replace '\{FrontendSection\}', $feSection ` -replace '\{Entities\}', $allEntitiesStr ` -replace '\{TestSection\}', $testSection ` -replace '\{CiSection\}', $ciSection ` -replace '\{ObsSection\}', $obsSection ` -replace '\{IdeSection\}', $ideSection ` -replace '\{WebGuideRow\}', $webRow ` -replace '\{MobileGuideRow\}', $mobileRow ` -replace '\{UiRow\}', $uiRow ` -replace '\{DbConnectionNote\}', $dbConnectionNote Write-Guide "README.md" $readmeContent # ─── devlog.md ──────────────────────────────────────────── $devlogDate = (Get-Date -Format "yyyy-MM-dd") $featureFlags = @() if (-not $SkipTests) { $featureFlags += "xUnit + Moq + FluentAssertions test altyapisi" } if (-not $SkipCi) { $featureFlags += "GitHub Actions CI/CD (ci.yml + docker.yml)" } if ($Observability) { $featureFlags += "Serilog + OpenTelemetry observability stack" } if (-not $SkipFrontend) { $featureFlags += "$FrontendMode frontend" } $featureFlagsStr = if ($featureFlags.Count -gt 0) { ($featureFlags | ForEach-Object { "- $_" }) -join "`n" } else { "- Ek ozellik secilmedi" } $ormDecision = switch ($OrmMode) { "Dapper" { "Ham SQL kontrolu ve performans onceligi nedeniyle Dapper tercih edildi. EF Core bagimliligini minimize eder." } "EFCore" { "Kod-oncelikli migration, LINQ sorgu kolayligi ve global query filter (soft delete) icin EF Core 10 tercih edildi." } "Hybrid" { "Yazma islemleri Dapper ile (INSERT performansi), okuma islemleri EF Core ile (LINQ + global filter). En iyi iki dunya." } } $dbDecision = switch ($DbProvider) { "Postgres" { "PostgreSQL: Acik kaynak, JSON destegi ve gelismis sorgu planlayicisi nedeniyle tercih edildi." } default { "MS SQL Server: Kurumsal ortam gereksinimleri ve mevcut altyapi ile uyum nedeniyle tercih edildi." } } $feSuffix = if (-not $SkipFrontend) { " / Frontend" } else { "" } $devlogContent = @' # Dev Log - {ProjectName} Bu dosya, projedeki mimari kararlari, ozellik eklemelerini ve degisikliklerin nedenlerini kronolojik olarak kaydeder. AI asistan olarak bu dosyayi okuyarak: - Gecmiste neden bu kararin alindigi - Hangi alternatiflerin degerlendirildigi - Mevcut yapiyla nasil tutarli kalinacagi hakkinda baglamsal bilgi edinebilirsin. --- ## Yeni Giris Sablonu Yeni bir ozellik veya karar eklendiginde asagidaki formati kullan: ``` ## [YYYY-AA-GG] <Kisa baslik> **Neden:** <Motivasyon - problem ne idi, neden bu yapildi> **Nasil:** <Yaklasim - hangi pattern/teknik kullanildi> **Karar:** <Net karar ifadesi - baska bir AI okudugunda ne yapacagini bilmeli> **Etkilenen:** <Degistirilen/eklenen dosyalar veya katmanlar> ``` --- ## [{DevlogDate}] Proje Olusturuldu - cleanarch v{GeneratorVersion} **Neden:** {ProjectName} projesi Clean Architecture prensipleriyle sifirdan kuruldu. Bakimi kolay, test edilebilir ve buyuyebilir bir yapi hedeflendi. **Nasil:** cleanarch generator'i ile otomatik iskelet olusturuldu. Tum katmanlar, bagimliliklar ve cross-cutting concerns basta tanimlanarak manuel tekrar kodlamadan kacinildi. **Karar:** - ORM: {OrmMode} — {OrmDecision} - Veritabani: {DbNote} — {DbDecision} - CQRS: MediatR ile komut/sorgu ayrimi; handler'lar ince, controller'lar saf HTTP - Validasyon: FluentValidation pipeline behavior — controller'larda try/catch yok - Hata yonetimi: GlobalExceptionHandler merkezi — handler'larda try/catch yok - Auth: JWT Bearer + BCrypt + rol tabanli policy (AdminOnly / UserOnly) - Silme: Soft delete zorunlu — fiziksel DELETE hic kullanilmiyor - Sayfalama: Tum liste endpoint'leri /paged ile basliyor — GetAll sadece ic kullanim **Ek ozellikler:** {FeatureFlags} **Etkilenen:** Tum proje altyapisi (Domain / Application / Infrastructure / Persistence / WebApi{FrontendSuffix}) --- ## Nasil Giris Eklenir? 1. Yeni bir entity, ozellik veya mimari karar aldiysan bu dosyaya ekle. 2. Tarih formatini koru: `[YYYY-AA-GG]` 3. **Neden** kismini atlama — bu, AI icin en degerli kisimdir. 4. Kararlar kalici; eski girisler silinmez, uzerine yeni giris eklenir. '@ $devlogContent = $devlogContent ` -replace '\{ProjectName\}', $ProjectName ` -replace '\{DevlogDate\}', $devlogDate ` -replace '\{GeneratorVersion\}', $generatorVersion ` -replace '\{OrmMode\}', $OrmMode ` -replace '\{OrmDecision\}', $ormDecision ` -replace '\{DbNote\}', $dbNote ` -replace '\{DbDecision\}', $dbDecision ` -replace '\{FeatureFlags\}', $featureFlagsStr ` -replace '\{FrontendSuffix\}', $feSuffix Write-Guide "devlog.md" $devlogContent |