Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create New Admin Route get_quest_participants #325

Open
Marchand-Nicolas opened this issue Nov 17, 2024 · 2 comments
Open

Create New Admin Route get_quest_participants #325

Marchand-Nicolas opened this issue Nov 17, 2024 · 2 comments
Labels
Good first issue Good for newcomers OD Hack Issue reserved for the OD Hack open for contribution An issue that is available for an Only Dust contribution

Comments

@Marchand-Nicolas
Copy link
Collaborator

Marchand-Nicolas commented Nov 17, 2024

Description 📹

Implement a new admin route get_quest_participants that retrieves a list of addresses who have completed all tasks of a specific quest. The route will accept a quest_id parameter, fetch all task IDs associated with that quest, and then identify the addresses that have completed all these tasks. This will allow admin users to see which participants have fully completed a quest. The route should be secured using the existing authentication middleware to ensure only authorized admin users can access this information.
The returned addresses should be in hex format.

Proposed Actions 🛠️

Here’s a checklist of actions to follow for resolving this issue:

  1. Fork and Create Branch:
    Fork the repository and create a new branch using the issue number:

    git checkout -b fix-[issue-number]
  2. Implement Changes:

    • Create the Route: add a new handler in src/endpoints/admin/quest_boost: get_boost_winners.rs

    • Define Request Parameters:

      pub_struct!(Deserialize; GetQuestParticipantsParams {
          quest_id: i64,
      });
    • Implement the Handler Logic (should look something like that):

      #[route(get, "/admin/quests/get_quest_participants", auth_middleware)]
      pub async fn get_quest_participants_handler(
          State(state): State<Arc<AppState>>,
          Extension(_sub): Extension<String>, // Assuming admin authentication is handled
          Query(params): Query<GetQuestParticipantsParams>,
      ) -> impl IntoResponse {
          let tasks_collection = state.db.collection::<QuestTaskDocument>("tasks");
          let completed_tasks_collection = state.db.collection::<CompletedTaskDocument>("completed_tasks");
      
          // Fetch all task IDs for the given quest_id
          let task_filter = doc! { "quest_id": params.quest_id };
          let task_cursor = match tasks_collection.find(task_filter, None).await {
              Ok(cursor) => cursor,
              Err(e) => return get_error(format!("Error fetching tasks: {}", e)),
          };
      
          let task_ids: Vec<i64> = match task_cursor
              .map_ok(|doc| doc.id)
              .collect::<Vec<Result<i64, _>>>()
              .await
              .into_iter()
              .collect::<Result<Vec<_>, _>>()
          {
              Ok(ids) => ids,
              Err(e) => return get_error(format!("Error processing tasks: {}", e)),
          };
      
          if task_ids.is_empty() {
              return get_error(format!("No tasks found for quest_id {}", params.quest_id));
          }
      
          // Fetch all completed tasks for these task IDs
          let completed_task_filter = doc! { "task_id": { "$in": &task_ids } };
          let completed_task_cursor = match completed_tasks_collection.find(completed_task_filter, None).await {
              Ok(cursor) => cursor,
              Err(e) => return get_error(format!("Error fetching completed tasks: {}", e)),
          };
      
          let mut address_task_map: HashMap<String, HashSet<i64>> = HashMap::new();
      
          let completed_tasks = completed_task_cursor.try_collect::<Vec<CompletedTaskDocument>>().await;
      
          match completed_tasks {
              Ok(tasks) => {
                  for task in tasks {
                      address_task_map
                          .entry(task.address.clone())
                          .or_insert_with(HashSet::new)
                          .insert(task.task_id);
                  }
      
                  // Filter addresses who have completed all tasks
                  let total_tasks = task_ids.len();
                  let participants: Vec<String> = address_task_map
                      .into_iter()
                      .filter_map(|(address, tasks_completed)| {
                          if tasks_completed.len() == total_tasks {
                              Some(address)
                          } else {
                              None
                          }
                      })
                      .collect();
      
                  (
                      StatusCode::OK,
                      Json(json!({ "participants": participants })).into_response(),
                  )
              }
              Err(e) => get_error(format!("Error processing completed tasks: {}", e)),
          }
      }
  3. Run Tests and Commit Changes:

    • Testing:

      • Verify the new route works as expected by testing with valid and invalid quest_id values.
      • Ensure that unauthorized access is correctly blocked by the auth_middleware.
      • Test with quests that have no tasks, quests with tasks but no participants, and quests with participants who have completed some or all tasks.
    • Commit Changes:

      git commit -m "Fix: Implement get_quest_participants admin route"

Required 📋

To keep our workflow smooth, please make sure you follow these guidelines:

  • Assignment: Don't create a pull request if you weren’t assigned to this issue.
  • Timeframe: Complete the task within 3 business days.
  • Closing the Issue: In your PR description, close the issue by writing Close #[issue_id].
  • Review Process:
    • Once you've submitted your PR, change the label to "ready for review".
    • If changes are requested, address them and then update the label back to "ready for review" once done.
  • Testing: Test your PR locally before pushing, and verify that tests and build are working after pushing.

Thank you for your contribution 🙏

⚠️ WARNING: Failure to follow the requirements above may result in being added to the OnlyDust blacklist, affecting your ability to receive future rewards.

@Marchand-Nicolas Marchand-Nicolas added Good first issue Good for newcomers open for contribution An issue that is available for an Only Dust contribution OD Hack Issue reserved for the OD Hack labels Nov 17, 2024
@847850277
Copy link

Can you assign this issue to me? I can complete it.

@GideonBature
Copy link
Contributor

Greetings @Marchand-Nicolas, can you please assign this issue to me?

I am a software engineer and have participated and contributed to previous ODHacks. I would love to contribute once again to Starknet by solving this issue. I have experience with Rust and some of it's framework (Axum and Actix-web) and I believe I should be able to solve this issue within 48 hrs.

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good first issue Good for newcomers OD Hack Issue reserved for the OD Hack open for contribution An issue that is available for an Only Dust contribution
Projects
None yet
Development

No branches or pull requests

3 participants