030e59e
zhenyi
refactor(lib): migrate storage and security tier to central lib/config (auth, cache, db, email, jwt, payment, queue, rate_limit, storage)
030e59e
use db::issue::issue as issue_entity;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use time::format_description::well_known::Rfc3339;
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;
fn fmt_ts(ts: OffsetDateTime) -> String {
ts.format(&Rfc3339).unwrap_or_default()
}
fn fmt_ts_opt(ts: Option<OffsetDateTime>) -> Option<String> {
ts.map(fmt_ts)
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum IssueState {
Open,
Closed,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IssueView {
pub id: Uuid,
pub collection_id: Uuid,
pub autoincrement_id: i32,
pub author_id: Uuid,
pub title: String,
pub description: Option<String>,
pub body: String,
pub milestone_id: Option<Uuid>,
pub state: IssueState,
pub created_at: String,
pub updated_at: Option<String>,
pub closed_at: Option<String>,
}
impl From<issue_entity::Model> for IssueView {
fn from(m: issue_entity::Model) -> Self {
let state = if m.closed_at.is_some() {
IssueState::Closed
} else {
IssueState::Open
};
Self {
id: m.id,
collection_id: m.collection_id,
autoincrement_id: m.autoincrement_id,
author_id: m.author_id,
title: m.title,
description: m.description,
body: m.body,
milestone_id: m.milestone_id,
state,
created_at: fmt_ts(m.created_at),
updated_at: fmt_ts_opt(m.updated_at),
closed_at: fmt_ts_opt(m.closed_at),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct IssuePage {
pub items: Vec<IssueView>,
pub total: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CreateIssueOption {
pub title: String,
pub description: Option<String>,
pub body: String,
pub milestone_id: Option<Uuid>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct UpdateIssueOption {
pub title: Option<String>,
pub description: Option<Option<String>>,
pub body: Option<String>,
pub milestone_id: Option<Option<Uuid>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct CloseIssueOption {
pub closed: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, IntoParams)]
pub struct ListIssueQuery {
pub state: Option<IssueState>,
pub author_id: Option<Uuid>,
pub milestone_id: Option<Uuid>,
pub q: Option<String>,
pub limit: Option<u64>,
pub offset: Option<u64>,
}