Diagnostics Built
Four read-only screens that let you see exactly what the system did behind the scenes on any given day — every scheduler run, every record they skipped, every automated health check, and every notification the portal sent — without touching a server log.
Background Schedulers describes the four jobs that run unattended every day — auto-reservation, auto-wave creation, the health check and gateway settlement bifurcation. This page is where you go to find out, after the fact, exactly what each run did: how many records it touched, what it skipped and why, and whether the system's own health check found anything wrong. The fourth screen, Notification Logs, is the same idea for outbound messages — a record of every notification the portal tried to send. Nothing here is created or edited by hand — every row is written automatically by the system.
Where to find it & who can see it
All four screens sit together under the Diagnostics group in the left navigation — Scheduler Runs, Dropped Records, Health Checks and Notification Logs. Every one of them is gated on the single permission diagnostics.view (or super administrator); there is no finer split between them, and none of them has a create, edit or delete page — they are strictly read-only history.
Scheduler Runs
Every time one of the four daily jobs executes, it writes one Scheduler Runs row for that execution — a record of what it was asked to do and how it went. This is the first place to check if you suspect a job didn't run, ran late, or ran into trouble.
| Column | Shows |
|---|---|
job_key | Badge identifying which job produced this run — for example air:auto-reserve, air:auto-wave, air:health-check or air:bifurcate-settlements (see Schedulers for what each one does). Searchable and sortable. |
| Status | A coloured badge: Running, Success, Warning or Failed. |
started_at | Date and time the run began. Sortable — this is the list's default sort, most recent first. |
finished_at | Date and time the run ended. Sortable; blank (shown as "—") while a run is still Running. |
| In | input_count — how many candidate records the run considered. |
| Done | processed_count — how many it successfully processed. |
| Skipped | skipped_count — how many it deliberately left alone (see Dropped Records below for the individual reasons). |
| Failed | failed_count — how many it attempted but could not complete. |
| Message | A free-text summary from the job, truncated to 50 characters with the full text on hover. Toggleable column. |
Select Filters to narrow by Status (all four values) or by Job key (a drop-down built from every distinct job key seen so far — so it always lists exactly the jobs that have actually run).
Dropped Records
When a job deliberately declines to process something — a stock move it won't auto-reserve, a statement line it can't match, a candidate that fails a business rule — it writes one Dropped Records row per skipped item, linked back to the Scheduler Run that produced it. This is the "why" behind every skipped_count you see above.
| Column | Shows |
|---|---|
| Run | schedulerRun.job_key, badge — which job's run this record belongs to. |
| Stage | Badge naming the point in the job's process where it stopped — a short label the job itself assigns. |
| Model | The type of record that was skipped, shown as its short class name (for example StockMove) rather than the full namespaced class. |
| Record | record_identifier — the identifying reference of the specific record that was skipped. Searchable. |
| Reason | A free-text explanation from the job, truncated to 60 characters with the full text on hover. Searchable. |
| Field | field — where relevant, the specific field the job's decision turned on. |
created_at | Date and time the record was written. Sortable — this is the list's default sort, most recent first. |
Select Filters to narrow by Stage (built from every distinct stage value seen so far) or by Run (a searchable drop-down of Scheduler Run job keys, so you can pull up everything one specific run dropped).
If a colleague asks why a particular stock move never got auto-reserved, filter Dropped Records by Run for the relevant air:auto-reserve execution (found via Scheduler Runs), then search by the move's reference in Record. The Reason column tells you exactly what rule stopped it — see Stock Moves to then act on the move itself.
Health Check Results
The daily health-check job (air:health-check, see Schedulers) runs a set of individual checks against the system and writes one Health Check Results row per check, each linked back to that day's Scheduler Run. This is where you read the outcome of that job — there is no separate dashboard for it.
| Column | Shows |
|---|---|
check_key | Badge identifying which check this row is. Searchable. |
| Label | A human-readable name for the check. Searchable. |
| OK | is_ok — a boolean icon: a tick if the check passed, a cross if it did not. |
| Issues | issue_count — how many individual problems the check found (zero when is_ok is true). |
| Result | Free-text detail from the check, truncated to 50 characters with the full text on hover. |
checked_at | Date and time the check ran. Sortable — this is the list's default sort, most recent first. |
| Run | schedulerRun.job_key — the health-check run this result belongs to. Hidden by default; switch it on from the column toggle. |
Select Filters to narrow by Status — a three-way toggle over is_ok (all / passing / failing) — or by Check key (built from every distinct check seen so far).
Notification Log
Every time the portal notifies someone — a staff member or a customer — it fans the message out across one or more channels: the in-app bell, a mobile push, an SMS and an email. The Notification Log writes one row for each channel of each notification, recording whether that channel went out or failed. It is the answer to "did we actually tell the customer their order shipped, and over which channel?"
| Column | Shows |
|---|---|
| Sent at | When the delivery was attempted. The list is sorted newest-first. |
| Recipient | The user the notification was addressed to (blank if that user has since been removed). |
| Channel | Which channel this row is for — In app, Push, SMS or Email. A single notification sent over three channels produces three rows. |
| Status | Sent if the channel dispatched without error, or Failed if it threw. Filterable. |
| Category / Title | The notification's type and headline, captured from the message so you can tell what it was about. |
| Error | On a failed row, the error message the channel raised — the starting point for diagnosing a delivery problem. Blank on successful rows. |
Use Filters to narrow by Channel or Status — for example, show only Failed SMS rows to spot a gateway problem. The Notifications page covers the in-app inbox those messages also land in.
A Sent row means the portal handed the message to its channel without an error — not that the carrier or mailbox confirmed delivery. True delivery receipts arrive later, once the real SMS/email providers are connected. Treat this log as "what AIR tried to send", which is exactly what you need to prove a customer was notified and to catch failures early.
Related pages
Start at Schedulers to understand what each job does and when it runs — this page only shows their history. See Stock Moves and Stock on hand for the records auto-reservation and auto-wave actually touch, Picking Waves for what auto-wave creation feeds into, and Bank Reconciliation for the statements gateway settlement bifurcation works against.