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
72 lines
2.1 KiB
Rust
72 lines
2.1 KiB
Rust
//! Thread participant membership — maps to `message_thread_participant` table.
|
|
//!
|
|
//! Tracks which users are part of a thread. A user becomes a participant when
|
|
//! they reply in a thread, get @mentioned, or are explicitly added.
|
|
//! Without this table, `message_thread.participants_count` is un-verifiable.
|
|
|
|
use chrono::{DateTime, Utc};
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
/// A user participating in a thread.
|
|
///
|
|
/// Maps to the `message_thread_participant` table. Users become participants
|
|
/// when they reply, get @mentioned, or are explicitly added.
|
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
|
pub struct MessageThreadParticipant {
|
|
pub id: Uuid,
|
|
pub thread_id: Uuid,
|
|
pub user_id: Uuid,
|
|
/// How the user joined the thread.
|
|
pub joined_reason: Option<String>,
|
|
pub last_read_message_id: Option<Uuid>,
|
|
pub last_read_at: Option<DateTime<Utc>>,
|
|
pub joined_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum JoinReason {
|
|
/// User sent a reply in the thread.
|
|
#[default]
|
|
Reply,
|
|
/// User was @mentioned in a thread message.
|
|
Mentioned,
|
|
/// User was explicitly added by another participant.
|
|
Added,
|
|
/// User joined the thread themselves.
|
|
Joined,
|
|
}
|
|
|
|
impl JoinReason {
|
|
pub fn as_str(&self) -> &'static str {
|
|
match self {
|
|
Self::Reply => "reply",
|
|
Self::Mentioned => "mentioned",
|
|
Self::Added => "added",
|
|
Self::Joined => "joined",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_participant_serialize() {
|
|
let p = MessageThreadParticipant {
|
|
id: Uuid::now_v7(),
|
|
thread_id: Uuid::now_v7(),
|
|
user_id: Uuid::now_v7(),
|
|
joined_reason: Some(JoinReason::Reply.as_str().into()),
|
|
last_read_message_id: None,
|
|
last_read_at: None,
|
|
joined_at: Utc::now(),
|
|
};
|
|
|
|
let json = serde_json::to_value(&p).unwrap();
|
|
assert_eq!(json["joined_reason"], "reply");
|
|
}
|
|
}
|