Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Yazı Tipi BoyutlandırıcıAa
  • Anasayfa
  • Teknoloji
    • Siber Güvenlik
    • Yapay Zeka
    • Donanım
    • Bilim
  • Yazılım
  • Savunma & İstihbarat
  • Oyun
  • Yaşam
    • Finans
    • Sinema
    • Dünyadan Haberler
  • İş Birliği
Okuma: Değiştirilemez Kayıtlarla Denetim Kanıtı Finansal İş Akışları Tasarlama
Paylaş
Yazı Tipi BoyutlandırıcıAa
Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Ara
Bizi Takip Et
  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti
© 2026 Teknomers. All Rights Reserved.

Anasayfa » Değiştirilemez Kayıtlarla Denetim Kanıtı Finansal İş Akışları Tasarlama

Yazılım

Değiştirilemez Kayıtlarla Denetim Kanıtı Finansal İş Akışları Tasarlama

teknomers
Son güncelleme: 17 Nisan 2026 16:14
teknomers
Paylaş
Paylaş

Mutable Kayıtların Denetim Altında Nasıl Bozulduğu

Çoğu web uygulaması, bir kaydın güncel durumunu saklar. Örneğin, bir fatura durumu “beklemede” iken “ödenmiş” durumuna geçtiğinde, veritabanı satırı yerinde güncellenir. Önceki durum kaybolur.

Bu, çoğu uygulama için sorun yaratmaz. Ancak finansal sistemler için ciddi bir risk teşkil eder:

  • Tarihçe yok: Faturanın durumunun dün saat 15:00’te ne olduğunu kanıtlayamazsınız.
  • Atıf yok: Durumu kimin ve neden değiştirdiğini belirleyemezsiniz.
  • Uzlaştırma yolu yok: Sayılar eşleşmediğinde, takip edilecek bir iz yoktur.
  • Manipülasyon kanıtı yok: Değiştirilmiş bir kayıt, yasal görünür.

Finansal düzenlemeler — PCI DSS, SOX, FCA yönergeleri — sistemlerin tüm finansal işlemler ve durum değişiklikleri için tam, değiştirilemez bir kayıt tutmasını gerektirir. Bir UPDATE ifadesi, saklamanız gereken kanıtları tam olarak yok eder.


Değiştirilemez Kayıt Deseni

Çözüm, finansal kayıtları asla güncellememek veya silmemektir. Bunun yerine, her değişiklik yeni, eklenebilir bir olay olarak kaydedilir:

[Olay 1] Fatura #1042 OLUŞTURULDU — tutar: £5,000 — kimden: user_42 — saat: 2025-03-01T09:15:00Z
[Olay 2] Fatura #1042 ONAYLANDI — onaylayan: user_15 — saat: 2025-03-01T14:30:00Z
[Olay 3] Fatura #1042 ÖDEME_ALINDI — tutar: £5,000 — referans: PAY_8821 — saat: 2025-03-05T11:00:00Z
[Olay 4] Fatura #1042 UYUMLANDI — bankayla eşleşen: BANK_TXN_4401 — saat: 2025-03-06T08:45:00Z

Faturanın güncel durumu, olayların sırasını yeniden oynatarak elde edilir. Denetim yolu, olayların kendisidir. Hiçbir şey kaybolmaz, hiçbir şey üzerine yazılmaz.


Mimari Genel Görünüm

[Müşteri Talebi]
       |
       v
[Uygulama Katmanı]
  - İş kurallarını doğrula
  - Olay kaydını oluştur
       |
       v
[DB İşlemi]
  - Olayı audit_events tablosuna yaz (sadece ekleme)
  - Materyalize edilmiş görünümü / güncel durum tablosunu güncelle
       |
       v
[Denetim Olayları Tablosu]           [Güncel Durum Tablosu]
  (değiştirilemez, yalnızca ekleme)      (türetilebilir, yeniden oluşturulabilir)
       |
       v
[Asenkron Tüketiciler]
  - Uyum raporlama
  - Uzlaştırma motoru
  - Bildirim servisi

Kritik tasarım kararı: denetim olayları tablosu gerçeğin kaynağıdır. Güncel durum tablosu, olaylardan herhangi bir zamanda yeniden inşa edilebilecek bir projeksiyondur.


Laravel’de Uygulama

Denetim Olayları Göçü

Schema::create('audit_events', function (Blueprint $table) {
    $table->uuid('id')->primary();
    $table->string('aggregate_type');
    $table->string('aggregate_id');
    $table->unsignedBigInteger('sequence_number');
    $table->string('event_type');
    $table->json('payload');
    $table->json('metadata');
    $table->string('actor_id');
    $table->string('actor_type');
    $table->string('ip_address')->nullable();
    $table->string('checksum');
    $table->timestamp('occurred_at');
    $table->timestamp('created_at');

    $table->unique(['aggregate_type', 'aggregate_id', 'sequence_number']);
    $table->index(['aggregate_type', 'aggregate_id']);
    $table->index(['event_type']);
    $table->index(['occurred_at']);
    $table->index(['actor_id']);
});

checksum sütunu, olay verisinin ve önceki olayın checksum’ının bir hash’ini saklar. Geçmiş bir kayıtta yapılan herhangi bir değişiklik zinciri bozar.

Denetim Olayı Servisi

namespace App\Services;

use App\Models\AuditEvent;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class AuditEventService
{
    public function record(
        string $aggregateType,
        string $aggregateId,
        string $eventType,
        array $payload,
        string $actorId,
        string $actorType = 'user',
        ?string $ipAddress = null,
    ): AuditEvent {
        return DB::transaction(function () use (
            $aggregateType,
            $aggregateId,
            $eventType,
            $payload,
            $actorId,
            $actorType,
            $ipAddress
        ) {
            $lastEvent = AuditEvent::where('aggregate_type', $aggregateType)
                ->where('aggregate_id', $aggregateId)
                ->orderByDesc('sequence_number')
                ->lockForUpdate()
                ->first();

            $sequenceNumber = $lastEvent ? $lastEvent->sequence_number + 1 : 1;
            $previousChecksum = $lastEvent ? $lastEvent->checksum : 'GENESIS';

            $eventData = [
                'aggregate_type' => $aggregateType,
                'aggregate_id' => $aggregateId,
                'sequence_number' => $sequenceNumber,
                'event_type' => $eventType,
                'payload' => $payload,
                'actor_id' => $actorId,
                'occurred_at' => now(),
            ];

            $checksum = hash('sha256', $previousChecksum . json_encode($eventData));

            return AuditEvent::create([
                'id' => Str::uuid(),
                ...$eventData,
                'metadata' => [
                    'previous_checksum' => $previousChecksum,
                    'schema_version' => '1.0',
                ],
                'actor_type' => $actorType,
                'ip_address' => $ipAddress,
                'checksum' => $checksum,
                'created_at' => now(),
            ]);
        });
    }

    public function verifyChain(string $aggregateType, string $aggregateId): bool
    {
        $events = AuditEvent::where('aggregate_type', $aggregateType)
            ->where('aggregate_id', $aggregateId)
            ->orderBy('sequence_number')
            ->get();

        $previousChecksum = 'GENESIS';

        foreach ($events as $event) {
            $eventData = [
                'aggregate_type' => $event->aggregate_type,
                'aggregate_id' => $event->aggregate_id,
                'sequence_number' => $event->sequence_number,
                'event_type' => $event->event_type,
                'payload' => $event->payload,
                'actor_id' => $event->actor_id,
                'occurred_at' => $event->occurred_at,
            ];

            $expectedChecksum = hash('sha256', $previousChecksum . json_encode($eventData));

            if ($expectedChecksum !== $event->checksum) {
                return false;
            }

            $previousChecksum = $event->checksum;
        }

        return true;
    }

    public function getHistory(string $aggregateType, string $aggregateId): \Illuminate\Support\Collection
    {
        return AuditEvent::where('aggregate_type', $aggregateType)
            ->where('aggregate_id', $aggregateId)
            ->orderBy('sequence_number')
            ->get();
    }
}

Finansal Bir İş Akışında Kullanımı

class InvoiceService
{
    public function __construct(
        private AuditEventService $auditService,
    ) {}

    public function createInvoice(array $data, string $userId, string $ip): Invoice
    {
        return DB::transaction(function () use ($data, $userId, $ip) {
            $invoice = Invoice::create([
                'number' => $this->generateInvoiceNumber(),
                'client_id' => $data['client_id'],
                'amount' => $data['amount'],
                'currency' => $data['currency'],
                'status' => 'draft',
                'due_date' => $data['due_date'],
            ]);

            $this->auditService->record(
                aggregateType: 'invoice',
                aggregateId: (string)$invoice->id,
                eventType: 'invoice.created',
                payload: [
                    'number' => $invoice->number,
                    'amount' => $invoice->amount,
                    'currency' => $invoice->currency,
                    'client_id' => $invoice->client_id,
                ],
                actorId: $userId,
                ipAddress: $ip,
            );

            return $invoice;
        });
    }

    public function approveInvoice(Invoice $invoice, string $approverId, string $ip): Invoice
    {
        return DB::transaction(function () use ($invoice, $approverId, $ip) {
            $invoice->update(['status' => 'approved']);

            $this->auditService->record(
                aggregateType: 'invoice',
                aggregateId: (string)$invoice->id,
                eventType: 'invoice.approved',
                payload: [
                    'previous_status' => 'draft',
                    'new_status' => 'approved',
                ],
                actorId: $approverId,
                ipAddress: $ip,
            );

            return $invoice->fresh();
        });
    }
}

Uygulama Sonuçları

Finansal platformlarda değiştirilemez denetim kaydı uygulandığında:

MetrikÖnceSonra
Uzlaştırma süresi (haftalık)4+ saat manuel15 dakika otomatik
Denetim hazırlık süresi2-3 hafta2 gün
Çözümsüz farklılıklarAylık 8-12Aylık 0-1
Uyum denetimi bulgularıHer incelemede birden fazlaHiçbir maddi bulgu yok
Veri uyuşmazlığı çözülme süresi3-5 gün

Anahtar Noktalar

  1. Finansal kayıtları asla yerinde güncellemeyin. Bunun yerine yeni olaylar ekleyin. Güncel durum, olay geçmişinin bir projeksiyonudur.

  2. Manipülasyon kanıtı için hash zincirleri kullanın. Her olayın checksum’ı, önceki olayın checksum’ını içerir. Herhangi bir değişiklik zinciri bozar.

  3. Kim, ne, ne zaman ve neden kaydedin. Her olay bir aktör, bir zaman damgası ve iş bağlamı içermelidir. IP adresleri ve oturum tanımlayıcıları, adli değer katar.

  4. Gün başından itibaren süreyi planlayın. Denetim kayıtları hızla büyür. Katmanlı depolama (hot/warm/cold) maliyetleri yönetilebilir tutarken uyum gereksinimlerini karşılar.

  5. Otomatik uzlaştırma yapın. Değiştirilemez kayıtlar, saatler süren manuel tablo karşılaştırmasını ortadan kaldıran programatik uzlaştırmayı mümkün kılar.

  6. Olayları ve iş verilerini aynı işlem içinde yazın. Eğer atomik değillerse, gerçeğiniz ile denetim iziniz arasındaki tutarsızlık riski taşır.


Sonuç

Denetim kanıtı niteliğindeki finansal iş akışları, daha fazla günlük üretmekle ilgili değildir — her durum değişikliğinin kaydedildiği, zincirlendiği ve doğrulanabilir olduğu sistemler tasarlamakla ilgilidir. Sadece ekleme yazımları, hash-zinciri bütünlüğü ve katmanlı süreler, herhangi bir denetçinin sorusuna kanıt ile, açıklama değil, cevap verir.

Laravel veya Node.js ile inşa etseniz de, yapılar aynıdır. Bu altyapı, her defasında bir düzenleyici soru sorduğunda veya bir farklılık çözülmesi gerektiğinde değerini öder.

Kaynak: Orijinal Makale

Contents
  • Mutable Kayıtların Denetim Altında Nasıl Bozulduğu
  • Değiştirilemez Kayıt Deseni
  • Mimari Genel Görünüm
  • Laravel’de Uygulama
    • Denetim Olayları Göçü
    • Denetim Olayı Servisi
    • Finansal Bir İş Akışında Kullanımı
  • Uygulama Sonuçları
  • Anahtar Noktalar
  • Sonuç
Bir Geliştirici Olarak Tek Başıma TikTok Reklamları Otomasyon SaaS’ımı Günde 7M İsteğe Ölçeklendirdim
cPanel’de Laravel storage:link Çalışmıyor mu? Dağıtım Sonrası Görseller Kayboluyor
Laravel’de Ek Yük Olmadan Hata İzleme Kurulumu
Yinelenen Webhook İşlemlerini Durdurma: Laravel’de İdempotentlik ve Güvenlik
Ham SQL Tarih Fonksiyonlarını Kullanmayı Neden Bıraktım ve Laravel’de Carbon’a Geçtim
Bu Makaleyi Paylaş
Facebook Bağlantıyı Kopyala Yazdır
Paylaş
Önceki Makale Amazon Eero Günlüğü: Eero Mesh Ağı için 4G LTE İnternet Yedeği
Sonraki Makale AI’nin Kaçınılmaz Olma Tuzakları

Sanal Medya

FacebookBeğen
452Takip Et
PinterestSabitle
237Takip Et

Son Eklenenler

Rusya’nın ‘Starlink Tarzı’ Rassvet filosu ilk uydusunu kaybetti
Donanım
Kontrolü Ele Geçirmek Üzerine Bir Oyun Deneyimi
Oyun
Xbox’ın 25. Yılı İçin Şeffaf Yeşil Konsol Geliyor
Liste
Mars’a Gidecek El Çantası Boyutunda Uzay Aracı için Yeni Motor Teknolojisi
Bilim
Diyabeti Yenen Yeni Enjeksiyon Kan Şekerini ve Kiloyu Azaltıyor!
Finans
RetroPad: XP Notepad’ın 2,749 Byte’lık Tam Versiyonu
Donanım
//

Siber güvenlik, yapay zeka ve savunma sanayiinden; finans ve sinema dünyasına uzanan geniş bir yelpaze. Teknomers; teknoloji, strateji ve yazılım dünyasını sade bir dille sizlerle buluşturuyor.

Kurumsal

  • Hakkımızda
  • Gizlilik politikası
  • Tanıtım Yazısı ve Backlink Hizmeti

Kategoriler

  • Teknoloji
  • Oyun
  • Sinema
  • Siber Güvenlik
  • Bilim
  • Finans
  • Dünyadan Güncel Haberler

Populer

  • TV'de Ücretsiz İzlenebilen Şifresiz Erotik Kanallar (2025 Güncel Frekans Listesi)

  • The Last of Us PC Kontrolleri: Hızlı Silah Değiştirme ve Tüm Tuşlar (2025)

  • Hogwarts Legacy'de Odaklanma İksiri Nasıl Yapılır?

Teknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor HaberleriTeknomers | Dünyadan Güncel Teknoloji | Oyun | Müzik | Film | Spor Haberleri
Bizi Takip Et
© 2026 Teknomers. All Rights Reserved.
Welcome Back!

Sign in to your account

Kullanıcı Adı veya E-posta Adresi
Şifre

Şifrenizi mi unuttunuz?