mod edit_history;
mod queries;
#[cfg(test)]
mod tests;
pub use edit_history::{get_edit_history, record_edit, EditHistoryEntry};
pub use queries::*;
#[derive(Debug, Clone, sqlx::FromRow)]
struct ApprovalRow {
id: i64,
action_type: String,
target_tweet_id: String,
target_author: String,
generated_content: String,
topic: String,
archetype: String,
score: f64,
status: String,
created_at: String,
media_paths: String,
reviewed_by: Option<String>,
review_notes: Option<String>,
reason: Option<String>,
detected_risks: String,
qa_report: String,
qa_hard_flags: String,
qa_soft_flags: String,
qa_recommendations: String,
qa_score: f64,
qa_requires_override: i64,
qa_override_by: Option<String>,
qa_override_note: Option<String>,
qa_override_at: Option<String>,
source_node_id: Option<i64>,
source_seed_id: Option<i64>,
source_chunks_json: String,
scheduled_for: Option<String>,
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ApprovalItem {
pub id: i64,
pub action_type: String,
pub target_tweet_id: String,
pub target_author: String,
pub generated_content: String,
pub topic: String,
pub archetype: String,
pub score: f64,
pub status: String,
pub created_at: String,
#[serde(serialize_with = "serialize_json_string")]
pub media_paths: String,
pub reviewed_by: Option<String>,
pub review_notes: Option<String>,
pub reason: Option<String>,
#[serde(serialize_with = "serialize_json_string")]
pub detected_risks: String,
#[serde(serialize_with = "serialize_json_string")]
pub qa_report: String,
#[serde(serialize_with = "serialize_json_string")]
pub qa_hard_flags: String,
#[serde(serialize_with = "serialize_json_string")]
pub qa_soft_flags: String,
#[serde(serialize_with = "serialize_json_string")]
pub qa_recommendations: String,
pub qa_score: f64,
pub qa_requires_override: bool,
pub qa_override_by: Option<String>,
pub qa_override_note: Option<String>,
pub qa_override_at: Option<String>,
pub source_node_id: Option<i64>,
pub source_seed_id: Option<i64>,
#[serde(serialize_with = "serialize_json_string")]
pub source_chunks_json: String,
pub scheduled_for: Option<String>,
}
fn serialize_json_string<S: serde::Serializer>(
value: &str,
serializer: S,
) -> Result<S::Ok, S::Error> {
use serde::Serialize;
let parsed: serde_json::Value =
serde_json::from_str(value).unwrap_or(serde_json::Value::Array(vec![]));
parsed.serialize(serializer)
}
impl From<ApprovalRow> for ApprovalItem {
fn from(r: ApprovalRow) -> Self {
Self {
id: r.id,
action_type: r.action_type,
target_tweet_id: r.target_tweet_id,
target_author: r.target_author,
generated_content: r.generated_content,
topic: r.topic,
archetype: r.archetype,
score: r.score,
status: r.status,
created_at: r.created_at,
media_paths: r.media_paths,
reviewed_by: r.reviewed_by,
review_notes: r.review_notes,
reason: r.reason,
detected_risks: r.detected_risks,
qa_report: r.qa_report,
qa_hard_flags: r.qa_hard_flags,
qa_soft_flags: r.qa_soft_flags,
qa_recommendations: r.qa_recommendations,
qa_score: r.qa_score,
qa_requires_override: r.qa_requires_override != 0,
qa_override_by: r.qa_override_by,
qa_override_note: r.qa_override_note,
qa_override_at: r.qa_override_at,
source_node_id: r.source_node_id,
source_seed_id: r.source_seed_id,
source_chunks_json: r.source_chunks_json,
scheduled_for: r.scheduled_for,
}
}
}
#[derive(Debug, Clone, serde::Serialize)]
pub struct ApprovalStats {
pub pending: i64,
pub approved: i64,
pub rejected: i64,
pub failed: i64,
pub scheduled: i64,
}
#[derive(Debug, Clone, Default, serde::Deserialize)]
pub struct ReviewAction {
pub actor: Option<String>,
pub notes: Option<String>,
}