tuitbot_core/storage/approval_queue/
mod.rs1mod edit_history;
7mod queries;
8#[cfg(test)]
9mod tests;
10
11pub use edit_history::{get_edit_history, record_edit, EditHistoryEntry};
12pub use queries::*;
13
14#[derive(Debug, Clone, sqlx::FromRow)]
16struct ApprovalRow {
17 id: i64,
18 action_type: String,
19 target_tweet_id: String,
20 target_author: String,
21 generated_content: String,
22 topic: String,
23 archetype: String,
24 score: f64,
25 status: String,
26 created_at: String,
27 media_paths: String,
28 reviewed_by: Option<String>,
29 review_notes: Option<String>,
30 reason: Option<String>,
31 detected_risks: String,
32 qa_report: String,
33 qa_hard_flags: String,
34 qa_soft_flags: String,
35 qa_recommendations: String,
36 qa_score: f64,
37 qa_requires_override: i64,
38 qa_override_by: Option<String>,
39 qa_override_note: Option<String>,
40 qa_override_at: Option<String>,
41 source_node_id: Option<i64>,
42 source_seed_id: Option<i64>,
43 source_chunks_json: String,
44 scheduled_for: Option<String>,
45}
46
47#[derive(Debug, Clone, serde::Serialize)]
49pub struct ApprovalItem {
50 pub id: i64,
51 pub action_type: String,
52 pub target_tweet_id: String,
53 pub target_author: String,
54 pub generated_content: String,
55 pub topic: String,
56 pub archetype: String,
57 pub score: f64,
58 pub status: String,
59 pub created_at: String,
60 #[serde(serialize_with = "serialize_json_string")]
62 pub media_paths: String,
63 pub reviewed_by: Option<String>,
64 pub review_notes: Option<String>,
65 pub reason: Option<String>,
66 #[serde(serialize_with = "serialize_json_string")]
68 pub detected_risks: String,
69 #[serde(serialize_with = "serialize_json_string")]
71 pub qa_report: String,
72 #[serde(serialize_with = "serialize_json_string")]
74 pub qa_hard_flags: String,
75 #[serde(serialize_with = "serialize_json_string")]
77 pub qa_soft_flags: String,
78 #[serde(serialize_with = "serialize_json_string")]
80 pub qa_recommendations: String,
81 pub qa_score: f64,
83 pub qa_requires_override: bool,
85 pub qa_override_by: Option<String>,
87 pub qa_override_note: Option<String>,
89 pub qa_override_at: Option<String>,
91 pub source_node_id: Option<i64>,
93 pub source_seed_id: Option<i64>,
95 #[serde(serialize_with = "serialize_json_string")]
97 pub source_chunks_json: String,
98 pub scheduled_for: Option<String>,
100}
101
102fn serialize_json_string<S: serde::Serializer>(
107 value: &str,
108 serializer: S,
109) -> Result<S::Ok, S::Error> {
110 use serde::Serialize;
111 let parsed: serde_json::Value =
112 serde_json::from_str(value).unwrap_or(serde_json::Value::Array(vec![]));
113 parsed.serialize(serializer)
114}
115
116impl From<ApprovalRow> for ApprovalItem {
117 fn from(r: ApprovalRow) -> Self {
118 Self {
119 id: r.id,
120 action_type: r.action_type,
121 target_tweet_id: r.target_tweet_id,
122 target_author: r.target_author,
123 generated_content: r.generated_content,
124 topic: r.topic,
125 archetype: r.archetype,
126 score: r.score,
127 status: r.status,
128 created_at: r.created_at,
129 media_paths: r.media_paths,
130 reviewed_by: r.reviewed_by,
131 review_notes: r.review_notes,
132 reason: r.reason,
133 detected_risks: r.detected_risks,
134 qa_report: r.qa_report,
135 qa_hard_flags: r.qa_hard_flags,
136 qa_soft_flags: r.qa_soft_flags,
137 qa_recommendations: r.qa_recommendations,
138 qa_score: r.qa_score,
139 qa_requires_override: r.qa_requires_override != 0,
140 qa_override_by: r.qa_override_by,
141 qa_override_note: r.qa_override_note,
142 qa_override_at: r.qa_override_at,
143 source_node_id: r.source_node_id,
144 source_seed_id: r.source_seed_id,
145 source_chunks_json: r.source_chunks_json,
146 scheduled_for: r.scheduled_for,
147 }
148 }
149}
150
151#[derive(Debug, Clone, serde::Serialize)]
153pub struct ApprovalStats {
154 pub pending: i64,
155 pub approved: i64,
156 pub rejected: i64,
157 pub failed: i64,
158 pub scheduled: i64,
159}
160
161#[derive(Debug, Clone, Default, serde::Deserialize)]
163pub struct ReviewAction {
164 pub actor: Option<String>,
165 pub notes: Option<String>,
166}