Preface
Actual solution cannot be shared. It does not include any HIPAA non-compliant information, but the solution does involve proprietary technologies owned by my employer. This was developed as a stop-gap solution to an issue posed as a change in legislation required more rigid break systems for Illinois based employers. This was not intended to be a permanent solution, rather an improvement over an existing one.
Background
In January 2023, the One Day Rest in Seven Act was passed in the state of Illinois. The largest item of note was the requirement for employers to only schedule employees a maximum of six continuous days. However, a smaller footnote would cement policies that most workplaces would follow, dictating when an employee is entitled to a half-hour meal break and a twenty (20) minute break. To ensure that all campuses complied with Illinois state law, our HR policy was amended to indicate the requirement of department heads and leadership to ensure that employees took their breaks. However, to effectively do this, there are 2 parts of each step in each part of the process. In my experience, the more complex an implementation is, the less likely a policy is to be followed fully. And as expected, this was what happened. Employees were not fully completing all steps to ensure proper documentation of their meal breaks. What then was this process?
- Employees would need to claim their meal break time at the start of their shift in a document to ensure department head tracking and access.
- Employees would need to indicate the start of their meal break by messaging a specific chat to ensure leadership knew the gap in coverage.
- Employees would need to indicate the return from their meal break by messaging a specific chat to ensure leadership knew the coverage was filled.
- Employees would need to sign off on their meal break time after their break was completed but before the end of their shift.
In comparison to how this was done by most other employers, it was clear that this was a short term solution waiting to burst at the seams for multiple reasons.
- Finding the correct document to claim their meal break time was difficult, especially for employees who were not regularly attached to a single computer. The vast majority of our department is designed to go between units to complete clerical work as needed.
- Finding the correct chat to indicate the start and end of a break suffered the same issue while existing in an entirely different location.
- Policies on properly indicating were communicated in a manner that did not clear up repeated confusion on the subject, most notably lacking examples of proper communication of break start and end times.
And as silly as it sounds, it only seemed odd to me that something wasn’t implemented sooner. Documenting meal times was normal for every other company I had worked for. However, since it was a new system, everyone in my department was complaining. It quickly became my point of frustration, not that it was complicated, but that people would not stop complaining that there wasn’t a better solution.
The Problem
It can be boiled down to a user experience issue. It’s cumbersome, complicated, and slow, and to the user, there is very little to get out of it. I think it would be most comparable to fishing in the intro of The Legend of Zelda: Twilight Princess, being strictly required to progress the story and grants no direct reward to the player. As my portfolio suggests, streamlining processes can be quite enjoyable to me and while we did not implement this pending a new official process being released the first of June, it still provided a learning experience.
Conceptualizing the solution
The actual problem is a solved one, which I think is important to note. We have a baseline that we can reference or augment to create a better solution. This also makes it easier to understand if progress was actually made. In general, there are only three (3) steps needed out of the employee.
- Employee claims their desired meal time.
- Employee communicates the gap in coverage.
- Employee communicates return to workstation.
But on the backend, we need this information communicated across two (2) different channels: a short term and a long term one. Leadership needs a quick point of reference to know if and when their subordinates have been breaked. Department heads need to know trends of how long and when employees go on break. While my department loves to use Microsoft Word inappropriately, the long-term answer is an Microsoft Excel workbook that includes separate sheets for every day with a table containing all pertinent information: employee, claimed slot, start time, and end time. And since we are already in Excel, calculating the duration of breaks is as trivial as =[@[End Time]]-[@[Start Time]]
. Short term can be contained within a Microsoft Teams channel that will already inherit the corporate retention policy. There is still one missing piece of information which is the start times of each shift and their available claims. Illinois requires employees to have a meal break starting within the first 5 hours of their shift. So in addition to the data output table, we would need a data input table to say when the shifts start being when the claim cards should spawn and when the expected scheduled meal starts. I elected to also have this tied to the start time as breaks may start slightly earlier than designated. With a table containing all the information we need, we can pipe each row into a claim card. All we have to do is receive user input.
Adaptive Card Interface
Since we are using Teams, it would be easiest to use native systems to detect user input. Using Microsoft Power Automate, we can spawn adaptive cards one of a few ways. Adaptive cards are an easy way to create consistency in design across platforms for getting user input. This can range from a digital business card to a tee shirt order form. Since we are using Power Automate to pipe data through the claim cards, each row will be its own entity with the submit action adding additional information. In theory, we could do this with radio buttons, but it will make more sense why we feed it through this way later. The cards themselves end up being very basic, titled with the slot’s name, the anticipated start and end times, and a submit action button, but they will be shared top level inside the channel itself, not requiring the end user to navigate a file structure. Originally, I designed it all to happen concurrently using the Power Automate command “Post an adaptive card in a channel or chat and wait for user input”; however, this requires the explicit creation and declaration of every position within Power Automate’s flow. Since this is a stop-gap solution, this wouldn’t be too much of an issue, but it does mean that I would have to explicitly declare every position. Instead, I used the command “Post a card in a channel or chat”, this differs in that it does not wait for user input directly. It triggers an event “When user interacts with an adaptive card”, which can be paired one of the card’s properties. Now, we just set the trigger property for all cards to be a meal claim event.
Meal Start and Meal End
Similar to meal claim cards, we can use adaptive cards to test user inputs of meal start. However, to prevent meal start cards getting buried in the user’s direct messages, we only submit it just prior to the user’s meal start time. And just the same, we can use the same method to wait to just shy of the user’s meal’s end (possession in English is great). We can even throw on the times we expect the user to go from the meal properties that were piped from the source card and then the submission time of meal start card. One problem I have been dancing around though is a big one, one that requires tricking Power Automate to do something it isn’t exactly designed to do.
Halting and Waiting within Power Automate
Power Automate makes it incredibly easy to do things concurrently or sequentially, but what it doesn’t like to wait. At least in the sense of specific durations or till a specific time while staying within the same flow. Something you can find in some form in most scripting languages is simply missing as an explicit function or command. That is without thinking outside the box.
Power Automate features a module called Control that has a command called “Do Until”. By its name, you would think that it in fact can wait until a specific time, but it is more like most languages while statements. It does commands until a condition is met. The question becomes how do we make it check the time to make it our needed halt script command. The obvious solution is to tell it to check the time and make that our condition. Using the expression utcNow()
, we can see the current time. Using a bit of nesting, we get convertFromUtc(utcNow(),’Central Standard Time’)
so I don’t have to explain to my boss why keeping track of time zones is a headache. Unfortunately for me, JSON does not natively have a time object, and in the infinite wisdom of the universe, JSON stores date-time like objects as strings. So to effectively get the hour, we use the expression float(convertFromUtc(utcNow(),’Central Standard Time’,'HH.mm'))
. This should allow us to use functions for time being equal-to or greater-than-or-equal-to to directly compare now to our target time. Since we are only going as far as to check minutes, we can tell the function only to check every minute. Where we once again run into the problem, how do we make it pause for time?
We can nest “Do Until” commands within each other, and we can almost make “Do Until” commands run indefinitely. That is with a big asterisk of its exit conditions. “Do Until” will not let you run something run indefinitely, there must be a count or time restriction associated with the command. That time restriction cannot be piped in as a variable. That does allow us to cleverly make something that runs for exact durations of time, like 1 minute. So “Do Until 0 equals 1 for PT1M”. This however causes a new problem, “Do Until” requires commands to function. In the outer layer of “Do Until” have “Do Until” and update the variable representing the current time. The inner layer needs something happening, like a counter that ticks up for no reason.
Review
Overall, discovering the solution was informative about the limitations of Power Automate, but also how to work around these limitations. Unfortunately, unlike with the included flowcharts, Power Automate does not let the user call lambda functions or subroutines. I hope in the future that Power Automate adds features like “halt for this duration” or “halt until this time” in a more official capacity. The hacky nature of the actual process is endearing in a way, but it also can be seen as headache for readability. And since the new designer for Power Automate has less than official ways to add comments, it becomes a bit annoying to explain why things function the way they do.
Stray Thoughts
Power Automate is extremely powerful, even without being an owner on a Teams account. It still permits me to post adaptive cards and read data from them which could be a bit of a security concern if Teams was actually more secure than it is. The nature of Teams only has the level of security that exists within an instance of Active Directory and SharePoint, the former is well known by most organizations. The latter is a bit cryptic, as it acts like an older version of OneDrive, something that uses Active Directory user permissions as its structure. But since it’s its own beast, it functions in a wholly unique way. So while Teams feels like an obvious answer to quick communication, it comes with its own set of challenges that are better answered by programs like Slack or Discord better. Do keep in mind that each comes with their own EULAs which may not work for your company.