A maintenance plan is a recurring instruction to perform a specific intervention on a specific asset, on a specific trigger. Every 250 hours on the forklift. Every 6 months on the HVAC. When the press’s vibration exceeds 8 mm/s. Plans are how Beelocity distinguishes itself from a reactive ticket system — without plans, all maintenance is breakdown maintenance, and the module is mostly post-mortem.
The plan header
A plan carries:
- Code and name — stable identifier and human label.
- Flavour —
PREVENTIVE,INSPECTION,CALIBRATION, orCONDITION_BASED. Drives default remedy filtering and KPI bucketing. - Scope — either a single asset (this specific press) or an asset class, narrowed if you want by criticality: every CNC mill, or every A-critical HVAC unit. You choose which of the two the plan covers and the page asks only for that one; the ranks are picked from the three rather than typed.
- Default team — the crew that picks up the work orders this plan raises.
- Default priority — written onto each work order the plan raises; the lower the number, the more urgent.
- Advance notice (days) — how far ahead of the due date the scheduler raises the work order. One value (14 days by default) applies to every trigger type. This is the planner’s review window, not a parts lead time. It read Lead time until the two senses were split; French and Arabic had always said Délai d’anticipation /
مهلة الاستباق, and the English says it now. - Slack % — tolerance around the nominal trigger. A 250-hour plan with 10% slack generates anywhere between 225 and 275 hours. Prevents drift accumulation.
- Suspended until — optional pause date when the asset is mothballed or a plan is on hold.
Triggers
A plan has one or more triggers. Each says “fire when this condition is met.”
- Time triggers — every N days / weeks / months / years, counted from either a fixed base date, the previous due date, or the previous work-order close (each cycle starts after the last one).
- Meter triggers — every N units of a counter, relative to either the previous work order’s at-close meter (every N hours of usage since last service) or zero (a milestone service at the 1000-hour mark).
- Condition triggers — when a windowed statistic of condition readings crosses a threshold. Examples: replace the bearing when vibration RMS exceeds 8 mm/s across the last 5 readings; escalate when oil acidity crosses 0.5 pH delta sustained over 7 days.
Multi-trigger plans (e.g., service every 500 hours or every 6 months, whichever first) fire on whichever trigger crosses first; the at-close meter and date become the new baseline for both.
Task templates
The plan detail page has a Tasks tab listing the ordered template the technician must perform on each work order the plan raises. Each task has:
- A sequence number (10, 20, 30 — leaves room for insertions).
- A name and free-form instructions.
- An estimated duration in seconds — used for the duration rollup and downtime previews.
- An optional skill code — the team picker warns if the assigned crew lacks the skill.
- A Lockout required flag — the machine has to be isolated and tagged before the step, and the work order asks the technician to confirm it.
Tasks are copied onto each work order the plan raises, so editing the plan does not reach a job already raised.
Parts templates
The plan detail page also has a Parts tab listing the spare parts the plan typically consumes — engine oil, filter, grease. These rows are copied onto the work orders the plan raises, so the storeroom can pick them in advance; the technician confirms what actually went out when the job closes. Optional parts are flagged separately so the technician knows they might not be needed.
The scheduler
The scheduler is a background job that runs hourly. It is also called synchronously after each meter reading, so meter-based plans fire within milliseconds of the reading that crosses the threshold.
Four principles:
- Idempotent — re-running the scheduler doesn’t raise duplicates. The plan is only eligible again once the work order it last raised closes or is cancelled.
- Resilient to missed ticks — the next-fire computation is a function of the asset’s current state and the plan configuration, not of when the scheduler last ran. A scheduler that misses six hours of ticks catches up on the next run without losing or duplicating triggers.
- Synchronous on meter reading — meter-based plans fire within milliseconds of the reading.
- Multi-trigger first-wins — whichever trigger crosses first raises the work order and resets the others.
The work orders land in PLANNED status. The planner reviews, possibly bundles adjacent ones on the same asset (one downtime window covers all three), and explicitly releases them to SCHEDULED.
Plan governance
Plans drift. A plan written for a forklift that’s since been replaced may still be triggering services based on stale assumptions. Two governance hooks keep the catalog honest:
- Reviewed-at watchdog — when a plan has not been opened, edited or marked reviewed for more than 12 months it’s flagged Stale. The list page writes Stale in amber on the Reviewed column, and choosing Stale — Yes in the list’s filter panel (the funnel beside the search box) narrows the grid down to just those rows so the planning team can sweep through them at audit time; Stale — No is the other half, the plans reviewed within the year. The verdict is computed once, where the plans are served, so the flag and the filter can never disagree.
- Drift watchdog — when the last five work orders a plan raised all overshot their labor estimate by more than two times, the plan is marked Drift detected on the list, and a Drift warning section appears on the plan’s own page. The task durations are out of date — open the plan, tighten each task’s estimated duration on the Tasks tab, and the flag clears on the next edit. Drift — Yes in the filter panel lists them.
The same panel narrows by Flavour, Asset, Asset / class, Default team, Active, a lead-time, slack or priority range, or a Suspended until / Reviewed date window (Working with lists).
Neither hook auto-mutates a plan — every change is human-driven.
Marking a plan reviewed
When you open a plan, confirm the triggers, tasks, parts, advance notice and slack still match how the asset is actually maintained, and either edit the plan or — if nothing needs changing — click More actions → Mark reviewed at the bottom of the page. The action stamps today’s date as the new last-reviewed timestamp, clears the Stale flag, and silences the watchdog for another 12 months.
The plan’s tabs narrow on their own filter button too: Triggers by Kind, Interval unit, Meter unit, Active or an interval / threshold range; Tasks by Lockout, Active, Skill code or an estimated-duration range; Parts by Part, Unit, Optional, Active or a quantity range.
Preview and manual run
Two helper actions live under More actions, at the bottom of the plan’s page:
- Preview — opens a side drawer listing the next firings for each active trigger across a horizon you control (1 to 365 days, default 30). Time-based triggers project a date; meter-based and condition-based triggers can’t be projected without live usage or sensor readings, so they appear in the list with no date and an explanatory note. Opening the drawer is strictly read-only — no work orders are created.
- Run scheduler — bypass the hourly tick and run the scheduler for one specific plan now. Useful after editing a trigger configuration, or to shorten the loop while debugging a new plan.
Running the scheduler manually
Open the plan’s page and choose More actions → Run scheduler. A confirmation dialog warns that the action is non-reversible — any triggers inside their lead-time window will materialise PLANNED work orders against every in-scope asset, and you’ll have to cancel them manually if you didn’t want them. Confirming runs the scheduler immediately; a toast at the bottom of the screen reports how many work orders were materialised (zero if no trigger crossed since the last run).
The action is gated by the MAINTENANCE_SCHEDULER_RUN permission. Planners typically have it; technicians don’t. If the action isn’t in the menu on your plan’s page, ask an admin to grant the permission to your role.
The scheduler is idempotent — running it twice in a row won’t generate duplicates. The second run only picks up triggers that crossed between the two calls.