---
# System prepended metadata

title: Invitations for membership
tags: [Product]

---

---
tags: Product
--- 

# Invitations for membership
To cover: 
* Users who do not have an account already
* Users that do already have an Alkemio account

# Random Points to Consider
## Having a separate model
When designing User Invites, one has the choice between adding fields like `invite_token: string` to the existing model (e.g. `CommunityMembership`) or creating a new model, e.g. `Invite { token: string, targetId: string, targetType: 'CommunityMembership' }`. While the latter allows for greater flexibility while keeping the source model clean, the former simplifies things such as counting total users per organization including invites to that ogranization (may be needed to restrict inviting new users in case of e.g. paid plan limits).

## Setting up data structure in advance vs at the moment of accepting
The other subject to decide on is having an `Invite` pointing to a newly created semi-blank record (such as a User without the password) (1) or having the `Invite` holding all the fields that are used to initialize the new record at the moment invite is accepted (2).

1. The former simplifies the structure of the `Invite` as well as the `acceptInvite()` function (you just need to associate that semi-blank record with the current session and ask for missing info). It also allows to pre-setup complex associations between the invited user and a target community. E.g.: `user -> community_user_memberships -> community`.
2. The latter allows to use `Invite.token` as a self-sufficient credential whose holder has the flexibility to join under an existing user or create a new user using any login information/flow. While this approach seems to be more powerful and conceptually complete, it can also make it harder to create a UI like this:

| Name | Email | Status |
|------|-------|--------|
| Andrew | andrew@alkem.io | Active |
| John | john@example.com | Invited |
| 1, 2 ... N pages |

## Lifespan and Storage
Another thing to consider is the lifespan of an Invite. If invites are by design temporary, it may make sense to keep them in a temporary storage such as Redis, so that you don't need to run an e.g. Cron job to cleanup the DB. On the other side, it makes it even harder to query all invitations if invitations data is needed to build a UI.