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}
42
43#[derive(Debug, Clone, serde::Serialize)]
45pub struct ApprovalItem {
46 pub id: i64,
47 pub action_type: String,
48 pub target_tweet_id: String,
49 pub target_author: String,
50 pub generated_content: String,
51 pub topic: String,
52 pub archetype: String,
53 pub score: f64,
54 pub status: String,
55 pub created_at: String,
56 #[serde(serialize_with = "serialize_json_string")]
58 pub media_paths: String,
59 pub reviewed_by: Option<String>,
60 pub review_notes: Option<String>,
61 pub reason: Option<String>,
62 #[serde(serialize_with = "serialize_json_string")]
64 pub detected_risks: String,
65 #[serde(serialize_with = "serialize_json_string")]
67 pub qa_report: String,
68 #[serde(serialize_with = "serialize_json_string")]
70 pub qa_hard_flags: String,
71 #[serde(serialize_with = "serialize_json_string")]
73 pub qa_soft_flags: String,
74 #[serde(serialize_with = "serialize_json_string")]
76 pub qa_recommendations: String,
77 pub qa_score: f64,
79 pub qa_requires_override: bool,
81 pub qa_override_by: Option<String>,
83 pub qa_override_note: Option<String>,
85 pub qa_override_at: Option<String>,
87}
88
89fn serialize_json_string<S: serde::Serializer>(
94 value: &str,
95 serializer: S,
96) -> Result<S::Ok, S::Error> {
97 use serde::Serialize;
98 let parsed: serde_json::Value =
99 serde_json::from_str(value).unwrap_or(serde_json::Value::Array(vec![]));
100 parsed.serialize(serializer)
101}
102
103impl From<ApprovalRow> for ApprovalItem {
104 fn from(r: ApprovalRow) -> Self {
105 Self {
106 id: r.id,
107 action_type: r.action_type,
108 target_tweet_id: r.target_tweet_id,
109 target_author: r.target_author,
110 generated_content: r.generated_content,
111 topic: r.topic,
112 archetype: r.archetype,
113 score: r.score,
114 status: r.status,
115 created_at: r.created_at,
116 media_paths: r.media_paths,
117 reviewed_by: r.reviewed_by,
118 review_notes: r.review_notes,
119 reason: r.reason,
120 detected_risks: r.detected_risks,
121 qa_report: r.qa_report,
122 qa_hard_flags: r.qa_hard_flags,
123 qa_soft_flags: r.qa_soft_flags,
124 qa_recommendations: r.qa_recommendations,
125 qa_score: r.qa_score,
126 qa_requires_override: r.qa_requires_override != 0,
127 qa_override_by: r.qa_override_by,
128 qa_override_note: r.qa_override_note,
129 qa_override_at: r.qa_override_at,
130 }
131 }
132}
133
134#[derive(Debug, Clone, serde::Serialize)]
136pub struct ApprovalStats {
137 pub pending: i64,
138 pub approved: i64,
139 pub rejected: i64,
140}
141
142#[derive(Debug, Clone, Default, serde::Deserialize)]
144pub struct ReviewAction {
145 pub actor: Option<String>,
146 pub notes: Option<String>,
147}