396 lines
9.3 KiB
Rust
396 lines
9.3 KiB
Rust
use chrono::{DateTime, Utc};
|
|
use minio::s3::client::Client as MinioClient;
|
|
use rdkafka::producer::FutureProducer;
|
|
use redis::aio::ConnectionManager as RedisConnectionManager;
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::PgPool;
|
|
use uuid::Uuid;
|
|
//use zitadel::api::zitadel::auth::v1::auth_service_client::AuthServiceClient;
|
|
use serde_json::Value as JsonValue;
|
|
use std::str::FromStr;
|
|
|
|
use crate::config::AppConfig;
|
|
|
|
#[derive(Debug)]
|
|
pub struct CoreError(pub String);
|
|
|
|
// Add these near the top with other type definitions
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum CustomerStatus {
|
|
Active,
|
|
Inactive,
|
|
Suspended,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub enum SubscriptionTier {
|
|
Free,
|
|
Pro,
|
|
Enterprise,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Instance {
|
|
pub id: Uuid,
|
|
pub customer_id: Uuid,
|
|
pub name: String,
|
|
pub status: String,
|
|
pub shard_id: i32,
|
|
pub region: String,
|
|
pub config: JsonValue,
|
|
pub created_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Room {
|
|
pub id: Uuid,
|
|
pub instance_id: Uuid,
|
|
pub name: String,
|
|
pub kind: String,
|
|
pub status: String,
|
|
pub config: JsonValue,
|
|
pub created_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Message {
|
|
pub id: Uuid,
|
|
pub customer_id: Uuid,
|
|
pub instance_id: Uuid,
|
|
pub conversation_id: Uuid,
|
|
pub sender_id: Uuid,
|
|
pub kind: String,
|
|
pub content: String,
|
|
pub metadata: JsonValue,
|
|
pub created_at: Option<DateTime<Utc>>,
|
|
pub shard_key: Option<i32>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct MessageFilter {
|
|
pub conversation_id: Option<Uuid>,
|
|
pub sender_id: Option<Uuid>,
|
|
pub from_date: Option<DateTime<Utc>>,
|
|
pub to_date: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct SearchQuery {
|
|
pub query: String,
|
|
pub conversation_id: Option<Uuid>,
|
|
pub from_date: Option<DateTime<Utc>>,
|
|
pub to_date: Option<DateTime<Utc>>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct FileUpload {
|
|
pub content: Vec<u8>,
|
|
pub filename: String,
|
|
pub content_type: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct FileContent {
|
|
pub content: Vec<u8>,
|
|
pub content_type: String,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Status {
|
|
pub code: String,
|
|
pub timestamp: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub enum UserStatus {
|
|
Active,
|
|
Inactive,
|
|
Suspended,
|
|
}
|
|
|
|
impl FromStr for UserStatus {
|
|
type Err = CoreError;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
match s {
|
|
"active" => Ok(UserStatus::Active),
|
|
"inactive" => Ok(UserStatus::Inactive),
|
|
"suspended" => Ok(UserStatus::Suspended),
|
|
_ => Ok(UserStatus::Inactive),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Track {
|
|
pub id: Uuid,
|
|
pub room_id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub media_type: String,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct User {
|
|
pub id: Uuid,
|
|
pub customer_id: Uuid,
|
|
pub instance_id: Uuid,
|
|
pub name: String,
|
|
pub email: String,
|
|
pub password_hash: String,
|
|
pub status: UserStatus,
|
|
pub metadata: JsonValue,
|
|
pub created_at: DateTime<Utc>,
|
|
}
|
|
|
|
// Update the Customer struct to include these fields
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Customer {
|
|
pub id: Uuid,
|
|
pub name: String,
|
|
pub max_instances: u32,
|
|
pub email: String,
|
|
pub status: CustomerStatus, // Add this field
|
|
pub subscription_tier: SubscriptionTier, // Add this field
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
impl Customer {
|
|
pub fn new(
|
|
name: String,
|
|
email: String,
|
|
subscription_tier: SubscriptionTier,
|
|
max_instances: u32,
|
|
) -> Self {
|
|
Customer {
|
|
id: Uuid::new_v4(),
|
|
name,
|
|
email,
|
|
max_instances,
|
|
subscription_tier,
|
|
status: CustomerStatus::Active, // Default to Active
|
|
created_at: Utc::now(),
|
|
updated_at: Utc::now(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RoomConfig {
|
|
pub instance_id: Uuid,
|
|
pub name: String,
|
|
pub max_participants: u32,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Connection {
|
|
pub id: Uuid,
|
|
pub room_id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub connected_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct TrackInfo {
|
|
pub room_id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub media_type: String,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Subscription {
|
|
pub id: Uuid,
|
|
pub track_id: Uuid,
|
|
pub subscriber_id: Uuid,
|
|
pub created_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct Participant {
|
|
pub user_id: Uuid,
|
|
pub room_id: Uuid,
|
|
pub joined_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct RoomStats {
|
|
pub participant_count: u32,
|
|
pub track_count: u32,
|
|
pub duration: i64,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct MessageId(pub Uuid);
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct FileInfo {
|
|
pub id: Uuid,
|
|
pub filename: String,
|
|
pub content_type: String,
|
|
pub size: usize,
|
|
pub url: String,
|
|
pub created_at: DateTime<Utc>,
|
|
}
|
|
|
|
// App state shared across all handlers
|
|
|
|
|
|
// App state shared across all handlers
|
|
pub struct AppState {
|
|
pub minio_client: Option<MinioClient>,
|
|
pub config: Option<AppConfig>,
|
|
pub db_pool: Option<PgPool>,
|
|
}
|
|
|
|
// File models
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct File {
|
|
pub id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub folder_id: Option<Uuid>,
|
|
pub name: String,
|
|
pub path: String,
|
|
pub mime_type: String,
|
|
pub size: i64,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Folder {
|
|
pub id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub parent_id: Option<Uuid>,
|
|
pub name: String,
|
|
pub path: String,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
// Conversation models
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Conversation {
|
|
pub id: Uuid,
|
|
pub name: String,
|
|
pub created_by: Uuid,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct ConversationMember {
|
|
pub conversation_id: Uuid,
|
|
pub user_id: Uuid,
|
|
pub joined_at: DateTime<Utc>,
|
|
}
|
|
|
|
// Calendar models
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct CalendarEvent {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub description: Option<String>,
|
|
pub location: Option<String>,
|
|
pub start_time: DateTime<Utc>,
|
|
pub end_time: DateTime<Utc>,
|
|
pub user_id: Uuid,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
// Task models
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct Task {
|
|
pub id: Uuid,
|
|
pub title: String,
|
|
pub description: Option<String>,
|
|
pub due_date: Option<DateTime<Utc>>,
|
|
pub status: TaskStatus,
|
|
pub priority: TaskPriority,
|
|
pub user_id: Uuid,
|
|
pub created_at: DateTime<Utc>,
|
|
pub updated_at: DateTime<Utc>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub enum TaskStatus {
|
|
Pending,
|
|
InProgress,
|
|
Completed,
|
|
Cancelled,
|
|
}
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub enum TaskPriority {
|
|
Low,
|
|
Medium,
|
|
High,
|
|
Urgent,
|
|
}
|
|
|
|
// Response models
|
|
#[derive(Debug, Serialize)]
|
|
pub struct ApiResponse<T> {
|
|
pub success: bool,
|
|
pub message: Option<String>,
|
|
pub data: Option<T>,
|
|
}
|
|
|
|
// Error models
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum AppError {
|
|
#[error("Database error: {0}")]
|
|
Database(#[from] sqlx::Error),
|
|
|
|
#[error("Redis error: {0}")]
|
|
Redis(#[from] redis::RedisError),
|
|
|
|
#[error("Kafka error: {0}")]
|
|
Kafka(String),
|
|
|
|
#[error("Zitadel error: {0}")]
|
|
Zitadel(#[from] tonic::Status),
|
|
|
|
#[error("Minio error: {0}")]
|
|
Minio(String),
|
|
|
|
#[error("Validation error: {0}")]
|
|
Validation(String),
|
|
|
|
#[error("Not found: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("Unauthorized: {0}")]
|
|
Unauthorized(String),
|
|
|
|
#[error("Forbidden: {0}")]
|
|
Forbidden(String),
|
|
|
|
#[error("Internal server error: {0}")]
|
|
Internal(String),
|
|
}
|
|
|
|
impl actix_web::ResponseError for AppError {
|
|
fn error_response(&self) -> actix_web::HttpResponse {
|
|
let (status, error_message) = match self {
|
|
AppError::Validation(_) => (actix_web::http::StatusCode::BAD_REQUEST, self.to_string()),
|
|
AppError::NotFound(_) => (actix_web::http::StatusCode::NOT_FOUND, self.to_string()),
|
|
AppError::Unauthorized(_) => {
|
|
(actix_web::http::StatusCode::UNAUTHORIZED, self.to_string())
|
|
}
|
|
AppError::Forbidden(_) => (actix_web::http::StatusCode::FORBIDDEN, self.to_string()),
|
|
_ => (
|
|
actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Internal server error".to_string(),
|
|
),
|
|
};
|
|
|
|
actix_web::HttpResponse::build(status).json(ApiResponse::<()> {
|
|
success: false,
|
|
message: Some(error_message),
|
|
data: None,
|
|
})
|
|
}
|
|
}
|