Factorizer/Cluster ERP WikiCluster ERP English
Ana sayfa / Platform

Açıklama

Değişiklik geçmişi

core/change_history.py her varlığın her değişikliğini işlemi yapan, zaman ve alan düzeyi farkla nasıl kaydeder.

Cluster ERP, her iş varlığındaki her değişiklik için değişiklikle aynı işlemde otomatik olarak bir geçmiş satırı yazar. Bu sayfa core/change_history.py içindeki yakalamayı, core/sensitive_fields.py içindeki değer gizlemeyi, core/audit.py içindeki eski audit_log tablosunu ve core/audit_backfill.py içindeki dolgusunu ve core/migration_history.py içindeki göç kanıt satırlarını anlatır. Geçmişi gösteren ekranlar logs modülüne aittir; bkz. logs.

Kısaca

  • Session üzerindeki tek bir SQLAlchemy before_flush dinleyicisi, sınıfı Base'den türeyen her nesnenin her eklemesini, güncellemesini ve silmesini yakalar (src/cluster_erp/core/change_history.py:318-351, src/cluster_erp/core/change_history.py:262-270).
  • Geçmiş satırları değişiklikle aynı işlemde core_change_history tablosuna gider (src/cluster_erp/core/change_history.py:12-14, src/cluster_erp/core/change_history.py:349-350).
  • İşlemi yapan ve ilişki kimliği işlev argümanlarından değil, istek bağlamından gelir (src/cluster_erp/core/change_history.py:320-321).
  • Kimlik bilgisi, özel nitelikli ve tanımlayıcı sütunlar değişiklik kaydını korur ama değerlerini kaybeder (src/cluster_erp/core/change_history.py:166-169, src/cluster_erp/core/sensitive_fields.py:61-82).
  • Modül, dinleyici herhangi bir oturum flush etmeden önce kaydedilsin diye server/app.py tarafından içe aktarılır (src/cluster_erp/server/app.py:33-35).

Nasıl çalışır

Yakalama

Akış şeması dinleyicinin her flush'ta yaptığını gösterir.

flowchart TD
 start["before_flush"] --> ctx["işlemi yapanı ve ilişki kimliğini oku"]
 ctx --> new["session.new içindeki her nesne"]
 new --> create["kimliği güvenceye al, created_by damgala, anlık görüntü, action create"]
 ctx --> dirty["session.dirty içindeki her nesne"]
 dirty --> deact{"deleted_at NULL'dan değere mi?"}
 deact -->|evet| stamp["deleted_by, neden, not damgala"]
 deact -->|hayır| diff["alan farkı"]
 stamp --> diff
 diff --> classify["updated_by damgala, eylemi sınıfla"]
 ctx --> del["session.deleted içindeki her nesne"]
 del --> snap["anlık görüntü, action delete"]
 create --> add["geçmiş satırlarını session.add"]
 classify --> add
 snap --> add
 add --> queue["TenantFieldValuesChanged kuyruğa al"]

Düz metinle:

  1. Dinleyici current_actor_id() ve current_correlation_id() değerlerini okur (src/cluster_erp/core/change_history.py:320-321).
  2. Her yeni nesne için birincil anahtar boşsa atar, created_by damgalar ve create eylemiyle tam bir anlık görüntü kaydeder (src/cluster_erp/core/change_history.py:324-329).
  3. Her değişen nesne için önce deleted_at NULL'dan bir değere geçiyorsa kullanımdan kaldırma verilerini damgalar, sonra alan farkını hesaplar. Fark boşsa satır yazılmaz. Değilse updated_by damgalar ve eylemi sınıflar (src/cluster_erp/core/change_history.py:331-342).
  4. Her silinen nesne için delete eylemiyle bir anlık görüntü kaydeder (src/cluster_erp/core/change_history.py:344-347).
  5. Geçmiş satırlarını oturuma ekler ve kiracı alanı olaylarını kuyruğa alır (src/cluster_erp/core/change_history.py:349-351).

Eylemler

Eylem Ne zaman Kaynak
create Yeni bir nesne flush edildiğinde src/cluster_erp/core/change_history.py:324-329
update Kullanımdan kaldırma veya etkinleştirme olmayan değişmiş bir nesne src/cluster_erp/core/change_history.py:213
deactivate deleted_at boştan doluya geçtiğinde ya da deleted_at değişmeden is_active true'dan false'a geçtiğinde src/cluster_erp/core/change_history.py:202-210
activate deleted_at doludan boşa geçtiğinde ya da is_active false'tan true'ya geçtiğinde src/cluster_erp/core/change_history.py:204, src/cluster_erp/core/change_history.py:211-212
delete Bir nesne ORM üzerinden fiziksel olarak silindiğinde src/cluster_erp/core/change_history.py:344-347
migration Bir veri göçü record_data_migration çağırdığında src/cluster_erp/core/migration_history.py:20-53

Tablo

core_change_history şu sütunları taşır: id, actor_id, correlation_id, entity_type (sınıf adı), table_name, entity_id, action, changes (JSONB) ve occurred_at (src/cluster_erp/core/change_history.py:78-98). (table_name, entity_id), actor_id ve occurred_at üzerinde dizinleri vardır (src/cluster_erp/core/change_history.py:94-98). changes her alan adını {"from":..., "to":...} biçimine eşler; değerler JSON'a uygun hale getirilir ve UUID, tarihler ve Decimal dizgiye çevrilir (src/cluster_erp/core/change_history.py:101-114, src/cluster_erp/core/change_history.py:154-176).

Atlananlar

  • Base'den türemeyen nesneler; örneğin kontrol düzlemi varlıkları (src/cluster_erp/core/change_history.py:262-269).
  • Dokuz tablo: core_change_history, core_sequences, audit_log, deleted_records, activity_log, error_log, auth_token_blacklist, alembic_version ve core_retention_runs (src/cluster_erp/core/change_history.py:42-52).
  • Farktaki altı defter tutma sütunu: updated_at, version, created_by, updated_by, deleted_by ve deactivated_by (src/cluster_erp/core/change_history.py:55).

Kiracı tanımlı değerler

extra JSONB torbası anahtar anahtar extra.<key> olarak karşılaştırılır; böylece kiracı tanımlı bir alanın geçmişi bir sütununki ile aynıdır (src/cluster_erp/core/change_history.py:137-151, src/cluster_erp/core/change_history.py:172-174). EXTRA_REDACTED_KEYS içindeki anahtarlar değişikliklerini korur ama değerlerini korumaz (src/cluster_erp/core/change_history.py:130-134, src/cluster_erp/core/change_history.py:147-148). Onaydan sonra değişen her kayıt için TenantFieldValuesChanged yayınlanır (src/cluster_erp/core/change_history.py:357-386). Bkz. kiracı alanları.

Gizleme

is_redacted_column, bir değerin [redacted] ile değiştirilip değiştirilmeyeceğine karar verir (src/cluster_erp/core/sensitive_fields.py:25, src/cluster_erp/core/sensitive_fields.py:61-82). Politikanın dört parçası vardır:

  • Herhangi bir tabloda alt dizgiyle eşleşen kimlik bilgisi sütunları (src/cluster_erp/core/sensitive_fields.py:28-37, src/cluster_erp/core/sensitive_fields.py:56-58).
  • Tam table.column çiftleri olarak özel nitelikli sütunlar (src/cluster_erp/core/sensitive_fields.py:42-45).
  • Herhangi bir tabloda tam eşleşen doğrudan tanımlayıcılar (src/cluster_erp/core/sensitive_fields.py:49-53).
  • Açılışta yüklenen, change_history_redact_columns ayarından gelen kurulumun kendi listesi (src/cluster_erp/config/settings.py:708-711, src/cluster_erp/server/app.py:1307, src/cluster_erp/core/change_history.py:68-71).

Aynı modül istek günlüğü gövde temizleyicisini de besler (src/cluster_erp/core/sensitive_fields.py:85-103). Belge dizgisi, audit_log tetikleyicisinin aynı listeleri SQL'de taşıdığını ve tests/test_sensitive_fields_policy.py testinin ikisini birbirine bağladığını belirtir (src/cluster_erp/core/sensitive_fields.py:1-18).

Eski denetim günlüğü

audit_log, bir veritabanı tetikleyicisinin yazdığı eski bir tablodur; actor_id, entity_type, entity_id, action, diff_jsonb, occurred_at, ip, user_agent, session_id ve correlation_id sütunlarını taşır (src/cluster_erp/core/audit.py:15-69). İstek oturumu böyle bir tetikleyicinin okuyabileceği beş app.* PostgreSQL ayarını kurar (src/cluster_erp/server/dependencies.py:43-58). core/audit_backfill.py, dm01 sürümünden önce yazılmış satırları hassas değerleri kaldırmak için küçük gruplar halinde yeniden yazar. Açılışta arka plan görevi olarak ve istendiğinde python -m cluster_erp.core.audit_backfill ile çalışır (src/cluster_erp/core/audit_backfill.py:1-16, src/cluster_erp/server/app.py:164).

Veri göçleri

Satırları ham SQL ile yeniden yazan bir göç record_data_migration(connection, revision, table_name, note, rows) çağırır; bu, migration eylemli ve işlemi yapanı olmayan bir geçmiş satırı ekler (src/cluster_erp/core/migration_history.py:1-10, src/cluster_erp/core/migration_history.py:30-53). migrations/versions/ içindeki dokuz dosya onu çağırır (grep -l record_data_migration ile sayıldı).

Neden böyle kurulmuştur

  • Modül belge dizgisi tasarımı belirtir: tek dinleyici her modeli otomatik kapsar, atlanamaz ve işlemi yapan süreç içi bağlamdan gelir; böylece modüller arası çağrı olmaz (src/cluster_erp/core/change_history.py:1-14).
  • Projenin yazılı mühendislik kuralları değişiklik geçmişinin otomatik olduğunu, kimsenin geçmiş satırını elle yazmadığını ve işlemi yapanın istek bağlamından geldiğini belirtir.
  • _ensure_pk belge dizgisi kimliğin neden erken atandığını belirtir: aksi halde create satırının entity_id değeri olmazdı (src/cluster_erp/core/change_history.py:273-278).

Kurallar ve sınırlar

  • Modüldeki hiçbir şey bir geçmiş satırını güncellemez veya silmez; onları yalnızca saklama temizliği kaldırır (src/cluster_erp/core/change_history.py:12-14).
  • ORM'yi atlayan yazımlar (Core UPDATE veya DELETE ifadeleri gibi) yakalanmaz. bulk_soft_delete ve orm_delete_where bu nedenle ORM üzerinden gider (src/cluster_erp/core/bulk_operations.py:26-34, src/cluster_erp/core/bulk_operations.py:59-61).

Diğer parçalarla etkileşim

  • Veritabanı ve oturumlar işlemi yapanı ve kullanımdan kaldırma bağlamını ayarlar.
  • Yumuşak silme ve kullanımdan kaldırma kullanımdan kaldırma damgasına dayanır.
  • logs modülü core_change_history üzerinde GET rotaları sunar (src/cluster_erp/modules/logs/change_history/routes.py:29, src/cluster_erp/modules/logs/change_history/routes.py:65, src/cluster_erp/modules/logs/change_history/routes.py:74).
  • Geçmiş satırlarının saklanması zamanlanmış işler ve saklama sayfasında belgelenir.

Sınırlar ve açık noktalar

  • Bir istek dışında yapılan değişikliklerin, çağıran istek bağlamını ayarlamadıkça işlemi yapanı yoktur (src/cluster_erp/core/change_history.py:320, src/cluster_erp/core/request_context.py:30-32).
  • _NOISE, deactivated_by sütununu listeler, ama src/cluster_erp içinde hiçbir model bu sütunu bildirmez (grep -rn deactivated_by ile arandı).

Tanıtılan terimler

Terim Kod tanımlayıcısı Tanım Türkçe terim Kaynak
change history ChangeHistory İşlemi yapan ve zamanla alan düzeyi değişikliklerin yalnızca eklenen tablosu. değişiklik geçmişi src/cluster_erp/core/change_history.py:78
redaction REDACTED Değişiklik kaydını korurken hassas bir değeri [redacted] ile değiştirmek. gizleme src/cluster_erp/core/sensitive_fields.py:25
correlation id correlation_id Bir isteğin değişikliklerini gruplayan kimlik. ilişki kimliği src/cluster_erp/core/change_history.py:83

İlgili sayfalar


92f8051 numaralı commit ile 2026-11-13 tarihinde doğrulandı.

Doğrulanan commit 92f8051 · 2026-11-13