feat(db): migration mekanizması ve ilk index migration'ı
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
import { AuditLogModel } from "@/models/audit-log";
|
||||
import { HouseholdModel } from "@/models/household";
|
||||
import { HouseholdMemberModel } from "@/models/household-member";
|
||||
import type { Migration } from "./types";
|
||||
|
||||
/** Hane, üyelik ve denetim kaydı index'leri (Mongoose şemalarındaki tanımlarla). */
|
||||
export const migration: Migration = {
|
||||
name: "001-initial-indexes",
|
||||
description: "households, householdMembers ve auditLogs index'leri",
|
||||
async up() {
|
||||
await HouseholdModel.createIndexes();
|
||||
await HouseholdMemberModel.createIndexes();
|
||||
await AuditLogModel.createIndexes();
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,35 @@
|
||||
import { getDb } from "@/lib/db/mongo";
|
||||
import { connectMongoose } from "@/lib/db/mongoose";
|
||||
import { migration as m001 } from "./001-initial-indexes";
|
||||
import type { Migration } from "./types";
|
||||
|
||||
/** Sıralı migration listesi. Yeni migration: dosyayı ekle ve buraya sırayla ekle. */
|
||||
export const MIGRATIONS: Migration[] = [m001];
|
||||
|
||||
const COLLECTION = "migrations";
|
||||
|
||||
/**
|
||||
* Uygulanmamış migration'ları sırayla çalıştırır; her biri bir kez (`migrations` koleksiyonu).
|
||||
* Aynı anda iki çalıştırma olursa benzersiz `name` index'i ikinci kaydı reddeder.
|
||||
*/
|
||||
export async function runMigrations(log: (line: string) => void = console.log): Promise<string[]> {
|
||||
const db = getDb();
|
||||
await connectMongoose();
|
||||
const col = db.collection<{ name: string; appliedAt: Date; durationMs: number }>(COLLECTION);
|
||||
await col.createIndex({ name: 1 }, { unique: true });
|
||||
const applied = new Set(
|
||||
(await col.find({}, { projection: { name: 1 } }).toArray()).map((d) => d.name),
|
||||
);
|
||||
|
||||
const ran: string[] = [];
|
||||
for (const m of MIGRATIONS) {
|
||||
if (applied.has(m.name)) continue;
|
||||
const started = Date.now();
|
||||
await m.up(db);
|
||||
await col.insertOne({ name: m.name, appliedAt: new Date(), durationMs: Date.now() - started });
|
||||
ran.push(m.name);
|
||||
log(`✓ Migration: ${m.name} — ${m.description}`);
|
||||
}
|
||||
if (!ran.length) log("• Bekleyen migration yok.");
|
||||
return ran;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { Db } from "mongodb";
|
||||
|
||||
/** Bir migration: adı dosya adıyla aynı olmalı (ör. "001-initial-indexes"). Geri alma yok; ileri yönlü. */
|
||||
export type Migration = {
|
||||
name: string;
|
||||
description: string;
|
||||
up: (db: Db) => Promise<void>;
|
||||
};
|
||||
Reference in New Issue
Block a user