meteor_detection_system/meteor-web-backend/src/entities/device-configuration.entity.ts
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

207 lines
4.9 KiB
TypeScript

import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToOne,
JoinColumn,
CreateDateColumn,
UpdateDateColumn,
DeleteDateColumn,
Index,
} from 'typeorm';
import { Device } from './device.entity';
export enum ConfigurationStatus {
ACTIVE = 'active',
PENDING = 'pending',
ARCHIVED = 'archived',
FAILED = 'failed',
}
export enum ConfigurationSource {
DEFAULT = 'default',
USER = 'user',
ADMIN = 'admin',
AUTO_GENERATED = 'auto_generated',
INHERITED = 'inherited',
}
@Entity('device_configurations')
@Index(['deviceId'])
@Index(['status'])
@Index(['version'])
@Index(['createdAt'])
@Index(['isActive'])
export class DeviceConfiguration {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ name: 'device_id' })
deviceId: string;
@ManyToOne(() => Device, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'device_id' })
device: Device;
@Column({ name: 'version', type: 'varchar', length: 50 })
version: string;
@Column({
name: 'status',
type: 'enum',
enum: ConfigurationStatus,
default: ConfigurationStatus.PENDING,
})
status: ConfigurationStatus;
@Column({
name: 'source',
type: 'enum',
enum: ConfigurationSource,
default: ConfigurationSource.DEFAULT,
})
source: ConfigurationSource;
@Column({ name: 'is_active', type: 'boolean', default: false })
isActive: boolean;
@Column({ name: 'device_settings', type: 'jsonb' })
deviceSettings: {
device_id?: string;
name: string;
timezone: string;
location?: {
latitude: number;
longitude: number;
altitude?: number;
accuracy?: number;
};
auto_update: boolean;
debug_mode: boolean;
};
@Column({ name: 'network_settings', type: 'jsonb' })
networkSettings: {
wifi_configs: Array<{
ssid: string;
priority: number;
security_type: string;
}>;
fallback_hotspot: {
ssid: string;
password: string;
security_type: string;
};
api_endpoints: {
events: string;
telemetry: string;
config: string;
heartbeat: string;
commands: string;
};
connection_timeout: number;
retry_attempts: number;
health_check_interval: number;
};
@Column({ name: 'camera_settings', type: 'jsonb' })
cameraSettings: {
device_path: string;
resolution: string;
frame_rate: number;
auto_exposure: boolean;
gain?: number;
flip_horizontal: boolean;
flip_vertical: boolean;
roi?: {
x: number;
y: number;
width: number;
height: number;
};
};
@Column({ name: 'detection_settings', type: 'jsonb' })
detectionSettings: {
enabled: boolean;
algorithms: string[];
sensitivity: number;
min_duration_ms: number;
max_duration_ms: number;
cool_down_period_ms: number;
consensus_threshold: number;
};
@Column({ name: 'storage_settings', type: 'jsonb' })
storageSettings: {
base_path: string;
max_storage_gb: number;
retention_days: number;
auto_cleanup: boolean;
compression_enabled: boolean;
backup_to_cloud: boolean;
};
@Column({ name: 'monitoring_settings', type: 'jsonb' })
monitoringSettings: {
heartbeat_interval_seconds: number;
telemetry_interval_seconds: number;
log_level: string;
metrics_retention_hours: number;
performance_profiling: boolean;
error_reporting: boolean;
};
@Column({ name: 'security_settings', type: 'jsonb' })
securitySettings: {
device_token?: string;
certificate_path?: string;
private_key_path?: string;
ca_certificate_path?: string;
verify_server_certificate: boolean;
request_signing_enabled: boolean;
};
@Column({ name: 'configuration_signature', type: 'varchar', length: 255 })
configurationSignature: string;
@Column({ name: 'checksum', type: 'varchar', length: 64 })
checksum: string;
@Column({ name: 'applied_at', type: 'timestamptz', nullable: true })
appliedAt?: Date;
@Column({ name: 'applied_by_device', type: 'boolean', default: false })
appliedByDevice: boolean;
@Column({ name: 'rollback_configuration_id', type: 'uuid', nullable: true })
rollbackConfigurationId?: string;
@Column({ name: 'validation_result', type: 'jsonb', nullable: true })
validationResult?: {
is_valid: boolean;
errors: string[];
warnings: string[];
validated_at: string;
};
@Column({ name: 'deployment_metadata', type: 'jsonb', nullable: true })
deploymentMetadata?: {
deployment_id: string;
deployment_strategy: string;
rollout_percentage?: number;
target_devices?: string[];
deployment_notes?: string;
};
@CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ name: 'updated_at', type: 'timestamptz' })
updatedAt: Date;
// Soft delete support (added in migration 1766300000005)
@DeleteDateColumn({ name: 'deleted_at', type: 'timestamptz', nullable: true })
@Index('idx_device_configurations_deleted_at', { where: 'deleted_at IS NULL' })
deletedAt?: Date;
}