use async_trait::async_trait;
use sqlx::{Database, Pool, Row};
use uuid::Uuid;
use chrono::{DateTime, Utc};
use std::collections::HashMap;
use burncloud_service_models as service;
use crate::models::*;
use crate::converters::*;
#[async_trait]
pub trait DatabaseRepository<DB: Database> {
type Error: std::error::Error + Send + Sync + 'static;
async fn pool(&self) -> &Pool<DB>;
}
#[async_trait]
pub trait ModelRepository<DB: Database>: DatabaseRepository<DB> {
async fn get_all_models(&self) -> Result<Vec<service::Model>, Self::Error>;
async fn get_model_by_id(&self, id: Uuid) -> Result<Option<service::Model>, Self::Error>;
async fn get_model_by_name(&self, name: &str) -> Result<Option<service::Model>, Self::Error>;
async fn create_model(&self, model: &service::Model) -> Result<(), Self::Error>;
async fn update_model(&self, model: &service::Model) -> Result<(), Self::Error>;
async fn delete_model(&self, id: Uuid) -> Result<(), Self::Error>;
async fn search_models(&self, query: &str, limit: Option<i64>) -> Result<Vec<service::Model>, Self::Error>;
async fn get_models_by_type(&self, model_type: &service::ModelType) -> Result<Vec<service::Model>, Self::Error>;
async fn get_models_by_provider(&self, provider: &str) -> Result<Vec<service::Model>, Self::Error>;
}
#[async_trait]
pub trait InstalledModelRepository<DB: Database>: DatabaseRepository<DB> {
async fn get_all_installed_models(&self) -> Result<Vec<service::InstalledModel>, Self::Error>;
async fn get_installed_model_by_model_id(&self, model_id: Uuid) -> Result<Option<service::InstalledModel>, Self::Error>;
async fn install_model(&self, installed_model: &service::InstalledModel) -> Result<(), Self::Error>;
async fn update_installed_model(&self, installed_model: &service::InstalledModel) -> Result<(), Self::Error>;
async fn uninstall_model(&self, model_id: Uuid) -> Result<(), Self::Error>;
async fn get_installed_models_by_status(&self, status: &service::ModelStatus) -> Result<Vec<service::InstalledModel>, Self::Error>;
async fn update_model_usage(&self, model_id: Uuid) -> Result<(), Self::Error>;
}
#[async_trait]
pub trait RuntimeRepository<DB: Database>: DatabaseRepository<DB> {
async fn get_all_runtime_configs(&self) -> Result<Vec<service::RuntimeConfig>, Self::Error>;
async fn create_runtime_config(&self, config: &service::RuntimeConfig) -> Result<Uuid, Self::Error>;
async fn get_model_runtime(&self, model_id: Uuid) -> Result<Option<service::ModelRuntime>, Self::Error>;
async fn create_model_runtime(&self, runtime: &service::ModelRuntime) -> Result<(), Self::Error>;
async fn update_model_runtime(&self, runtime: &service::ModelRuntime) -> Result<(), Self::Error>;
async fn delete_model_runtime(&self, runtime_id: Uuid) -> Result<(), Self::Error>;
async fn record_runtime_metrics(&self, metrics: &service::RuntimeMetrics) -> Result<(), Self::Error>;
async fn get_runtime_metrics_history(
&self,
runtime_id: Uuid,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> Result<Vec<service::RuntimeMetrics>, Self::Error>;
async fn record_runtime_event(&self, event: &service::RuntimeEvent) -> Result<(), Self::Error>;
async fn get_runtime_events(
&self,
runtime_id: Uuid,
limit: Option<i64>,
) -> Result<Vec<service::RuntimeEvent>, Self::Error>;
}
#[async_trait]
pub trait RepositoryManagementRepository<DB: Database>: DatabaseRepository<DB> {
async fn get_all_repositories(&self) -> Result<Vec<service::ModelRepository>, Self::Error>;
async fn get_repository_by_id(&self, id: Uuid) -> Result<Option<service::ModelRepository>, Self::Error>;
async fn create_repository(&self, repository: &service::ModelRepository) -> Result<(), Self::Error>;
async fn update_repository(&self, repository: &service::ModelRepository) -> Result<(), Self::Error>;
async fn delete_repository(&self, id: Uuid) -> Result<(), Self::Error>;
async fn record_sync_result(&self, sync_result: &service::SyncResult) -> Result<(), Self::Error>;
async fn get_sync_history(&self, repository_id: Uuid, limit: Option<i64>) -> Result<Vec<service::SyncResult>, Self::Error>;
}
#[async_trait]
pub trait MonitoringRepository<DB: Database>: DatabaseRepository<DB> {
async fn record_system_metrics(&self, metrics: &service::SystemMetrics) -> Result<(), Self::Error>;
async fn get_system_metrics_history(
&self,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> Result<Vec<service::SystemMetrics>, Self::Error>;
async fn record_application_metrics(&self, metrics: &service::ApplicationMetrics) -> Result<(), Self::Error>;
async fn get_application_metrics_history(
&self,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> Result<Vec<service::ApplicationMetrics>, Self::Error>;
async fn record_model_metrics(&self, metrics: &service::ModelMetrics) -> Result<(), Self::Error>;
async fn get_model_metrics_history(
&self,
model_id: Uuid,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> Result<Vec<service::ModelMetrics>, Self::Error>;
async fn create_alert_event(&self, alert: &service::AlertEvent) -> Result<(), Self::Error>;
async fn update_alert_event(&self, alert: &service::AlertEvent) -> Result<(), Self::Error>;
async fn get_active_alerts(&self) -> Result<Vec<service::AlertEvent>, Self::Error>;
async fn get_alert_history(&self, limit: Option<i64>) -> Result<Vec<service::AlertEvent>, Self::Error>;
}
#[async_trait]
pub trait ConfigRepository<DB: Database>: DatabaseRepository<DB> {
async fn get_global_config(&self) -> Result<Option<service::GlobalConfig>, Self::Error>;
async fn save_global_config(&self, config: &service::GlobalConfig) -> Result<(), Self::Error>;
async fn get_config_history(&self, limit: Option<i64>) -> Result<Vec<service::GlobalConfig>, Self::Error>;
}
#[async_trait]
pub trait TaskRepository<DB: Database>: DatabaseRepository<DB> {
async fn create_task(&self, task: &DbTask) -> Result<(), Self::Error>;
async fn get_pending_tasks(&self, limit: Option<i64>) -> Result<Vec<DbTask>, Self::Error>;
async fn update_task_status(&self, task_id: Uuid, status: &str) -> Result<(), Self::Error>;
async fn complete_task(&self, task_id: Uuid, result: Option<&str>) -> Result<(), Self::Error>;
async fn fail_task(&self, task_id: Uuid, error: &str) -> Result<(), Self::Error>;
async fn create_download_task(&self, task: &DbDownloadTask) -> Result<(), Self::Error>;
async fn update_download_progress(
&self,
task_id: Uuid,
downloaded_size: i64,
progress_percent: f32,
speed_bps: i64,
) -> Result<(), Self::Error>;
async fn get_download_tasks_by_model(&self, model_id: Uuid) -> Result<Vec<DbDownloadTask>, Self::Error>;
}
#[async_trait]
pub trait SessionRepository<DB: Database>: DatabaseRepository<DB> {
async fn create_session(&self, session: &DbUserSession) -> Result<(), Self::Error>;
async fn get_session_by_token(&self, token: &str) -> Result<Option<DbUserSession>, Self::Error>;
async fn update_session_last_accessed(&self, session_id: Uuid) -> Result<(), Self::Error>;
async fn delete_session(&self, session_id: Uuid) -> Result<(), Self::Error>;
async fn cleanup_expired_sessions(&self) -> Result<i64, Self::Error>;
async fn record_api_usage(&self, usage: &DbApiUsage) -> Result<(), Self::Error>;
async fn get_api_usage_stats(
&self,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> Result<Vec<DbApiUsage>, Self::Error>;
}
#[derive(Debug, thiserror::Error)]
pub enum RepositoryError {
#[error("Database error: {0}")]
Database(#[from] sqlx::Error),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("Not found")]
NotFound,
#[error("Validation error: {0}")]
Validation(String),
#[error("Conflict: {0}")]
Conflict(String),
}
#[derive(Debug, Clone)]
pub struct Pagination {
pub offset: i64,
pub limit: i64,
}
impl Default for Pagination {
fn default() -> Self {
Self {
offset: 0,
limit: 20,
}
}
}
#[derive(Debug, Clone)]
pub struct QueryFilter {
pub search: Option<String>,
pub model_type: Option<service::ModelType>,
pub provider: Option<String>,
pub status: Option<service::ModelStatus>,
pub tags: Vec<String>,
pub created_after: Option<DateTime<Utc>>,
pub created_before: Option<DateTime<Utc>>,
}
impl Default for QueryFilter {
fn default() -> Self {
Self {
search: None,
model_type: None,
provider: None,
status: None,
tags: Vec::new(),
created_after: None,
created_before: None,
}
}
}
#[derive(Debug, Clone)]
pub enum SortOrder {
Asc,
Desc,
}
#[derive(Debug, Clone)]
pub struct SortBy {
pub field: String,
pub order: SortOrder,
}
impl Default for SortBy {
fn default() -> Self {
Self {
field: "created_at".to_string(),
order: SortOrder::Desc,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct QueryOptions {
pub pagination: Pagination,
pub filter: QueryFilter,
pub sort_by: SortBy,
}
#[derive(Debug, Clone)]
pub struct QueryResult<T> {
pub items: Vec<T>,
pub total_count: i64,
pub has_more: bool,
}
impl<T> QueryResult<T> {
pub fn new(items: Vec<T>, total_count: i64, pagination: &Pagination) -> Self {
let has_more = (pagination.offset + pagination.limit) < total_count;
Self {
items,
total_count,
has_more,
}
}
}