Veritabanı Yönetimi
Sequelize Sync Kuralı (alter: false / alter: true)
Backend ayağa kalkarken src/index.js içinde şu satır çalışır:
await db.sequelize.sync({ alter: false });
Bu satır, Sequelize'ın mevcut modelleri veritabanıyla eşleştirmesini tetikler. alter: false modunda yalnızca eksik tablolar oluşturulur, mevcut tablolara sütun eklenmez ve mevcut sütunlar değiştirilmez.
Yani bir modele yeni bir sütun eklediysen, production'da bu sütun otomatik olarak tabloya gelmez. Uygulama hata da vermez, sütunu görmezden gelir.
Yeni sütun veya tablo eklendiğinde ne yapmalı?
src/index.jsiçindealter: falseolan satırı geçici olarakalter: trueyap.- Uygulamayı bir kez başlat. Sequelize mevcut tabloları gerçek model tanımlarıyla karşılaştırır ve farkları uygular.
- İşlem bittikten sonra tekrar
alter: falseyap ve kaydet.
Dikkat:
alter: truebazen veri kaybına yol açabilir. Özellikle bir sütunun tipini değiştirirken mevcut verileri dönüştüremezse hata fırlatır. Bu yüzden production'daalter: truekullanmadan önce yedeği almak iyi bir alışkanlıktır.
alter: true ile yapılan işlemler:
- Eksik sütunlar eklenir
- Eksik tablolar oluşturulur
- Sütun tipi değişiklikleri uygulanır (uyumluysa)
- Sütun silinmez — Sequelize modelden çıkardığın bir sütunu veritabanından otomatik silmez
Kafka Event Sistemi
src/models/index.js dosyasında Sequelize'a global hook'lar tanımlanmıştır. Bu hook'lar, sisteme kayıtlı tüm modellerde otomatik olarak çalışır.
Herhangi bir model üzerinde create, update veya destroy işlemi yapıldığında ilgili Kafka topic'ine otomatik bir mesaj gönderilir. Bunu özel olarak elle yazmak gerekmez.
Topic Formatı
yesv3-{TENANT}-{modelName}-created
yesv3-{TENANT}-{modelName}-updated
yesv3-{TENANT}-{modelName}-deleted
TENANT, .env dosyasındaki TENANT değişkeninden gelir. modelName ise Sequelize model adının küçük harfli halidir (örneğin calendar, user, task).
Örnek:
yesv3-okul1-calendar-created
yesv3-okul1-user-updated
yesv3-okul1-task-deleted
Transaction İçinde Ne Olur?
Hook'lar transaction-aware'dir. Eğer işlem bir transaction içinde yapılıyorsa, mesaj doğrudan değil afterCommit ile gönderilir. Transaction rollback yaparsa Kafka'ya hiçbir şey gitmez.
// models/index.js içindeki hook mantığı:
afterCreate: (record, options) => {
if (options.transaction) {
options.transaction.afterCommit(() => sendKafkaEvent('created', record));
} else {
sendKafkaEvent('created', record);
}
}
Bu Sistemi Neden Kullanıyoruz?
Kafka mesajları dış sistemlerin (bildirim servisi, analitik, entegrasyon katmanı) bu olayları yakalamasını sağlar. Backend kendi işlemini yapar, Kafka üzerinden ilgili consumer'lar haberdar olur.
Model Tanımı ve Association'lar
src/models/index.js tüm Sequelize modellerini yükler ve db objesine bağlar. Modeller src/models/ dizinindeki dosyalardan otomatik olarak taranıp kayıt edilir.
Model dosyalarına ayrı ayrı associate metodu eklenir. Tüm modeller yüklendikten sonra db.setupAssociations() çağrılır; bu metot, her modelin associate(db) metodunu sırasıyla çağırarak ilişkileri kurar.
// Örnek model association yapısı:
module.exports = (sequelize, DataTypes) => {
const Calendar = sequelize.define('calendar', { ... });
Calendar.associate = (db) => {
Calendar.belongsTo(db.user, { foreignKey: 'userId' });
Calendar.belongsTo(db.department, { foreignKey: 'departmentId' });
};
return Calendar;
};
Association'lar setupAssociations() çağrılmadan önce tanımlı olmaz, dolayısıyla servis dosyalarında include ile ilişkili tablo çekebilmek için bu çağrının tamamlanmış olması gerekir. Bu src/index.js içinde senkronizasyondan önce çalıştırılır.
Path Alias (@/)
Proje genelinde require('@/...') şeklinde import yapılabilir. @/ ifadesi src/ klasörünü işaret eder. Bu alias module-alias paketi tarafından sağlanır ve src/index.js'in en üstündeki şu satırla aktif olur:
require("module-alias/register");
package.json içinde de şu tanım bulunur:
"_moduleAliases": {
"@": "src"
}