Temel kural: Çocuk entity’ler dışarıya doğrudan açılmaz.
User.Sessions koleksiyonuna yeni oturum eklemek için user.StartSession(...) çağrılır — user.Sessions.Add(...) değil. Repository yalnızca root için vardır.User aggregate’i — derinlemesine
User, back-office (personel) kullanıcısını temsil eden en zengin aggregate’tir. Tüm desenleri tek örnekte gösterir.
Value object alanları
FullName, Phone, Email birer value object’tir (nullable — kullanıcı telefon veya e-posta ile kaydolabilir). Totp ise TotpConfigurationInfo VO’sudur. Setter’lar private’tır; değişim yalnızca davranış metotları üzerinden olur.
Çocuk entity’ler
| Çocuk entity | Rolü |
|---|---|
UserSession | Refresh token tabanlı oturum (cihaz + IP bilgisi ile). |
UserOtpChallenge | SMS/E-posta OTP doğrulama denemesi (deneme/yeniden gönderim sayacı). |
UserIdentityProvider | Dış IdP bağlantısı (Google/Meta/Apple/Keycloak). |
UserRole | Rol atama kaydı (opsiyonel TenantId ile). |
internal ctor — factory zorunluluğu
Constructorinternal’dır. Bu, User’ın yalnızca aynı assembly içindeki factory (UserFactory) veya domain service (UserRegistrationService) tarafından oluşturulabilmesini garanti eder. Böylece uniqueness gibi kurallar atlanamaz.
UserStatus — durum makinesi
Davranış metotları
Aggregate’in tüm yetenekleri açık niyetli (intention-revealing) metotlardır. Birkaç örnek:Oturum: StartSession / RefreshSession
Oturum: StartSession / RefreshSession
RefreshSession, mevcut token’ı eşleştirip yeni token’a döndürür (rotation).OTP: AddOtpChallenge / ResendOtp / VerifyOtp / VerifyChallenge
OTP: AddOtpChallenge / ResendOtp / VerifyOtp / VerifyChallenge
VerifyOtp/VerifyChallenge doğru kodda ilgili kanalı doğrular ve UserPhoneNumberVerifiedDomainEvent / UserEmailVerifiedDomainEvent yayar.TOTP: ConfigureTotp / EnableTotp / DisableTotp / VerifyTotp
TOTP: ConfigureTotp / EnableTotp / DisableTotp / VerifyTotp
TotpConfigurationInfo immutable bir VO’dur; her geçiş yeni bir örnek döndürür.RBAC: AssignRole / RevokeRole / InvalidateTokens
RBAC: AssignRole / RevokeRole / InvalidateTokens
InvalidateTokens(), TokenVersion’ı artırarak mevcut tüm JWT’leri geçersiz kılar.Dış IdP: AddOrUpdateExternalProvider / ActivateOnExternalLogin
Dış IdP: AddOrUpdateExternalProvider / ActivateOnExternalLogin
ActivateOnExternalLogin(), başarılı dış login’de Draft/Pending kullanıcıyı Active’e geçirir; Banned/Suspended’e dokunmaz, Active ise idempotent çıkar.Citizen aggregate — User’a paralel
Citizen, vatandaş portalının kullanıcısıdır ve User ile neredeyse birebir aynı yapıya sahiptir (FullName/Phone/Email, OTP/TOTP/oturum, dış IdP, CitizenStatus). Ama ayrı bir aggregate’tir — farklı tablolar, farklı Keycloak realm’i ve farklı iş kuralları taşır. Ek olarak CitizenProfileImageInfo (profil fotoğrafı) içerir.
İki aggregate’i kasıtlı olarak ayrı tutmak, personel ve vatandaş kimlik akışlarının bağımsız evrilmesini sağlar. Ortak ihtiyaçlar value object düzeyinde (
FullName, Phone…) paylaşılır.Diğer aggregate’ler — özet
Organization (+ Branch, StaffMember, StaffPermission)
Organization (+ Branch, StaffMember, StaffPermission)
Kurum/tenant.
Branch (şube) ve StaffMember (personel) çocuk entity’leri; StaffPermission izin kayıtları. AddBranch(...) gibi root metotları ile yönetilir.RolePermission
RolePermission
RBAC rol–izin eşlemesi. Hangi rolün hangi
PermissionCode’a sahip olduğunu tutar.BagisBasvuru / BagisBasvuruPlan
BagisBasvuru / BagisBasvuruPlan
Bağış başvurusu bir state machine’dir:
OnBasvuru → Incelemede → ... Her geçiş BagisBasvuruStatusHistory kaydı ve domain event üretir (IncelemeyeAl, Onayla, Reddet, IptalEt). BagisBasvuruPlan başvuru şablonudur.EtkinlikBasvuru / EtkinlikBasvuruPlan
EtkinlikBasvuru / EtkinlikBasvuruPlan
Etkinlik başvurusu; bağış ile paralel state machine. Plan kontenjanı dolunca
EtkinlikBasvuruPlanKontenjanDolduDomainEvent yayılır, iptalde kontenjan geri verilir.SupportTicket
SupportTicket
Destek talebi. Çocuklar:
SupportTicketComment, SupportTicketAttachment, SupportTicketStatusHistory. Atama ve durum değişiminde event yayar.AdminNotification, LegalDocument, Center, SiteSettings, District
AdminNotification, LegalDocument, Center, SiteSettings, District
AdminNotification: SSE ile yayınlanan admin bildirimi. LegalDocument: yasal metin + LegalDocumentVersion. Center: merkez lokasyonu. SiteSettings: tekil site ayarı. District: int kimlikli sabit ilçe referans verisi.Tüm aggregate tablosu
| Aggregate | Çocuk entity’ler / VO’lar | Enumeration’lar |
|---|---|---|
User | UserSession, UserOtpChallenge, UserIdentityProvider, UserRole | UserStatus |
Citizen | CitizenSession, CitizenOtpChallenge, CitizenIdentityProvider, CitizenProfileImageInfo | CitizenStatus |
Organization | Branch, StaffMember, StaffPermission | OrganizationStatus, BranchStatus, StaffStatus, StaffRole |
RolePermission | Permission, PermissionCodes | Role |
Announcement | AnnouncementImageInfo | — |
BagisBasvuru | BagisBasvuruStatusHistory, BagisOdemeInfo | BagisBasvuruStatus, OdemeStatus |
BagisBasvuruPlan | BagisPlanImageInfo | BagisBasvuruPlanType |
EtkinlikBasvuru | EtkinlikBasvuruStatusHistory | EtkinlikBasvuruStatus |
EtkinlikBasvuruPlan | EtkinlikPlanImageInfo | EtkinlikBasvuruPlanType |
SupportTicket | SupportTicketComment, SupportTicketAttachment, SupportTicketStatusHistory, DiagnosticContext | SupportTicketStatus/Priority/Type/Source/ReporterType |
AdminNotification | AdminNotificationRead | NotificationCategory, NotificationSeverity |
LegalDocument | LegalDocumentVersion | LegalDocumentType |
Center | — | — |
SiteSettings | — | — |
District | — | City |
Sonraki adımlar
Value Object'ler
Aggregate alanlarında kullanılan VO kataloğu.
Domain Event'ler
AddDomainEvent ile yayılan olayların dispatch akışı.Factory ve Servisler
internal ctor’lu aggregate’ler nasıl oluşturulur.SharedKernel
Entity, Enumeration ve guard altyapısı.