gitdataai/lib/service/users/summary.rs

71 lines
2.1 KiB
Rust

use db::sqlx;
use model::users::UserModel;
use serde::{Deserialize, Serialize};
use crate::{AppService, error::AppError};
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct UserSummaryResponse {
pub username: String,
pub display_name: String,
pub avatar_url: String,
pub website_url: String,
#[schema(value_type = String)]
pub created_at: chrono::DateTime<chrono::Utc>,
}
impl AppService {
pub async fn users_summary_by_username(
&self,
username: &str,
) -> Result<UserSummaryResponse, AppError> {
let user = self.users_find_active_user_by_username(username).await?;
Ok(user.into())
}
/// Get a user's avatar URL by username.
pub async fn users_get_avatar_url(
&self,
username: &str,
) -> Result<String, AppError> {
let user = self.users_find_active_user_by_username(username).await?;
if user.avatar_url.is_empty() {
return Err(AppError::NotFound("avatar not found".to_string()));
}
Ok(user.avatar_url)
}
pub async fn users_find_active_user_by_username(
&self,
username: &str,
) -> Result<UserModel, AppError> {
let user = sqlx::query_as::<_, UserModel>(
"SELECT id, username, display_name, avatar_url, website_url, allow_use, can_search, \
last_sign_in_at, created_at, updated_at \
FROM \"user\" WHERE username = $1",
)
.bind(username)
.fetch_optional(self.db.reader())
.await
.map_err(|e| AppError::DatabaseError(e.to_string()))?
.ok_or(AppError::UserNotFound)?;
if !user.allow_use {
return Err(AppError::UserNotFound);
}
Ok(user)
}
}
impl From<UserModel> for UserSummaryResponse {
fn from(value: UserModel) -> Self {
Self {
username: value.username,
display_name: value.display_name,
avatar_url: value.avatar_url,
website_url: value.website_url,
created_at: value.created_at,
}
}
}