Skip to content

Part 1 of 7 · Training reminder bot series ~6 min read

A training reminder bot on AWS for a few dollars a month

Required training is a problem that looks solved and is not. Somebody keeps a spreadsheet, everybody does their induction, and then two years pass. In that time four people changed roles, six refreshers came due, and two new starters joined during a busy month. Nobody was negligent; the spreadsheet just has no way to notice any of that. This post walks through a small system that derives the requirements rather than storing them.

person holding white printer paper
Photo by Dan Burton on Unsplash

Key takeaways

  • Requirements are derived from the role, so a role change recomputes them automatically.
  • A completion with a validity period generates its own next assignment.
  • The system tracks that training happened. It has no opinion about how it was delivered.
  • Nothing is marked complete by the system. A person confirms, and it is recorded who.
  • Designed on AWS for about $2 a month.

The whole system on one page

Before any code, here is the shape of what we are designing.

System: roles and requirements in, assignments and chases outThree boxes across the top sit outside the AWS account. On the left, Staff and roles: who does what. In the middle, Requirements: the mapping from role to training, each with a validity period. On the right, People and managers: who gets assigned and chased. Each connects by an arrow to the AWS account container below. Who holds which role flows down into the account. The requirements feed in what each role needs. Assignments and chases go back out. Inside the AWS account are three components in a row. On the left, the Requirements engine, which takes a role and produces a training list. In the middle, the Assigner, which acts on joining, on a role change and on expiry. On the right, the Chaser, which handles what is outstanding and produces the weekly gap report. A note at the bottom says requirements are derived and never stored per person, which is what makes changes free.AWS ACCOUNTStaff and roleswho does whatRequirementsrole to training,with validityPeople and managersassigned and chasedRequirements enginerole in,training list outAssigneron join, on change,on expiryChaseroutstanding, thenthe weekly gapwho holds whichrolewhat each roleneedsassignments andchasesRequirements are derived, never stored per person. That is what makes changes free.
Fig 1. Three things outside the account, three pieces inside it. Deriving requirements rather than storing them per person is the decision that makes role changes and new requirements propagate without anybody doing anything.
  • App integration
  • Analytics
  • People

Derived, not stored

The obvious model is a list per person of what they need. It works on the day it is built and decays from then on, because when a requirement is added to a role, somebody has to go and add it to every person in that role, and that is exactly the step that does not happen.

So requirements live once, against roles, and a person’s list is computed. Adding manual handling to the warehouse role assigns it to everybody in the warehouse that afternoon. Moving somebody from warehouse to delivery recomputes both lists. Neither requires anybody to remember anything, and that is nearly the whole value.

What runs (the inside)

  • The requirements engine. Takes a person’s role, plus any site or equipment attributes, and produces their required training list. It runs on a schedule as well as on change, so a requirement added in the sheet takes effect without a deploy or a trigger.
  • The assigner. Creates an assignment when a requirement appears that has no valid completion. Three causes: somebody joined, somebody’s role changed, or a completion expired. The third is most of them after the first year.
  • The chaser. Nudges the person, then their manager, then reports the gap weekly. It is deliberately gentle about individual chasing and quite direct about the aggregate, because a training gap is a management problem rather than a personal failing.

One requirement, end to end

One training requirement from role to refresher, in five stagesA horizontal row of five boxes joined by arrows. Role held: warehouse operative. Requirement: manual handling, valid three years. Assigned: because there is no valid completion. Completed: confirmed by a person. Re-assigned: in three years, automatically. A note says the fifth box needs nobody to remember anything, which is the entire product.ONE REQUIREMENT, END TO ENDRole heldwarehouse operativeRequirementmanual handling, 3yrAssignedno valid completionCompletedconfirmed by a personRe-assignedin three years, automaticallyThe fifth box needs nobody to remember anything, which is the entire product.
Fig 2. The same system as one line. The loop closes on itself: a completion with a validity period schedules its own successor.
  • Machine learning
  • Management
  • People

In plain words

A new warehouse operative joins in March. The requirements engine reads their role and produces four requirements: manual handling, fire safety, the site induction and abrasive wheels. None has a valid completion, so four assignments are created on their first day, each with a due date from the requirement’s own grace period — the induction is due day one, manual handling within two weeks, abrasive wheels within a month.

Three of the four are done in the first fortnight and their supervisor confirms each one. Abrasive wheels is not, because the course is monthly and the next one is the 14th. The chaser nudges at the due date, then tells the supervisor at a week over, and the person appears in the weekly gap report until it is done. Two years and eleven months later, the manual handling completion approaches its three-year validity, an assignment appears, and the whole cycle repeats without a single human having thought about a date.

Design rules that shaped every decision

  • Derive requirements from roles. A stored per-person list is correct on the day it is written and decays from then on.
  • A completion with a validity period schedules its own successor. Refreshers must not depend on memory.
  • Never mark anything complete automatically. A completion is a claim somebody makes, and the record says who made it.
  • Chase people gently and report the aggregate directly. A training gap is a management problem.
  • A requirement removed from a role becomes not-required, not deleted. Past completions still matter.
  • Grace periods belong to the requirement. An induction is due on day one; a course that runs monthly is not.

Why this shape

Training tracking is one of those problems where the data is easy and the maintenance is everything. Any spreadsheet can record who did what. The difficulty is that the right answer changes constantly for reasons nobody notices — a role changes, a requirement is added, three years pass — and each of those changes requires somebody to go and update rows by hand.

So the design removes the per-person list entirely. There is a role-to-training mapping, a set of completions, and everything else is computed on a schedule. The system has almost no state of its own, which is why it is still correct two years after anybody last thought about it.

The next four posts walk through each piece: how requirements are derived, how assignments are created, how completions get recorded, and what the gap report shows. One diagram per post, a cost breakdown, and an engineering reference at the end.

All posts