// file: kb_lib/src/db/dtos/wallet_participation.rs //! Wallet-participation DTO. /// Application-facing wallet-participation DTO. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct KbWalletParticipationDto { /// Optional numeric primary key. pub id: std::option::Option, /// Related wallet id. pub wallet_id: i64, /// Related transaction id. pub transaction_id: i64, /// Optional related decoded event id. pub decoded_event_id: std::option::Option, /// Optional related pool id. pub pool_id: std::option::Option, /// Optional related pair id. pub pair_id: std::option::Option, /// Stable participation role. pub role: std::string::String, /// Stable unique key used for idempotent upserts. pub unique_key: std::string::String, /// Observation source kind. pub source_kind: crate::KbObservationSourceKind, /// Optional logical source endpoint name. pub source_endpoint_name: std::option::Option, /// Creation timestamp. pub created_at: chrono::DateTime, /// Update timestamp. pub updated_at: chrono::DateTime, } impl KbWalletParticipationDto { /// Creates a new wallet-participation DTO. pub fn new( wallet_id: i64, transaction_id: i64, decoded_event_id: std::option::Option, pool_id: std::option::Option, pair_id: std::option::Option, role: std::string::String, source_kind: crate::KbObservationSourceKind, source_endpoint_name: std::option::Option, ) -> Self { let now = chrono::Utc::now(); let unique_key = kb_build_wallet_participation_unique_key( wallet_id, transaction_id, decoded_event_id, pool_id, pair_id, role.as_str(), ); return Self { id: None, wallet_id, transaction_id, decoded_event_id, pool_id, pair_id, role, unique_key, source_kind, source_endpoint_name, created_at: now, updated_at: now, }; } } impl TryFrom for KbWalletParticipationDto { type Error = crate::KbError; fn try_from(entity: crate::KbWalletParticipationEntity) -> Result { let source_kind_result = crate::KbObservationSourceKind::from_i16(entity.source_kind); let source_kind = match source_kind_result { Ok(source_kind) => source_kind, Err(error) => return Err(error), }; let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at); let created_at = match created_at_result { Ok(created_at) => created_at.with_timezone(&chrono::Utc), Err(error) => { return Err(crate::KbError::Db(format!( "cannot parse wallet_participation created_at '{}': {}", entity.created_at, error ))); }, }; let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at); let updated_at = match updated_at_result { Ok(updated_at) => updated_at.with_timezone(&chrono::Utc), Err(error) => { return Err(crate::KbError::Db(format!( "cannot parse wallet_participation updated_at '{}': {}", entity.updated_at, error ))); }, }; return Ok(Self { id: Some(entity.id), wallet_id: entity.wallet_id, transaction_id: entity.transaction_id, decoded_event_id: entity.decoded_event_id, pool_id: entity.pool_id, pair_id: entity.pair_id, role: entity.role, unique_key: entity.unique_key, source_kind, source_endpoint_name: entity.source_endpoint_name, created_at, updated_at, }); } } fn kb_build_wallet_participation_unique_key( wallet_id: i64, transaction_id: i64, decoded_event_id: std::option::Option, pool_id: std::option::Option, pair_id: std::option::Option, role: &str, ) -> std::string::String { let decoded_event_id_value = decoded_event_id.unwrap_or_default(); let pool_id_value = pool_id.unwrap_or_default(); let pair_id_value = pair_id.unwrap_or_default(); return format!( "{}:{}:{}:{}:{}:{}", wallet_id, transaction_id, decoded_event_id_value, pool_id_value, pair_id_value, role ); }