meteor_detection_system/meteor-web-backend/migrations/1766300000001_add-weather-station-location.js
grabbit f557c06771 feat: complete database schema migration to UUID primary keys
## Database Migrations (18 new)
- Migrate all primary keys from SERIAL to UUID
- Add soft delete (deleted_at) to all 19 entities
- Add missing indexes for performance optimization
- Add CHECK constraints for data validation
- Add user audit fields (last_login_at, timezone, locale)
- Add weather station location fields (latitude, longitude, elevation)
- Add foreign key relationships (CameraDevice→Device, ValidatedEvent→WeatherStation)
- Prepare private key encryption fields

## Backend Entity Updates
- All entities updated with UUID primary keys
- Added @DeleteDateColumn for soft delete support
- Updated relations and foreign key types

## Backend Service/Controller Updates
- Changed ID parameters from number to string (UUID)
- Removed ParseIntPipe from controllers
- Updated TypeORM queries for string IDs

## Frontend Updates
- Updated all service interfaces to use string IDs
- Fixed CameraDevice.location as JSONB object
- Updated weather.ts with new fields (elevation, timezone)
- Added Supabase integration hooks and lib
- Fixed chart components for new data structure

## Cleanup
- Removed deprecated .claude/agents configuration files

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 03:33:26 +08:00

87 lines
2.6 KiB
JavaScript

/**
* Migration: Add location coordinates to weather_stations table
*
* Fixes: WeatherStation has no location/coordinates - how do you know where the station is?
*
* @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> | void}
*/
export const up = (pgm) => {
console.log('Adding location coordinates to weather_stations...');
// Add location coordinate columns
pgm.addColumns('weather_stations', {
latitude: {
type: 'decimal(10,7)',
notNull: false,
comment: 'Latitude coordinate of the weather station (-90 to 90)',
},
longitude: {
type: 'decimal(10,7)',
notNull: false,
comment: 'Longitude coordinate of the weather station (-180 to 180)',
},
elevation: {
type: 'decimal(6,1)',
notNull: false,
comment: 'Elevation above sea level in meters',
},
timezone: {
type: 'varchar(50)',
notNull: false,
comment: 'Timezone identifier (e.g., Asia/Shanghai)',
},
});
// Add CHECK constraints for coordinate validation
pgm.addConstraint('weather_stations', 'chk_weather_stations_latitude', {
check: 'latitude IS NULL OR (latitude >= -90 AND latitude <= 90)',
});
pgm.addConstraint('weather_stations', 'chk_weather_stations_longitude', {
check: 'longitude IS NULL OR (longitude >= -180 AND longitude <= 180)',
});
// Add index for geospatial queries (basic, for more advanced use PostGIS)
pgm.createIndex('weather_stations', ['latitude', 'longitude'], {
name: 'idx_weather_stations_coordinates',
where: 'latitude IS NOT NULL AND longitude IS NOT NULL',
});
console.log('Weather station location columns added successfully.');
};
/**
* @param pgm {import('node-pg-migrate').MigrationBuilder}
* @param run {() => void | undefined}
* @returns {Promise<void> | void}
*/
export const down = (pgm) => {
console.log('Removing location coordinates from weather_stations...');
// Drop index first
pgm.dropIndex('weather_stations', ['latitude', 'longitude'], {
name: 'idx_weather_stations_coordinates',
ifExists: true,
});
// Drop constraints
pgm.dropConstraint('weather_stations', 'chk_weather_stations_longitude', {
ifExists: true,
});
pgm.dropConstraint('weather_stations', 'chk_weather_stations_latitude', {
ifExists: true,
});
// Drop columns
pgm.dropColumns('weather_stations', ['latitude', 'longitude', 'elevation', 'timezone']);
console.log('Weather station location columns removed.');
};