Ön Hazırlık ve Gereksinimler
Dinamik bir iş akış sistemi kurmak için Laravel 11 veya üzeri bir sürüm kullanmanız önerilir. Veritabanı modelleme tarafında ilişkisel veritabanı (MySQL veya PostgreSQL) kullanacağız. Sisteminizde temel Laravel kurulumunun yapıldığını ve veritabanı bağlantılarının ayarlandığını varsayıyoruz.
- Laravel 11.x
- PHP 8.2+
- Veritabanı: MySQL 8.0+
- Composer paket yöneticisi
Veritabanı Şeması ve İlişkisel Yapı
Dinamik iş akışlarının kalbi, süreçleri ve bu süreçlerin hangi birimlere ait olduğunu tutan tablolardır. workflows, workflow_steps ve departments tabloları ile temel yapıyı kurarız.
// Migration: workflow_steps tablosu oluşturma
Schema::create('workflow_steps', function (Blueprint $table) {
$table->id();
$table->foreignId('workflow_id')->constrained();
$table->string('step_name');
$table->integer('order'); // Adım sırası
$table->foreignId('department_id')->constrained(); // Hangi birim sorumlu?
$table->timestamps();
});
Bu yapı, her adımın hangi departmana ait olduğunu belirler. order sütunu, sürecin hangi sırayla ilerleyeceğini kontrol etmemizi sağlar.
İş Akışı Modellerini Tanımlama
Eloquent ORM kullanarak modeller arasındaki ilişkileri kurmalıyız. Bir iş akışının birden fazla adımı, bir adımın ise bir departmanı olmalıdır.
// Workflow.php Modeli
public function steps()
{
return $this->hasMany(WorkflowStep::class)->orderBy('order', 'asc');
}
// WorkflowStep.php Modeli
public function department()
{
return $this->belongsTo(Department::class);
}
Bu ilişkiler, $workflow->steps üzerinden tüm süreci kolayca çekmemizi sağlar. Eloquent, bu tür veritabanı ilişkilerini yönetmek için en verimli yöntemdir.
Dinamik Onay Mekanizması Geliştirme
İş akışının bir sonraki adıma geçmesi için bir "onaylayıcı" mantığına ihtiyacımız var. WorkflowInstance modeli üzerinden mevcut durumu takip ederiz.
// İş akışını bir sonraki adıma taşıyan servis metodu
public function advanceStep(WorkflowInstance $instance)
{
$currentStep = $instance->currentStep;
$nextStep = WorkflowStep::where('workflow_id', $instance->workflow_id)
->where('order', '>', $currentStep->order)
->first();
if ($nextStep) {
$instance->update(['current_step_id' => $nextStep->id]);
} else {
$instance->update(['status' => 'completed']);
}
}
Bu kod, mevcut adımın sırasından daha büyük bir sıra numarasına sahip olan ilk adımı bulur. Eğer adım yoksa, süreç tamamlanmış sayılır.
Departman Bazlı Yetkilendirme
Güvenlik için, sadece ilgili departman kullanıcılarının süreci onaylamasına izin vermeliyiz. Laravel Policies kullanarak bu işlemi merkezi hale getirebiliriz.
// WorkflowPolicy.php
public function approve(User $user, WorkflowInstance $instance)
{
return $user->department_id === $instance->currentStep->department_id;
}
Bu policy, kullanıcının departman ID'si ile mevcut adımın departman ID'sini karşılaştırır. $this->authorize('approve', $instance) çağrısı ile controller içerisinde kolayca güvenlik kontrolü yapabilirsiniz.
Güvenlik Uyarısı: Kullanıcıdan gelen departman verilerine asla güvenmeyin. Kullanıcı departman bilgisini her zaman oturum (Auth) üzerinden, veritabanından çekin. Form verisi olarak gelen departman ID'leri manipüle edilebilir.
İş Akış Yönetim Yöntemlerinin Karşılaştırılması
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Hard-coded (Kod içi) | Hızlı geliştirme | Esneklik yok, bakım zor |
| Veritabanı Bazlı (Dinamik) | Yüksek esneklik | Karmaşık veritabanı sorguları |
| State Machine Paketi | Standart yapı | Öğrenme eğrisi |
Sıkça Sorulan Sorular
Dinamik iş akışlarında hata ayıklama nasıl yapılır?
Laravel'in Log facade'ini kullanarak her adım geçişini ve onaylayan kullanıcıyı veritabanı log tablosunda tutmanız önerilir.
Süreç tıkandığında (bottleneck) ne yapmalı?
Süreç adımlarına bir 'deadline' (son tarih) sütunu ekleyerek, süresi dolan işleri cron job ile otomatik olarak yöneticilere bildirebilirsiniz.
Birden fazla departman aynı adımı onaylayabilir mi?
Evet, workflow_steps tablosuna bir many-to-many ilişkisi kurarak bir adımın birden fazla departmana atanmasını sağlayabilirsiniz.
Performans kaybı yaşanır mı?
İlişkileri with() metodu ile "eager loading" yaparak (örneğin WorkflowInstance::with('currentStep.department')) sorgu sayısını minimize edebilirsiniz.
Bu yapı 2026 standartlarına uygun mu?
Evet, Laravel 11'in sunduğu modern tip tanımlamaları ve veritabanı özellikleri ile tam uyumludur.
Sorumluluk Reddi: Bu rehberdeki kod örnekleri eğitim amaçlıdır. Üretim ortamında kullanmadan önce tüm girdileri doğrulayın (validation) ve yetkilendirme katmanlarını (authorization) kapsamlı bir şekilde test edin.
İleri Seviye Senaryo: Koşullu Dallanma ve Dinamik Yönlendirme
İş akışlarınızda her zaman doğrusal bir ilerleme olmayabilir. Örneğin, bir satın alma talebi 5.000 TL üzerindeyse "Finans Direktörü" onayı, altında ise sadece "Birim Müdürü" onayı gerektirebilir. Bu tür koşullu dallanmaları yönetmek için iş akışı adımlarınıza conditions adında bir JSON sütunu eklemek en verimli yöntemdir.
Aşağıdaki örnekte, bir adımın tetiklenmesi için gereken mantıksal koşulu nasıl kontrol edeceğimizi görüyoruz:
public function shouldTrigger(WorkflowStep $step, Request $request): bool
{
$conditions = json_decode($step->conditions, true);
if (!$conditions) return true;
foreach ($conditions as $field => $value) {
if ($request->input($field) < $value) {
return false;
}
}
return true;
}
Bu yapı sayesinde, veritabanındaki workflow_steps tablosuna {"amount": 5000} gibi bir veri girerek, kod değişikliği yapmadan iş mantığını değiştirebilirsiniz.
İş Akışlarında Test Stratejileri ve Birim Testleri
Dinamik sistemlerde en büyük risk, yanlış yapılandırılmış bir adımın tüm süreci kilitlemesidir. Laravel'in Pest veya PHPUnit kütüphanelerini kullanarak, iş akışlarınızın farklı senaryolarda nasıl tepki verdiğini mutlaka test etmelisiniz. Özellikle "bir sonraki adım" (next step) hesaplama mantığı kritik öneme sahiptir.
Aşağıdaki test örneği, bir iş akışının doğru birime yönlendirilip yönlendirilmediğini doğrular:
public function test_workflow_routes_to_correct_department()
{
$workflow = Workflow::factory()->create();
$step = WorkflowStep::factory()->for($workflow)->create(['department_id' => 2]);
$response = $this->postJson('/api/workflows/next', [
'workflow_id' => $workflow->id,
'current_step_id' => $step->id
]);
$response->assertStatus(200)
->assertJsonPath('next_department_id', 2);
}
Performans Optimizasyonu: Önbellekleme (Caching) Stratejileri
İş akışı tanımları (workflow definitions) nadiren değişen ancak her işlemde sürekli sorgulanan verilerdir. Veritabanı üzerindeki yükü azaltmak için Workflow ve WorkflowStep modellerini remember metodu ile önbelleğe almanız önerilir. Bu, özellikle yüksek trafikli kurumsal uygulamalarda yanıt sürelerini milisaniyeler seviyesine çeker.
Önbellek stratejisi için şu yaklaşımı kullanabilirsiniz:
public function getWorkflowSteps(int $workflowId)
{
return Cache::remember("workflow_{$workflowId}_steps", 3600, function () use ($workflowId) {
return WorkflowStep::where('workflow_id', $workflowId)
->orderBy('order', 'asc')
->get();
});
}
Önemli İpucu: İş akışı tanımında bir güncelleme yaptığınızda, ilgili önbelleği Cache::forget("workflow_{$workflowId}_steps") komutu ile temizlemeyi unutmayın. Aksi takdirde sistem eski iş akışı kuralları ile çalışmaya devam edecektir.
Sonuç
Laravel ile iş birimlerine özel dinamik iş akış yönetimi, veritabanı tasarımı ve yetkilendirme mantığının doğru kurulmasına dayanır. Bu yapıyı kurduğunuzda, iş birimlerinizin süreçleri değiştiğinde kodunuzu değiştirmek zorunda kalmaz, sadece veritabanındaki kayıtları güncelleyerek sistemi yönetebilirsiniz. Bir sonraki adım olarak, bu iş akışlarına "onay reddedildiğinde başa dön" veya "koşullu dallanma" gibi mantıksal katmanlar ekleyerek sistemi daha da geliştirebilirsiniz.


Yorumlar (0)
Yorum Yaz