API tek bir .NET 10 projesidir: src/DiyanetCleanArchitecture.API. Tüm servis kayıtları ve HTTP pipeline’ı Program.cs içinde elle (minimal API host) kurulur. Bu sayfa kayıt sırasını ve middleware sırasını birebir gösterir — her ikisi de kritiktir, sıra bozulursa uygulama sessizce yanlış çalışır.
Servis kayıt sırası (builder.Services)
Program.Main içinde servisler şu sırayla kaydedilir. Sıra, bazı bileşenler için zorunludur (aşağıda işaretli).
// ── Layer Registration ──────────────────────────────────────
builder.Services.AddHangfireServers(builder.Configuration);
builder.Services.AddInfrastructureEFCore(builder.Configuration); // DbContext, repository, interceptor, MassTransit Outbox
builder.Services.AddSmsService(builder.Configuration); // OtpSmsService (NetGSM)
builder.Services.AddEmailService(builder.Configuration); // EmailService (MailKit + Scriban)
builder.Services.AddAuthenticatorService(builder.Configuration); // TOTP (OtpNet)
builder.Services.AddOAuthProviders(builder.Configuration); // Google / Meta / Keycloak OAuth
builder.Services.AddNotificationService(builder.Configuration); // SSE admin notification broadcaster
builder.AddApplication(); // MediatR + pipeline behavior'lar + AutoMapper
// ── Building Blocks ─────────────────────────────────────────
builder.Services.AddJwt(builder.Configuration); // BB.Jwt — uygulamanın kendi JWT scheme'i
builder.Services.AddDeviceDetector(builder.Configuration);
builder.Services.AddRedisCache(builder.Configuration); // ① IDistributedCache (Redis)
builder.Services.AddCache(builder.Configuration); // ② IHybridRequestCache abstraction
builder.Services.AddHybridCache(/* L1 + L2 TTL */); // ③ HybridCache (L1 memory + L2 Redis)
builder.Services.AddKeycloak(builder.Configuration); // İki Keycloak JWT Bearer scheme (Vatandas + Personel)
builder.Services.AddKeycloakProvisioning(builder.Configuration); // IHostedService — realm/client/user otomatik kurar
builder.Services.AddKeycloakExternalLoginProvisioning(); // OnTokenValidated → davetli kullanıcı aktivasyonu
builder.Services.AddDiyanetObservability(builder.Configuration); // OTel + Prometheus (opt-in)
Cache kayıt sırası kritik. AddRedisCache (IDistributedCache) mutlaka AddHybridCache’ten önce gelmelidir. HybridCache kayıt anında bir IDistributedCache bulamazsa kalıcı olarak L1-only (memory) moduna düşer ve sonradan eklenen Redis’i hiç görmez — yani Redis’e hiçbir zaman yazmaz.
Bu blokların ardından RBAC, CORS ve sunum servisleri gelir:
- RBAC Authorization —
DynamicPermissionPolicyProvider (singleton), PermissionAuthorizationHandler, ScopeAuthorizationHandler, ActiveAccountAuthorizationHandler; ICurrentUser / ICurrentCitizen / ICurrentTenant / ICurrentActor; ApiCompositeClaimsTransformation. Üç named policy: PersonelAuthenticated, VatandasAuthenticated, AnyKeycloakAuthenticated.
- CORS — beş policy:
AllowedBackofficePolicy, AllowedPublicPolicy, AllowedWebsitePolicy, AllowedDiyanetCleanArchitectureAPIPolicy, AllowAll. Origin’ler AllowedCorsOrigins:* config’inden okunur (yoksa exception fırlatılır).
AddControllers() (camelCase JSON), AddOutputCache(), ProblemDetails (Hellang), NSwag (AddOpenApiDocument), RequestLocalization (tr-TR).
Middleware pipeline sırası (app)
app.UseHttpsRedirection();
app.UseStaticFiles(); // wwwroot/uploads/* — duyuru kapak görselleri
app.UseProblemDetails(); // RFC 7807 — exception → ProblemDetails
app.UseSerilogRequestLoggingMiddleware();
app.UseRequestLocalization(/* tr-TR default */);
app.UseRouting();
app.UseCors(/* Prod/Stage: Backoffice · Dev: AllowAll */);
app.UseAuthentication();
app.UseTokenVersionValidation(); // Feature flag: Security:TokenVersionValidation — RBAC invalidation
app.UseAuthorization();
app.UseHangfireDashboard(/* /jobs */);
app.UseOutputCache();
app.MapControllers();
app.MapHealthCheckEndpoints(); // /health/live, /health/ready, /health/external, /health/startup, /health
app.MapDiyanetObservabilityEndpoints();// /metrics (Observability:Enabled=true ise)
// Dev/Stage: MapOpenApi + Swagger UI + Scalar · Prod: Scalar (RequireAuthorization)
UseProblemDetails Routing’den önce çağrılır — pipeline’ın herhangi bir yerinde oluşan exception’lar yakalanır. UseTokenVersionValidation Authentication ile Authorization arasına girer: token’ın TokenVersion claim’i kullanıcının güncel versiyonuyla eşleşmezse (örn. rol değişti) istek reddedilir. Bu, RBAC değişikliğinin anında etki etmesini sağlar.
Ortama göre değişen davranış
| Davranış | Development | Staging | Production |
|---|
| CORS policy | AllowAll | AllowedBackofficePolicy | AllowedBackofficePolicy |
| Swagger UI + Scalar | Açık | Açık | Kapalı |
| Scalar | Açık | Açık | RequireAuthorization() |
ASPNETCORE_ENVIRONMENT | Development | Staging | Production |
Sonraki adımlar
Controller deseni
İnce controller’lar, base class’lar, ProblemDetails hata yanıtları.
OpenAPI / Swagger
NSwag, üç security scheme, Scalar, client üretimi.
Frontend SPA'lar
React 19 + Vite, axios interceptor, Keycloak entegrasyonu.
Gözlemlenebilirlik
Serilog → Seq, Prometheus /metrics, health endpoint’leri.