Skip to main content

headless_lms_models/
chatbot_action_logs.rs

1use crate::prelude::*;
2use utoipa::ToSchema;
3
4/// The audit record of one privileged mutation a support chatbot admin confirmed and the server
5/// executed. See the table's own `COMMENT ON` for why this exists alongside per-domain logs.
6#[derive(Clone, PartialEq, Deserialize, Serialize, ToSchema)]
7pub struct ChatbotActionLog {
8    pub id: Uuid,
9    pub created_at: DateTime<Utc>,
10    pub updated_at: DateTime<Utc>,
11    pub deleted_at: Option<DateTime<Utc>>,
12    pub acting_user_id: Uuid,
13    pub tool_call_id: Uuid,
14    pub tool_name: String,
15    #[schema(value_type = Object)]
16    pub arguments: serde_json::Value,
17    pub target_user_id: Option<Uuid>,
18    pub course_id: Option<Uuid>,
19    pub summary: String,
20}
21
22/// The fields a caller supplies to record an executed action; the rest are assigned by the insert.
23pub struct NewChatbotActionLog {
24    pub acting_user_id: Uuid,
25    pub tool_call_id: Uuid,
26    pub tool_name: String,
27    pub arguments: serde_json::Value,
28    pub target_user_id: Option<Uuid>,
29    pub course_id: Option<Uuid>,
30    pub summary: String,
31}
32
33pub async fn insert(conn: &mut PgConnection, input: NewChatbotActionLog) -> ModelResult<Uuid> {
34    let res = sqlx::query!(
35        r#"
36INSERT INTO chatbot_action_logs (
37    acting_user_id,
38    tool_call_id,
39    tool_name,
40    arguments,
41    target_user_id,
42    course_id,
43    summary
44  )
45VALUES ($1, $2, $3, $4, $5, $6, $7)
46RETURNING id
47        "#,
48        input.acting_user_id,
49        input.tool_call_id,
50        input.tool_name,
51        input.arguments,
52        input.target_user_id,
53        input.course_id,
54        input.summary
55    )
56    .fetch_one(conn)
57    .await?;
58    Ok(res.id)
59}