/** * Migration: Add ValidatedEvent weather_station_id FK * * Fixes: ValidatedEvent has station_name as varchar instead of FK to WeatherStation * Changes: * - Add weather_station_id UUID FK * - Migrate data by matching station_name * - Keep station_name for historical reference * * @type {import('node-pg-migrate').ColumnDefinitions | undefined} */ export const shorthands = undefined; /** * @param pgm {import('node-pg-migrate').MigrationBuilder} * @param run {() => void | undefined} * @returns {Promise | void} */ export const up = (pgm) => { console.log('Adding ValidatedEvent weather_station_id FK...'); // Step 1: Add weather_station_id column pgm.addColumn('validated_events', { weather_station_id: { type: 'uuid', notNull: false, comment: 'Foreign key to weather_stations table', }, }); // Step 2: Migrate data by matching station_name pgm.sql(` UPDATE validated_events ve SET weather_station_id = ws.id FROM weather_stations ws WHERE ve.station_name IS NOT NULL AND ve.station_name != '' AND LOWER(TRIM(ve.station_name)) = LOWER(TRIM(ws.station_name)); `); // Step 3: Add FK constraint pgm.addConstraint('validated_events', 'validated_events_weather_station_id_fkey', { foreignKeys: { columns: 'weather_station_id', references: 'weather_stations(id)', onDelete: 'SET NULL', }, }); // Step 4: Add index pgm.createIndex('validated_events', 'weather_station_id', { name: 'idx_validated_events_weather_station_id', where: 'weather_station_id IS NOT NULL', }); // Step 5: Add comment to station_name indicating it's for historical reference pgm.sql(` COMMENT ON COLUMN validated_events.station_name IS 'Historical station name (kept for reference). Use weather_station_id for queries.'; `); console.log('ValidatedEvent weather_station_id FK added.'); console.log('Note: station_name column preserved for historical reference.'); }; /** * @param pgm {import('node-pg-migrate').MigrationBuilder} * @param run {() => void | undefined} * @returns {Promise | void} */ export const down = (pgm) => { console.log('Rolling back ValidatedEvent weather_station_id FK...'); // Remove index pgm.dropIndex('validated_events', 'weather_station_id', { name: 'idx_validated_events_weather_station_id', ifExists: true, }); // Remove FK constraint pgm.dropConstraint('validated_events', 'validated_events_weather_station_id_fkey', { ifExists: true, }); // Remove column pgm.dropColumn('validated_events', 'weather_station_id', { ifExists: true }); // Restore station_name comment pgm.sql(` COMMENT ON COLUMN validated_events.station_name IS 'Name of the weather station associated with this event'; `); console.log('ValidatedEvent weather_station_id FK rollback complete.'); };