a06673b
use db::conn::sea_orm::sea_query::OnConflict;
use db::conn::sea_orm::*;
use db::common::watch_mode::WatchMode;
use db::issue::issue_watch as watch_entity;
use time::OffsetDateTime;
use uuid::Uuid;
use crate::error::{IssueError, IssueResult};
use crate::features::IssueService;
pub fn require_authenticated(actor: Uuid) -> IssueResult<()> {
if actor.is_nil() {
return Err(IssueError::Unauthorized("authentication required".into()));
}
Ok(())
}
fn parse_mode(s: &str) -> IssueResult<WatchMode> {
Ok(match s {
"normal" | "Normal" => WatchMode::Normal,
"no_watch" | "NoWatch" => WatchMode::NoWatch,
"watch" | "Watch" => WatchMode::Watch,
"ignore" | "Ignore" => WatchMode::Ignore,
other => {
return Err(IssueError::BadRequest(format!(
"invalid watch mode: {other}"
)));
}
})
}
pub async fn load_my_watch(
svc: &IssueService,
issue_id: Uuid,
user_id: Uuid,
) -> IssueResult<watch_entity::Model> {
let db = svc.db.reader();
let row = watch_entity::Entity::find()
.filter(watch_entity::COLUMN.issue_id.eq(issue_id))
.filter(watch_entity::COLUMN.user_id.eq(user_id))
.one(&db)
.await?
.ok_or_else(|| IssueError::NotFound("watch record".into()))?;
Ok(row)
}
pub async fn upsert_watch(
svc: &IssueService,
actor: Uuid,
channel_id: Uuid,
issue_id: Uuid,
mode_str: &str,
) -> IssueResult<crate::features::issue_watch::WatchView> {
require_authenticated(actor)?;
crate::features::issue::usecase::load_issue(svc, channel_id, issue_id).await?;
let mode = parse_mode(mode_str)?;
let db = svc.db.writer();
let now = OffsetDateTime::now_utc();
let active: watch_entity::ActiveModel = watch_entity::ActiveModel::builder()
.set_id(Uuid::new_v4())
.set_issue_id(issue_id)
.set_user_id(actor)
.set_mode(mode)
.set_created_at(now)
.set_updated_at(Some(now))
.into();
let saved = watch_entity::Entity::insert(active)
.on_conflict(
OnConflict::columns([watch_entity::COLUMN.issue_id, watch_entity::COLUMN.user_id])
.update_column(watch_entity::COLUMN.mode)
.update_column(watch_entity::COLUMN.updated_at)
.to_owned(),
)
.exec_with_returning(&db)
.await?;
Ok(saved.into())
}