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
+28
View File
@@ -0,0 +1,28 @@
use crate::models::common::{AgentType, Status, Visibility};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Agent {
pub id: Uuid,
pub owner_id: Uuid,
pub workspace_id: Option<Uuid>,
pub name: String,
pub slug: String,
pub description: Option<String>,
pub avatar_url: Option<String>,
pub agent_type: AgentType,
pub status: Status,
pub visibility: Visibility,
pub default_model_id: Option<Uuid>,
pub current_version_id: Option<Uuid>,
pub system_prompt: Option<String>,
pub tools: Vec<String>,
pub tags: Vec<String>,
pub enabled: bool,
pub last_run_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1,19 @@
use crate::models::common::EventType;
use crate::models::json_types::{AgentEventFilters, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentEventSubscription {
pub id: Uuid,
pub agent_id: Uuid,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub event_type: EventType,
pub filters: Option<TypedJson<AgentEventFilters>>,
pub enabled: bool,
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, Status, StepType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentExecutionStep {
pub id: Uuid,
pub execution_id: Uuid,
pub step_index: i32,
pub step_type: StepType,
pub name: String,
pub status: Status,
pub model_id: Option<Uuid>,
pub tool_name: Option<String>,
pub input: Option<JsonValue>,
pub output: Option<JsonValue>,
pub error_message: Option<String>,
pub token_input_count: Option<i32>,
pub token_output_count: Option<i32>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
+25
View File
@@ -0,0 +1,25 @@
use crate::models::common::{JsonValue, Status, TriggerType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentExecution {
pub id: Uuid,
pub agent_id: Uuid,
pub agent_version_id: Option<Uuid>,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub issue_id: Option<Uuid>,
pub pull_request_id: Option<Uuid>,
pub triggered_by: Option<Uuid>,
pub trigger_type: TriggerType,
pub status: Status,
pub input: Option<JsonValue>,
pub output: Option<JsonValue>,
pub error_message: Option<String>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use crate::models::common::{FeedbackType, JsonValue};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentFeedback {
pub id: Uuid,
pub agent_id: Uuid,
pub execution_id: Option<Uuid>,
pub user_id: Uuid,
pub rating: i32,
pub feedback_type: FeedbackType,
pub comment: Option<String>,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+22
View File
@@ -0,0 +1,22 @@
use crate::models::json_types::{AgentSchedulePayload, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentSchedule {
pub id: Uuid,
pub agent_id: Uuid,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub name: String,
pub cron_expr: String,
pub timezone: String,
pub payload: Option<TypedJson<AgentSchedulePayload>>,
pub enabled: bool,
pub last_run_at: Option<DateTime<Utc>>,
pub next_run_at: Option<DateTime<Utc>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+24
View File
@@ -0,0 +1,24 @@
use crate::models::json_types::{AgentVersionConfig, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentVersion {
pub id: Uuid,
pub agent_id: Uuid,
pub version: String,
pub name: Option<String>,
pub description: Option<String>,
pub model_id: Option<Uuid>,
pub system_prompt: String,
pub instructions: Option<String>,
pub tools: Vec<String>,
pub config: Option<TypedJson<AgentVersionConfig>>,
pub changelog: Option<String>,
pub stable: bool,
pub published_by: Uuid,
pub published_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use crate::models::common::{Permission, Role};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AgentWorkspaceBinding {
pub id: Uuid,
pub agent_id: Uuid,
pub workspace_id: Uuid,
pub repo_id: Option<Uuid>,
pub role: Role,
pub permissions: Vec<Permission>,
pub enabled: bool,
pub bound_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+17
View File
@@ -0,0 +1,17 @@
pub mod agent;
pub mod agent_event_subscriptions;
pub mod agent_execution_steps;
pub mod agent_executions;
pub mod agent_feedback;
pub mod agent_schedules;
pub mod agent_versions;
pub mod agent_workspace_bindings;
pub use agent::Agent;
pub use agent_event_subscriptions::AgentEventSubscription;
pub use agent_execution_steps::AgentExecutionStep;
pub use agent_executions::AgentExecution;
pub use agent_feedback::AgentFeedback;
pub use agent_schedules::AgentSchedule;
pub use agent_versions::AgentVersion;
pub use agent_workspace_bindings::AgentWorkspaceBinding;
+15
View File
@@ -0,0 +1,15 @@
use crate::models::json_types::{AiModelCapabilityConfig, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AiModelCapability {
pub id: Uuid,
pub ai_model_id: Uuid,
pub capability: String,
pub supported: bool,
pub config: Option<TypedJson<AiModelCapabilityConfig>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use crate::models::common::Status;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AiModelHealth {
pub id: Uuid,
pub ai_model_id: Uuid,
pub status: Status,
pub latency_ms: Option<i32>,
pub error_rate: Option<String>,
pub last_error: Option<String>,
pub checked_at: DateTime<Utc>,
pub created_at: DateTime<Utc>,
}
+19
View File
@@ -0,0 +1,19 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AiModelVersion {
pub id: Uuid,
pub ai_model_id: Uuid,
pub version: String,
pub provider_model_id: String,
pub context_window: Option<i32>,
pub max_output_tokens: Option<i32>,
pub changelog: Option<String>,
pub stable: bool,
pub deprecated: bool,
pub released_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+30
View File
@@ -0,0 +1,30 @@
use crate::models::common::{AiFeature, AiModelType, Modality, PricingUnit, Provider};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct AiModel {
pub id: Uuid,
pub provider: Provider,
pub model_id: String,
pub name: String,
pub description: Option<String>,
pub model_type: AiModelType,
pub family: Option<String>,
pub version: Option<String>,
pub context_window: Option<i32>,
pub max_output_tokens: Option<i32>,
pub input_modalities: Vec<Modality>,
pub output_modalities: Vec<Modality>,
pub supported_features: Vec<AiFeature>,
pub pricing_unit: Option<PricingUnit>,
pub input_price_per_unit: Option<String>,
pub output_price_per_unit: Option<String>,
pub enabled: bool,
pub deprecated: bool,
pub released_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
+9
View File
@@ -0,0 +1,9 @@
pub mod ai_model_capabilities;
pub mod ai_model_health;
pub mod ai_model_versions;
pub mod ai_models;
pub use ai_model_capabilities::AiModelCapability;
pub use ai_model_health::AiModelHealth;
pub use ai_model_versions::AiModelVersion;
pub use ai_models::AiModel;
+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>>,
}
+794
View File
@@ -0,0 +1,794 @@
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use sqlx::encode::IsNull;
use sqlx::error::BoxDynError;
use sqlx::postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef};
use sqlx::{Decode, Encode, Postgres, Type};
use std::fmt;
use std::str::FromStr;
pub type JsonValue = serde_json::Value;
macro_rules! string_enum {
(
$(#[$meta:meta])*
pub enum $name:ident {
$( $variant:ident => $value:literal ),+ $(,)?
}
) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, utoipa::ToSchema)]
pub enum $name {
$( $variant, )+
}
impl $name {
pub const fn as_str(self) -> &'static str {
match self {
$( Self::$variant => $value, )+
}
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for $name {
type Err = ();
fn from_str(value: &str) -> Result<Self, Self::Err> {
Ok(match value {
$( $value => Self::$variant, )+
_ => Self::Unknown,
})
}
}
impl Serialize for $name {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.as_str())
}
}
impl<'de> Deserialize<'de> for $name {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
Ok(value.parse().unwrap_or(Self::Unknown))
}
}
impl Type<Postgres> for $name {
fn type_info() -> PgTypeInfo {
<String as Type<Postgres>>::type_info()
}
fn compatible(ty: &PgTypeInfo) -> bool {
<String as Type<Postgres>>::compatible(ty)
}
}
impl<'r> Decode<'r, Postgres> for $name {
fn decode(value: PgValueRef<'r>) -> Result<Self, BoxDynError> {
let value = <String as Decode<Postgres>>::decode(value)?;
Ok(value.parse().unwrap_or(Self::Unknown))
}
}
impl<'q> Encode<'q, Postgres> for $name {
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> Result<IsNull, BoxDynError> {
<&str as Encode<Postgres>>::encode_by_ref(&self.as_str(), buf)
}
fn size_hint(&self) -> usize {
<&str as Encode<Postgres>>::size_hint(&self.as_str())
}
}
impl PgHasArrayType for $name {
fn array_type_info() -> PgTypeInfo {
<String as PgHasArrayType>::array_type_info()
}
fn array_compatible(ty: &PgTypeInfo) -> bool {
<String as PgHasArrayType>::array_compatible(ty)
}
}
};
}
string_enum! {
/// Cross-domain lifecycle/status values persisted as snake_case text.
pub enum Status {
Active => "active",
Inactive => "inactive",
Enabled => "enabled",
Disabled => "disabled",
Pending => "pending",
Queued => "queued",
Running => "running",
Processing => "processing",
Completed => "completed",
Success => "success",
Failed => "failed",
Error => "error",
Canceled => "canceled",
Cancelled => "cancelled",
Draft => "draft",
Open => "open",
Closed => "closed",
Merged => "merged",
Archived => "archived",
Deleted => "deleted",
Revoked => "revoked",
Expired => "expired",
Accepted => "accepted",
Rejected => "rejected",
Approved => "approved",
Healthy => "healthy",
Degraded => "degraded",
Unhealthy => "unhealthy",
Online => "online",
Offline => "offline",
Added => "added",
Modified => "modified",
Removed => "removed",
Renamed => "renamed",
Copied => "copied",
Unknown => "unknown",
}
}
string_enum! {
pub enum State {
Open => "open",
Closed => "closed",
Merged => "merged",
Draft => "draft",
Pending => "pending",
Queued => "queued",
Running => "running",
Success => "success",
Failure => "failure",
Failed => "failed",
Error => "error",
Skipped => "skipped",
Blocked => "blocked",
Clean => "clean",
Dirty => "dirty",
Unknown => "unknown",
}
}
string_enum! {
pub enum Role {
Owner => "owner",
Admin => "admin",
Maintainer => "maintainer",
Member => "member",
Guest => "guest",
Viewer => "viewer",
Editor => "editor",
Contributor => "contributor",
Moderator => "moderator",
User => "user",
Bot => "bot",
Agent => "agent",
Assistant => "assistant",
System => "system",
Author => "author",
Reviewer => "reviewer",
Assignee => "assignee",
Unknown => "unknown",
}
}
string_enum! {
pub enum Visibility {
Public => "public",
Private => "private",
Internal => "internal",
Workspace => "workspace",
Protected => "protected",
Hidden => "hidden",
Secret => "secret",
Unknown => "unknown",
}
}
string_enum! {
pub enum Priority {
None => "none",
Low => "low",
Medium => "medium",
High => "high",
Critical => "critical",
Urgent => "urgent",
Unknown => "unknown",
}
}
string_enum! {
pub enum MessageRole {
System => "system",
User => "user",
Assistant => "assistant",
Agent => "agent",
Tool => "tool",
Developer => "developer",
Unknown => "unknown",
}
}
string_enum! {
pub enum MessageType {
Text => "text",
Markdown => "markdown",
Html => "html",
System => "system",
Event => "event",
File => "file",
Image => "image",
Code => "code",
ToolCall => "tool_call",
ToolResult => "tool_result",
Audio => "audio",
Video => "video",
Unknown => "unknown",
}
}
string_enum! {
pub enum ContentFormat {
PlainText => "plain_text",
Markdown => "markdown",
Html => "html",
Json => "json",
Unknown => "unknown",
}
}
string_enum! {
pub enum EventType {
Created => "created",
Updated => "updated",
Deleted => "deleted",
Closed => "closed",
Reopened => "reopened",
Assigned => "assigned",
Unassigned => "unassigned",
Labeled => "labeled",
Unlabeled => "unlabeled",
Commented => "commented",
Mentioned => "mentioned",
Pushed => "pushed",
Merged => "merged",
Reviewed => "reviewed",
Archived => "archived",
Restored => "restored",
Joined => "joined",
Left => "left",
Invited => "invited",
Accepted => "accepted",
Revoked => "revoked",
DraftReady => "draft_ready",
Unknown => "unknown",
}
}
string_enum! {
pub enum TargetType {
User => "user",
Workspace => "workspace",
Repo => "repo",
Issue => "issue",
PullRequest => "pull_request",
Channel => "channel",
Message => "message",
Conversation => "conversation",
Agent => "agent",
AiModel => "ai_model",
Commit => "commit",
Branch => "branch",
Release => "release",
Unknown => "unknown",
}
}
string_enum! {
pub enum NotificationType {
Mention => "mention",
Assignment => "assignment",
Review => "review",
Comment => "comment",
Build => "build",
Security => "security",
Billing => "billing",
System => "system",
Digest => "digest",
Unknown => "unknown",
}
}
string_enum! {
pub enum DeliveryChannel {
Email => "email",
Web => "web",
Push => "push",
Slack => "slack",
Discord => "discord",
Webhook => "webhook",
Sms => "sms",
Unknown => "unknown",
}
}
string_enum! {
pub enum SubscriptionLevel {
All => "all",
Participating => "participating",
Mention => "mention",
Watch => "watch",
Ignore => "ignore",
None => "none",
Custom => "custom",
Unknown => "unknown",
}
}
string_enum! {
pub enum Provider {
Github => "github",
Gitlab => "gitlab",
Google => "google",
Slack => "slack",
Discord => "discord",
Email => "email",
Web => "web",
Push => "push",
Openai => "openai",
Anthropic => "anthropic",
Gemini => "gemini",
Ollama => "ollama",
Azure => "azure",
Aws => "aws",
Stripe => "stripe",
Unknown => "unknown",
}
}
string_enum! {
pub enum AgentType {
Assistant => "assistant",
Automation => "automation",
Reviewer => "reviewer",
Triage => "triage",
Scheduler => "scheduler",
Bot => "bot",
Unknown => "unknown",
}
}
string_enum! {
pub enum AiModelType {
Chat => "chat",
Completion => "completion",
Embedding => "embedding",
Reranker => "reranker",
Image => "image",
Audio => "audio",
Multimodal => "multimodal",
Moderation => "moderation",
Unknown => "unknown",
}
}
string_enum! {
pub enum ConversationType {
Chat => "chat",
Issue => "issue",
PullRequest => "pull_request",
Review => "review",
Agent => "agent",
Support => "support",
Incident => "incident",
Unknown => "unknown",
}
}
string_enum! {
pub enum StepType {
Model => "model",
Tool => "tool",
Reasoning => "reasoning",
Retrieval => "retrieval",
Planning => "planning",
Execution => "execution",
Validation => "validation",
Unknown => "unknown",
}
}
string_enum! {
pub enum TriggerType {
Manual => "manual",
Schedule => "schedule",
Webhook => "webhook",
Event => "event",
Issue => "issue",
PullRequest => "pull_request",
Push => "push",
Message => "message",
Unknown => "unknown",
}
}
string_enum! {
pub enum RelationType {
Closes => "closes",
Fixes => "fixes",
References => "references",
Blocks => "blocks",
Duplicates => "duplicates",
Related => "related",
Implements => "implements",
Mentions => "mentions",
Resolves => "resolves",
Unknown => "unknown",
}
}
string_enum! {
pub enum RequestType {
Join => "join",
Invite => "invite",
Access => "access",
Approval => "approval",
Billing => "billing",
Delete => "delete",
Transfer => "transfer",
Unknown => "unknown",
}
}
string_enum! {
pub enum DeviceType {
Desktop => "desktop",
Laptop => "laptop",
Mobile => "mobile",
Tablet => "tablet",
Browser => "browser",
Cli => "cli",
Api => "api",
Unknown => "unknown",
}
}
string_enum! {
pub enum KeyType {
Rsa => "rsa",
Ed25519 => "ed25519",
Ecdsa => "ecdsa",
Dsa => "dsa",
Unknown => "unknown",
}
}
string_enum! {
pub enum PasswordAlgorithm {
Argon2id => "argon2id",
Bcrypt => "bcrypt",
Scrypt => "scrypt",
Pbkdf2 => "pbkdf2",
Unknown => "unknown",
}
}
string_enum! {
pub enum DigestFrequency {
Never => "never",
Daily => "daily",
Weekly => "weekly",
Monthly => "monthly",
Realtime => "realtime",
Unknown => "unknown",
}
}
string_enum! {
pub enum GitService {
Local => "local",
Gitea => "gitea",
Gitlab => "gitlab",
Github => "github",
Unknown => "unknown",
}
}
string_enum! {
pub enum FeedbackType {
Bug => "bug",
Quality => "quality",
Safety => "safety",
Performance => "performance",
Suggestion => "suggestion",
Other => "other",
Unknown => "unknown",
}
}
string_enum! {
pub enum ParticipantType {
User => "user",
Agent => "agent",
Bot => "bot",
System => "system",
Unknown => "unknown",
}
}
string_enum! {
pub enum SummaryType {
Short => "short",
Detailed => "detailed",
Rolling => "rolling",
Final => "final",
ActionItems => "action_items",
Unknown => "unknown",
}
}
string_enum! {
pub enum LinkType {
Primary => "primary",
Mirror => "mirror",
Notification => "notification",
Automation => "automation",
Related => "related",
Unknown => "unknown",
}
}
string_enum! {
pub enum ChannelType {
Public => "public",
Private => "private",
Direct => "direct",
Group => "group",
Repo => "repo",
System => "system",
Unknown => "unknown",
}
}
string_enum! {
pub enum MergeStrategyKind {
Merge => "merge",
Squash => "squash",
Rebase => "rebase",
FastForward => "fast_forward",
Unknown => "unknown",
}
}
string_enum! {
pub enum PricingUnit {
Token => "token",
OneKTokens => "1k_tokens",
OneMTokens => "1m_tokens",
Request => "request",
Image => "image",
Minute => "minute",
Unknown => "unknown",
}
}
string_enum! {
pub enum Theme {
System => "system",
Light => "light",
Dark => "dark",
Unknown => "unknown",
}
}
string_enum! {
pub enum ColorScheme {
System => "system",
Light => "light",
Dark => "dark",
HighContrast => "high_contrast",
Unknown => "unknown",
}
}
string_enum! {
pub enum Density {
Compact => "compact",
Comfortable => "comfortable",
Spacious => "spacious",
Unknown => "unknown",
}
}
string_enum! {
pub enum FontSize {
Small => "small",
Medium => "medium",
Large => "large",
ExtraLarge => "extra_large",
Unknown => "unknown",
}
}
string_enum! {
pub enum Scope {
Read => "read",
Write => "write",
Admin => "admin",
RepoRead => "repo:read",
RepoWrite => "repo:write",
IssueRead => "issue:read",
IssueWrite => "issue:write",
PullRequestRead => "pull_request:read",
PullRequestWrite => "pull_request:write",
WorkspaceRead => "workspace:read",
WorkspaceWrite => "workspace:write",
UserRead => "user:read",
UserWrite => "user:write",
Unknown => "unknown",
}
}
string_enum! {
pub enum Permission {
Read => "read",
Write => "write",
Admin => "admin",
Execute => "execute",
ManageMembers => "manage_members",
ManageSettings => "manage_settings",
ManageWebhooks => "manage_webhooks",
ManageBilling => "manage_billing",
Unknown => "unknown",
}
}
string_enum! {
pub enum Modality {
Text => "text",
Image => "image",
Audio => "audio",
Video => "video",
File => "file",
Unknown => "unknown",
}
}
string_enum! {
pub enum AiFeature {
Streaming => "streaming",
ToolCalling => "tool_calling",
JsonMode => "json_mode",
Vision => "vision",
Audio => "audio",
Reasoning => "reasoning",
Caching => "caching",
Unknown => "unknown",
}
}
string_enum! {
pub enum PresenceStatus {
Online => "online",
Idle => "idle",
Dnd => "dnd",
Invisible => "invisible",
Offline => "offline",
Away => "away",
Unknown => "unknown",
}
}
string_enum! {
pub enum ActivityType {
Playing => "playing",
Listening => "listening",
Watching => "watching",
Streaming => "streaming",
Competing => "competing",
Custom => "custom",
Unknown => "unknown",
}
}
string_enum! {
pub enum SyncDirection {
Inbound => "inbound",
Outbound => "outbound",
Bidirectional => "bidirectional",
Unknown => "unknown",
}
}
string_enum! {
pub enum OverwriteTarget {
User => "user",
Role => "role",
Unknown => "unknown",
}
}
string_enum! {
pub enum EmbedType {
Link => "link",
Article => "article",
Image => "image",
Video => "video",
Rich => "rich",
Unknown => "unknown",
}
}
string_enum! {
pub enum ChannelKind {
Text => "text",
Voice => "voice",
Stage => "stage",
Forum => "forum",
Announcement => "announcement",
Unknown => "unknown",
}
}
string_enum! {
pub enum ForumSortOrder {
LatestActivity => "latest_activity",
CreationDate => "creation_date",
Unknown => "unknown",
}
}
string_enum! {
pub enum ForumLayout {
Default => "default",
ListView => "list_view",
GalleryView => "gallery_view",
Unknown => "unknown",
}
}
string_enum! {
pub enum StagePrivacyLevel {
Public => "public",
GuildOnly => "guild_only",
Unknown => "unknown",
}
}
string_enum! {
pub enum PollLayout {
Default => "default",
SingleChoice => "single_choice",
MultipleChoice => "multiple_choice",
Unknown => "unknown",
}
}
string_enum! {
pub enum ArticleStatus {
Draft => "draft",
Scheduled => "scheduled",
Published => "published",
Archived => "archived",
Unpublished => "unpublished",
Unknown => "unknown",
}
}
+29
View File
@@ -0,0 +1,29 @@
use crate::models::common::{ConversationType, JsonValue, Status, Visibility};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Conversation {
pub id: Uuid,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub issue_id: Option<Uuid>,
pub pull_request_id: Option<Uuid>,
pub agent_id: Option<Uuid>,
pub created_by: Uuid,
pub title: String,
pub description: Option<String>,
pub conversation_type: ConversationType,
pub status: Status,
pub visibility: Visibility,
pub pinned: bool,
pub archived: bool,
pub metadata: Option<JsonValue>,
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>>,
}
@@ -0,0 +1,21 @@
use crate::models::json_types::{ConversationAttachmentMetadata, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ConversationAttachment {
pub id: Uuid,
pub conversation_id: Uuid,
pub message_id: Option<Uuid>,
pub file_id: Option<Uuid>,
pub uploaded_by: Option<Uuid>,
pub name: String,
pub content_type: Option<String>,
pub size_bytes: i64,
pub storage_path: Option<String>,
pub url: Option<String>,
pub metadata: Option<TypedJson<ConversationAttachmentMetadata>>,
pub created_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
@@ -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 ConversationBookmark {
pub id: Uuid,
pub conversation_id: Uuid,
pub message_id: Option<Uuid>,
pub user_id: Uuid,
pub title: Option<String>,
pub note: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,26 @@
use crate::models::common::{ContentFormat, JsonValue, MessageRole, MessageType, Status};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ConversationMessage {
pub id: Uuid,
pub conversation_id: Uuid,
pub parent_message_id: Option<Uuid>,
pub author_id: Option<Uuid>,
pub agent_id: Option<Uuid>,
pub ai_model_id: Option<Uuid>,
pub role: MessageRole,
pub message_type: MessageType,
pub content: String,
pub content_format: ContentFormat,
pub status: Status,
pub metadata: Option<JsonValue>,
pub token_input_count: Option<i32>,
pub token_output_count: Option<i32>,
pub edited_at: Option<DateTime<Utc>>,
pub deleted_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,22 @@
use crate::models::common::{ParticipantType, Role, Status};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ConversationParticipant {
pub id: Uuid,
pub conversation_id: Uuid,
pub user_id: Option<Uuid>,
pub agent_id: Option<Uuid>,
pub role: Role,
pub participant_type: ParticipantType,
pub status: Status,
pub muted: 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,20 @@
use crate::models::common::{JsonValue, SummaryType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ConversationSummary {
pub id: Uuid,
pub conversation_id: Uuid,
pub ai_model_id: Option<Uuid>,
pub generated_by: Option<Uuid>,
pub from_message_id: Option<Uuid>,
pub to_message_id: Option<Uuid>,
pub summary_type: SummaryType,
pub content: String,
pub token_count: Option<i32>,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,22 @@
use crate::models::common::{JsonValue, Status};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct ConversationToolCall {
pub id: Uuid,
pub conversation_id: Uuid,
pub message_id: Uuid,
pub agent_id: Option<Uuid>,
pub tool_name: String,
pub call_id: Option<String>,
pub status: Status,
pub arguments: Option<JsonValue>,
pub result: Option<JsonValue>,
pub error_message: Option<String>,
pub started_at: Option<DateTime<Utc>>,
pub finished_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+15
View File
@@ -0,0 +1,15 @@
pub mod conversation;
pub mod conversation_attachments;
pub mod conversation_bookmarks;
pub mod conversation_messages;
pub mod conversation_participants;
pub mod conversation_summaries;
pub mod conversation_tool_calls;
pub use conversation::Conversation;
pub use conversation_attachments::ConversationAttachment;
pub use conversation_bookmarks::ConversationBookmark;
pub use conversation_messages::ConversationMessage;
pub use conversation_participants::ConversationParticipant;
pub use conversation_summaries::ConversationSummary;
pub use conversation_tool_calls::ConversationToolCall;
+130
View File
@@ -0,0 +1,130 @@
use crate::config::AppConfig;
use crate::error::AppResult;
use sqlx::PgPool;
use sqlx::postgres::PgPoolOptions;
use std::ops::Deref;
use std::time::Duration;
pub trait PoolProvider: Clone + Send + Sync + 'static {
fn read(&self) -> &PgPool;
fn write(&self) -> &PgPool;
}
#[derive(Clone, Debug)]
pub struct AppDatabase {
primary: PgPool,
replica: Option<PgPool>,
}
impl AppDatabase {
pub fn reader(&self) -> &PgPool {
self.replica.as_ref().unwrap_or(&self.primary)
}
pub fn writer(&self) -> &PgPool {
&self.primary
}
pub fn new(primary: PgPool) -> Self {
Self {
primary,
replica: None,
}
}
pub fn with_replica(primary: PgPool, replica: PgPool) -> Self {
Self {
primary,
replica: Some(replica),
}
}
pub async fn from_config(config: &AppConfig) -> AppResult<Self> {
let primary_url = config.database_url()?;
let primary = Self::build_pool(&primary_url, config, false).await?;
if config.database_read_write_split()? {
let replicas = config.database_read_replicas()?;
if let Some(replica_url) = replicas.first() {
let replica = Self::build_pool(replica_url, config, true).await?;
return Ok(Self {
primary,
replica: Some(replica),
});
}
}
Ok(Self {
primary,
replica: None,
})
}
async fn build_pool(url: &str, config: &AppConfig, is_replica: bool) -> AppResult<PgPool> {
let (max_conn, min_conn, idle_timeout, max_lifetime, conn_timeout) = if is_replica {
(
config.database_replica_max_connections()?,
config.database_replica_min_connections()?,
config.database_replica_idle_timeout()?,
config.database_replica_max_lifetime()?,
config.database_replica_connection_timeout()?,
)
} else {
(
config.database_max_connections()?,
config.database_min_connections()?,
config.database_idle_timeout()?,
config.database_max_lifetime()?,
config.database_connection_timeout()?,
)
};
Ok(PgPoolOptions::new()
.max_connections(max_conn)
.min_connections(min_conn)
.idle_timeout(Duration::from_secs(idle_timeout))
.max_lifetime(Duration::from_secs(max_lifetime))
.acquire_timeout(Duration::from_secs(conn_timeout))
.connect(url)
.await?)
}
pub fn has_replica(&self) -> bool {
self.replica.is_some()
}
pub async fn close(&self) {
self.primary.close().await;
if let Some(replica) = &self.replica {
replica.close().await;
}
}
}
impl PoolProvider for AppDatabase {
fn read(&self) -> &PgPool {
self.replica.as_ref().unwrap_or(&self.primary)
}
fn write(&self) -> &PgPool {
&self.primary
}
}
impl Deref for AppDatabase {
type Target = PgPool;
fn deref(&self) -> &Self::Target {
&self.primary
}
}
impl PoolProvider for PgPool {
fn read(&self) -> &PgPool {
self
}
fn write(&self) -> &PgPool {
self
}
}
+25
View File
@@ -0,0 +1,25 @@
use crate::models::common::{Priority, State, Visibility};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Issue {
pub id: Uuid,
pub workspace_id: Uuid,
pub author_id: Uuid,
pub number: i64,
pub title: String,
pub body: Option<String>,
pub state: State,
pub priority: Priority,
pub visibility: Visibility,
pub locked: bool,
pub milestone_id: Option<Uuid>,
pub closed_by: Option<Uuid>,
pub closed_at: Option<DateTime<Utc>>,
pub due_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<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 IssueAssignee {
pub id: Uuid,
pub issue_id: Uuid,
pub assignee_id: Uuid,
pub assigned_by: Option<Uuid>,
pub created_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 IssueComment {
pub id: Uuid,
pub issue_id: Uuid,
pub author_id: Uuid,
pub body: String,
pub reply_to_comment_id: Option<Uuid>,
pub edited_at: Option<DateTime<Utc>>,
pub deleted_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use crate::models::common::RelationType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueCommitRelation {
pub id: Uuid,
pub issue_id: Uuid,
pub repo_id: Uuid,
pub push_commit_id: Option<Uuid>,
pub commit_sha: String,
pub relation_type: RelationType,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use crate::models::common::{EventType, JsonValue};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueEvent {
pub id: Uuid,
pub issue_id: Uuid,
pub actor_id: Option<Uuid>,
pub event_type: EventType,
pub old_value: Option<JsonValue>,
pub new_value: Option<JsonValue>,
pub metadata: Option<JsonValue>,
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 IssueLabelRelation {
pub id: Uuid,
pub issue_id: Uuid,
pub label_id: Uuid,
pub created_by: Option<Uuid>,
pub created_at: 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 IssueLabel {
pub id: Uuid,
pub repo_id: Uuid,
pub name: String,
pub color: String,
pub description: Option<String>,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use crate::models::common::State;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueMilestone {
pub id: Uuid,
pub repo_id: Uuid,
pub title: String,
pub description: Option<String>,
pub state: State,
pub due_at: Option<DateTime<Utc>>,
pub closed_at: Option<DateTime<Utc>>,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use crate::models::common::RelationType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssuePrRelation {
pub id: Uuid,
pub issue_id: Uuid,
pub pull_request_id: Uuid,
pub relation_type: RelationType,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
}
+43
View File
@@ -0,0 +1,43 @@
use sqlx::PgPool;
use uuid::Uuid;
use super::issue::Issue;
impl Issue {
pub async fn find_by_id(pool: &PgPool, id: Uuid) -> Result<Option<Self>, sqlx::Error> {
sqlx::query_as::<_, Issue>(
"SELECT id, workspace_id, author_id, number, title, body, state, priority, visibility, \
locked, milestone_id, closed_by, closed_at, due_at, created_at, updated_at, deleted_at \
FROM issue WHERE id = $1 AND deleted_at IS NULL",
)
.bind(id)
.fetch_optional(pool)
.await
}
pub async fn find_by_number(
pool: &PgPool,
workspace_id: Uuid,
number: i64,
) -> Result<Option<Self>, sqlx::Error> {
sqlx::query_as::<_, Issue>(
"SELECT id, workspace_id, author_id, number, title, body, state, priority, visibility, \
locked, milestone_id, closed_by, closed_at, due_at, created_at, updated_at, deleted_at \
FROM issue WHERE workspace_id = $1 AND number = $2 AND deleted_at IS NULL",
)
.bind(workspace_id)
.bind(number)
.fetch_optional(pool)
.await
}
pub async fn next_number<'e, E>(executor: E, workspace_id: Uuid) -> Result<i64, sqlx::Error>
where
E: sqlx::PgExecutor<'e>,
{
sqlx::query_scalar("SELECT COALESCE(MAX(number), 0) + 1 FROM issue WHERE workspace_id = $1")
.bind(workspace_id)
.fetch_one(executor)
.await
}
}
+15
View File
@@ -0,0 +1,15 @@
use crate::models::common::TargetType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueReaction {
pub id: Uuid,
pub issue_id: Uuid,
pub user_id: Uuid,
pub content: String,
pub target_type: TargetType,
pub target_id: Option<Uuid>,
pub created_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 IssueReminder {
pub id: Uuid,
pub issue_id: Uuid,
pub user_id: Uuid,
pub remind_at: DateTime<Utc>,
pub message: Option<String>,
pub sent_at: Option<DateTime<Utc>>,
pub canceled_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+14
View File
@@ -0,0 +1,14 @@
use crate::models::common::RelationType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueRepoRelation {
pub id: Uuid,
pub issue_id: Uuid,
pub repo_id: Uuid,
pub relation_type: RelationType,
pub created_by: Option<Uuid>,
pub created_at: 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 IssueStats {
pub issue_id: Uuid,
pub comments_count: i64,
pub reactions_count: i64,
pub assignees_count: i64,
pub labels_count: i64,
pub subscribers_count: i64,
pub last_commented_at: Option<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 IssueSubscriber {
pub id: Uuid,
pub issue_id: Uuid,
pub user_id: Uuid,
pub reason: String,
pub muted: bool,
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;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct IssueTemplate {
pub id: Uuid,
pub repo_id: Uuid,
pub name: String,
pub description: Option<String>,
pub title_template: Option<String>,
pub body_template: String,
pub labels: Vec<String>,
pub active: bool,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+32
View File
@@ -0,0 +1,32 @@
pub mod issue;
pub mod issue_assignees;
pub mod issue_comments;
pub mod issue_commit_relations;
pub mod issue_events;
pub mod issue_label_relations;
pub mod issue_labels;
pub mod issue_milestones;
pub mod issue_pr_relations;
pub mod issue_queries;
pub mod issue_reaction;
pub mod issue_reminder;
pub mod issue_repo_relations;
pub mod issue_stats;
pub mod issue_subscribers;
pub mod issue_templates;
pub use issue::Issue;
pub use issue_assignees::IssueAssignee;
pub use issue_comments::IssueComment;
pub use issue_commit_relations::IssueCommitRelation;
pub use issue_events::IssueEvent;
pub use issue_label_relations::IssueLabelRelation;
pub use issue_labels::IssueLabel;
pub use issue_milestones::IssueMilestone;
pub use issue_pr_relations::IssuePrRelation;
pub use issue_reaction::IssueReaction;
pub use issue_reminder::IssueReminder;
pub use issue_repo_relations::IssueRepoRelation;
pub use issue_stats::IssueStats;
pub use issue_subscribers::IssueSubscriber;
pub use issue_templates::IssueTemplate;
+94
View File
@@ -0,0 +1,94 @@
use crate::models::common::{
AiFeature, EventType, JsonValue, Modality, Permission, Priority, Scope, Status, TargetType,
};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use uuid::Uuid;
pub type TypedJson<T> = sqlx::types::Json<T>;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ModelParameters {
pub temperature: Option<String>,
pub top_p: Option<String>,
pub max_tokens: Option<i32>,
pub stop_sequences: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct RetryPolicy {
pub max_attempts: Option<i32>,
pub initial_backoff_ms: Option<i32>,
pub max_backoff_ms: Option<i32>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct AgentVersionConfig {
pub parameters: Option<ModelParameters>,
pub retry: Option<RetryPolicy>,
pub timeout_seconds: Option<i32>,
pub parallel_tool_calls: Option<bool>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct AgentEventFilters {
pub event_actions: Vec<EventType>,
pub branch_patterns: Vec<String>,
pub path_patterns: Vec<String>,
pub label_names: Vec<String>,
pub actor_ids: Vec<Uuid>,
pub include_bots: Option<bool>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct AgentSchedulePayload {
pub target_type: Option<TargetType>,
pub target_id: Option<Uuid>,
pub variables: BTreeMap<String, JsonValue>,
pub dry_run: Option<bool>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct AiModelCapabilityConfig {
pub input_modalities: Vec<Modality>,
pub output_modalities: Vec<Modality>,
pub supported_features: Vec<AiFeature>,
pub max_input_tokens: Option<i32>,
pub max_output_tokens: Option<i32>,
pub limits: BTreeMap<String, JsonValue>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default, utoipa::ToSchema)]
pub struct WorkspaceIntegrationConfig {
pub scopes: Vec<Scope>,
pub permissions: Vec<Permission>,
pub repo_ids: Vec<Uuid>,
pub channel_ids: Vec<Uuid>,
pub callback_url: Option<String>,
pub settings: BTreeMap<String, JsonValue>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default, utoipa::ToSchema)]
pub struct NotificationMetadata {
pub source: Option<String>,
pub severity: Option<Priority>,
pub dedupe_key: Option<String>,
pub template_data: BTreeMap<String, JsonValue>,
pub extra: BTreeMap<String, JsonValue>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ConversationAttachmentMetadata {
pub checksum_sha256: Option<String>,
pub width: Option<i32>,
pub height: Option<i32>,
pub duration_ms: Option<i64>,
pub preview_url: Option<String>,
pub virus_scan_status: Option<Status>,
pub extra: BTreeMap<String, JsonValue>,
}
+14
View File
@@ -0,0 +1,14 @@
pub mod agents;
pub mod ais;
pub mod channels;
pub mod common;
pub mod conversations;
pub mod db;
pub mod issues;
pub mod json_types;
pub mod notifications;
pub mod prs;
pub mod repos;
pub mod users;
pub mod wiki;
pub mod workspaces;
+11
View File
@@ -0,0 +1,11 @@
pub mod notification;
pub mod notification_blocks;
pub mod notification_deliveries;
pub mod notification_subscriptions;
pub mod notification_templates;
pub use notification::Notification;
pub use notification_blocks::NotificationBlock;
pub use notification_deliveries::NotificationDelivery;
pub use notification_subscriptions::NotificationSubscription;
pub use notification_templates::NotificationTemplate;
+31
View File
@@ -0,0 +1,31 @@
use crate::models::common::{NotificationType, Priority, TargetType};
use crate::models::json_types::{NotificationMetadata, TypedJson};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct Notification {
pub id: Uuid,
pub user_id: Uuid,
pub actor_id: Option<Uuid>,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub issue_id: Option<Uuid>,
pub pull_request_id: Option<Uuid>,
pub channel_id: Option<Uuid>,
pub message_id: Option<Uuid>,
pub notification_type: NotificationType,
pub title: String,
pub body: Option<String>,
pub target_type: Option<TargetType>,
pub target_id: Option<Uuid>,
pub action_url: Option<String>,
pub priority: Priority,
pub read_at: Option<DateTime<Utc>>,
pub dismissed_at: Option<DateTime<Utc>>,
pub metadata: Option<TypedJson<NotificationMetadata>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub deleted_at: Option<DateTime<Utc>>,
}
@@ -0,0 +1,20 @@
use crate::models::common::{DeliveryChannel, NotificationType, TargetType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct NotificationBlock {
pub id: Uuid,
pub user_id: Uuid,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub target_type: TargetType,
pub target_id: Option<Uuid>,
pub notification_type: Option<NotificationType>,
pub channel: Option<DeliveryChannel>,
pub reason: Option<String>,
pub expires_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,24 @@
use crate::models::common::{DeliveryChannel, Provider, Status};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct NotificationDelivery {
pub id: Uuid,
pub notification_id: Uuid,
pub user_id: Uuid,
pub channel: DeliveryChannel,
pub destination: Option<String>,
pub status: Status,
pub provider: Option<Provider>,
pub provider_message_id: Option<String>,
pub attempts: i32,
pub last_error: Option<String>,
pub scheduled_at: Option<DateTime<Utc>>,
pub sent_at: Option<DateTime<Utc>>,
pub delivered_at: Option<DateTime<Utc>>,
pub failed_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,21 @@
use crate::models::common::{EventType, SubscriptionLevel, TargetType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct NotificationSubscription {
pub id: Uuid,
pub user_id: Uuid,
pub workspace_id: Option<Uuid>,
pub repo_id: Option<Uuid>,
pub target_type: TargetType,
pub target_id: Option<Uuid>,
pub event_types: Vec<EventType>,
pub channels: Vec<String>,
pub level: SubscriptionLevel,
pub muted: bool,
pub muted_until: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
@@ -0,0 +1,21 @@
use crate::models::common::{DeliveryChannel, NotificationType};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct NotificationTemplate {
pub id: Uuid,
pub key: String,
pub notification_type: NotificationType,
pub channel: DeliveryChannel,
pub locale: String,
pub subject_template: Option<String>,
pub title_template: String,
pub body_template: String,
pub action_text_template: Option<String>,
pub enabled: bool,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+30
View File
@@ -0,0 +1,30 @@
pub mod pr_assignees;
pub mod pr_check_runs;
pub mod pr_commits;
pub mod pr_events;
pub mod pr_files;
pub mod pr_label_relations;
pub mod pr_labels;
pub mod pr_merge_strategy;
pub mod pr_reactions;
pub mod pr_review;
pub mod pr_review_comment;
pub mod pr_status;
pub mod pr_subscriptions;
pub mod pull_request;
pub mod pull_request_queries;
pub use pr_assignees::PrAssignee;
pub use pr_check_runs::PrCheckRun;
pub use pr_commits::PrCommit;
pub use pr_events::PrEvent;
pub use pr_files::PrFile;
pub use pr_label_relations::PrLabelRelation;
pub use pr_labels::PrLabel;
pub use pr_merge_strategy::PrMergeStrategy;
pub use pr_reactions::PrReaction;
pub use pr_review::PrReview;
pub use pr_review_comment::PrReviewComment;
pub use pr_status::PrStatus;
pub use pr_subscriptions::PrSubscription;
pub use pull_request::PullRequest;
+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 PrAssignee {
pub id: Uuid,
pub pull_request_id: Uuid,
pub assignee_id: Uuid,
pub assigned_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
}
+20
View File
@@ -0,0 +1,20 @@
use crate::models::common::Status;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrCheckRun {
pub id: Uuid,
pub pull_request_id: Uuid,
pub commit_sha: String,
pub name: String,
pub status: Status,
pub conclusion: Option<Status>,
pub details_url: Option<String>,
pub external_id: Option<String>,
pub started_at: Option<DateTime<Utc>>,
pub completed_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: 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 PrCommit {
pub id: Uuid,
pub pull_request_id: Uuid,
pub repo_id: Uuid,
pub commit_sha: String,
pub position: i32,
pub authored_at: Option<DateTime<Utc>>,
pub committed_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
}
+16
View File
@@ -0,0 +1,16 @@
use crate::models::common::{EventType, JsonValue};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrEvent {
pub id: Uuid,
pub pull_request_id: Uuid,
pub actor_id: Option<Uuid>,
pub event_type: EventType,
pub old_value: Option<JsonValue>,
pub new_value: Option<JsonValue>,
pub metadata: Option<JsonValue>,
pub created_at: DateTime<Utc>,
}
+19
View File
@@ -0,0 +1,19 @@
use crate::models::common::Status;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrFile {
pub id: Uuid,
pub pull_request_id: Uuid,
pub path: String,
pub old_path: Option<String>,
pub status: Status,
pub additions: i32,
pub deletions: i32,
pub changes: i32,
pub patch: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_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 PrLabelRelation {
pub id: Uuid,
pub pull_request_id: Uuid,
pub label_id: Uuid,
pub created_by: Option<Uuid>,
pub created_at: 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 PrLabel {
pub id: Uuid,
pub repo_id: Uuid,
pub name: String,
pub color: String,
pub description: Option<String>,
pub created_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+18
View File
@@ -0,0 +1,18 @@
use crate::models::common::MergeStrategyKind;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrMergeStrategy {
pub pull_request_id: Uuid,
pub strategy: MergeStrategyKind,
pub auto_merge: bool,
pub squash_title: Option<String>,
pub squash_message: Option<String>,
pub delete_source_branch: bool,
pub merge_when_checks_pass: bool,
pub selected_by: Option<Uuid>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+15
View File
@@ -0,0 +1,15 @@
use crate::models::common::TargetType;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrReaction {
pub id: Uuid,
pub pull_request_id: Uuid,
pub user_id: Uuid,
pub content: String,
pub target_type: TargetType,
pub target_id: Option<Uuid>,
pub created_at: DateTime<Utc>,
}
+19
View File
@@ -0,0 +1,19 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrReview {
pub id: Uuid,
pub pull_request_id: Uuid,
pub author_id: Uuid,
pub state: String,
pub body: Option<String>,
pub commit_sha: Option<String>,
pub submitted_at: Option<DateTime<Utc>>,
pub dismissed_at: Option<DateTime<Utc>>,
pub dismissed_by: Option<Uuid>,
pub dismiss_reason: Option<String>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+22
View File
@@ -0,0 +1,22 @@
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrReviewComment {
pub id: Uuid,
pub review_id: Uuid,
pub pull_request_id: Uuid,
pub author_id: Uuid,
pub body: String,
pub path: String,
pub line: Option<i32>,
pub original_line: Option<i32>,
pub start_line: Option<i32>,
pub original_start_line: Option<i32>,
pub diff_hunk: Option<String>,
pub in_reply_to_id: Option<Uuid>,
pub edited_at: Option<DateTime<Utc>>,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
+19
View File
@@ -0,0 +1,19 @@
use crate::models::common::State;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)]
pub struct PrStatus {
pub pull_request_id: Uuid,
pub head_commit_sha: String,
pub checks_state: State,
pub mergeable_state: State,
pub conflicts: bool,
pub approvals_count: i32,
pub requested_reviews_count: i32,
pub changed_files_count: i32,
pub additions_count: i32,
pub deletions_count: i32,
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 PrSubscription {
pub id: Uuid,
pub pull_request_id: Uuid,
pub user_id: Uuid,
pub reason: String,
pub muted: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}

Some files were not shown because too many files have changed in this diff Show More