Skip to content
Clone
d5939db
60 lines 2.0 KB Rust
use db::conn::sea_orm::*;
use db::issue::milestone as milestone_entity;
use time::OffsetDateTime;
use time::format_description::well_known::Rfc3339;
use uuid::Uuid;
use crate::error::{IssueError, IssueResult};
use crate::features::IssueService;
use super::super::super::issue::usecase::load_issue_collection;
use super::super::{CreateMilestoneOption, MilestoneView};
use super::helpers::require_authenticated;
pub async fn create_milestone(
svc: &IssueService,
actor: Uuid,
channel_id: Uuid,
input: CreateMilestoneOption,
) -> IssueResult<MilestoneView> {
require_authenticated(actor)?;
let name = input.name.trim().to_string();
if name.is_empty() || name.len() > svc.config.max_milestone_title_len {
return Err(IssueError::BadRequest(format!(
"milestone name length must be in 1..={}",
svc.config.max_milestone_title_len
)));
}
if let Some(ref d) = input.description
&& d.len() > svc.config.max_milestone_description_len
{
return Err(IssueError::BadRequest("milestone description too long".into()));
}
let due_at = match input.due_at.as_deref() {
Some(s) => Some(
OffsetDateTime::parse(s, &Rfc3339)
.map_err(|e| IssueError::BadRequest(format!("invalid due_at: {e}")))?,
),
None => None,
};
let collection = load_issue_collection(svc, channel_id).await?;
let db = svc.db.writer();
let now = OffsetDateTime::now_utc();
let id = Uuid::new_v4();
let active: milestone_entity::ActiveModel = milestone_entity::ActiveModel::builder()
.set_id(id)
.set_collection_id(collection.id)
.set_name(name)
.set_description(input.description)
.set_is_closed(false)
.set_due_at(due_at)
.set_num_issues(0)
.set_num_closed_issues(0)
.set_created_at(now)
.set_updated_at(None)
.into();
let saved = active.insert(&db).await?;
Ok(MilestoneView::from(saved))
}