Skip to content
Clone

feat(issues): add issue_watch usecase helpers

zhenyi committed
parent ff7934f commit 3fa228b Browse files

1 file changed

+77 −0

Added lib/issues/features/issue_watch/usecase/helpers.rs View lib/issues/features/issue_watch/usecase/helpers.rs
@@ -0,0 +1,77 @@
1use db::conn::sea_orm::sea_query::OnConflict;
2use db::conn::sea_orm::*;
3use db::common::watch_mode::WatchMode;
4use db::issue::issue_watch as watch_entity;
5use time::OffsetDateTime;
6use uuid::Uuid;
7
8use crate::error::{IssueError, IssueResult};
9use crate::features::IssueService;
10
11pub fn require_authenticated(actor: Uuid) -> IssueResult<()> {
12 if actor.is_nil() {
13 return Err(IssueError::Unauthorized("authentication required".into()));
14 }
15 Ok(())
16}
17
18fn parse_mode(s: &str) -> IssueResult<WatchMode> {
19 Ok(match s {
20 "normal" | "Normal" => WatchMode::Normal,
21 "no_watch" | "NoWatch" => WatchMode::NoWatch,
22 "watch" | "Watch" => WatchMode::Watch,
23 "ignore" | "Ignore" => WatchMode::Ignore,
24 other => {
25 return Err(IssueError::BadRequest(format!(
26 "invalid watch mode: {other}"
27 )));
28 }
29 })
30}
31
32pub async fn load_my_watch(
33 svc: &IssueService,
34 issue_id: Uuid,
35 user_id: Uuid,
36) -> IssueResult<watch_entity::Model> {
37 let db = svc.db.reader();
38 let row = watch_entity::Entity::find()
39 .filter(watch_entity::COLUMN.issue_id.eq(issue_id))
40 .filter(watch_entity::COLUMN.user_id.eq(user_id))
41 .one(&db)
42 .await?
43 .ok_or_else(|| IssueError::NotFound("watch record".into()))?;
44 Ok(row)
45}
46
47pub async fn upsert_watch(
48 svc: &IssueService,
49 actor: Uuid,
50 channel_id: Uuid,
51 issue_id: Uuid,
52 mode_str: &str,
53) -> IssueResult<crate::features::issue_watch::WatchView> {
54 require_authenticated(actor)?;
55 crate::features::issue::usecase::load_issue(svc, channel_id, issue_id).await?;
56 let mode = parse_mode(mode_str)?;
57 let db = svc.db.writer();
58 let now = OffsetDateTime::now_utc();
59 let active: watch_entity::ActiveModel = watch_entity::ActiveModel::builder()
60 .set_id(Uuid::new_v4())
61 .set_issue_id(issue_id)
62 .set_user_id(actor)
63 .set_mode(mode)
64 .set_created_at(now)
65 .set_updated_at(Some(now))
66 .into();
67 let saved = watch_entity::Entity::insert(active)
68 .on_conflict(
69 OnConflict::columns([watch_entity::COLUMN.issue_id, watch_entity::COLUMN.user_id])
70 .update_column(watch_entity::COLUMN.mode)
71 .update_column(watch_entity::COLUMN.updated_at)
72 .to_owned(),
73 )
74 .exec_with_returning(&db)
75 .await?;
76 Ok(saved.into())
77}
No newline at end of file