KM SOFT

Dedicated CRM for homeowners

Implementing user invitations

Duration: 2021.09 - 2021.11 (3 months)
Technologies: Ruby, Rails, PostgreSQL, JavaScript, HTML, CSS
Methodology: Kanban

Overview

At Ironin Software House, my role involved developing few features to a web application tailored for property owners. This platform enables users to catalog their properties and manage related communications and digital documents, such as bills, contracts, and maintenance records.

The application was developed using Ruby on Rails, with HTML content generated on the backend and the Trailblazer framework for extra architectural building blocks (form objects, operations).

Project Scope

The project’s scope included several functionalities:

  • User Invitations: Implementing a feature that allows property owners to send invitations to other users, to delegate the properties’ management process, This also included the capability for owners to manage these invitations (listing sent invitations, deleting, re-sending).

  • Access Control List: Developing a page that lists all users who have access to their properties’ panel.

  • Role-Based Access Control: Allow the owner to limit access to certain areas of their properties’ panel based on the user’s role. Each invitation sent to a user specified their role, determining the level of access granted within the platform.

Implementing User Invitations

While the initial task description recommended using the Devise Invitable gem, I evaluated this approach and determined it would not meet our requirements.

The fact that the inviteable creates user records upon sending the invitation, polluting the user table with invitation-related columns we don’t even need, was my first concern.

But what if two owners send invitations to the same email address within a short period of time (so that user receive 2 invitations on the email)?

Or what if invited email address already already exists in our database?

These questions guided my thought process to realize that our use case is different. The inviteable gem use case is to invite the user to the application itself.

While our case it to invite the user to an owner’s properties’ panel.

The fact that a user is already registered in the system should not prevent the owner from inviting them. It should not even be considered a special case. Whether the user already has an account in the application is merely a detail and is irrelevant to the owner.

And so I’ve came up with a design to:

  • create a separate table for user invitations (for keeping the invitation tokens and relevant data, like who invited, to which properties’ panel, etc),
  • delete the invitation record after the user accepted the it,
  • does not matter if user exists in the db, send invitations anyway (handle accepting differently),
  • list the invitations record to the owners in it’s panel so that they could re-send, edit/correct details, delete.

Here is the flow chart:

User invitation flow
User invitation flow

The above flow handles the following cases:

  • the invited user may or may not have an account in the application,
  • 2 or more property owners have invited the same e-mail and so user should be able to seemingly proceed by clicking first one of the links, then the second (in irrelevant order),
  • the user has created an account in the meantime (after the invitation was sent and before clicking the link),
  • the user had an account at the time of sending the invitation, but then deleted the account, and then clicked the invitation link.

After describing my argument to the CTO, we’ve agreed that this would be better approach.

Nothing worse that quickly implement the happy path and then struggle in the QA process as edge cases are being found.