DDD
Bu döküman, starter kit'in kullandığı domain odaklı yapıyı açıklar. Controller merkezli değil domain merkezli bir DDD düzeni uygulanır.
Amaç
Temel amaç, iş kurallarını büyüyen controller dosyalarından çıkarıp öngörülebilir domain klasörlerine taşımaktır.
Domain Yapısı
Kurulumdan sonra tipik yapı şöyledir:
app/Domain/
├── Auth/
├── Role/
│ └── BulkActions/
└── User/
└── BulkActions/
Tamamen paket tarafından yönetilen ve vendor'dan çalışan domain'ler, fresh install'da app/'e scaffold edilmez. Ayrıntılar için aşağıdaki Vendor-resident domain'ler bölümüne bakın.
Vendor-resident domain'ler
Aşağıdaki domain'lerin runtime katmanı (Actions, DTOs, Queries, Events, Listeners, Services) paket içinde yer alır (src/Domain/, Lvntr\StarterKit\Domain\). Kurulumda uygulamanıza kopyalanmaz.
| Domain | Vendor namespace |
|---|---|
FileManager |
Lvntr\StarterKit\Domain\FileManager\ |
Shared |
Lvntr\StarterKit\Domain\Shared\ |
ActivityLog |
Lvntr\StarterKit\Domain\ActivityLog\ |
Logs |
Lvntr\StarterKit\Domain\Logs\ |
Session |
Lvntr\StarterKit\Domain\Session\ |
Media |
Lvntr\StarterKit\Domain\Media\ |
ApiClient |
Lvntr\StarterKit\Domain\ApiClient\ |
ApiRoute |
Lvntr\StarterKit\Domain\ApiRoute\ |
Role |
Lvntr\StarterKit\Domain\Role\ |
Setting |
Lvntr\StarterKit\Domain\Setting\ |
User |
Lvntr\StarterKit\Domain\User\ |
Import uyumluluğu: App\Domain\<Module>\... import yollarını kullanan controller ve provider'lar çalışmaya devam eder — StarterKitServiceProvider, bunları vendor namespace'ine çözen class_alias girişlerini kaydeder. Yerel app/Domain/<Module>/ kopyası varsa her zaman öncelik alır (dosya diskte varken guard alias'ı atlar).
Yüzey sahipliği modül bazında ayrılır. Model'ler her zaman app-owned kalır (policy discovery ve route-model binding çalışmaya devam etsin diye). Kullanıcıya dönük modüllerde (User, Role, Dashboard, Auth, Profile) Controller'lar, FormRequest'ler, Vue sayfaları ve route dosyaları uygulamanıza scaffold edilir. Vendor-first davranış modüllerinde (Files, Logs, Activity Logs, API Routes, Settings, …) HTTP + Vue yüzeyinin tamamı paketten çalışır — yalnızca Model'leri app/'te yaşar; sahiplenmek için sk:eject <Module> çalıştırın. Modül Sahipliği tablosu için README'ye bakın.
Mevcut uygulama kopyaları: projeniz bir domain vendor'a taşınmadan önce kurulduysa mevcut app/Domain/<Module>/ dosyalarınız korunur ve çalışmaya devam eder. Bunları silmek isteğe bağlıdır — reconcile adımları için UPGRADE.md belgelerine bakın.
Bir domain içinde genelde şu katmanlar bulunur:
- yazma işlemleri ve use-case akışı için
Actions - doğrulanmış veriyi taşımak için
DTOs - listeleme ve datatable sorgu mantığı için
Queries - domain olayları için
Events - loglama gibi yan etkiler için
Listeners - soyutlama gerektiğinde
RepositoriesveyaContracts
Request Akışı
Tipik akış:
- Controller isteği alır.
- Form Request doğrulama yapar.
- DTO veriyi normalize eder.
- Action iş kuralını çalıştırır.
- Gerekirse Event fırlatılır.
- Listener controller'ı şişirmeden yan etkileri işler.
- Yanıt
to_api()ya da Inertia redirect ile döner.
Temel Kurallar
- controller'ları ince tutun
- doğrulamayı Form Request içinde tutun
- karmaşık yazma işlemlerini Action içine alın
- tekrar kullanılan liste mantığını Query içinde tutun
- yan etkileri Listener katmanına taşıyın
- kit seviyesindeki domainler arası ortak kodu
src/Domain/Sharedaltında tutun;app/Domain/Sharedyolunu yalnızca proje sahipli veya eject edilmiş kod için kullanın
Neden Faydalı
- büyük admin projelerinde okunabilirliği artırır
- iş kurallarını test etmeyi kolaylaştırır
- zaman içinde refactor sürecini güvenli hale getirir
- web ve API controller'ları arasında tekrarları azaltır
İlgili Komutlar
Domain yapısı scaffolding komutlarıyla desteklenir, ancak komut referansı artisan-commands.tr.md içinde tutulur. Bu dosya özellikle DDD anlatımını komut dökümanından ayrı tutmak için vardır.
make:sk-domain temel flag'leri
Domain adı ve --fields= dışında, sihirbazın katman/ID/Vue seçimlerinin tamamı non-interaktif olarak geçilebilir:
| Flag | Ne yapar |
|---|---|
--fields="name:string,age:integer" |
Virgülle ayrılmış alan:tip çiftleri. Mevcut tipler: string, integer, bigInteger, unsignedBigInteger, float, decimal, boolean, text, longText, json, date, dateTime, timestamp. Atlanırsa alan alan interaktif sorulur. |
--id-type=id|uuid|ulid |
Primary key stratejisi. id (varsayılan) auto-increment bigint'tir; uuid/ulid model'e ilgili HasUuids/HasUlids concern'ini ekler ve migration'daki id kolonunu değiştirir. Atlanırsa interaktif sorulur — --from-migration kullanıldığında tamamen atlanır (migration dosyasından tespit edilir). |
--api / --no-api |
API controller + route'ları zorla üretir veya zorla atlar. İkisi de verilmezse (varsayılan: evet) sorulur. |
--admin / --no-admin |
Admin controller + route'ları zorla üretir veya zorla atlar. İkisi de verilmezse (varsayılan: evet) sorulur. |
--events / --no-events |
Created/Updated/Deleted event'lerini ve loglayan listener'larını zorla üretir veya zorla atlar. İkisi de verilmezse (varsayılan: evet) sorulur. |
--soft-deletes / --no-soft-deletes |
Model ve migration'da SoftDeletes'i zorla etkinleştirir veya zorla devre dışı bırakır. İkisi de verilmezse (varsayılan: evet) sorulur — --from-migration kullanıldığında tamamen atlanır (migration dosyasından tespit edilir). |
--vue=none|empty|full |
Vue sayfa üretim modu; yalnızca Admin katmanı üretiliyorsa geçerlidir (aksi halde none'a zorlanır). full Index (DataTable) + Create/Edit (FormBuilder) üretir; empty yalnızca boş bir Index sayfası üretir; none Vue üretimini atlar. Atlanırsa interaktif sorulur (varsayılan: full). |
--vue-fields / --no-vue-fields |
Yalnızca --vue=full ile anlamlıdır. Üretilen DataTable kolonlarına ve FormBuilder'a model alanlarını dahil eder ya da yalnızca id içeren bir iskelet üretir. İkisi de verilmezse ve alan varsa (varsayılan: evet) sorulur. |
--from-migration=<dosya adı> |
Alanları, ID tipini ve soft-delete'i --fields/--id-type/promptlar yerine var olan bir migration dosyasından ayrıştırır, örn. --from-migration=2026_03_21_create_products_table.php. Tam ya da kısmi dosya adı kabul edilir (database/migrations/ altında glob ile eşleştirilir). |
make:sk-domain v2 opt-in flag'leri
Komutun flag'siz çağrılması v13.5.x davranışını korur (geriye dönük uyumlu).
Tek tek flag'ler:
| Flag | Üretilen dosya |
|---|---|
--with-policy |
Policy sınıfı |
--with-factory |
Factory |
--with-seeder |
Seeder |
--with-test |
Feature test |
--with-relations |
İlişki scaffold'ı (--relations ile birlikte kullanılır) |
Toplu syntax — policy, factory, seeder, test, relations'ın herhangi bir kombinasyonunu tek flag ile geçin (tekil --with-* flag'leri buna eklemeli olarak uygulanır):
php artisan make:sk-domain Article --with=policy,factory,test
İlişki syntax'ı:
php artisan make:sk-domain Article --with-relations --relations="belongsTo:User,hasMany:Comment,morphTo:commentable"
Desteklenen ilişki türleri: belongsTo, hasMany, morphTo. --relations= verilmesi --with-relations'ı zımnen içerir.
Örnekler:
# Sadece domain — v13.5.x davranışı, geriye dönük uyumlu
php artisan make:sk-domain Article
# Policy ve factory ile
php artisan make:sk-domain Article --with-policy --with-factory
# Toplu syntax
php artisan make:sk-domain Article --with=policy,factory,test
# İlişkilerle
php artisan make:sk-domain Article --with-relations --relations="belongsTo:User,hasMany:Comment"
# Tam
php artisan make:sk-domain Article --with=policy,factory,seeder,test,relations --relations="belongsTo:User,morphTo:commentable"