use crate::{Result, Tenant};
use sqlx::PgPool;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct TenantRepository {
pool: PgPool,
}
impl TenantRepository {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
pub async fn find_by_id(&self, id: &Uuid) -> Result<Option<Tenant>> {
let tenant = sqlx::query_as::<_, Tenant>(
"SELECT id, name, slug, encryption_key_id, created_at, updated_at, deleted_at
FROM tenants
WHERE id = $1 AND deleted_at IS NULL",
)
.bind(id)
.fetch_optional(&self.pool)
.await?;
Ok(tenant)
}
pub async fn find_by_slug(&self, slug: &str) -> Result<Option<Tenant>> {
let tenant = sqlx::query_as::<_, Tenant>(
"SELECT id, name, slug, encryption_key_id, created_at, updated_at, deleted_at
FROM tenants
WHERE slug = $1 AND deleted_at IS NULL",
)
.bind(slug)
.fetch_optional(&self.pool)
.await?;
Ok(tenant)
}
pub async fn list_all(&self) -> Result<Vec<Tenant>> {
let tenants = sqlx::query_as::<_, Tenant>(
"SELECT id, name, slug, encryption_key_id, created_at, updated_at, deleted_at
FROM tenants
WHERE deleted_at IS NULL
ORDER BY created_at DESC",
)
.fetch_all(&self.pool)
.await?;
Ok(tenants)
}
pub async fn create(&self, name: &str, slug: &str, encryption_key_id: &str) -> Result<Tenant> {
let tenant = sqlx::query_as::<_, Tenant>(
"INSERT INTO tenants (name, slug, encryption_key_id)
VALUES ($1, $2, $3)
RETURNING id, name, slug, encryption_key_id, created_at, updated_at, deleted_at",
)
.bind(name)
.bind(slug)
.bind(encryption_key_id)
.fetch_one(&self.pool)
.await?;
Ok(tenant)
}
pub async fn soft_delete(&self, id: &Uuid) -> Result<()> {
sqlx::query("UPDATE tenants SET deleted_at = NOW() WHERE id = $1")
.bind(id)
.execute(&self.pool)
.await?;
Ok(())
}
}