package models import ( "encoding/json" "time" "github.com/google/uuid" ) // RawEvent represents a raw event from the database type RawEvent struct { ID uuid.UUID `json:"id" db:"id"` DeviceID uuid.UUID `json:"device_id" db:"device_id"` UserProfileID uuid.UUID `json:"user_profile_id" db:"user_profile_id"` FilePath string `json:"file_path" db:"file_path"` FileSize *int64 `json:"file_size" db:"file_size"` FileType *string `json:"file_type" db:"file_type"` OriginalFilename *string `json:"original_filename" db:"original_filename"` EventType string `json:"event_type" db:"event_type"` EventTimestamp time.Time `json:"event_timestamp" db:"event_timestamp"` Metadata json.RawMessage `json:"metadata" db:"metadata"` ProcessingStatus string `json:"processing_status" db:"processing_status"` SqsMessageID *string `json:"sqs_message_id" db:"sqs_message_id"` ProcessedAt *time.Time `json:"processed_at" db:"processed_at"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // ValidatedEvent represents a validated event that will be stored in the database type ValidatedEvent struct { ID uuid.UUID `json:"id" db:"id"` RawEventID uuid.UUID `json:"raw_event_id" db:"raw_event_id"` DeviceID uuid.UUID `json:"device_id" db:"device_id"` UserProfileID uuid.UUID `json:"user_profile_id" db:"user_profile_id"` MediaURL string `json:"media_url" db:"media_url"` FileSize *int64 `json:"file_size" db:"file_size"` FileType *string `json:"file_type" db:"file_type"` OriginalFilename *string `json:"original_filename" db:"original_filename"` EventType string `json:"event_type" db:"event_type"` EventTimestamp time.Time `json:"event_timestamp" db:"event_timestamp"` Metadata json.RawMessage `json:"metadata" db:"metadata"` ValidationScore *float64 `json:"validation_score" db:"validation_score"` ValidationDetails json.RawMessage `json:"validation_details" db:"validation_details"` IsValid bool `json:"is_valid" db:"is_valid"` ValidationAlgorithm *string `json:"validation_algorithm" db:"validation_algorithm"` CreatedAt time.Time `json:"created_at" db:"created_at"` UpdatedAt time.Time `json:"updated_at" db:"updated_at"` } // ProcessingStatus constants for raw events const ( ProcessingStatusPending = "pending" ProcessingStatusProcessing = "processing" ProcessingStatusCompleted = "completed" ProcessingStatusFailed = "failed" ) // EventType constants const ( EventTypeMotion = "motion" EventTypeAlert = "alert" EventTypeMeteor = "meteor" ) // ValidationResult represents the result of event validation type ValidationResult struct { IsValid bool `json:"is_valid"` Score float64 `json:"score"` Algorithm string `json:"algorithm"` Details json.RawMessage `json:"details"` Reason string `json:"reason,omitempty"` ProcessedAt time.Time `json:"processed_at"` } // CreateValidatedEventFromRaw creates a ValidatedEvent from a RawEvent func CreateValidatedEventFromRaw(rawEvent *RawEvent, validationResult *ValidationResult) *ValidatedEvent { // Generate media URL from file path (this would typically involve S3 signed URLs or CloudFront) mediaURL := generateMediaURL(rawEvent.FilePath) // Serialize validation details validationDetails, err := json.Marshal(validationResult.Details) if err != nil { validationDetails = json.RawMessage("{}") } return &ValidatedEvent{ ID: uuid.New(), RawEventID: rawEvent.ID, DeviceID: rawEvent.DeviceID, UserProfileID: rawEvent.UserProfileID, MediaURL: mediaURL, FileSize: rawEvent.FileSize, FileType: rawEvent.FileType, OriginalFilename: rawEvent.OriginalFilename, EventType: rawEvent.EventType, EventTimestamp: rawEvent.EventTimestamp, Metadata: rawEvent.Metadata, ValidationScore: &validationResult.Score, ValidationDetails: validationDetails, IsValid: validationResult.IsValid, ValidationAlgorithm: &validationResult.Algorithm, CreatedAt: time.Now().UTC(), UpdatedAt: time.Now().UTC(), } } // generateMediaURL creates a publicly accessible URL for the media file // In a real implementation, this would create S3 signed URLs or CloudFront URLs func generateMediaURL(filePath string) string { // For MVP, we'll use a simple URL format // In production, this should use AWS S3 signed URLs or CloudFront baseURL := "https://meteor-media.example.com" return baseURL + "/" + filePath }