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

🚀 Feature: Add a Membership ID parameter on creating membership #7193

Open
1 of 2 tasks
moshOntong-IT opened this issue Nov 22, 2023 · 7 comments
Open
1 of 2 tasks
Assignees
Labels
enhancement New feature or request product / auth Fixes and upgrades for the Appwrite Auth / Users / Teams services.

Comments

@moshOntong-IT
Copy link

moshOntong-IT commented Nov 22, 2023

🔖 Feature description

Currently, the createMembership api, does not provide a id parameter here. It seems that it automatically use the unique() to create a membership ID. so can we add a id parameter on createMembership api method.

🎤 Pitch

In my use case, I manage an org collection and an org-member collection. My approach for assigning roles to each member led to the creation of the org-member collection. When creating an org-member, a function triggers a call to Appwrite's createMembership API. I aim to reference the membership ID from the createMembership API to the ID of the document in my org-member collection. This strategy simplifies the process, as it avoids the need for additional queries to retrieve member information.

👀 Have you spent some time to check if this issue has been raised before?

  • I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

@Haimantika
Copy link
Contributor

Thanks for the feature request @moshOntong-IT. Will be keeping this open to the community to get some upvotes and conversation ongoing. Meanwhile, I have also brought up this conversation internally with the team.

@stnguyen90
Copy link
Contributor

This strategy simplifies the process, as it avoids the need for additional queries to retrieve member information.

@moshOntong-IT would you please provide more detail about this part?

@stnguyen90 stnguyen90 added the product / auth Fixes and upgrades for the Appwrite Auth / Users / Teams services. label Nov 24, 2023
@moshOntong-IT
Copy link
Author

This strategy simplifies the process, as it avoids the need for additional queries to retrieve member information.

@moshOntong-IT would you please provide more detail about this part?

Oh what I am talking about here is that, It will simplifies the queries, since My document ID from org-member collection is not the same to the membership id from Team service. Because in my org-member collection will handle more information about the member. So If I am querying about the member so I hope the document ID and membership Id is the same, something like I can use in my future implementation.

@moshOntong-IT
Copy link
Author

This strategy simplifies the process, as it avoids the need for additional queries to retrieve member information.

@moshOntong-IT would you please provide more detail about this part?

The other detail is also that. I have these membership and taramed license collections.. The membership collections contains, a healthcare professional. As we know that the healthcare professional will have numerous profession. Because they can take Pre med. Some healthcare professional has profession of Pharmacist, Pathologist, and etc; these are Pre med before they take doctor course. Hence, my membership collection will have more than profession. Hence, the two collection I mentioned have relationship. Taramed License will have more than one of membership, while membership contains one Taramed License (One to many) .This profession I talk about will be consider as ROLES of the team.

Membership collection, have status enum attribute (pending,approved, reject). When our administration approved their membership, they will be added on specific team (the team I mean here is the team feature of appwrite). Now I have this function listen to the update event of this membership collection, the function is the handler of automatically adding this member to the team. Now here is the point of why we need membership ID. First thing is that I have to check first if this member is already on the team, I want to use the ID OF the Taramed License as the membership id. But the problem here is that the createMembership method does not provide an Membership ID. So I cannot achieve my goal, however I have alternative solution, I have to create a seperate attribute for membership id in Taramed License collection. The default value of membership id from Taramed License collection is null. So overall, it needs for additional queries. So I hope so we will have efficient way by providing a membership id in createMembership method. And again I want to make the Taramed License ID as the membership ID so when I creating a membership in team I can use that ID of the Taramed License document.

@moshOntong-IT
Copy link
Author

This strategy simplifies the process, as it avoids the need for additional queries to retrieve member information.

@moshOntong-IT would you please provide more detail about this part?

The other detail is also that. I have these membership and taramed license collections.. The membership collections contains, a healthcare professional. As we know that the healthcare professional will have numerous profession. Because they can take Pre med. Some healthcare professional has profession of Pharmacist, Pathologist, and etc; these are Pre med before they take doctor course. Hence, my membership collection will have more than profession. Hence, the two collection I mentioned have relationship. Taramed License will have more than one of membership, while membership contains one Taramed License (One to many) .This profession I talk about will be consider as ROLES of the team.

Membership collection, have status enum attribute (pending,approved, reject). When our administration approved their membership, they will be added on specific team (the team I mean here is the team feature of appwrite). Now I have this function listen to the update event of this membership collection, the function is the handler of automatically adding this member to the team. Now here is the point of why we need membership ID. First thing is that I have to check first if this member is already on the team, I want to use the ID OF the Taramed License as the membership id. But the problem here is that the createMembership method does not provide an Membership ID. So I cannot achieve my goal, however I have alternative solution, I have to create a seperate attribute for membership id in Taramed License collection. The default value of membership id from Taramed License collection is null. So overall, it needs for additional queries. So I hope so we will have efficient way by providing a membership id in createMembership method. And again I want to make the Taramed License ID as the membership ID so when I creating a membership in team I can use that ID of the Taramed License document.

If you curious about why we need to check first if this member is already exist on team. Well, as I said that the healthcare professional have numerious profession/specialist. So if this member is already exist then I just update the Role.

@stnguyen90
Copy link
Contributor

@moshOntong-IT, thanks for the details! 🙏 Are you saying if you were able to set the membership id, you wouldn't need to do additional queries? Can you maybe provide some code to clarify your problem with additional queries?

@moshOntong-IT
Copy link
Author

@moshOntong-IT, thanks for the details! 🙏 Are you saying if you were able to set the membership id, you wouldn't need to do additional queries? Can you maybe provide some code to clarify your problem with additional queries?

I dont have yet code for additional queries, but I just implement the alternative solution here.

import { ID, Databases, Query, Permission, Role, Teams } from 'node-appwrite';

export const confirmMembershipHandler = async (
  req,
  res,
  log,
  error,
  client
) => {
  const data = req.body;
  const teams = new Teams(client);
  const databases = new Databases(client);
  var {
    userId,
    profession,
    taramedLicense: { membershipId },
  } = data;
  const { $id = '' } = profession ?? {};

  try {
    log(`Checking if user is existing on taramed team`);

    const { roles } = await getTeamMembership({
      client,
      userId,
      log,
      error,
    });

    if (!profession) {
      // * Why $id not code attribute?
      // * I decide to use the $id attribute because it is the unique identifier of the profession.
      // * Instead of using  the code attribute which it takes more space and more configuration.
      profession = {
        $id: 'Member',
      };
    }

    const response = await teams.updateMembership(
      process.env.TARAMED_TEAM_ID,
      membershipLicense.$id,
      [...roles, profession.$id]
    );

    return res.send(
      {
        message: 'Membership Approved successfully',
        data: response,
      },
      201,
      {
        'content-type': 'application/json',
      }
    );
  } catch (e) {
    error(`Membership Approval failed: ${e}`);
    return res.send(
      {
        message: e.message || 'Membership Approval failed',
      },
      e.code || 500,
      {
        'content-type': 'application/json',
      }
    );
  }
};

const getTeamMembership = async ({
  client,
  log,
  membershipId,

  userId,
}) => {
  const teams = new Teams(client);
  log(`Getting team membership with id: ${membershipId}`);

  if (!membershipId) {
    log(
      'User does not have membership yet in Taramed Professional, starting creation process'
    );
    const response = await teams.createMembership(
      process.env.TARAMED_TEAM_ID,
      [],
      undefined,
      userId
    );
    log(`Membership created: ${JSON.stringify(response)}`);
    return response;
  }

  const response = await teams.getMembership(
    process.env.TARAMED_TEAM_ID,
    membershipId
  );

  log(`Membership found: ${JSON.stringify(response)}`);
  return response;
};

This is my current solution I just added new attribute in my collection named membership ID and default value is null so I have condition here, This is a cloud function that listend to the update document of my collection. This is the sample req.body

{
    "type": "hcp",
    "status": "pending",
    "userRef": "6556394d221f8bc02090",
    "taramedLicenseRef": "65648e60f1dad50d21f7",
    "$id": "656490a862db6521ce2a",
    "$createdAt": "2023-11-27T12:50:48.683+00:00",
    "$updatedAt": "2023-11-27T12:50:48.683+00:00",
    "$permissions": [
        "read(\"users\")",
        "update(\"user:6556394d221f8bc02090\")",
        "delete(\"user:6556394d221f8bc02090\")"
    ],
    "license": {
        "backSide": "656490a728fdc835cb58",
        "frontSide": "656490a54bde30252749",
        "license": "andawbdhabwd",
        "$id": "656490a864117c3d5360",
        "$createdAt": "2023-11-27T12:50:48.687+00:00",
        "$updatedAt": "2023-11-27T12:50:48.687+00:00",
        "$permissions": [],
        "$databaseId": "6518bb74579884c77dcf",
        "$collectionId": "6554d86ade28313f6bfa"
    },
    "profession": {
        "name": "Pathologist",
        "$id": "TM002-A",
        "$createdAt": "2023-11-27T10:16:11.951+00:00",
        "$updatedAt": "2023-11-27T10:16:11.951+00:00",
        "$permissions": [],
        "$databaseId": "6518bb74579884c77dcf",
        "$collectionId": "655571d8c8f61e764e37"
    },
    "user": {
        "name": "Muslimin Ontong",
        "avatar": null,
        "$id": "6556394d221f8bc02090",
        "$createdAt": "2023-11-16T15:46:21.989+00:00",
        "$updatedAt": "2023-11-16T15:46:21.989+00:00",
        "$permissions": [
            "update(\"user:6556394d221f8bc02090\")",
            "delete(\"user:6556394d221f8bc02090\")"
        ],
        "$databaseId": "6518bb74579884c77dcf",
        "$collectionId": "6518bb8a8d94e9ed0ac3"
    },
    "taramedLicense": {
        "userRef": "6556394d221f8bc02090",
        "membershipId": null,
        "$id": "65648e60f1dad50d21f7",
        "$createdAt": "2023-11-27T12:41:04.992+00:00",
        "$updatedAt": "2023-11-27T12:41:04.992+00:00",
        "$permissions": [
            "read(\"users\")",
            "update(\"user:6556394d221f8bc02090\")",
            "delete(\"user:6556394d221f8bc02090\")"
        ],
        "user": {
            "name": "Muslimin Ontong",
            "avatar": null,
            "$id": "6556394d221f8bc02090",
            "$createdAt": "2023-11-16T15:46:21.989+00:00",
            "$updatedAt": "2023-11-16T15:46:21.989+00:00",
            "$permissions": [
                "update(\"user:6556394d221f8bc02090\")",
                "delete(\"user:6556394d221f8bc02090\")"
            ],
            "$databaseId": "6518bb74579884c77dcf",
            "$collectionId": "6518bb8a8d94e9ed0ac3"
        },
        "$databaseId": "6518bb74579884c77dcf",
        "$collectionId": "6554d5f710da1488287a"
    },
    "$databaseId": "6518bb74579884c77dcf",
    "$collectionId": "65648766a7b661dd6817"
}

As you can see here in taramedLicense object I have membershipId as my alternative solution. But I am hoping to not have membershipId attribute, I would like to use the id of taramedLicense as my membership ID.

    "taramedLicense": {
        "userRef": "6556394d221f8bc02090",
        "membershipId": null,
        "$id": "65648e60f1dad50d21f7",
        "$createdAt": "2023-11-27T12:41:04.992+00:00",
        "$updatedAt": "2023-11-27T12:41:04.992+00:00",
       ....

Now in regards of queries, for example that the user want to get his/her team membership, by using this

const promise = teams.listMemberships('[HIS_ORGANIZATION_ID]');

then get the ID of the specifc membership then execute this

databases.listDocuments('[DATABASE_ID]', '[COLLECTION_ID]', [Query.equal('membershipId', membershipId)])

I think is is not a efficient way, It prefer if I can execute like this. To avoid using queries

const promise = databases.getDocument('[DATABASE_ID]', '[COLLECTION_ID]', membershID);

As of now this is my idea yet. Idunno think so if we have alternative solution.

@stnguyen90 stnguyen90 self-assigned this Dec 11, 2023
@stnguyen90 stnguyen90 added enhancement New feature or request and removed feature labels Mar 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request product / auth Fixes and upgrades for the Appwrite Auth / Users / Teams services.
Projects
None yet
Development

No branches or pull requests

3 participants