use sea_orm::entity::prelude::*;
use sea_orm::{Condition, QueryOrder, QuerySelect};
use toolkit_db::secure::{AccessScope, DBRunner, SecureEntityExt};
use toolkit_db_macros::Scopable;
use uuid::Uuid;
use crate::domain::error::ChatEngineError;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Scopable)]
#[sea_orm(table_name = "message_parts")]
#[secure(unrestricted)]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub message_id: Uuid,
pub r#type: MessagePartType,
#[sea_orm(column_type = "JsonBinary")]
pub content: serde_json::Value,
pub number: i32,
}
#[derive(Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum)]
#[sea_orm(rs_type = "String", db_type = "String(StringLen::N(16))")]
pub enum MessagePartType {
#[sea_orm(string_value = "text")]
Text,
#[sea_orm(string_value = "code")]
Code,
#[sea_orm(string_value = "images")]
Images,
#[sea_orm(string_value = "videos")]
Videos,
#[sea_orm(string_value = "links")]
Links,
#[sea_orm(string_value = "statuses")]
Statuses,
}
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::message::Entity",
from = "Column::MessageId",
to = "super::message::Column::MessageId",
on_update = "NoAction",
on_delete = "Cascade"
)]
Message,
}
impl Related<super::message::Entity> for Entity {
fn to() -> RelationDef {
Relation::Message.def()
}
}
impl ActiveModelBehavior for ActiveModel {}
pub async fn compute_next_part_number<R>(
runner: &R,
message_id: Uuid,
) -> Result<i32, ChatEngineError>
where
R: DBRunner,
{
let scope = AccessScope::allow_all();
let row = Entity::find()
.order_by_desc(Column::Number)
.limit(1)
.secure()
.scope_with(&scope)
.filter(Condition::all().add(Column::MessageId.eq(message_id)))
.one(runner)
.await?;
Ok(match row {
Some(row) => row.number + 1,
None => 0,
})
}