/** * Schema Migration System for @robojs/xp * * This module handles versioned data migrations for the XP plugin. Migrations run automatically * when data is accessed via getUser() or getConfig(), ensuring backward compatibility across * plugin versions. * * @module store/migrations * * ## Architecture * * - **Per-Guild, Per-Store**: Each (guildId, storeId) pair has an independent schema version * - **Sequential Execution**: Migrations run in order (e.g., v1→v2→v3) to support multi-version upgrades * - **On-Demand Strategy**: Migrations trigger lazily when data is accessed, not at boot time * - **Idempotent**: Safe to run multiple times; schema version prevents re-execution * * ## Adding New Migrations * * When incrementing SCHEMA_VERSION, add a migration function: * * ```typescript * async function migrateV2ToV3(guildId: string, options?: FlashcoreOptions): Promise { * const storeId = resolveStoreId(options) * logger.info(`Migrating guild ${guildId} store ${storeId} from v2 to v3`) * * // Load all users * const members = await getMembers(guildId, options) * * // Modify data structure * for (const userId of members) { * const user = await getUser(guildId, userId, options) * if (user) { * const updated = { ...user, newField: defaultValue } * await putUser(guildId, userId, updated, options) * } * } * } * * // Register migration * migrations.set(3, migrateV2ToV3) * ``` * * ## Error Handling * * - Migrations wrap operations in try-catch blocks * - Schema version only updates on successful completion * - Failed migrations are safe to retry (schema version unchanged) * - Errors include context: guildId, storeId, target version */ import type { FlashcoreOptions } from '../types.js'; /** * Current schema version for future migrations * Must match SCHEMA_VERSION in index.ts */ export declare const SCHEMA_VERSION = 1; /** * Migration function type definition * * @param guildId - Discord guild ID to migrate * @param options - Flashcore options (includes storeId for multi-store support) * @returns Promise that resolves when migration completes * * @example * ```typescript * const migrateV1ToV2: MigrationFunction = async (guildId, options) => { * // Migration logic here * } * ``` */ export type MigrationFunction = (guildId: string, options?: FlashcoreOptions) => Promise; /** * Checks if a guild's data needs migration * * Compares the stored schema version with the current SCHEMA_VERSION constant. * Returns true if stored version is older than current version. * * @param guildId - Discord guild ID to check * @param options - Flashcore options (includes storeId) * @returns True if migration needed, false otherwise * * @example * ```typescript * if (await needsMigration(guildId, { storeId: 'custom' })) { * await migrateGuildData(guildId, currentVersion, SCHEMA_VERSION, { storeId: 'custom' }) * } * ``` */ export declare function needsMigration(guildId: string, options?: FlashcoreOptions): Promise; export declare function migrateGuildData(guildId: string, fromVersion: number, toVersion: number, options?: FlashcoreOptions): Promise;