feat: init

This commit is contained in:
zhenyi
2026-06-07 11:30:56 +08:00
commit 563381c1ca
361 changed files with 41327 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Discussion comment on an article (similar to blog comments).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ArticleComment {
pub id: Uuid,
pub article_id: Uuid,
pub channel_id: Uuid,
pub author_id: Uuid,
pub parent_comment_id: Option<Uuid>,
pub body: String,
pub edited_at: Option<DateTime<Utc>>,
pub deleted_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+22
View File
@@ -0,0 +1,22 @@
use crate::models::common::Status;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Tracks a single cross-post delivery when an article is published
/// to a follower channel/workspace.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ArticleCrossPost {
pub id: Uuid,
pub article_id: Uuid,
pub follow_id: Uuid,
pub target_workspace_id: Uuid,
pub target_channel_id: Option<Uuid>,
pub status: Status,
pub attempts: i32,
pub last_error: Option<String>,
pub sent_at: Option<DateTime<Utc>>,
pub delivered_at: Option<DateTime<Utc>>,
pub failed_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Reaction on an article (emoji reactions, separate from message reactions).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ArticleReaction {
pub id: Uuid,
pub article_id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub content: String,
pub created_at: DateTime<Utc>,
}
+35
View File
@@ -0,0 +1,35 @@
use crate::models::common::{ArticleStatus, JsonValue, Visibility};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Long-form article for announcement/news channels.
/// Unlike a plain Message, an article has a title, cover image,
/// publish lifecycle, and can be cross-posted to followers.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Article {
pub id: Uuid,
pub channel_id: Uuid,
pub author_id: Uuid,
pub title: String,
pub slug: String,
pub summary: Option<String>,
pub body: String,
pub cover_image_url: Option<String>,
pub status: ArticleStatus,
pub visibility: Visibility,
pub tags: Vec<String>,
pub published_at: Option<DateTime<Utc>>,
pub published_by: Option<Uuid>,
pub scheduled_at: Option<DateTime<Utc>>,
pub unpublished_at: Option<DateTime<Utc>>,
pub views_count: i64,
pub comments_count: i64,
pub reactions_count: i64,
pub cross_posted: bool,
pub cross_posted_from: Option<Uuid>,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
+43
View File
@@ -0,0 +1,43 @@
use crate::models::common::{
ChannelKind, ChannelType, ForumLayout, ForumSortOrder, JsonValue, Visibility,
};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Channel {
pub id: Uuid,
pub workspace_id: Uuid,
pub repo_id: Option<Uuid>,
pub category_id: Option<Uuid>,
pub created_by: Uuid,
pub name: String,
pub topic: Option<String>,
pub description: Option<String>,
pub channel_type: ChannelType,
pub channel_kind: ChannelKind,
pub visibility: Visibility,
pub position: Option<i32>,
pub nsfw: bool,
pub archived: bool,
pub read_only: bool,
pub bitrate: Option<i32>,
pub user_limit: Option<i32>,
pub rtc_region: Option<String>,
pub default_auto_archive_duration: Option<i32>,
pub default_reaction_emoji: Option<String>,
pub default_sort_order: Option<ForumSortOrder>,
pub default_forum_layout: Option<ForumLayout>,
pub require_tag: Option<bool>,
pub available_tags: Option<JsonValue>,
pub default_thread_rate_limit: Option<i32>,
pub rate_limit_per_user: Option<i32>,
pub parent_channel_id: Option<Uuid>,
pub last_message_id: Option<Uuid>,
pub last_message_at: Option<DateTime<Utc>>,
pub archived_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
+15
View File
@@ -0,0 +1,15 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelCategory {
pub id: Uuid,
pub workspace_id: Uuid,
pub name: String,
pub position: i32,
pub collapsed: bool,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use crate::models::common::{EventType, JsonValue, TargetType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelEvent {
pub id: Uuid,
pub channel_id: Uuid,
pub actor_id: Option<Uuid>,
pub event_type: EventType,
pub target_type: Option<TargetType>,
pub target_id: Option<Uuid>,
pub old_value: Option<JsonValue>,
pub new_value: Option<JsonValue>,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
}
+23
View File
@@ -0,0 +1,23 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Follow relationship on an announcement channel.
/// Allows another workspace or channel to receive cross-posts
/// when articles are published.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelFollow {
pub id: Uuid,
pub source_channel_id: Uuid,
pub target_workspace_id: Uuid,
pub target_channel_id: Option<Uuid>,
pub webhook_url: Option<String>,
pub webhook_secret_ciphertext: Option<String>,
pub enabled: bool,
pub followed_by: Uuid,
pub unfollowed_at: Option<DateTime<Utc>>,
pub last_delivery_at: Option<DateTime<Utc>>,
pub last_delivery_status: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+20
View File
@@ -0,0 +1,20 @@
use crate::models::common::Role;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelInvitation {
pub id: Uuid,
pub channel_id: Uuid,
pub workspace_id: Uuid,
pub invited_user_id: Option<Uuid>,
pub email: Option<String>,
pub role: Role,
pub token_hash: String,
pub invited_by: Uuid,
pub accepted_at: Option<DateTime<Utc>>,
pub revoked_at: Option<DateTime<Utc>>,
pub expires_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
}
+17
View File
@@ -0,0 +1,17 @@
use crate::models::common::Permission;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelMemberRole {
pub id: Uuid,
pub channel_id: Uuid,
pub name: String,
pub description: Option<String>,
pub permissions: Vec<Permission>,
pub assignable: bool,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+21
View File
@@ -0,0 +1,21 @@
use crate::models::common::{Role, Status};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelMember {
pub id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub role: Role,
pub status: Status,
pub muted: bool,
pub pinned: bool,
pub last_read_message_id: Option<Uuid>,
pub last_read_at: Option<DateTime<Utc>>,
pub joined_at: Option<DateTime<Utc>>,
pub left_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,17 @@
use crate::models::common::{OverwriteTarget, Permission};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelPermissionOverwrite {
pub id: Uuid,
pub channel_id: Uuid,
pub target_type: OverwriteTarget,
pub target_id: Uuid,
pub allow: Vec<Permission>,
pub deny: Vec<Permission>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+17
View File
@@ -0,0 +1,17 @@
use crate::models::common::{EventType, LinkType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelRepoLink {
pub id: Uuid,
pub channel_id: Uuid,
pub repo_id: Uuid,
pub link_type: LinkType,
pub notify_events: Vec<EventType>,
pub active: bool,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+20
View File
@@ -0,0 +1,20 @@
use crate::models::common::Scope;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelSlashCommand {
pub id: Uuid,
pub channel_id: Option<Uuid>,
pub workspace_id: Uuid,
pub command: String,
pub description: Option<String>,
pub request_url: String,
pub secret_ciphertext: Option<String>,
pub scopes: Vec<Scope>,
pub enabled: bool,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelStats {
pub channel_id: Uuid,
pub members_count: i64,
pub messages_count: i64,
pub threads_count: i64,
pub reactions_count: i64,
pub mentions_count: i64,
pub files_count: i64,
pub last_activity_at: Option<DateTime<Utc>>,
pub updated_at: DateTime<Utc>,
}
+20
View File
@@ -0,0 +1,20 @@
use crate::models::common::EventType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ChannelWebhook {
pub id: Uuid,
pub channel_id: Uuid,
pub name: String,
pub url: String,
pub secret_ciphertext: Option<String>,
pub events: Vec<EventType>,
pub active: bool,
pub last_delivery_status: Option<String>,
pub last_delivery_at: Option<DateTime<Utc>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct CustomEmoji {
pub id: Uuid,
pub workspace_id: Uuid,
pub name: String,
pub url: String,
pub animated: bool,
pub managed: bool,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Forum channel post tags (similar to Discord forum tags).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ForumTag {
pub id: Uuid,
pub channel_id: Uuid,
pub name: String,
pub emoji_id: Option<String>,
pub emoji_name: Option<String>,
pub moderated: bool,
pub position: i32,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+24
View File
@@ -0,0 +1,24 @@
use crate::models::common::{JsonValue, Provider, SyncDirection};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ImIntegration {
pub id: Uuid,
pub workspace_id: Uuid,
pub provider: Provider,
pub name: String,
pub external_workspace_id: Option<String>,
pub internal_channel_id: Option<Uuid>,
pub external_channel_id: Option<String>,
pub bot_token_ciphertext: Option<String>,
pub webhook_url: Option<String>,
pub sync_direction: SyncDirection,
pub user_mapping: Option<JsonValue>,
pub enabled: bool,
pub installed_by: Uuid,
pub last_sync_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+23
View File
@@ -0,0 +1,23 @@
use crate::models::common::{JsonValue, MessageType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Message {
pub id: Uuid,
pub channel_id: Uuid,
pub author_id: Uuid,
pub thread_id: Option<Uuid>,
pub reply_to_message_id: Option<Uuid>,
pub seq: i64,
pub message_type: MessageType,
pub body: String,
pub metadata: Option<JsonValue>,
pub pinned: bool,
pub system: bool,
pub edited_at: Option<DateTime<Utc>>,
pub deleted_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+21
View File
@@ -0,0 +1,21 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageAttachment {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub filename: String,
pub url: String,
pub proxy_url: Option<String>,
pub size_bytes: i64,
pub mime_type: String,
pub width: Option<i32>,
pub height: Option<i32>,
pub duration_ms: Option<i64>,
pub thumbnail_url: Option<String>,
pub blurhash: Option<String>,
pub created_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageBookmark {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub note: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+17
View File
@@ -0,0 +1,17 @@
use crate::models::common::JsonValue;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageDraft {
pub id: Uuid,
pub user_id: Uuid,
pub channel_id: Uuid,
pub thread_id: Option<Uuid>,
pub reply_to_message_id: Option<Uuid>,
pub content: String,
pub attachments: Option<JsonValue>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+13
View File
@@ -0,0 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageEditHistory {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub previous_body: String,
pub edited_by: Uuid,
pub edited_at: DateTime<Utc>,
}
+34
View File
@@ -0,0 +1,34 @@
use crate::models::common::{EmbedType, JsonValue};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageEmbed {
pub id: Uuid,
pub message_id: Uuid,
pub embed_type: EmbedType,
pub title: Option<String>,
pub description: Option<String>,
pub url: Option<String>,
pub author_name: Option<String>,
pub author_url: Option<String>,
pub author_icon_url: Option<String>,
pub thumbnail_url: Option<String>,
pub thumbnail_width: Option<i32>,
pub thumbnail_height: Option<i32>,
pub image_url: Option<String>,
pub image_width: Option<i32>,
pub image_height: Option<i32>,
pub video_url: Option<String>,
pub video_width: Option<i32>,
pub video_height: Option<i32>,
pub color: Option<i32>,
pub fields: Option<JsonValue>,
pub footer_text: Option<String>,
pub footer_icon_url: Option<String>,
pub provider_name: Option<String>,
pub provider_url: Option<String>,
pub timestamp: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageMention {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub mentioned_user_id: Uuid,
pub mentioned_by: Uuid,
pub read_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
+12
View File
@@ -0,0 +1,12 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessagePin {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub pinned_by: Uuid,
pub pinned_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Poll option.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessagePollOption {
pub id: Uuid,
pub poll_id: Uuid,
pub position: i32,
pub text: String,
pub emoji_id: Option<String>,
pub emoji_name: Option<String>,
pub vote_count: i64,
pub created_at: DateTime<Utc>,
}
+13
View File
@@ -0,0 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// User vote record for a poll option.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessagePollVote {
pub id: Uuid,
pub poll_id: Uuid,
pub option_id: Uuid,
pub user_id: Uuid,
pub voted_at: DateTime<Utc>,
}
+22
View File
@@ -0,0 +1,22 @@
use crate::models::common::{JsonValue, PollLayout};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Message poll (similar to Discord Polls).
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessagePoll {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub question: String,
pub description: Option<String>,
pub layout: PollLayout,
pub allow_multiselect: bool,
pub duration_hours: Option<i32>,
pub ends_at: Option<DateTime<Utc>>,
pub total_votes: i64,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+13
View File
@@ -0,0 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageReaction {
pub id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub content: String,
pub created_at: DateTime<Utc>,
}
+27
View File
@@ -0,0 +1,27 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct MessageThread {
pub id: Uuid,
pub channel_id: Uuid,
pub root_message_id: Uuid,
pub created_by: Uuid,
pub replies_count: i64,
pub participants_count: i64,
pub last_reply_message_id: Option<Uuid>,
pub last_reply_at: Option<DateTime<Utc>>,
pub resolved: bool,
pub resolved_by: Option<Uuid>,
pub resolved_at: Option<DateTime<Utc>>,
// ── Forum post specific ──
pub title: Option<String>,
pub tags: Vec<String>,
pub pinned: bool,
pub locked: bool,
pub rate_limit_per_user: Option<i32>,
pub auto_archive_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+73
View File
@@ -0,0 +1,73 @@
pub mod article_comments;
pub mod article_cross_posts;
pub mod article_reactions;
pub mod articles;
pub mod channel;
pub mod channel_categories;
pub mod channel_events;
pub mod channel_follows;
pub mod channel_invitations;
pub mod channel_member_roles;
pub mod channel_members;
pub mod channel_permission_overwrites;
pub mod channel_repo_links;
pub mod channel_slash_commands;
pub mod channel_stats;
pub mod channel_webhooks;
pub mod custom_emojis;
pub mod forum_tags;
pub mod im_integrations;
pub mod message;
pub mod message_attachments;
pub mod message_bookmarks;
pub mod message_drafts;
pub mod message_edit_history;
pub mod message_embeds;
pub mod message_mentions;
pub mod message_pins;
pub mod message_poll_options;
pub mod message_poll_votes;
pub mod message_polls;
pub mod message_reactions;
pub mod message_threads;
pub mod saved_messages;
pub mod stages;
pub mod thread_read_states;
pub mod voice_participants;
pub use article_comments::ArticleComment;
pub use article_cross_posts::ArticleCrossPost;
pub use article_reactions::ArticleReaction;
pub use articles::Article;
pub use channel::Channel;
pub use channel_categories::ChannelCategory;
pub use channel_events::ChannelEvent;
pub use channel_follows::ChannelFollow;
pub use channel_invitations::ChannelInvitation;
pub use channel_member_roles::ChannelMemberRole;
pub use channel_members::ChannelMember;
pub use channel_permission_overwrites::ChannelPermissionOverwrite;
pub use channel_repo_links::ChannelRepoLink;
pub use channel_slash_commands::ChannelSlashCommand;
pub use channel_stats::ChannelStats;
pub use channel_webhooks::ChannelWebhook;
pub use custom_emojis::CustomEmoji;
pub use forum_tags::ForumTag;
pub use im_integrations::ImIntegration;
pub use message::Message;
pub use message_attachments::MessageAttachment;
pub use message_bookmarks::MessageBookmark;
pub use message_drafts::MessageDraft;
pub use message_edit_history::MessageEditHistory;
pub use message_embeds::MessageEmbed;
pub use message_mentions::MessageMention;
pub use message_pins::MessagePin;
pub use message_poll_options::MessagePollOption;
pub use message_poll_votes::MessagePollVote;
pub use message_polls::MessagePoll;
pub use message_reactions::MessageReaction;
pub use message_threads::MessageThread;
pub use saved_messages::SavedMessage;
pub use stages::Stage;
pub use thread_read_states::ThreadReadState;
pub use voice_participants::VoiceParticipant;
+13
View File
@@ -0,0 +1,13 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct SavedMessage {
pub id: Uuid,
pub user_id: Uuid,
pub message_id: Uuid,
pub channel_id: Uuid,
pub note: Option<String>,
pub created_at: DateTime<Utc>,
}
+20
View File
@@ -0,0 +1,20 @@
use crate::models::common::StagePrivacyLevel;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Voice stage — similar to Discord Stage Channel.
/// Only one active stage instance per channel at a time.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Stage {
pub id: Uuid,
pub channel_id: Uuid,
pub topic: String,
pub privacy_level: StagePrivacyLevel,
pub discoverable: bool,
pub started_by: Uuid,
pub started_at: DateTime<Utc>,
pub ended_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ThreadReadState {
pub id: Uuid,
pub user_id: Uuid,
pub thread_id: Uuid,
pub channel_id: Uuid,
pub last_read_message_id: Option<Uuid>,
pub last_read_at: Option<DateTime<Utc>>,
pub updated_at: DateTime<Utc>,
}
+21
View File
@@ -0,0 +1,21 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
/// Real-time voice/video channel participant state.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct VoiceParticipant {
pub id: Uuid,
pub channel_id: Uuid,
pub user_id: Uuid,
pub session_id: Option<String>,
pub deafened: bool,
pub muted: bool,
pub self_deafened: bool,
pub self_muted: bool,
pub self_video: bool,
pub streaming: bool,
pub speaking: bool,
pub joined_at: DateTime<Utc>,
pub left_at: Option<DateTime<Utc>>,
}