mas_handlers/graphql/mutations/
compat_session.rs1use anyhow::Context as _;
8use async_graphql::{Context, Enum, ID, InputObject, Object};
9use mas_storage::{
10 RepositoryAccess,
11 compat::CompatSessionRepository,
12 queue::{QueueJobRepositoryExt as _, SyncDevicesJob},
13};
14
15use crate::graphql::{
16 model::{CompatSession, NodeType},
17 state::ContextExt,
18};
19
20#[derive(Default)]
21pub struct CompatSessionMutations {
22 _private: (),
23}
24
25#[derive(InputObject)]
27pub struct EndCompatSessionInput {
28 compat_session_id: ID,
30}
31
32pub enum EndCompatSessionPayload {
34 NotFound,
35 Ended(Box<mas_data_model::CompatSession>),
36}
37
38#[derive(Enum, Copy, Clone, PartialEq, Eq, Debug)]
40enum EndCompatSessionStatus {
41 Ended,
43
44 NotFound,
46}
47
48#[Object]
49impl EndCompatSessionPayload {
50 async fn status(&self) -> EndCompatSessionStatus {
52 match self {
53 Self::Ended(_) => EndCompatSessionStatus::Ended,
54 Self::NotFound => EndCompatSessionStatus::NotFound,
55 }
56 }
57
58 async fn compat_session(&self) -> Option<CompatSession> {
60 match self {
61 Self::Ended(session) => Some(CompatSession::new(*session.clone())),
62 Self::NotFound => None,
63 }
64 }
65}
66
67#[Object]
68impl CompatSessionMutations {
69 async fn end_compat_session(
70 &self,
71 ctx: &Context<'_>,
72 input: EndCompatSessionInput,
73 ) -> Result<EndCompatSessionPayload, async_graphql::Error> {
74 let state = ctx.state();
75 let mut rng = state.rng();
76 let compat_session_id = NodeType::CompatSession.extract_ulid(&input.compat_session_id)?;
77 let requester = ctx.requester();
78
79 let mut repo = state.repository().await?;
80 let clock = state.clock();
81
82 let session = repo.compat_session().lookup(compat_session_id).await?;
83 let Some(session) = session else {
84 return Ok(EndCompatSessionPayload::NotFound);
85 };
86
87 if !requester.is_owner_or_admin(&session) {
88 return Ok(EndCompatSessionPayload::NotFound);
89 }
90
91 let user = repo
92 .user()
93 .lookup(session.user_id)
94 .await?
95 .context("Could not load user")?;
96
97 repo.queue_job()
99 .schedule_job(&mut rng, &clock, SyncDevicesJob::new(&user))
100 .await?;
101
102 let session = repo.compat_session().finish(&clock, session).await?;
103
104 repo.save().await?;
105
106 Ok(EndCompatSessionPayload::Ended(Box::new(session)))
107 }
108}