diff options
| author | Santo Cariotti <santo@dcariotti.me> | 2024-08-23 22:37:46 +0200 | 
|---|---|---|
| committer | Santo Cariotti <santo@dcariotti.me> | 2024-08-23 22:37:46 +0200 | 
| commit | d1160f2aa59db4489aad506aaa063be4966609ce (patch) | |
| tree | 255e7849e677ff1f50b30ffa168ba1a15f85c50b /src/graphql | |
| parent | 7b9e9d2da5d85f23d43724fe2ca5012918ea54be (diff) | |
Add `lastPositions` query with filter by `movingActivity` param
Diffstat (limited to 'src/graphql')
| -rw-r--r-- | src/graphql/query.rs | 12 | ||||
| -rw-r--r-- | src/graphql/types/position.rs | 63 | 
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)) +        } +    } +}  |