summaryrefslogtreecommitdiff
path: root/src/graphql
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2024-08-23 22:37:46 +0200
committerSanto Cariotti <santo@dcariotti.me>2024-08-23 22:37:46 +0200
commitd1160f2aa59db4489aad506aaa063be4966609ce (patch)
tree255e7849e677ff1f50b30ffa168ba1a15f85c50b /src/graphql
parent7b9e9d2da5d85f23d43724fe2ca5012918ea54be (diff)
Add `lastPositions` query with filter by `movingActivity` param
Diffstat (limited to 'src/graphql')
-rw-r--r--src/graphql/query.rs12
-rw-r--r--src/graphql/types/position.rs63
2 files changed, 75 insertions, 0 deletions
diff --git a/src/graphql/query.rs b/src/graphql/query.rs
index 9a7ac87..c751543 100644
--- a/src/graphql/query.rs
+++ b/src/graphql/query.rs
@@ -31,4 +31,16 @@ impl Query {
) -> Result<Option<Vec<position::Position>>, String> {
position::get_positions(ctx, user_id, limit, offset).await
}
+
+ /// Returns all the last positions for each user.
+ /// It is restricted to only admin users.
+ async fn last_positions<'ctx>(
+ &self,
+ ctx: &Context<'ctx>,
+ #[graphql(desc = "Filter by moving activity")] moving_activity: Option<
+ position::MovingActivity,
+ >,
+ ) -> Result<Option<Vec<position::Position>>, String> {
+ position::last_positions(ctx, moving_activity).await
+ }
}
diff --git a/src/graphql/types/position.rs b/src/graphql/types/position.rs
index 86e219c..5807534 100644
--- a/src/graphql/types/position.rs
+++ b/src/graphql/types/position.rs
@@ -179,3 +179,66 @@ pub async fn get_positions<'ctx>(
}
}
}
+
+/// Get last positions from the database for each user.
+/// It is restricted to only admin users.
+pub async fn last_positions<'ctx>(
+ ctx: &Context<'ctx>,
+
+ // Optional filter by moving activity
+ moving_activity: Option<MovingActivity>,
+) -> Result<Option<Vec<Position>>, String> {
+ 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("Unauthorized".to_string()),
+ 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("Unauthorized".to_string());
+ }
+
+ let rows = client
+ .query(
+ "SELECT DISTINCT ON (user_id)
+ id, user_id, created_at, ST_Y(location::geometry) AS latitude, ST_X(location::geometry) AS longitude, activity
+ FROM positions ORDER BY user_id, created_at DESC",
+ &[],
+ )
+ .await
+ .unwrap();
+
+ let positions: Vec<Position> = match moving_activity {
+ Some(activity) => rows
+ .iter()
+ .map(|row| Position {
+ id: row.get("id"),
+ user_id: row.get("user_id"),
+ created_at: GraphQLDate(Utc::now()),
+ latitude: row.get("latitude"),
+ longitude: row.get("longitude"),
+ moving_activity: row.get("activity"),
+ })
+ .filter(|x| x.moving_activity == activity)
+ .collect(),
+ None => rows
+ .iter()
+ .map(|row| Position {
+ id: row.get("id"),
+ user_id: row.get("user_id"),
+ created_at: GraphQLDate(Utc::now()),
+ latitude: row.get("latitude"),
+ longitude: row.get("longitude"),
+ moving_activity: row.get("activity"),
+ })
+ .collect(),
+ };
+
+ Ok(Some(positions))
+ }
+ }
+}