105 lines
3.3 KiB
Rust
105 lines
3.3 KiB
Rust
//! List and retrieve project skills.
|
|
|
|
use crate::AppService;
|
|
use crate::error::AppError;
|
|
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder};
|
|
use serde::{Deserialize, Serialize};
|
|
use session::Session;
|
|
use utoipa::ToSchema;
|
|
|
|
#[derive(Debug, Clone, Serialize, ToSchema)]
|
|
pub struct SkillResponse {
|
|
pub id: i64,
|
|
pub project_uuid: String,
|
|
pub slug: String,
|
|
pub name: String,
|
|
pub description: Option<String>,
|
|
pub source: String,
|
|
pub repo_id: Option<String>,
|
|
pub commit_sha: Option<String>,
|
|
pub blob_hash: Option<String>,
|
|
pub content: String,
|
|
pub metadata: serde_json::Value,
|
|
pub enabled: bool,
|
|
pub created_by: Option<String>,
|
|
pub created_at: chrono::DateTime<chrono::Utc>,
|
|
pub updated_at: chrono::DateTime<chrono::Utc>,
|
|
}
|
|
|
|
impl From<models::projects::project_skill::Model> for SkillResponse {
|
|
fn from(s: models::projects::project_skill::Model) -> Self {
|
|
Self {
|
|
id: s.id,
|
|
project_uuid: s.project_uuid.to_string(),
|
|
slug: s.slug,
|
|
name: s.name,
|
|
description: s.description,
|
|
source: s.source,
|
|
repo_id: s.repo_id.map(|id| id.to_string()),
|
|
commit_sha: s.commit_sha,
|
|
blob_hash: s.blob_hash,
|
|
content: s.content,
|
|
metadata: s.metadata,
|
|
enabled: s.enabled,
|
|
created_by: s.created_by.map(|id| id.to_string()),
|
|
created_at: s.created_at,
|
|
updated_at: s.updated_at,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Deserialize, utoipa::IntoParams)]
|
|
pub struct SkillListQuery {
|
|
pub source: Option<String>,
|
|
pub enabled: Option<bool>,
|
|
}
|
|
|
|
impl AppService {
|
|
/// List all skills registered to a project.
|
|
pub async fn skill_list(
|
|
&self,
|
|
project_uuid: String,
|
|
query: SkillListQuery,
|
|
_ctx: &Session,
|
|
) -> Result<Vec<SkillResponse>, AppError> {
|
|
let project_id = uuid::Uuid::parse_str(&project_uuid)
|
|
.map_err(|_| AppError::BadRequest("Invalid project UUID".to_string()))?;
|
|
|
|
use models::projects::project_skill::Column as C;
|
|
let mut q = models::projects::project_skill::Entity::find()
|
|
.filter(C::ProjectUuid.eq(project_id))
|
|
.order_by_asc(C::Name);
|
|
|
|
if let Some(source) = &query.source {
|
|
q = q.filter(C::Source.eq(source.clone()));
|
|
}
|
|
if let Some(enabled) = query.enabled {
|
|
q = q.filter(C::Enabled.eq(enabled));
|
|
}
|
|
|
|
let skills = q.all(&self.db).await?;
|
|
Ok(skills.into_iter().map(SkillResponse::from).collect())
|
|
}
|
|
|
|
/// Get a single skill by slug within a project.
|
|
pub async fn skill_get(
|
|
&self,
|
|
project_uuid: String,
|
|
slug: String,
|
|
_ctx: &Session,
|
|
) -> Result<SkillResponse, AppError> {
|
|
let project_id = uuid::Uuid::parse_str(&project_uuid)
|
|
.map_err(|_| AppError::BadRequest("Invalid project UUID".to_string()))?;
|
|
|
|
use models::projects::project_skill::Column as C;
|
|
let skill = models::projects::project_skill::Entity::find()
|
|
.filter(C::ProjectUuid.eq(project_id))
|
|
.filter(C::Slug.eq(slug))
|
|
.one(&self.db)
|
|
.await?
|
|
.ok_or_else(|| AppError::NotFound("Skill not found".to_string()))?;
|
|
|
|
Ok(SkillResponse::from(skill))
|
|
}
|
|
}
|