Polimorfik Denetim Günlüklerinin Sorunları
<p>B2B SaaS mühendisliğinde, Smart Tech Devs'te sağlam bir denetim izi oluşturmak—tam olarak kimin neyi değiştirdiğini ve ne zaman değiştirdiğini takip etmek—genellikle zorunlu bir uyumluluk gereksinimidir. Standart Laravel yaklaşımı, merkezi bir <code>audits</code> tablosuna polimorfik ilişkiler kullanarak her bir model güncellemesi için yeni bir satır oluşturmaktır.</p>
<p>Platformunuz <code>invoices</code> veya <code>users</code> gibi ana tablolarda milyonlarca satıra ölçeklendiğinde, bu denetim stratejisi artık işlevsel olmaktan çıkar. Merkezi denetim tablonuz devasa hale gelir, bu da veritabanınızı boğar ve eski verileri temizlemek pahalı bir kilitleme işlemi haline gelir. Dahası, standart günlük kaydı genellikle tüm model durumunu yakalar, sadece değişen verileri değil, bu da değerli disk alanı israfına yol açar. Kalıcı bir mimari oluşturmak için PostgreSQL JSONB gücünden yararlanmalıyız.</p>
<h2>JSONB Kompakt Değişiklik Kümeleri</h2>
<p>PostgreSQL'in JSONB veri türü, yapısal olmayan, indekslenmiş JSON verilerini verimli bir şekilde depolamamıza olanak tanır. Devasa polimorfik günlük tabloları oluşturmak yerine, bir "değişiklik kümesini" doğrudan ana modeldeki özel bir denetim sütununa veya bir yan tabloya JSONB ile ekleyebiliriz.</p>
<h3>Adım 1: Veritabanı Migration'ı</h3>
<p>Ayrı bir tablo yerine, denetimini yapmak istediğimiz modele bir <code>jsonb</code> sütunu ekliyoruz. Ayrıca bu sütunda hızlı aramalar için bir GIN indeksi oluşturduğumuzdan emin oluyoruz.</p>
<pre><code>use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddAuditLogToInvoicesTable extends Migration
{
public function up(): void
{
Schema::table(‘invoices’, function (Blueprint $table) {
// Değişiklik kümesinin kompakt bir dizisini saklıyoruz: [{user_id, changed_at, old: {}, new: {}}, …]
$table->jsonb(‘audit_log’)->nullable();
});
// JSONB verilerinde verimli sorgulama için bir GIN indeksi ekleyin
DB::statement('CREATE INDEX invoices_audit_log_gin ON invoices USING GIN (audit_log);');
}}
<h3>Adım 2: Model Gözlemcileri ile Verimli Denetim</h3>
<p>Tüm modeli yakalamıyoruz. Bir Eloquent Observer kullanarak <code>updating</code> olayına bağlanıyoruz, Laravel'in <code>getDirty()</code> ve <code>getOriginal()</code> yöntemlerini kullanarak sıkı bir değişiklik kümesi hesaplıyoruz ve minimal JSON delta'yı denetim sütunumuza ekliyoruz.</p>
<pre><code>namespace App\Observers;
use App\Models\Invoice;
use Illuminate\Support\Facades\Auth;
class InvoiceObserver
{
/
Invoice “updating” olayını ele al.
*/
public function updating(Invoice $invoice): void
{
// 1. Yalnızca değiştirilen özellikleri ve orijinal değerlerini al
$dirty = $invoice->getDirty();
$original = array_intersect_key($invoice->getOriginal(), $dirty);if (empty($dirty)) {
return; // Değişiklik yapılmadı
}// 2. Kompakt bir değişiklik kümesi oluştur
$changeset = [
‘user_id’ => Auth::id() ?? ‘system’,
‘changed_at’ => now()->toIso8601String(),
‘old’ => $original,
‘new’ => $dirty,
];// 3. Mevcut JSONB dizisine değişiklik kümesini ekleyin (veritabanı düzeyinde birleştirme kullanarak)
// Bunu yapmak, tüm denetim geçmişini belleğe yüklenmeden eklemeyi sağlıyor.
$invoice->audit_log = DB::raw(“jsonb_insert(COALESCE(audit_log, ‘[]’), ‘{0}’, ‘” . json_encode($changeset) . “‘)”);
}
}
<h2>Mühendislik ROI</h2>
<p>Modelin kendisinde (veya bir yan tabloda) JSONB değişiklik kümelerine geçmek, denetim altyapınızı temelden yükseltir:</p>
<ul>
<li>Veritabanı Şişmesini Dramatik Şekilde Azaltma: Değişen verileri saklıyorsunuz, tüm model durumunu birden fazla kez kopyalamadığınız için.
<h2>Sonuç</h2>
<p>Polimorfik denetim günlükleri, ölçeklendiğinde bir yük haline gelir. Laravel Gözlemcileri içinde PostgreSQL'in JSONB esnekliğinden ve performansından yararlanarak, veri bütünlüğünü tehlikeye atmadan sistem performansını koruyan dayanıklı, yüksek verimli bir denetim izi oluşturursunuz.</p>Kaynak: Orijinal Makale


