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 SQLAlchemybefore_flushdinleyicisi, 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_historytablosuna 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.pytarafı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:
- Dinleyici
current_actor_id()vecurrent_correlation_id()değerlerini okur (src/cluster_erp/core/change_history.py:320-321). - Her yeni nesne için birincil anahtar boşsa atar,
created_bydamgalar vecreateeylemiyle tam bir anlık görüntü kaydeder (src/cluster_erp/core/change_history.py:324-329). - Her değişen nesne için önce
deleted_atNULL'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ğilseupdated_bydamgalar ve eylemi sınıflar (src/cluster_erp/core/change_history.py:331-342). - Her silinen nesne için
deleteeylemiyle bir anlık görüntü kaydeder (src/cluster_erp/core/change_history.py:344-347). - 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_versionvecore_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_byvedeactivated_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_columnsayarı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_pkbelge dizgisi kimliğin neden erken atandığını belirtir: aksi haldecreatesatırınınentity_iddeğ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
UPDATEveyaDELETEifadeleri gibi) yakalanmaz.bulk_soft_deleteveorm_delete_wherebu 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.
logsmodülücore_change_historyüzerindeGETrotaları 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_bysütununu listeler, amasrc/cluster_erpiçinde hiçbir model bu sütunu bildirmez (grep -rn deactivated_byile 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¶
- Platform çekirdeği
- Veritabanı ve oturumlar
- Yumuşak silme ve kullanımdan kaldırma
- Logs
- Alan ve satır erişimi
92f8051 numaralı commit ile 2026-11-13 tarihinde doğrulandı.