Making deletion non-automatic

This is now part four of my ongoing blog posts on writing our latest web app HR Partner.  Parts one, two and three are here.

One of the things that we have realised from previous web apps we have written, is that the process of deleting critical data is almost automatic for most of our users.  Even putting the usual "stop and confirm" dialog box in front of them to make the absolutely sure they want to delete a piece of data becomes an automated response after doing it a few times.

For minor data like lookup files etc., this is not really a problem.  However, in HR Partner, the most critical data we have is the employees themselves.  We wanted to make the process of deleting an employee a tad difficult - to be absolutely sure that they could not do it accidentally.

To this end, we came up with the idea of the user having to type in a short deletion code, very similar to a Captcha code, each time they wanted to delete an employee.  Thankfully deleting employees is not a task done regularly, so we hope that the added thinking and stopgaps involved will not irritate users too much, but instead that they may be grateful for it.

When generating these codes, we also discovered that users could easily get confused between the letter O and the number 0 etc., so we decided to 'borrow' an algorithm that we spotted on StackOverflow to generate a non confusing code.  There should not be any guessing between the characters.  Here is the short helper code to generate the deletion code:

def generate_activation_code(size = 6)
  charset = %w{ 2 3 4 6 7 9 A C D E F G H J K M N P Q R T V W X Y Z}
  (0...size).map{ charset.to_a[rand(charset.size)] }.join
end

Have we gone overboard with this?  Would love to hear from other programmers and designers out there as to what you think about our approach.

Making user onboarding a smooth and pleasurable experience

This is part three of my regular blog posts describing the building of our new web app product, HR Partner.  Previous posts are available here and here.

In part one, I explained about the sign on methodology used - more specifically, how we would separate the user authentication system from the company databases.  This was to facilitate one user being able to work across multiple companies easily.

This workflow also meant that is user Bob wanted to work with company Acme Industries, then Bob would have to request an invitation to join Acme Industries as a user.  To do this, Bob simply clicks a link on the login screen and fills out his name and email address.

This information is then sent to the Acme Industries company admin user.  They can then log in to HR Partner and in 2 clicks, approve Bob's application to join (or ignore it).

In our early Alpha testing, whenever the company admin approved a user's request, the requesting user (Bob in this case) would automatically have an account created for him, and be sent back a generic congratulatory email telling them that they could now log into the system and begin working with Acme Industries.

But wait - we have an edge case here that needs to be looked at more closely.

We have to consider whether Bob is a brand new user to the HR Partner ecosystem, or whether he has been around for a while and already has an active logon account.

If he already has an account, then he does not need to do anything more than to click on the custom company HR Partner URL to log in immediately.

If he is a NEW user, then his account would have been created automatically when he was approved, and now he has to create his password before he can log in.

TWO distinct paths of action, depending on their initial status.  However, our initial version of the invitation process had only ONE generic email back to the invitee, asking him or her to either login or go through the password reset process.

Actually, to be honest, the initial version was clunkier than that.  We actually sent back the congratulatory email, and added a proviso that if they were a new user, they were to expect a SECOND email shortly with the password reset instructions, upon which we would generate and send them a password reset email (the same password resent email as if the user had asked for one on the site).

I thought that it was ridiculous - getting one, sometimes two emails back from us depending on their status.  I resolved to make this easier by only sending back ONE email to the user, and changing the content according to their initial status.

So now, the user gets back a nice congratulatory email, and within the email, they are EITHER shown a link to the company sign up page, OR they are given a link to the password reset page (our app now generates the password reset token before sending then the email, if they are a new user).

User already has an account with HR Partner and was approved to join a company.

User already has an account with HR Partner and was approved to join a company.

User is new and has had their account auto created.

User is new and has had their account auto created.

The end result is much less email clutter, and (hopefully) less confusion for the end user as part of his or her onboarding process.

NB: Upon further consideration, we are now working on the change password screen a little more too.  We want to customise this screen a little more so that when the app detects that it is a new user changing their password for the first time, that it shows up a little welcome message in there too - just to make the screen a little more friendly than the usual stark password reset form.

Normal password reset screen.

Normal password reset screen.

Password setup screen for new users.

Password setup screen for new users.

Both the above screen are actually exactly the same - it is just the wording that has been changed depending on the context - whether they are a brand new user, or an existing user wanting a reset.

 

Reducing 'browser detritus'

In part two of my notes and observations about designing our new web app, HR Partner, (part one here) I would like to talk about 'browser detritus'.  What is it?  Well, consider the following scenario.

In most web apps, if you forget your password, there is usually a handy little button or link on the login page somewhere that the user can click.  Usually, this will present him or her with a simple form where they enter their username or email address, and a password reset email will be sent to them post haste.

It is what happens after this that concerns me.  You see, in nearly all cases, the user is sent back to the original login form, along with some sort of notice to check their email for further instructions on resetting their password.

Now, most users would then either switch tabs or apps to their favourite email client, and check their email.  Naturally, most of these reset emails have a special link to click on which will ask the user to reset their password.

But...

Clicking on this link always, always, always opens up a NEW browser window with the reset form on it.  Meaning that the old login screen is still sitting, waiting, in the back there somewhere - now lost among a sea of browser tabs (in MY case, those tabs are spread across 3 different browsers usually).

Invariably, after going through this scenario myself, I will go to do some 'tab housekeeping' at the end of the day, and I will come across sign on screens still waiting for me like a faithful puppy at a train station.  Some days I cannot remember if I indeed reset that password yet, or if it was still something I had to do?

But look - I am as guilty as the next programmer/designer.  Our own web apps to date follow this same paradigm.

I decided to change that with HR Partner though.

At the risk of incurring the wrath of UX specialists everywhere, I actually introduced 'dead ends' in our web app sign on procedure.  When you tell HR Partner that you have lost your password, you will still get that form asking for your email address, but then, you will see a screen that tells you to check your email, and nothing else.  The screen does not even link back to any other screens in HR Partner, but instead asks you to close that browser window down now.

Our normal sign on screen - Whoops, I have forgotten my password.  No problems, click on the link...

Our normal sign on screen - Whoops, I have forgotten my password.  No problems, click on the link...

This is easy - I'll just type in my email address here...

This is easy - I'll just type in my email address here...

Aaaand - dead end! No going back, no going forward. Just close the browser window and wait to open another one automatically when you get the email...

Aaaand - dead end! No going back, no going forward. Just close the browser window and wait to open another one automatically when you get the email...

Is this too regimented? I think it is a step towards avoiding tabmageddon myself.  We are still in development with our web app, so might change this later, but for now, we have introduced these dead ends in a few spots during the onboarding process, including:

1. When the user asks for a password reset. [We have a password reset link in the email]

2. When the user asks for a reminder email with their company specific sign on link. [We have links in the email which take them straight to their required company link]

3. When the user reaches out to a company admin to be invited to join an existing HR Partner company. [We have to wait for the request to be approved by an admin, after which an email will be sent out with a link to complete their sign on process]

I must admit that deliberately designing this many 'dead ends' in an app made me pause at first, but I think at the end of the day it might be a good thing for the end user experience.  What are you thoughts?

Company hopping - the new work culture

Well, we are busy building our latest web app project, and this particular one is interesting in that it has clearly demonstrated how this niche target industry has changed in the last decade.

Backstory: We design an HR management app call HR Partner a long time ago in 2004.  Back then, it was a Windows based app, and was tied in very specifically to a particular legacy payroll system.  We did very well out of that application, but lack of support from the legacy payroll vendor and other reasons meant that we let that project slowly die on the vine.

However, we have had a solid core of users still using that system to this day, and who keep asking us when we are going to update it and add more to it.

Well, that lead me to decide to take up the mantle again, but this time, we are doing it differently.  While the core of the product will be similar, we will now be (a) building it as a purely web based application, rather than Windows, and (b) we will not be locking it into one vendor, but instead be able to integrate with several other more modern payroll systems out there.

In talking to existing users though, one point that I had never considered became more apparent.

Back in 2004, it was quite normal for most medium to large companies to have an internal HR manager on the staff.  Quite frequently, the Payroll manager also acted as the HR manager, instead of having a complete separation of duties.  In any case, it was really easy to just have internal team members working on their own isolated HR system, and everyone seemed happy.

However, the current batch of users that we have been talking to are painting a completely different picture.  Nowadays, it seems that more and more of the HR work is being outsourced to external consultants who are not attached directly to the company.

When we spoke to some of these consultants, they in turn gave us a look at their typical work patterns; which was to provide services to multiple companies, either in the same or totally different fields.  They explained that a lot of the times, internal staff and managers wanted to have complete control of the data, but they would look to external agencies to analyse that data and tell them how they could actually make better use of it.

This threw our design specs off kilter a bit.  In all our other web apps, building the sign on and authentication systems was easy.  You had one company, that all the data belonged to.  And within that company, you have one or more users who could create accounts directly attached to that company so they could work on the data.  If a user wanted to do work on another company, they would have to create a new sign on account for the other company to do work there.

We looked at our audience, and figured that this old method would not work.  The considerations we had were:

  • We would have users that would still want to only work on their own company, and are not interested in working in others, and
  • We would have users who would not 'belong' to any one specific company, but instead would be working on several and jumping back and forth on a regular basis.

Trying to cover all these bases proved to be quite tricky.  There were a lot of edge cases where we were not sure that things would flow well.  Maintaining security and privacy in this industry is quite critical, but at the same time, we didn't want that to put up too many roadblocks to people onboarding and using the system.

What we decided to do was to divorce the user authentication system from the company database system.  

How it works is - Users could still sign on and create a new company.  They would then become the 'owners' of that company.

Other users could then apply to be invited to a company.  The company owners would have to approve them joining up.  Other users could apply to join multiple companies if they liked, and use a single sign on to interact with all the companies they belong to.

I know this is not new ground, and that plenty of other systems utilise this methodology, but it was a new thing for us to tackle in our own design and development work.

Technologically, it was quite simple to manage.  What really had us stuck was the UX factors.  We wanted to make the process as easy and seamless as possible.  As I mentioned, I was surprised at the number of edge cases we came across with this new paradigm.  Problems that we had to think through were:

1. The new user conundrum

What happens when a completely new user wants to join a company?  Should we make them go through the whole process to set up their account details first, verify their account, then shoot a request to the company to see if they will be allowed to join?  

Our answer to this one was NO.  We would simply collect their name and email address on the request form and send it to the company admin.  IF the company admin approved them joining, then we would quietly create their account in our system using this information, and send the invitee an email asking them to click a link to set a password on their newly created account and log in straight away.

BONUS - As part of the '2 click' approval steps the company admin has to do, they are presented with a screen where they can customise the security parameters for the applicant.  They can, for instance, opt to lock the new applicant out of certain sensitive screens or prevent them from editing employee information etc.  That way, when the applicant first logs in, they are already preconfigured for what they are allowed/not allowed to see.

2. The old user failing to remember

To enable quicker sign ons, we give every company on HR Partner their own custom sign on URL link.  The problem with a consultant who signs on to a dozen companies is remembering these links.

To solve this, we make it easy from the sign on screen for the user to get an email from us listing all the companies that they have been approved to work with, and a 'one click' sign on link for each company.  No need for them to write it down or save it.  If they move to another machine (or mobile device) without the bookmarks, they can easily get another list sent to them within seconds.

BONUS - The user does not have to remember different passwords.  Just the URL, which is actually just the subdomain of the company, in the form of [company id].hrpartner.io/user/login

3. Dealing with bad users

One problem we are still working on is - what do we do with users who are removed from a company because of bad behaviour?  Say someone did something naughty in Company A, and were booted out by the admin.  Do we then have an obligation to tell Company B and C (if the user is authorised to use those companies as well)?

At this stage, we don't collect any information as to WHY the user was dissociated from a company.  We simply let the admin 'deauthorise' them.  Perhaps later we can collect reasons, and look at a process for vetting out problematic users to protect all our customers.

4. Handing over admin control

At present, we allocate the first company who created a company as the site administrator, who is responsible for approving new users who want to join.  We have not yet built in a mechanism for handing over control of a company to another user, but given the transient nature of so many people's jobs these days, I am thinking this is something we will have to do.

Once again, this will have to be carefully managed, as the company admin is essentially 'god', with many powers over the data and privacy of information.  We will have to build in safety checks with respect to the handover, but once again without affecting the UX negatively.

 

I would appreciate some feedback from anyone else out there who has tackled these sorts of issues in the past, or who could offer some tips and suggestions as to how we handle further development.  I intend to post a few more posts like this as we come across design issues on HR Partner.  Hopefully it will prove useful to the design and development community.