## 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>
207 lines
4.9 KiB
TypeScript
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;
|
|
} |