robson-core 0.0.1

Rust async agent orchestrator for automated development workflows
Documentation
use anyhow::Result;
use chrono::Utc;
use sea_orm::entity::prelude::*;
use sea_orm::{ActiveValue::Set, QueryOrder};
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel, Serialize, Deserialize)]
#[sea_orm(table_name = "process_events")]
pub struct Model {
    #[sea_orm(primary_key)]
    pub id: i32,
    pub conversation_id: i32,
    pub kind: String,
    pub content: String,
    pub created_at: String,
    /// Unix epoch timestamp set when all registered gateways have delivered this event.
    /// NULL means delivery is still pending for at least one gateway.
    pub delivered_at: Option<i64>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}

impl Model {
    pub async fn insert(
        db: &DatabaseConnection,
        conversation_id: i32,
        kind: &str,
        content: &str,
    ) -> Result<()> {
        let now = Utc::now().to_rfc3339();
        let active = ActiveModel {
            conversation_id: Set(conversation_id),
            kind: Set(kind.to_string()),
            content: Set(content.to_string()),
            created_at: Set(now),
            delivered_at: Set(None),
            ..Default::default()
        };
        active.insert(db).await?;
        Ok(())
    }

    /// Returns all process_events where delivered_at IS NULL (not yet fully delivered).
    pub async fn find_undelivered(db: &DatabaseConnection) -> Result<Vec<Model>> {
        let rows = Entity::find()
            .filter(Column::DeliveredAt.is_null())
            .order_by_asc(Column::Id)
            .all(db)
            .await?;
        Ok(rows)
    }

    /// Marks a process_event as fully delivered (all gateways done) using current Unix epoch.
    pub async fn mark_delivered(db: &DatabaseConnection, id: i32) -> Result<()> {
        let now = Utc::now().timestamp();
        let active = ActiveModel {
            id: Set(id),
            delivered_at: Set(Some(now)),
            ..Default::default()
        };
        active.update(db).await?;
        Ok(())
    }

    pub async fn find_by_conversation(
        db: &DatabaseConnection,
        conversation_id: i32,
    ) -> Result<Vec<Model>> {
        let rows = Entity::find()
            .filter(Column::ConversationId.eq(conversation_id))
            .order_by_asc(Column::CreatedAt)
            .all(db)
            .await?;
        Ok(rows)
    }
}