summaryrefslogtreecommitdiff
path: root/src/graphql/mutation.rs
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2024-08-26 22:07:42 +0200
committerSanto Cariotti <santo@dcariotti.me>2024-08-26 22:07:42 +0200
commit6e6f2ce7c24acabdfd1f1f59378467ea225fb27a (patch)
treefd8e08320e6d7b57937023621770bb06f2c31fa9 /src/graphql/mutation.rs
parent8d36b0b75904812ba8f6b9e38b50660dfbe78d0d (diff)
Add alerts
A payload for alert creation can be ``` { "query": "mutation NewAlert($input: AlertInput!) { newAlert(input: $input) { id createdAt level } }", "variables": { "input": { "points": [ { "latitude": 40.73061, "longitude": -73.935242 }, { "latitude": 40.741895, "longitude": -73.989308 }, { "latitude": 40.712776, "longitude": -74.005974 }, { "latitude": 40.73061, "longitude": -73.935242 }, ], "level": "TWO" } } } ```
Diffstat (limited to 'src/graphql/mutation.rs')
-rw-r--r--src/graphql/mutation.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/graphql/mutation.rs b/src/graphql/mutation.rs
index 5a93038..540dd0f 100644
--- a/src/graphql/mutation.rs
+++ b/src/graphql/mutation.rs
@@ -1,8 +1,10 @@
use crate::{
dates::GraphQLDate,
graphql::types::{
+ alert,
jwt::{self, Authentication},
position,
+ user::find_user,
},
state::AppState,
};
@@ -92,4 +94,69 @@ impl Mutation {
}
}
}
+
+ /// Make GraphQL request to create new alert. Only for admins.
+ async fn new_alert<'ctx>(
+ &self,
+ ctx: &Context<'ctx>,
+ input: alert::AlertInput,
+ ) -> FieldResult<alert::Alert> {
+ let state = ctx.data::<AppState>().expect("Can't connect to db");
+ let client = &*state.client;
+
+ let auth: &Authentication = ctx.data().unwrap();
+ match auth {
+ Authentication::NotLogged => Err(Error::new("Can't find the owner")),
+ Authentication::Logged(claims) => {
+ let claim_user = find_user(client, claims.user_id)
+ .await
+ .expect("Should not be here");
+
+ if !claim_user.is_admin {
+ return Err(Error::new("Unauthorized"));
+ }
+
+ let polygon: Vec<String> = input
+ .points
+ .iter()
+ .map(|x| {
+ format!(
+ "ST_SetSRID(ST_MakePoint({}, {}), 4326)",
+ x.latitude, x.longitude
+ )
+ })
+ .collect();
+
+ let query = format!("INSERT INTO alerts (user_id, area, level)
+ VALUES($1, ST_MakePolygon(
+ ST_MakeLine(
+ ARRAY[{}]
+ )
+ ), $2)
+ RETURNING id, user_id, created_at, ST_AsText(area) as area, level, reached_users
+ ", polygon.join(","));
+
+ match client.query(&query, &[&claims.user_id, &input.level]).await {
+ Ok(rows) => {
+ let alerts: Vec<alert::Alert> = rows
+ .iter()
+ .map(|row| alert::Alert {
+ id: row.get("id"),
+ user_id: row.get("user_id"),
+ created_at: GraphQLDate(Utc::now()),
+ area: row.get("area"),
+ level: row.get("level"),
+ reached_users: row.get("reached_users"),
+ })
+ .collect();
+
+ // TODO: Send notifications
+
+ Ok(alerts[0].clone())
+ }
+ Err(e) => Err(e.into()),
+ }
+ }
+ }
+ }
}