use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
use uuid::Uuid;
#[derive(Debug, Clone, FromRow, Serialize, Deserialize)]
pub struct CloudService {
pub id: Uuid,
pub org_id: Uuid,
pub workspace_id: Option<Uuid>,
pub name: String,
pub description: String,
pub base_url: String,
pub enabled: bool,
pub tags: serde_json::Value,
pub routes: serde_json::Value,
pub created_by: Uuid,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[cfg(feature = "postgres")]
impl CloudService {
#[allow(clippy::too_many_arguments)]
pub async fn create(
pool: &sqlx::PgPool,
org_id: Uuid,
workspace_id: Option<Uuid>,
created_by: Uuid,
name: &str,
description: &str,
base_url: &str,
) -> sqlx::Result<Self> {
sqlx::query_as::<_, Self>(
r#"
INSERT INTO services (org_id, workspace_id, name, description, base_url, created_by)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING *
"#,
)
.bind(org_id)
.bind(workspace_id)
.bind(name)
.bind(description)
.bind(base_url)
.bind(created_by)
.fetch_one(pool)
.await
}
pub async fn find_by_id(pool: &sqlx::PgPool, id: Uuid) -> sqlx::Result<Option<Self>> {
sqlx::query_as::<_, Self>("SELECT * FROM services WHERE id = $1")
.bind(id)
.fetch_optional(pool)
.await
}
pub async fn find_by_org(pool: &sqlx::PgPool, org_id: Uuid) -> sqlx::Result<Vec<Self>> {
sqlx::query_as::<_, Self>(
"SELECT * FROM services WHERE org_id = $1 ORDER BY created_at DESC",
)
.bind(org_id)
.fetch_all(pool)
.await
}
pub async fn find_by_workspace(
pool: &sqlx::PgPool,
org_id: Uuid,
workspace_id: Uuid,
) -> sqlx::Result<Vec<Self>> {
sqlx::query_as::<_, Self>(
"SELECT * FROM services \
WHERE org_id = $1 AND workspace_id = $2 \
ORDER BY created_at DESC",
)
.bind(org_id)
.bind(workspace_id)
.fetch_all(pool)
.await
}
#[allow(clippy::too_many_arguments)]
pub async fn update(
pool: &sqlx::PgPool,
id: Uuid,
name: Option<&str>,
description: Option<&str>,
base_url: Option<&str>,
enabled: Option<bool>,
tags: Option<&serde_json::Value>,
routes: Option<&serde_json::Value>,
workspace_id: Option<Option<Uuid>>,
) -> sqlx::Result<Option<Self>> {
let update_workspace = workspace_id.is_some();
let workspace_value = workspace_id.flatten();
sqlx::query_as::<_, Self>(
r#"
UPDATE services
SET
name = COALESCE($2, name),
description = COALESCE($3, description),
base_url = COALESCE($4, base_url),
enabled = COALESCE($5, enabled),
tags = COALESCE($6, tags),
routes = COALESCE($7, routes),
workspace_id = CASE WHEN $9 THEN $8 ELSE workspace_id END,
updated_at = NOW()
WHERE id = $1
RETURNING *
"#,
)
.bind(id)
.bind(name)
.bind(description)
.bind(base_url)
.bind(enabled)
.bind(tags)
.bind(routes)
.bind(workspace_value)
.bind(update_workspace)
.fetch_optional(pool)
.await
}
pub async fn delete(pool: &sqlx::PgPool, id: Uuid) -> sqlx::Result<()> {
sqlx::query("DELETE FROM services WHERE id = $1").bind(id).execute(pool).await?;
Ok(())
}
}