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

feat: Add functionality for adding people to a tag (GSoC) #2612

Merged
merged 4 commits into from
Oct 27, 2024

Conversation

meetulr
Copy link

@meetulr meetulr commented Oct 25, 2024

What kind of change does this PR introduce?

Adds functionality for adding multiple to tag.

Issue Number:

Fixes #2552

Did you add tests for your changes?

Yes

Additional Context:

Admin issue: PalisadoesFoundation/talawa-admin#2302

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a mutation to assign multiple users to a tag, enhancing user tagging capabilities.
    • Added a resolver to retrieve users eligible for tagging, with support for filtering, sorting, and pagination.
    • Implemented a new input type for the mutation to streamline user tag assignments.
    • Added a new connection field to the UserTag type to view users not currently assigned to a tag.
  • Bug Fixes

    • Implemented error handling for various scenarios, ensuring appropriate responses for invalid user or tag inputs.
  • Tests

    • Added comprehensive unit tests for the new mutation and resolver, covering success and error scenarios.

Copy link

coderabbitai bot commented Oct 25, 2024

Warning

Rate limit exceeded

@meetulr has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 11 minutes and 50 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Files that changed from the base of the PR and between 8a5fb72 and acee76f.

Walkthrough

The changes introduce a new GraphQL mutation resolver, addPeopleToUserTag, enabling admins to assign tags to multiple users. It includes user and tag validation, caching for performance, and error handling. Additionally, a new resolver usersToAssignTo is added to manage user assignments to tags, with pagination and filtering capabilities. Input types and GraphQL schema are updated to support these functionalities. Comprehensive unit tests are included to ensure proper functionality and error handling for both the mutation and user assignment resolver.

Changes

File Path Change Summary
src/resolvers/Mutation/addPeopleToUserTag.ts Added addPeopleToUserTag mutation resolver for assigning tags to users.
src/resolvers/Mutation/index.ts Imported and added addPeopleToUserTag to the Mutation object.
src/resolvers/UserTag/index.ts Imported and added usersToAssignTo resolver to UserTag object.
src/resolvers/UserTag/usersToAssignTo.ts Added usersToAssignTo resolver, parseCursor, and getGraphQLConnectionFilter functions.
src/typeDefs/inputs.ts Introduced AddPeopleToUserTagInput input type for the mutation.
src/typeDefs/mutations.ts Added addPeopleToUserTag mutation to the GraphQL schema.
src/typeDefs/types.ts Added usersToAssignTo field to UserTag type for user assignment queries.
src/types/generatedGraphQLTypes.ts Defined new types for AddPeopleToUserTagInput and updated mutation signatures.
tests/resolvers/Mutation/addPeopleToUserTag.spec.ts Added unit tests for addPeopleToUserTag mutation resolver.
tests/resolvers/UserTag/usersToAssignTo.spec.ts Added unit tests for usersToAssignTo, parseCursor, and getGraphQLConnectionFilter.

Assessment against linked issues

Objective Addressed Explanation
Add support for adding people to tags (GSoC) (#2552)

Possibly related PRs

Suggested reviewers

  • palisadoes
  • DMills27
  • aashimawadhwa

Poem

🐇 In the garden where tags bloom bright,
Admins gather, ready for the fight.
With a hop and a skip, they assign with glee,
Users united, as happy as can be!
Tags and friends, a perfect match,
In our world, there’s no catch! 🌼


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

Our Pull Request Approval Process

We have these basic policies to make the approval process smoother for our volunteer team.

Testing Your Code

Please make sure your code passes all tests. Our test code coverage system will fail if these conditions occur:

  1. The overall code coverage drops below the target threshold of the repository
  2. Any file in the pull request has code coverage levels below the repository threshold
  3. Merge conflicts

The process helps maintain the overall reliability of the code base and is a prerequisite for getting your PR approved. Assigned reviewers regularly review the PR queue and tend to focus on PRs that are passing.

Reviewers

Do not assign reviewers. Our Queue Monitors will review your PR and assign them.
When your PR has been assigned reviewers contact them to get your code reviewed and approved via:

  1. comments in this PR or
  2. our slack channel

Reviewing Your Code

Your reviewer(s) will have the following roles:

  1. arbitrators of future discussions with other contributors about the validity of your changes
  2. point of contact for evaluating the validity of your work
  3. person who verifies matching issues by others that should be closed.
  4. person who gives general guidance in fixing your tests

CONTRIBUTING.md

Read our CONTRIBUTING.md file. Most importantly:

  1. PRs with issues not assigned to you will be closed by the reviewer
  2. Fix the first comment in the PR so that each issue listed automatically closes

Other

  1. 🎯 Please be considerate of our volunteers' time. Contacting the person who assigned the reviewers is not advised unless they ask for your input. Do not @ the person who did the assignment otherwise.
  2. Read the CONTRIBUTING.md file make

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (9)
tests/resolvers/UserTag/usersToAssignTo.spec.ts (3)

31-84: Consider enhancing test coverage and robustness.

While the basic cases are covered, consider these improvements:

  1. Add specific test cases for different invalid argument scenarios
  2. Make the test more robust by not assuming only one user exists
  3. Add verification that returned users are actually not assigned to the tag

Example improvement for the invalid arguments test:

 it(`throws GraphQLError if invalid arguments are provided to the resolver`, async () => {
   const parent = testTag as InterfaceOrganizationTagUser;
-
+  const invalidScenarios = [
+    { first: -1 },
+    { last: -1 },
+    { first: 1, last: 1 },
+    { after: 'invalid-cursor' },
+    { before: 'invalid-cursor' }
+  ];
+
+  for (const args of invalidScenarios) {
     try {
-      await usersToAssignToResolver?.(parent, {}, {});
+      await usersToAssignToResolver?.(parent, args, {});
+      fail('Should have thrown an error');
     } catch (error) {
       if (error instanceof GraphQLError) {
         expect(error.extensions.code).toEqual("INVALID_ARGUMENTS");
         expect(
           (error.extensions.errors as DefaultGraphQLArgumentError[]).length,
         ).toBeGreaterThan(0);
       }
     }
+  }
 });

86-118: Add edge cases to parseCursor tests.

Consider adding tests for these scenarios:

  1. Invalid ObjectId string format
  2. Empty string
  3. Null/undefined values

Example additional test cases:

it("handles invalid ObjectId format", async () => {
  const result = await parseCursor({
    cursorName: "after",
    cursorPath: ["after"],
    cursorValue: "invalid-object-id",
  });
  expect(result.isSuccessful).toEqual(false);
});

it("handles empty string", async () => {
  const result = await parseCursor({
    cursorName: "after",
    cursorPath: ["after"],
    cursorValue: "",
  });
  expect(result.isSuccessful).toEqual(false);
});

120-159: Enhance filter tests with query execution validation.

The tests verify filter object structure but don't validate if the filters work correctly with MongoDB queries. Consider adding integration tests that verify the actual query results.

Example integration test:

it("filters return correct results when executed", async () => {
  // Create test users with known IDs
  const user1 = await User.create({ /* user data */ });
  const user2 = await User.create({ /* user data */ });
  
  const filter = getGraphQLConnectionFilter({
    cursor: user1._id.toString(),
    direction: "FORWARD",
  });
  
  const results = await User.find(filter).lean();
  expect(results).toHaveLength(1);
  expect(results[0]._id.toString()).toBe(user2._id.toString());
});
src/typeDefs/inputs.ts (1)

435-438: Consider adding input validation for array size.

The input type is well-structured and follows the file's conventions. However, since userIds is an array that will be used for bulk operations, consider adding a size limit to prevent performance issues with very large arrays.

You can use the @constraint directive to add validation. Here's how:

  input AddPeopleToUserTagInput {
-    userIds: [ID!]!
+    userIds: [ID!]! @constraint(minItems: 1, maxItems: 100)
    tagId: ID!
  }

Note: Adjust the maxItems value based on your performance requirements and use case.

tests/resolvers/Mutation/addPeopleToUserTag.spec.ts (2)

62-220: LGTM! Comprehensive error cases with room for improvement.

The error test cases thoroughly cover various failure scenarios. Consider reducing code duplication by extracting common test setup and assertion logic into helper functions.

Example refactor to reduce duplication:

const expectTranslatedError = async (
  args: MutationAddPeopleToUserTagArgs,
  context: { userId: string },
  expectedError: { MESSAGE: string }
) => {
  const { requestContext } = await import("../../../src/libraries");
  const spy = vi
    .spyOn(requestContext, "translate")
    .mockImplementationOnce((message) => `Translated ${message}`);

  try {
    const { addPeopleToUserTag: addPeopleToUserTagResolver } = await import(
      "../../../src/resolvers/Mutation/addPeopleToUserTag"
    );
    await addPeopleToUserTagResolver?.({}, args, context);
    fail("Expected error was not thrown");
  } catch (error: unknown) {
    expect((error as Error).message).toEqual(
      `Translated ${expectedError.MESSAGE}`
    );
    expect(spy).toHaveBeenLastCalledWith(expectedError.MESSAGE);
  }
};

Also applies to: 357-394


222-322: LGTM! Success cases with suggestion for additional assertions.

The success test cases verify the basic functionality but could benefit from additional assertions:

  1. Verify that no unintended side effects occurred (e.g., other users' tag assignments weren't affected)
  2. Check the complete state of the TagUser collection after assignments

Example additional assertions:

// Verify no unintended assignments
const otherTagAssignments = await TagUser.find({
  tagId: args.input.tagId,
  userId: { $nin: args.input.userIds }
});
expect(otherTagAssignments).toHaveLength(0);

// Verify complete state
const allTagAssignments = await TagUser.find({
  tagId: args.input.tagId
});
expect(allTagAssignments).toHaveLength(args.input.userIds.length);
src/typeDefs/types.ts (1)

685-695: LGTM! Well-structured field definition with clear documentation.

The new usersToAssignTo field is well-implemented with:

  • Clear and descriptive documentation explaining its purpose
  • Proper pagination parameters following GraphQL best practices
  • Consistent return type (UsersConnection) matching the schema's pattern
  • Complementary functionality to existing usersAssignedTo field

Consider adding filtering capabilities to the field in the future to help users find specific unassigned users more efficiently, especially in organizations with many users. This could include parameters like:

  • searchQuery: String for name/email search
  • role: UserRole for filtering by user role
  • excludeBlockedUsers: Boolean to filter out blocked users
src/resolvers/Mutation/addPeopleToUserTag.ts (1)

181-181: Remove unnecessary optional chaining operator

Since currentParentTag is confirmed to exist, the optional chaining operator ?. is unnecessary when accessing _id. Simplify the code by removing it.

Apply this diff:

- allAncestorTags.push(currentParentTag?._id);
+ allAncestorTags.push(currentParentTag._id);
src/resolvers/UserTag/usersToAssignTo.ts (1)

165-167: Rename tagUser to user for clarity

The variable tagUser represents a User object fetched from the database. Renaming it to user improves readability and avoids confusion.

Apply this diff to rename the variable:

-const tagUser = await User.findOne({
+const user = await User.findOne({
   _id: cursorValue,
 });

Remember to update all references to tagUser within this function.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4a88fe6 and f18a687.

📒 Files selected for processing (10)
  • src/resolvers/Mutation/addPeopleToUserTag.ts (1 hunks)
  • src/resolvers/Mutation/index.ts (2 hunks)
  • src/resolvers/UserTag/index.ts (1 hunks)
  • src/resolvers/UserTag/usersToAssignTo.ts (1 hunks)
  • src/typeDefs/inputs.ts (1 hunks)
  • src/typeDefs/mutations.ts (1 hunks)
  • src/typeDefs/types.ts (1 hunks)
  • src/types/generatedGraphQLTypes.ts (9 hunks)
  • tests/resolvers/Mutation/addPeopleToUserTag.spec.ts (1 hunks)
  • tests/resolvers/UserTag/usersToAssignTo.spec.ts (1 hunks)
🧰 Additional context used
📓 Learnings (1)
tests/resolvers/Mutation/addPeopleToUserTag.spec.ts (2)
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-api#2460
File: tests/resolvers/Mutation/assignUserTag.spec.ts:35-44
Timestamp: 2024-08-15T13:37:37.956Z
Learning: The variable `testSubTag1` is used in the `assignUserTag` test suite to verify that ancestor tags are correctly assigned.
Learnt from: meetulr
PR: PalisadoesFoundation/talawa-api#2460
File: tests/resolvers/Mutation/assignUserTag.spec.ts:35-44
Timestamp: 2024-10-08T16:13:41.996Z
Learning: The variable `testSubTag1` is used in the `assignUserTag` test suite to verify that ancestor tags are correctly assigned.
🪛 GitHub Check: Check for linting, formatting, and type errors
src/resolvers/UserTag/usersToAssignTo.ts

[failure] 4-4:
Imports "GraphQLConnectionTraversalDirection" are only used as type

🔇 Additional comments (9)
src/resolvers/UserTag/index.ts (1)

6-6: LGTM! Clean implementation of the new resolver.

The changes follow the established patterns in the codebase and properly implement the UserTagResolvers interface. The addition aligns well with the PR objective of supporting user-tag associations.

Also applies to: 13-13

tests/resolvers/UserTag/usersToAssignTo.spec.ts (1)

1-30: LGTM! Well-structured test setup.

The test setup follows best practices with proper database connection management and test data initialization.

src/resolvers/Mutation/index.ts (1)

11-11: LGTM! Changes follow established patterns.

The import statement and mutation resolver addition are well-structured and properly integrated into the codebase. The changes align with the PR objectives to implement tag assignment functionality.

Also applies to: 129-129

tests/resolvers/Mutation/addPeopleToUserTag.spec.ts (3)

1-53: LGTM! Well-structured test setup.

The setup code properly initializes test data with a clear hierarchy of users, organizations, and tags. The cleanup is handled appropriately.


55-61: LGTM! Well-organized test suite structure.

The test suite follows best practices with proper grouping and mock cleanup.


324-355: LGTM! Well-implemented ancestor tags test.

The test case correctly verifies that assigning a sub-tag also assigns all ancestor tags, which is crucial functionality based on the retrieved learnings about testSubTag1.

src/types/generatedGraphQLTypes.ts (3)

118-121: LGTM! Well-structured input type definition.

The AddPeopleToUserTagInput type is properly defined with:

  • Non-nullable tagId ensuring a tag must be specified
  • Non-nullable array of userIds ensuring at least one user must be provided

1301-1304: LGTM! Consistent mutation argument type definition.

The mutation argument type is properly defined with:

  • Required input parameter using the AddPeopleToUserTagInput type
  • Nullable UserTag return type following the pattern of similar mutations

Line range hint 2997-3026: LGTM! Well-documented field with proper connection pattern.

The usersToAssignTo field is properly defined with:

  • Clear documentation explaining its purpose
  • Standard connection pattern with pagination support
  • Consistent use of UsersConnection type matching other user listing fields

src/typeDefs/mutations.ts Outdated Show resolved Hide resolved
src/resolvers/Mutation/addPeopleToUserTag.ts Outdated Show resolved Hide resolved
src/resolvers/UserTag/usersToAssignTo.ts Outdated Show resolved Hide resolved
src/resolvers/UserTag/usersToAssignTo.ts Outdated Show resolved Hide resolved
Copy link

codecov bot commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 98.44961% with 4 lines in your changes missing coverage. Please review.

Project coverage is 98.42%. Comparing base (4a88fe6) to head (8a5fb72).

Files with missing lines Patch % Lines
src/resolvers/UserTag/usersToAssignTo.ts 96.74% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##           develop    #2612    +/-   ##
=========================================
  Coverage    98.42%   98.42%            
=========================================
  Files          338      340     +2     
  Lines        16260    16518   +258     
  Branches      2328     2364    +36     
=========================================
+ Hits         16004    16258   +254     
- Misses         253      257     +4     
  Partials         3        3            

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (2)
schema.graphql (1)

Line range hint 53-1928: Architecture suggestion: Consider adding filtering capabilities.

While the current implementation covers the basic requirements, consider enhancing the usersToAssignTo field with filtering capabilities similar to other connection fields in the schema. This would allow clients to search/filter users before assignment.

Example enhancement:

  usersToAssignTo(
    after: String, 
    before: String, 
    first: PositiveInt, 
    last: PositiveInt,
+   where: UserWhereInput
  ): UsersConnection
src/resolvers/UserTag/usersToAssignTo.ts (1)

72-76: Fix the comment to reflect the correct field name joinedOrganizations.

The comment refers to joinedOrgs, but the code uses joinedOrganizations. For clarity and consistency, please update the comment to match the code.

Apply this diff:

-// Step 1: Match users whose joinedOrgs contains the orgId
+// Step 1: Match users whose joinedOrganizations contains the orgId
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between f18a687 and e18b739.

📒 Files selected for processing (2)
  • schema.graphql (3 hunks)
  • src/resolvers/UserTag/usersToAssignTo.ts (1 hunks)
🔇 Additional comments (3)
schema.graphql (3)

53-56: LGTM: Well-structured input type for bulk user assignment.

The input type is properly defined with clear field names and appropriate non-null constraints.


1066-1066: LGTM: Mutation follows GraphQL best practices.

The mutation signature is well-defined, taking the new input type and returning the updated UserTag.


1923-1928: LGTM: Connection field properly implements pagination.

The field follows GraphQL connection pattern best practices with:

  • Clear documentation
  • Standard pagination arguments
  • Proper return type (UsersConnection)

src/resolvers/UserTag/usersToAssignTo.ts Outdated Show resolved Hide resolved
src/resolvers/UserTag/usersToAssignTo.ts Outdated Show resolved Hide resolved
src/resolvers/UserTag/usersToAssignTo.ts Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
src/resolvers/UserTag/usersToAssignTo.ts (1)

1-3: Consider consolidating type imports

Consider moving InterfaceUser import to the first type import block for better organization of imports.

import type { UserTagResolvers } from "../../types/generatedGraphQLTypes";
+import type { InterfaceUser } from "../../models";
-import type { InterfaceUser } from "../../models";
import { User } from "../../models";
src/typeDefs/mutations.ts (1)

38-41: Add documentation and consider making the return type non-null.

While the role-based access control has been correctly implemented with @role(requires: ADMIN), there are still a couple of improvements to consider from the previous review:

  1. Add documentation comments to explain the mutation's purpose and behavior
  2. Consider making the return type non-null (UserTag!) since the operation should always return a tag when successful

Apply this diff to implement these improvements:

+"""
+Adds multiple users to a user tag.
+Requires admin role and authentication.
+@param input - Contains tagId and list of userIds to be tagged
+@returns The updated user tag with newly added users
+@throws If tag doesn't exist or users can't be added
+"""
-addPeopleToUserTag(input: AddPeopleToUserTagInput!): UserTag
+addPeopleToUserTag(input: AddPeopleToUserTagInput!): UserTag!
   @auth
   @role(requires: ADMIN)
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e18b739 and 8a5fb72.

📒 Files selected for processing (3)
  • src/resolvers/Mutation/addPeopleToUserTag.ts (1 hunks)
  • src/resolvers/UserTag/usersToAssignTo.ts (1 hunks)
  • src/typeDefs/mutations.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/resolvers/Mutation/addPeopleToUserTag.ts
🔇 Additional comments (1)
src/resolvers/UserTag/usersToAssignTo.ts (1)

38-129: Well-implemented resolver with proper error handling and optimization

The resolver implementation demonstrates several good practices:

  • Comprehensive input validation
  • Efficient use of MongoDB aggregation pipeline
  • Proper error handling with GraphQL errors
  • Optimized query execution using Promise.all

src/resolvers/UserTag/usersToAssignTo.ts Show resolved Hide resolved
@meetulr
Copy link
Author

meetulr commented Oct 25, 2024

@coderabbitai all good?

Copy link

coderabbitai bot commented Oct 25, 2024

@meetulr: Yes, everything looks good! Your implementation of the addPeopleToUserTag functionality is well-structured and includes comprehensive error handling and tests. Great work!

(_/)
(•_•)
/ >🎉

✅ Actions performed

Comments resolved and changes approved.

Copy link
Member

@beingnoble03 beingnoble03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@meetulr looks good to me. User tags are going to be super useful!

@meetulr
Copy link
Author

meetulr commented Oct 27, 2024

@palisadoes please merge this so I can raise the next one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants