From d1160f2aa59db4489aad506aaa063be4966609ce Mon Sep 17 00:00:00 2001 From: Santo Cariotti Date: Fri, 23 Aug 2024 22:37:46 +0200 Subject: Add `lastPositions` query with filter by `movingActivity` param --- src/graphql/query.rs | 12 +++++++++ src/graphql/types/position.rs | 63 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) 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>, 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>, 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, +) -> Result>, String> { + let state = ctx.data::().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 = 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)) + } + } +} -- cgit v1.2.3-18-g5258