use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use crate::author::AuthorStamp;
use crate::evidence::EvidenceId;
use crate::ids::{ProjectId, TenantId, VertexId};
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
pub struct ObservationId(pub String);
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Observation {
pub id: ObservationId,
pub tenant_id: TenantId,
pub project_id: ProjectId,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_event_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_uri: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject_id: Option<VertexId>,
pub predicate: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub object_id: Option<VertexId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub object_value: Option<serde_json::Value>,
pub observed_at: DateTime<Utc>,
pub extracted_at: DateTime<Utc>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub confidence: Option<f32>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub evidence_ids: Vec<EvidenceId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub extractor_version: Option<String>,
#[serde(default, skip_serializing_if = "serde_json::Value::is_null")]
pub metadata: serde_json::Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub author: Option<AuthorStamp>,
}