use std::sync::Arc;
use uuid::Uuid;
use crate::callback::AuthCallback;
use crate::errors::AppError;
use crate::repositories::{OrgEntity, OrgRole, SystemSetting};
use crate::services::EmailService;
use crate::AppState;
pub struct OrgAssignment {
pub org_id: Uuid,
pub role: OrgRole,
}
pub async fn resolve_org_assignment<C: AuthCallback, E: EmailService>(
state: &Arc<AppState<C, E>>,
creator_id: Uuid,
) -> Result<OrgAssignment, AppError> {
if let Some(setting) = state
.system_settings_repo
.get_by_key("default_org_id")
.await?
{
let org_id: Uuid = setting
.value
.parse()
.map_err(|_| AppError::Internal(anyhow::anyhow!("Invalid default_org_id setting")))?;
return Ok(OrgAssignment {
org_id,
role: OrgRole::Member,
});
}
let existing_orgs = state.org_repo.list_all(100, 0).await?;
if let Some(org) = existing_orgs.into_iter().find(|o| !o.is_personal) {
persist_default_org_id(state, org.id).await;
return Ok(OrgAssignment {
org_id: org.id,
role: OrgRole::Member,
});
}
let default_org = OrgEntity::new(
"Default".to_string(),
"default".to_string(),
creator_id,
false,
);
match state.org_repo.create(default_org).await {
Ok(created) => {
persist_default_org_id(state, created.id).await;
Ok(OrgAssignment {
org_id: created.id,
role: OrgRole::Member,
})
}
Err(_) => {
let setting = state
.system_settings_repo
.get_by_key("default_org_id")
.await?
.ok_or_else(|| {
AppError::Internal(anyhow::anyhow!(
"Failed to create or find default organization"
))
})?;
let org_id: Uuid = setting.value.parse().map_err(|_| {
AppError::Internal(anyhow::anyhow!("Invalid default_org_id setting"))
})?;
Ok(OrgAssignment {
org_id,
role: OrgRole::Member,
})
}
}
}
async fn persist_default_org_id<C: AuthCallback, E: EmailService>(
state: &Arc<AppState<C, E>>,
org_id: Uuid,
) {
let setting = SystemSetting::new(
"default_org_id".to_string(),
org_id.to_string(),
"org".to_string(),
);
if let Err(e) = state.system_settings_repo.upsert(setting).await {
tracing::warn!("Failed to persist default_org_id setting: {e}");
}
}