# .NET / ABP Kod Standardı
Bu doküman `api/` altındaki tüm projeler için bağlayıcıdır. Platform davranışına dair
kurallar için `ai.instructions.md` esastır; çelişki olursa o dosya kazanır.
Standart derlemede zorlanır: `api/Directory.Build.props` analizörleri açar,
`api/.editorconfig` kural şiddetlerini tanımlar. Bu iki dosya standardın tek
kaynağıdır; proje dosyalarında tekrar edilmez.
## 1. Hedef sürümler
| Katman | Sürüm | Nerede tanımlı |
| --- | --- | --- |
| SDK | .NET 10 (`10.0.300`) | `api/global.json` |
| TargetFramework | `net10.0` | proje dosyaları |
| Dil | C# 14 (`LangVersion=latest`) | `api/common.props` |
| ABP | 10.0.0 | `Volo.Abp.*` paket referansları |
Sürüm yükseltmesi tek noktadan yapılır: `global.json` + `common.props` + paket sürümleri.
Proje dosyalarına TFM/LangVersion tekrar yazılmaz.
## 2. Nullable
`Directory.Build.props` içinde **çözüm geneli `Nullable` ayarı yapılmaz.** Sebebi
EF Core: kolonun zorunlu olup olmadığını, entity assembly'sinin nullable annotation
bağlamından türetir. Global bir `enable`/`annotations` anahtarı, bir sonraki
`dotnet ef migrations add` çağrısında tüm `string` özelliklerini sessizce NOT NULL
kolona çevirir — seeder'ın doldurmadığı her alan da o anda kırılır.
Kural:
- Nullable, proje bazında ve bilinçli olarak açılır (`enable`).
Şu an açık olanlar: `Sozsoft.Platform.Application`, `Sozsoft.Notifications.*`,
test projeleri.
- **Entity taşıyan projelerde** (`*.Domain`) nullable açılacaksa, aynı PR'da
`dotnet ef migrations add` çıktısı gözden geçirilir; şema değişikliği isteniyorsa
kabul edilir, istenmiyorsa kolon zorunluluğu `PlatformDbContext` içinde
`.IsRequired(false)` ile açıkça sabitlenir.
- Kolon zorunluluğu tercihen NRT'ye değil, `PlatformDbContext` yapılandırmasına
yazılır; böylece derleyici anahtarından bağımsız olur.
## 3. Ölü kod politikası
Aşağıdaki kurallar ihlal edilmiş kod merge edilmez:
| Kural | Anlamı |
| --- | --- |
| IDE0005 | Kullanılmayan `using` |
| IDE0051 | Çağrılmayan private üye |
| IDE0052 | Yazılıp hiç okunmayan private alan (kullanılmayan enjekte bağımlılık) |
| IDE0059 | Gereksiz değer ataması |
| IDE0161 | `namespace X;` (file-scoped) |
Tarama ve otomatik düzeltme (kalıcı yapılandırma gerektirmez):
```bash
# Rapor
dotnet build api/Sozsoft.Platform.sln --no-incremental \
-p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true
# Düzeltme
dotnet format api/Sozsoft.Platform.sln --diagnostics IDE0005,IDE0161 --severity warn
```
> Kurallar `.editorconfig`'te `warning` seviyesindedir ve `EnforceCodeStyleInBuild`
> açık olduğu için normal `dotnet build` de bunları raporlar.
IDE0052 düzeltilirken alan ile birlikte **constructor parametresi de** silinir; yoksa
DI hâlâ gereksiz servisi çözer.
`CS0162` (erişilemez kod) `Directory.Build.props` içinde gerekçesiyle susturulmuştur:
veritabanı sağlayıcısı derleme zamanı sabiti olduğu için diğer sağlayıcının dalları
erişilemez görünür. Bu durum dışında erişilemez kod bırakılmaz.
Ek kurallar:
- Bir tip/dosya silinmeden önce **repo genelinde** (api + ui + configs) referans
taraması yapılır. DI ile çözülen tipler (AppService, Manager, Provider, Repository,
Seeder, Localizer, Notification sağlayıcıları) düz metin aramasında "referanssız"
görünür — bunlar yalnızca modül/DI kaydı incelendikten sonra silinir.
- Yorum satırına alınmış kod bloğu bırakılmaz; ihtiyaç varsa git geçmişinden alınır.
- "İleride lazım olur" gerekçesiyle kullanılmayan DTO/Input/Consts tutulmaz.
- `Migrations/` ve `*.g.cs` üretilmiş koddur, bu kuralların dışındadır.
## 4. Modern C# kullanımı (yeni kod)
- File-scoped namespace: `namespace Sozsoft.Platform.ListForms;`
- Primary constructor: `public class XAppService(IRepository repo) : PlatformAppService`
— parametre doğrudan kullanılır, `private readonly ... = param;` şeklinde
tekrar tanımlanmaz.
- Koleksiyon ifadeleri (`[]`, `[.. items]`), `is not null`, `switch` ifadesi,
desen eşleme, `Index/Range`, hedefi belli `new()`.
- `out var`, tuple deconstruction; kullanılmayan çıktı için `_`.
- `async` metotlar `Async` ile biter ve `Task`/`Task` döner; `async void` yasak.
ABP'de `ConfigureAwait` kullanılmaz.
- Biçim: `api/.editorconfig` geçerlidir (4 boşluk girinti, `using` blokları namespace
dışında ve System önce, dosya sonunda satır sonu, UTF-8 BOM).
## 5. ABP kuralları
- **Katman sınırı**: Domain.Shared → Domain → Application.Contracts → Application →
HttpApi → HttpApi.Host. Ters yönde referans verilmez; `EntityFrameworkCore` yalnızca
Domain'e bakar.
- **AppService**: `PlatformAppService`'ten türer, arayüzü Application.Contracts'ta
tanımlanır. Controller yazılmaz — ABP otomatik API üretir. Controller sadece ABP
konvansiyonunun karşılamadığı durumda (dosya indirme, harici webhook) eklenir.
- **Yetki**: her AppService/metot `[Authorize(PlatformConsts.AppCodes....)]` ile
korunur; izin adları `PermissionDefinitionProvider` içinde tanımlanır. Yetki
kontrolü koda gömülmez, izin adı sabitten okunur.
- **Tenant izolasyonu**: sorgular `ICurrentTenant` bağlamında çalışır; `IMultiTenant`
entity'lerde manuel `TenantId` filtresi yazılmaz, veri filtreleri devre dışı
bırakılacaksa (`ICurrentTenant.Change`, `IDataFilter`) gerekçe yorumla yazılır.
- **Repository**: özel sorgu gerekiyorsa Domain'de arayüz + EntityFrameworkCore'da
implementasyon. AppService içinde `DbContext` doğrudan kullanılmaz.
- **Dinamik SQL**: parametreli çalıştırılır; string birleştirme ile sorgu kurulmaz.
- **Mapping**: Mapperly (`[Mapper]` partial class) kullanılır; AutoMapper eklenmez.
RMG012 uyarısı "hedefte karşılığı olmayan alan" demektir; yeni mapper eklerken bu
uyarı bırakılmaz.
- **Localization**: kullanıcıya görünen metin koda gömülmez, `PlatformResource`
anahtarı üzerinden verilir.
- **Sabitler**: bağlantı dizesi, tenant id, anahtar/secret koda yazılmaz; konfigürasyon
veya `SettingDefinition` üzerinden okunur.
## 6. Değişiklik öncesi kontrol listesi
```bash
dotnet build api/Sozsoft.Platform.sln --no-incremental \
-p:EnforceCodeStyleInBuild=true -p:GenerateDocumentationFile=true # 0 hata, yeni IDE00xx yok
dotnet format api/Sozsoft.Platform.sln --verify-no-changes --diagnostics IDE0005,IDE0161 --severity warn
dotnet test api/test/Sozsoft.Platform.EntityFrameworkCore.Tests
```
> Not: EntityFrameworkCore testleri şu an SQLite şema oluşturmada
> (`nvarchar(max)` → `SQLite Error 1`) kırık; bu kırıklık bu standarttan önce de vardı
> ve ayrı bir iş olarak ele alınmalıdır.