Migration Playbook (Deterministik Sira)
Bu dokumanin amaci, migration calistirma sirasini tek kurala baglamak ve development/staging/production ortamlari arasinda ayni sonucu garantilemektir.
Garanti Sozlesmesi
Asagidaki 5 kural birlikte saglanmadan birebirlik garantisi verilmis sayilmaz:
- Her migration immutable olmalidir: merge sonrasi dosya icerigi degistirilemez.
- Calisma sirasi yalnizca
versionalanina gore belirlenmelidir. - Her migration checksum ile dogrulanmalidir.
- Migration kosumu tek yazici (global lock) ile korunmalidir.
- Kosum sonrasinda schema fingerprint ayni degere ulasmelidir.
Dosya Adlandirma Standardi
Migration dosyalari su formatla adlandirilir:
VYYYYMMDDHHMMSS__kisa-aciklama.sql
Ornek:
V20260409103000__create_rule_events_indexes.sql
V20260409104500__add_synthesis_scope_constraints.sql
Kurallar:
YYYYMMDDHHMMSSUTC olmalidir.- Ayni timestamp ikinci kez kullanilamaz.
- Sira lexicographic olarak da ayni kalmalidir.
Fazlara Gore Zorunlu Migration Sirasi
Bir release icindeki migrationlar asagidaki faz sirasiyla yazilir ve calistirilir:
TYPES: enum, domain, custom type degisiklikleriREF: sozluk/referans tablolari (statuses,message_types, vb.)CORE: ana varlik tablolari (users,devices,streams, vb.)REL: iliski/atama tablolari (*_assignments,*_state, vb.)CONSTRAINT: FK, unique, check, not nullINDEX: performans indeksleri ve index concurrent operasyonlariBACKFILL: veri tasima/normalizasyon scriptleriVIEW_TRG_JOB: view, trigger, function, scheduled-job baglantilariGRANT: rol ve yetki dagitimi
Not: INDEX CONCURRENTLY gibi transaction-disinda kosmasi gereken operasyonlar ayri migration dosyasinda tutulur.
Zorunlu Meta Tablolari
Tum ortamlarda ayni yapiyla bulunmalidir:
CREATE TABLE IF NOT EXISTS schema_migrations (
version varchar(20) PRIMARY KEY,
name varchar(255) NOT NULL,
checksum_sha256 varchar(64) NOT NULL,
executed_at timestamp NOT NULL DEFAULT now(),
execution_ms int NOT NULL,
tool_version varchar(64) NOT NULL
);
CREATE TABLE IF NOT EXISTS migration_lock (
id int PRIMARY KEY,
is_locked boolean NOT NULL,
updated_at timestamp NOT NULL DEFAULT now()
);
INSERT INTO migration_lock (id, is_locked)
VALUES (1, false)
ON CONFLICT (id) DO NOTHING;
Calistirma Protokolu (Her Ortam Icin Ayni)
- Migration lock al.
schema_migrationsicindeki sonversiondegerini oku.- Yeni dosyalari artan
versionsirasinda sec. - Her dosya icin checksum dogrula.
- Dosyayi calistir, basariliysa
schema_migrationskaydi yaz. - Tum dosyalar bitince lock birak.
Basarisizlik kurali:
- Hata halinde lock birakilir.
- Basarisiz migration tekrar denenmeden once yeni bir duzeltme migrationi yazilir.
- Daha once basarili kosmus migration dosyasi geriye donuk degistirilmez.
Schema Fingerprint Kontrolu
Her ortam migration sonrasi ayni fingerprint uretmelidir. Asagidaki sorgu mantigi kullanilir:
SELECT md5(string_agg(row_text, E'\n' ORDER BY row_text)) AS schema_fingerprint
FROM (
SELECT concat_ws('|', table_schema, table_name, column_name, data_type, is_nullable, ordinal_position) AS row_text
FROM information_schema.columns
WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
) t;
Kurallar:
schema_fingerprintdegeri release notuna yazilir.- staging ve production fingerprint degeri ayni degilse deploy tamamlanmis sayilmaz.
CI Gate (Zorunlu)
Her PR icin asagidaki kontroller kosulur:
- Sifir veritabani uzerinde bastan sona migration replay
- Son production snapshot klonu uzerinde ileri migration replay
- Checksum dogrulamasi (
schema_migrationsile dosya checksum karsilastirmasi) - Fingerprint uretimi ve beklenen deger karsilastirmasi
Bu adimlardan biri basarisizsa merge bloklanir.
Yedekleme, Geri Yukleme ve Rollback Tatbikati (Zorunlu)
Yedekleme ve rollback surecleri yalnizca dokumanda kalamaz; duzenli tatbikat ve kanit zorunludur.
Tatbikat Ritmi
- Her ay en az 1 kez tam tatbikat: backup -> restore -> rollback.
- Her release oncesi staging ortaminda en az 1 restore provasi.
- Her ceyrekte production benzeri snapshot ile game-day tatbikati.
Basari Kriterleri
- Backup dosyasi olusmali ve checksum dogrulanmali.
- Restore sonrasi
schema_fingerprintbeklenen degerle eslesmeli. - Rollback sonrasi uygulama kritik sorgulari hata vermeden calismali.
- RTO/RPO olcumleri kaydedilmeli ve hedef sinirlarin icinde olmali.
Kanit Zorunlulugu
Her tatbikat icin kanit dosyasi zorunludur:
- Dizin:
project-qapu/backend/migrations/drills/ - Dosya adi:
YYYY-MM-DD-backup-restore-rollback.md - Icerik: Backup Kaniti, Restore Kaniti, Rollback Kaniti, Sonuc bolumleri
- Her bolumde
Durum: PASSveyaDurum: FAILacikca yazilmalidir.
CI Denetimi
validate:drillskomutu son tatbikat tarihini ve kanit formatini denetler.- Son tatbikat 45 gunden eskiyse CI fail olur.
- Kanit dosyasinda zorunlu bolumler veya PASS/FAIL kaydi yoksa CI fail olur.
Otomasyon Komutlari
Bu repoda migration denetimi icin su komutlar kullanilir:
npm run lock:migration-checksums
npm run validate:migrations
Aciklama:
lock:migration-checksums:project-qapu/backend/migrationsaltindaki SQL dosyalarinin checksum manifestini (checksums.sha256) olusturur/gunceller.validate:migrations: dosya adi formati, sira ve checksum manifest tutarliligini dogrular.
Policy:
- PR merge oncesi
validate:migrationszorunlu pass etmelidir. - Migration dosyasi eklenip checksum manifest guncellenmediyse PR reddedilir.
Branch ve Hotfix Kurali
- Iki branch ayni anda migration eklediyse daha gec merge olan branch yeni timestamp ile migration dosyasini yeniden olusturur.
- Hotfix migrationlari da ayni naming ve checksum kurallarina tabidir.
- Rebase sirasinda migration dosyasi icerigi degistirilmez; gerekiyorsa yeni migration eklenir.
Data-Model ile Uyum
- FK ekleme/silme gibi iliski degisikliklerinde once Master ERD, sonra migration, sonra ilgili tablo dokumani guncellenir.
- Migration fazi
CONSTRAINTise FK degisikligi acikca migration isminde gecmelidir.
FK Davranis Zorunlulugu
Tum yeni FK migrationlari asagidaki kurala uymak zorundadir:
- Her FK tanimi acikca
ON DELETEveON UPDATEdavranisi icermelidir. NO ACTIONveya varsayilan davranisa birakma kabul edilmez.- Davranis secimi yalnizca
RESTRICT,CASCADE,SET NULLarasindan yapilir.
Kaynak politika:
- Kritik iliskiler icin resmi matris Master ERD sayfasindaki
Kritik FK Davranis Kurallaribolumudur.
Ornek migration kalibi:
ALTER TABLE child_table
ADD CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id)
REFERENCES parent_table(id)
ON DELETE RESTRICT
ON UPDATE CASCADE;
PR kontrolu:
- FK iceren migration dosyasinda
ON DELETEveON UPDATEifadeleri yoksa PR reddedilir.
Is Kurali Zorunlulugu (DB-First)
Is kurallari yalniz uygulama koduna birakilamaz. Veri butunlugunu koruyan kurallar veritabaninda zorunlu olarak tanimlanir.
Zorunlu araclar:
UNIQUEPartial UNIQUE INDEX(CREATE UNIQUE INDEX ... WHERE ...)CHECK
Uygulama kurali:
- Uygulama katmani ek kontrol yapabilir, ancak DB tarafindaki kuralin yerine gecemez.
- Constraint migrationlari
__constraint-adlandirma desenini kullanmalidir.
Ornek Kurallar
-- Ayni cihaz + grup atamasi ikinci kez yazilamaz
ALTER TABLE group_assignments
ADD CONSTRAINT uq_group_assignments_device_group UNIQUE (device_id, group_id);
-- Ayni user + message icin tek okuma durumu kaydi
ALTER TABLE message_read_state
ADD CONSTRAINT uq_message_read_state_message_user UNIQUE (message_id, user_id);
-- Scope tipi ile hedef kolonlarin tutarliligi
ALTER TABLE synthesis_assignments
ADD CONSTRAINT ck_synthesis_assignments_scope
CHECK (
(scope_type = 'global' AND device_id IS NULL AND group_id IS NULL) OR
(scope_type = 'device' AND device_id IS NOT NULL AND group_id IS NULL) OR
(scope_type = 'group' AND device_id IS NULL AND group_id IS NOT NULL)
);
-- Sadece aktif satirlar icin tek global atama
CREATE UNIQUE INDEX uq_synth_assignments_active_global
ON synthesis_assignments (rule_id)
WHERE scope_type = 'global' AND is_active = true;
CI Denetimi
validate:migrationskomutu su kontrolleri zorunlu uygular:- FK varsa
ON DELETE+ON UPDATEzorunlu __constraint-migrationlarinda en az birUNIQUE/Partial UNIQUE/CHECK/ADD CONSTRAINTtanimi zorunlu- Dosya adinda
partial-uniquegeciyorsa SQL icindeCREATE UNIQUE INDEX ... WHERE ...zorunlu
- FK varsa
Idempotency ve Duplicate Onleme (DB-Embedded)
Idempotency ve duplicate onleme uygulama koduna birakilamaz; veri modelinde zorunlu olarak tanimlanir.
Zorunlu Veri Modeli Kurallari
- Dis sistemden gelen write islemlerinde idempotency anahtari kalici tabloda saklanir.
- Ayni idempotency anahtari ikinci kez kabul edilmez (
UNIQUE). - Event/inbox/outbox benzeri tekrar riski olan tablolarda dogal anahtar veya kaynak olay kimligi uniq olmalidir.
- Tekrarli yazimlarda davranis acik olmalidir:
ON CONFLICT DO NOTHINGveyaON CONFLICT ... DO UPDATE.
Onerilen Sema Kalibi
CREATE TABLE IF NOT EXISTS idempotency_keys (
id bigserial PRIMARY KEY,
scope varchar(64) NOT NULL,
idempotency_key varchar(128) NOT NULL,
request_hash varchar(64) NOT NULL,
first_seen_at timestamp NOT NULL DEFAULT now(),
expires_at timestamp NULL,
CONSTRAINT uq_idempotency_keys_scope_key UNIQUE (scope, idempotency_key)
);
-- Harici olay duplicate onleme (ornek)
CREATE UNIQUE INDEX uq_rule_events_source_event
ON rule_events (source_system, source_event_id);
Yazma Semantigi
INSERT INTO idempotency_keys (scope, idempotency_key, request_hash)
VALUES ('rule-engine', :idempotency_key, :request_hash)
ON CONFLICT (scope, idempotency_key) DO NOTHING;
Yorum:
- Insert 0 satir etkilediyse islem duplicate kabul edilir ve side-effect calistirilmaz.
- Idempotency kaydina bagli asil write islemi ayni transaction sinirlari icinde ele alinmalidir.
CI Denetimi
- Dosya adinda
idempotency,dedupveyaduplicategecen migrationlar icinvalidate:migrationssu kurallari zorunlu uygular:- En az bir
UNIQUEveyaCREATE UNIQUE INDEXolmali. - SQL icinde
INSERT INTOvarsaON CONFLICTdavranisi da tanimli olmali.
- En az bir
Soft Delete, Audit Log ve Kim-Ne-Zaman Zorunlulugu
Kritik tablolarda degisiklik izi uygulama koduna birakilamaz; veri modelinde zorunlu tutulur.
Kritik Tablolar (Append-Only Istisna)
streamsrule_eventslogs
Bu tablolarda soft delete uygulanmaz; bunun yerine asagidaki kural zorunludur:
- Fiziksel
UPDATE/DELETEyasak (append-only yazma modeli) - Olay zamani zorunlu (
create_timeveyastream_time) - Kaynagi tanimlayan actor baglami zorunlu (
user_id,service_id,device_id,detailsvb.)
Audit Log Zorunlulugu
- Kritik mutable tablolarda UPDATE/DELETE aksiyonlari icin append-only audit log tablosuna yazim zorunludur.
- Audit kaydi asgari su alanlari icermelidir:
table_namerow_pkoperation(INSERT/UPDATE/SOFT_DELETE/RESTORE)changed_bychanged_atbefore_jsonafter_json
Mevcut logs tablosu uzerinden audit yapmak mumkundur; ancak yalnizca asagidaki sozlesme saglanirsa kabul edilir:
event_codezorunlu olarakAUDIT_MUTATIONolmalidir.detailsJSON icinde su alanlar zorunludur:table_namerow_pkoperationchanged_bychanged_atbefore_jsonafter_json
- Audit kayitlari append-only kalmali,
logsuzerinde UPDATE/DELETE uygulanmamalidir. - Audit saklama suresi operasyonel loglardan bagimsiz yonetilmelidir (retention ayrimi).
Ornek details semasi:
{
"table_name": "inbox",
"row_pk": "101",
"operation": "SOFT_DELETE",
"changed_by": 7,
"changed_at": "2026-04-09T12:10:00Z",
"before_json": {"is_deleted": false, "delete_time": null},
"after_json": {"is_deleted": true, "delete_time": "2026-04-09T12:10:00Z"}
}
CI Denetimi
- Dosya adinda
audit,soft-deleteveyadelete-policygecen migrationlar icinvalidate:migrationssu kontrolleri uygular:- Kritik tablolardan en az birine dokunulmus olmalidir.
- SQL icinde soft-delete (
is_deletedveyadeleted_at) ifadesi bulunmalidir. - SQL icinde audit actor/zaman (
created_by,updated_by,changed_by,changed_at) ifadelerinden en az biri bulunmalidir.
Enum ve Sozluk Versiyonlama
Enum ve sozluk (reference dictionary) degisiklikleri versiyonlu ve geri uyumlu yonetilir.
Zorunlu Adlandirma
- Enum tipi degisikligi iceren migration dosyalari:
__types-... - Sozluk veri/model degisikligi iceren migration dosyalari:
__ref-...
SQL Baslik Sozlesmesi (Zorunlu)
__types- ve __ref- migration dosyalarinin basinda asagidaki baslik bulunur:
-- COMPAT: backward-compatible
Eger degisiklik breaking ise ek alanlar zorunludur:
-- COMPAT: breaking
-- COMPATIBILITY-WINDOW: 2-release
-- FALLBACK: enum_alias_mapping_v2
Geriye Uyumluluk Kurallari
- Enum degerleri ayni major hatta silinmez veya yeniden adlandirilmaz; yalnizca ekleme yapilir.
- Sozluk kodlari (
code,namegibi dis entegrasyona acik anahtarlar) in-place degistirilmez; yeni versiyonlu kayit eklenir. - Breaking degisiklikte en az 2 release boyunca eski degerler
deprecatedolarak yasatilir. - Eski degerlerin kullanimdan cikmasi icin mapping/fallback katmani zorunludur.
- Uygulama kodu yeni degeri desteklemeden enum/sozluk breaking migration productiona cikamaz.
Sozluk Tablolari Icin Onerilen Sema
ALTER TABLE message_types
ADD COLUMN IF NOT EXISTS version integer NOT NULL DEFAULT 1;
ALTER TABLE message_types
ADD COLUMN IF NOT EXISTS is_deprecated boolean NOT NULL DEFAULT false;
ALTER TABLE message_types
ADD COLUMN IF NOT EXISTS replaced_by_code varchar(64) NULL;
Enum Degisimi Icin Onerilen Akis
__types-migration: yeni enum degerini ekle (breaking degilse append-only).__ref-migration: sozluk tablosuna yeni degeri ekle, eskiyiis_deprecated=trueyap.BACKFILL: gerekiyorsa eski kayitlari yeni degere map et.CONSTRAINT: yeni versiyon kurallarini zorunlu kil.
CI Denetimi
validate:migrationskomutu__types-ve__ref-dosyalarindaCOMPATbasligini zorunlu kontrol eder.COMPAT: breakingiseCOMPATIBILITY-WINDOWveFALLBACKsatirlari yoksa PR reddedilir.
Isimlendirme Standardi (Kesin)
Tum tablo ve SQL nesneleri tek dil ve tek formatta tutulur.
Dil Kurali
- SQL identifier adlari (tablo, kolon, constraint, index, enum/type) yalnizca Ingilizce ve ASCII olmalidir.
- Dokuman aciklamalari Turkce yazilir.
- Identifier icinde Turkce karakter, bosluk ve tire kullanilmaz.
Format Kurali
- Tablo adlari:
lower_snake_caseve cogul (users,rule_events,message_read_state) - Kolon adlari:
lower_snake_case - Constraint adlari:
- Primary key:
pk_<table> - Foreign key:
fk_<table>_<ref_table> - Unique:
uq_<table>_<columns> - Check:
ck_<table>_<rule>
- Primary key:
- Index adlari:
- Normal index:
ix_<table>_<columns> - Unique index:
uq_<table>_<columns>
- Normal index:
- Enum/type adlari:
lower_snake_case
Tablo Dokumani Format Kurali
project-qapu/backend/data-model/tables/** altindaki tum tablo dokumanlari su kalibi izler:
- Baslik:
<table_name> Tablosu - Ana H1:
`table_name` KolonlarbolumuIndekslerbolumuOrnek Kayitlarbolumu
Not: table_name daima SQL'deki canonical tablo adiyla birebir ayni yazilir.
CI Denetimi
validate:migrationskomutu migration SQL icindeki identifier adlandirma kurallarini zorunlu denetler.- Kural disi adlandirma tespit edilirse PR reddedilir.
Indeks Tasarimi ve EXPLAIN Zorunlulugu
Indeksler varsayimla degil, kritik sorgularin sorgu planiyla tasarlanir.
Faz ve Dosya Kurali
- Indeks migration dosyalari
__index-ile baslamalidir. - Her
__index-migration icin zorunlu bir plan raporu bulunmalidir:project-qapu/backend/migrations/explain/<migration-dosyasi>.md
Ornek:
V20260409120000__index-add-rule-events-device-time.sql
project-qapu/backend/migrations/explain/V20260409120000__index-add-rule-events-device-time.md
EXPLAIN Komutu (Zorunlu)
Her kritik sorgu icin asagidaki format kullanilir:
EXPLAIN (ANALYZE, BUFFERS, VERBOSE, FORMAT JSON)
<kritik-sorgu>;
Rapor hem oncesi hem sonrasi plani icermelidir.
Kritik Sorgu Katalogu
Kritik sorgular tek listede tutulur:
project-qapu/backend/migrations/explain/critical-queries.md
Indeks migration raporu, etkiledigi kritik sorgu kimliklerini acikca belirtmelidir.
Kabul Kriterleri
Bir indeks migrationinin kabul edilmesi icin:
- En az bir kritik sorgu icin
BEFORE PLANveAFTER PLANbulunmali. - Plan tipinde iyilesme hedeflenmeli (or.
Seq Scan -> Index Scan/Bitmap Heap Scan). actual total time,rows,shared read/hitgibi metrikler raporda yer almali.- Regresyon varsa migration merge edilmez.
CI Denetimi
validate:migrationskomutu__index-migrationlar icin explain raporu varligini ve temel bolumlerini zorunlu denetler.- Explain raporu yoksa veya eksikse PR reddedilir.