//! Mention CRUD operations on `MessageRepo`. use chrono::Utc; use uuid::Uuid; use crate::ImksResult; use crate::models::message_mention::MessageMention; use super::message_repo::MessageRepo; use super::pagination::{CursorPage, clamp_limit}; impl MessageRepo { /// Bulk record mentions for a message. Called right after message creation. pub async fn record_mentions( &self, message_id: Uuid, channel_id: Uuid, mentioned_by: Uuid, mentioned_user_ids: &[Uuid], ) -> ImksResult<()> { if mentioned_user_ids.is_empty() { return Ok(()); } let now = Utc::now(); for &user_id in mentioned_user_ids { sqlx::query( r#" INSERT INTO message_mention (id, message_id, channel_id, mentioned_user_id, mentioned_by, created_at) VALUES ($1, $2, $3, $4, $5, $6) "#, ) .bind(Uuid::now_v7()) .bind(message_id) .bind(channel_id) .bind(user_id) .bind(mentioned_by) .bind(now) .execute(self.pool()) .await?; } Ok(()) } /// List mentions for a specific user, newest first. pub async fn list_mentions_for_user( &self, user_id: Uuid, before: Option, limit: Option, ) -> ImksResult> { let effective_limit = clamp_limit(limit); let fetch_limit = effective_limit + 1; let rows = match before { Some(cursor) => { sqlx::query_as::<_, MessageMention>( r#" SELECT * FROM message_mention WHERE mentioned_user_id = $1 AND id < $2 ORDER BY id DESC LIMIT $3 "#, ) .bind(user_id) .bind(cursor) .bind(fetch_limit) .fetch_all(self.pool()) .await? } None => { sqlx::query_as::<_, MessageMention>( r#" SELECT * FROM message_mention WHERE mentioned_user_id = $1 ORDER BY id DESC LIMIT $2 "#, ) .bind(user_id) .bind(fetch_limit) .fetch_all(self.pool()) .await? } }; Ok(CursorPage::from_raw(rows, effective_limit, |m| m.id)) } /// Mark a mention as read. pub async fn mark_mention_read(&self, mention_id: Uuid) -> ImksResult<()> { sqlx::query("UPDATE message_mention SET read_at = $1 WHERE id = $2") .bind(Utc::now()) .bind(mention_id) .execute(self.pool()) .await?; Ok(()) } /// Delete all mentions for a message (e.g. on message delete). pub async fn delete_mentions(&self, message_id: Uuid) -> ImksResult<()> { sqlx::query("DELETE FROM message_mention WHERE message_id = $1") .bind(message_id) .execute(self.pool()) .await?; Ok(()) } }