821537186e
- Reorganized import statements in adapter tests for better readability - Replaced or_insert_with(Vec::new) with or_default() in test closures - Updated Cargo.lock with new dependency versions and checksums - Added TLS features to tonic dependency configuration - Included sqlx, chrono, and uuid dependencies with specific features - Added jsonwebtoken and arc-swap as project dependencies - Reformatted assertion statements to comply with line length limits - Adjusted base64 import order in engine codec module - Updated protobuf include statement formatting
78 lines
2.2 KiB
Rust
78 lines
2.2 KiB
Rust
//! Edit history CRUD operations on `MessageRepo`.
|
|
//!
|
|
//! Immutable append-only log. Every message body edit creates one row.
|
|
|
|
use chrono::Utc;
|
|
use sqlx::Row;
|
|
use uuid::Uuid;
|
|
|
|
use crate::ImksResult;
|
|
use crate::models::message_edit::{EditSummary, MessageEdit};
|
|
|
|
use super::message_repo::MessageRepo;
|
|
|
|
impl MessageRepo {
|
|
/// Record an edit to a message's body.
|
|
pub async fn record_edit(
|
|
&self,
|
|
message_id: Uuid,
|
|
edited_by: Uuid,
|
|
old_body: &str,
|
|
new_body: &str,
|
|
) -> ImksResult<MessageEdit> {
|
|
let id = Uuid::now_v7();
|
|
let now = Utc::now();
|
|
|
|
sqlx::query_as::<_, MessageEdit>(
|
|
r#"
|
|
INSERT INTO message_edit (id, message_id, edited_by, old_body, new_body, edited_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6)
|
|
RETURNING *
|
|
"#,
|
|
)
|
|
.bind(id)
|
|
.bind(message_id)
|
|
.bind(edited_by)
|
|
.bind(old_body)
|
|
.bind(new_body)
|
|
.bind(now)
|
|
.fetch_one(self.pool())
|
|
.await
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
/// Get the full edit history for a message, oldest first.
|
|
pub async fn get_edit_history(&self, message_id: Uuid) -> ImksResult<Vec<MessageEdit>> {
|
|
sqlx::query_as::<_, MessageEdit>(
|
|
"SELECT * FROM message_edit WHERE message_id = $1 ORDER BY edited_at ASC",
|
|
)
|
|
.bind(message_id)
|
|
.fetch_all(self.pool())
|
|
.await
|
|
.map_err(Into::into)
|
|
}
|
|
|
|
/// Get a summary of edits for a message (count + last editor).
|
|
pub async fn get_edit_summary(&self, message_id: Uuid) -> ImksResult<EditSummary> {
|
|
let row = sqlx::query(
|
|
r#"
|
|
SELECT
|
|
COUNT(*)::BIGINT AS edit_count,
|
|
MAX(edited_at) AS last_edited_at,
|
|
(ARRAY_AGG(edited_by ORDER BY edited_at DESC))[1] AS last_edited_by
|
|
FROM message_edit
|
|
WHERE message_id = $1
|
|
"#,
|
|
)
|
|
.bind(message_id)
|
|
.fetch_one(self.pool())
|
|
.await?;
|
|
|
|
Ok(EditSummary {
|
|
edit_count: row.get("edit_count"),
|
|
last_edited_at: row.get("last_edited_at"),
|
|
last_edited_by: row.get("last_edited_by"),
|
|
})
|
|
}
|
|
}
|