use crate::AppService; use crate::error::AppError; use chrono::{DateTime, Utc}; use sea_orm::*; use serde::{Deserialize, Serialize}; use session::Session; use utoipa::ToSchema; use uuid::Uuid; #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] pub struct UserInfoExternal { pub user_uid: Uuid, pub username: String, pub display_name: String, pub avatar_url: Option, pub master_email: Option, pub timezone: String, pub language: String, pub website_url: Option, pub organization: Option, pub last_sign_in_at: Option>, pub is_owner: bool, pub is_subscribe: bool, pub total_projects: u64, pub total_repos: u64, } impl AppService { pub async fn user_info( &self, context: Session, username: String, ) -> Result { let user = models::users::user::Entity::find() .filter(models::users::user::Column::Username.eq(&username)) .one(&self.db) .await? .ok_or(AppError::UserNotFound)?; let preferences = models::users::user_preferences::Entity::find() .filter(models::users::user_preferences::Column::User.eq(user.uid)) .one(&self.db) .await?; let master_email = models::users::user_email::Entity::find() .filter(models::users::user_email::Column::User.eq(user.uid)) .one(&self.db) .await? .map(|email| email.email); let is_subscribe = if let Some(current_uid) = context.user() { let relation = models::users::user_relation::Entity::find() .filter(models::users::user_relation::Column::User.eq(current_uid)) .filter(models::users::user_relation::Column::Target.eq(user.uid)) .filter(models::users::user_relation::Column::RelationType.eq("follow")) .one(&self.db) .await?; relation.is_some() } else { false }; // Get user's project memberships to find repos let user_project_ids: Vec = models::projects::project_members::Entity::find() .filter(models::projects::project_members::Column::User.eq(user.uid)) .select_only() .column(models::projects::project_members::Column::Project) .into_tuple::() .all(&self.db) .await?; // Count projects created by user let total_projects = models::projects::project::Entity::find() .filter(models::projects::project::Column::CreatedBy.eq(user.uid)) .count(&self.db) .await?; // Count repos in user's projects let total_repos = models::repos::repo::Entity::find() .filter(models::repos::repo::Column::Project.is_in(user_project_ids)) .count(&self.db) .await?; Ok(UserInfoExternal { user_uid: user.uid, username: user.username, display_name: user.display_name.unwrap_or_default(), avatar_url: user.avatar_url, master_email, timezone: preferences .as_ref() .map(|p| p.timezone.clone()) .unwrap_or_else(|| "UTC".to_string()), language: preferences .as_ref() .map(|p| p.language.clone()) .unwrap_or_else(|| "en".to_string()), website_url: user.website_url, organization: user.organization, last_sign_in_at: user.last_sign_in_at, is_owner: context.user().map(|u| u == user.uid).unwrap_or(false), is_subscribe, total_projects, total_repos, }) } }