tuitbot_core/automation/analytics_loop/
collector.rs1#[async_trait::async_trait]
8pub trait ProfileFetcher: Send + Sync {
9 async fn get_profile_metrics(&self) -> Result<ProfileMetrics, AnalyticsError>;
11}
12
13#[async_trait::async_trait]
15pub trait EngagementFetcher: Send + Sync {
16 async fn get_tweet_metrics(&self, tweet_id: &str) -> Result<TweetMetrics, AnalyticsError>;
18}
19
20#[async_trait::async_trait]
22pub trait AnalyticsStorage: Send + Sync {
23 async fn store_follower_snapshot(
25 &self,
26 followers: i64,
27 following: i64,
28 tweets: i64,
29 ) -> Result<(), AnalyticsError>;
30
31 async fn get_yesterday_followers(&self) -> Result<Option<i64>, AnalyticsError>;
33
34 async fn get_replies_needing_measurement(&self) -> Result<Vec<String>, AnalyticsError>;
36
37 async fn get_tweets_needing_measurement(&self) -> Result<Vec<String>, AnalyticsError>;
39
40 async fn store_reply_performance(
42 &self,
43 reply_id: &str,
44 likes: i64,
45 replies: i64,
46 impressions: i64,
47 score: f64,
48 ) -> Result<(), AnalyticsError>;
49
50 async fn store_tweet_performance(
52 &self,
53 tweet_id: &str,
54 likes: i64,
55 retweets: i64,
56 replies: i64,
57 impressions: i64,
58 score: f64,
59 ) -> Result<(), AnalyticsError>;
60
61 async fn update_content_score(
63 &self,
64 topic: &str,
65 format: &str,
66 score: f64,
67 ) -> Result<(), AnalyticsError>;
68
69 async fn log_action(
71 &self,
72 action_type: &str,
73 status: &str,
74 message: &str,
75 ) -> Result<(), AnalyticsError>;
76
77 async fn run_forge_sync_if_enabled(&self) -> Result<Option<ForgeSyncResult>, AnalyticsError> {
82 Ok(None)
84 }
85
86 async fn run_aggregations(&self) -> Result<(), AnalyticsError> {
91 Ok(())
92 }
93}
94
95#[derive(Debug, Clone)]
101pub struct ProfileMetrics {
102 pub follower_count: i64,
103 pub following_count: i64,
104 pub tweet_count: i64,
105}
106
107#[derive(Debug, Clone)]
109pub struct TweetMetrics {
110 pub likes: i64,
111 pub retweets: i64,
112 pub replies: i64,
113 pub impressions: i64,
114}
115
116#[derive(Debug)]
118pub enum AnalyticsError {
119 ApiError(String),
121 StorageError(String),
123 Other(String),
125}
126
127impl std::fmt::Display for AnalyticsError {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 match self {
130 Self::ApiError(msg) => write!(f, "API error: {msg}"),
131 Self::StorageError(msg) => write!(f, "storage error: {msg}"),
132 Self::Other(msg) => write!(f, "{msg}"),
133 }
134 }
135}
136
137impl std::error::Error for AnalyticsError {}
138
139#[derive(Debug, Default, Clone)]
141pub struct ForgeSyncResult {
142 pub tweets_synced: usize,
143 pub threads_synced: usize,
144}