diff --git a/services/identity/src/database/device_list.rs b/services/identity/src/database/device_list.rs --- a/services/identity/src/database/device_list.rs +++ b/services/identity/src/database/device_list.rs @@ -423,6 +423,58 @@ .map_err(Error::from) } + /// Gets user's device list history + pub async fn get_device_list_history( + &self, + user_id: impl Into, + since: Option>, + ) -> Result, Error> { + let rows = if let Some(since) = since { + // When timestamp is provided, it's better to query device lists by timestamp LSI + self + .client + .query() + .table_name(devices_table::NAME) + .index_name(devices_table::TIMESTAMP_INDEX_NAME) + .consistent_read(true) + .key_condition_expression("#user_id = :user_id AND #timestamp > :since") + .expression_attribute_names("#user_id", ATTR_USER_ID) + .expression_attribute_names("#timestamp", ATTR_TIMESTAMP) + .expression_attribute_values( + ":user_id", + AttributeValue::S(user_id.into()), + ) + .expression_attribute_values( + ":since", + AttributeValue::N(since.timestamp_millis().to_string()), + ) + .send() + .await + .map_err(|e| { + error!("Failed to query device list updates by index: {:?}", e); + Error::AwsSdk(e.into()) + })? + .items + } else { + // Query all device lists for user + query_rows_with_prefix(self, user_id, DEVICE_LIST_KEY_PREFIX) + .send() + .await + .map_err(|e| { + error!("Failed to query device list updates (all): {:?}", e); + Error::AwsSdk(e.into()) + })? + .items + }; + + rows + .unwrap_or_default() + .into_iter() + .map(DeviceListRow::try_from) + .collect::, DBItemError>>() + .map_err(Error::from) + } + /// Checks if given device exists on user's current device list pub async fn device_exists( &self,