toga-ai 1.0.596 → 1.0.598
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/knowledge/2.0/apps/worker2/INDEX.md +2 -1
- package/knowledge/2.0/apps/worker2/features/cross-account-aws-access.md +1 -0
- package/knowledge/2.0/apps/worker2/features/elastic-beanstalk-health-monitor.md +182 -0
- package/knowledge/2.0/apps/worker2/features/oneuptime-worker2-monitoring.md +101 -7
- package/knowledge/2.0/standards/backend-php.md +23 -1
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/aig/INDEX.md +1 -1
- package/knowledge/clients/aig/features/entitlement-intake.md +24 -0
- package/knowledge/clients/aig/profile.md +5 -1
- package/knowledge/clients/nycdoe/INDEX.md +1 -1
- package/knowledge/clients/nycdoe/features/servicenow-integration.md +29 -1
- package/knowledge/clients/nycdoe/profile.md +8 -2
- package/knowledge/clients/prudential/INDEX.md +1 -0
- package/knowledge/clients/prudential/features/oneuptime-order-pipeline-monitors.md +108 -0
- package/knowledge/clients/prudential/profile.md +9 -1
- package/package.json +1 -1
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
| [Compass VIP Support Importer (worker2)](features/compass-vip-support-importer.md) | A worker2 action that ingests Compass's quarterly VIP spreadsheet and assigns each VIP user's support technician by setting `Users.c_supportedByUserId` in `Clie | worker2/Worker/Client/Compass/VipSupport.php |
|
|
19
19
|
| [Creating Worker Actions](features/creating-worker-actions.md) | How to add a new callable Worker action — a PHP class whose `public static` methods are invoked as background jobs (via webhook, cron, or `_Worker::runTask()`). | worker2/Worker/, worker2/Controller/Index.php, _underscore/Worker.php |
|
|
20
20
|
| [Cross-account AWS access for worker2 crons (_Component_Aws_Workloads)](features/cross-account-aws-access.md) | `_Component_Aws_Workloads` is the **standard, and only sanctioned, way any new worker2 cron obtains AWS access** — for any account, any region, any AWS SDK clie | worker2/Component/Aws/Workloads/Workloads.php, worker2/Config/production.ini, worker2/Worker/Infrastructure/CloudWatch.php |
|
|
21
|
+
| [Elastic Beanstalk health monitor → OneUptime (ElasticBeanstalkHealth)](features/elastic-beanstalk-health-monitor.md) | `_Worker_Infrastructure_CloudWatch::ElasticBeanstalkHealth()` is a worker2 cron that reads each Elastic Beanstalk (EB) environment's **enhanced-health** status | worker2/Worker/Infrastructure/CloudWatch.php |
|
|
21
22
|
| [Elite Freshservice Sync (worker2)](features/elite-freshservice-sync.md) | `_Worker_Elite` processes Freshservice webhook events and syncs them into TOGA 2. | worker2/Worker/Elite.php, worker2/Config/dev-kmaramreddy-laptop.ini |
|
|
22
23
|
| [Error Escalation Cron (Errors::Escalate → ClickUp / email)](features/error-escalation-cron.md) | `_Worker_Infrastructure_Errors::Escalate` (renamed from `SyncWithClickup`) is the sole owner of **escalation, de-escalation, ClickUp ticketing, reminders, busin | worker2/Worker/Infrastructure/Errors.php, worker2/Worker/Notification/Email.php, worker2/Worker/Notification/EmailTemplate.php, worker2/Worker/Client/True.php, worker2/Worker/Clickup/ErrorTask.php, worker2/Worker/Clickup.php, worker2/Controller/Index.php, worker2/Config/production.ini, _underscore/Model/Core/Logs/Issue.php, dbchanges2/Core/2026-07-30a - Error escalation cron job.sql, dbchanges2/Logs/2026-08-03a - Issue clickupPriority.sql, dbchanges2/Core/2026-08-04a - Error neglect digest cron job.sql |
|
|
23
24
|
| [Error-Issue Auto-Resolution & Reopen (frequency-decay lifecycle)](features/error-issue-auto-resolution.md) | The error system could escalate and de-escalate an Issue's *urgency* but had no concept of an Issue being **resolved**. | worker2/Worker/Infrastructure/Errors.php, worker2/Worker/Clickup/ErrorTask.php, _underscore/Model/Core/Logs/Issue.php, tools/mvc/errors/get.php, tools/mvc/errors/issue/get.php, dbchanges2/Logs/2026-08-05a - Issue status baseline and auto-resolution.sql |
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
| [DB-Driven Notification (Internal) Email](features/notification-email.md) | Internal/notification emails (merge-conflict alerts, ops notices — anything system-generated, not client-facing transactional mail) are sent through one worker | worker2/Worker/Notification/Email.php, _underscore/Model/Client/EmailTemplate.php, dbchanges2/Client/2026-06-23a - EmailTemplateWrapper.sql, dbchanges2/Client_True/2026-06-23a - EmailTemplateWrapper.sql |
|
|
34
35
|
| [NYCHH Asset-Tag Backfill (worker2)](features/nychh-asset-tag-backfill.md) | Keeps NYC Health & Hospitals (`Client_Nychh`) unit asset tags and MAC addresses synced from NetSuite. | worker2/Worker/Client/Nychh.php, worker2/Worker/Client/Nychh/AssetTagBackfill.php, worker/crons/toga2/netsuite/verify_fulfillment_asset_tag_sync_nychh.php, worker/crons/toga2/netsuite/backfill_all_asset_tags_from_netsuite_nychh.php |
|
|
35
36
|
| [OneUptime Incident → ClickUp Task Sync (Monitor/Oneuptime/SyncIncidents)](features/oneuptime-incident-clickup-sync.md) | An internal/shared TOGA ops feature: worker2 polls the OneUptime API every 15 minutes for **currently-open** incidents and ensures a ClickUp task exists for eac | worker2/Component/Api/Oneuptime/Oneuptime.php, worker2/Worker/Monitor/Oneuptime.php, worker2/Config/production.ini, dbchanges2/Team/2026-08-10a - OneUptime Incident ClickUp Tasks.sql, dbchanges2/Core/2026-08-10b - OneUptime Incident Sync CronJob.sql, dbchanges2/Team/2026-08-12a - OneUptime Incident Tasks Closed Marker.sql |
|
|
36
|
-
| [OneUptime push-metric monitors for 2.0 workers](features/oneuptime-worker2-monitoring.md) | A second, **OneUptime-reporting** monitoring pattern for the 2.0 worker2 tier, ported from the 1.0 `App_SystemMonitor_Compass` monitors. | worker2/Worker/Monitor/Compass.php, worker2/Worker/Client/Compass.php, worker2/composer.json, _underscore/Cloud.php, worker2/Worker/Monitor/Operations.php |
|
|
37
|
+
| [OneUptime push-metric monitors for 2.0 workers](features/oneuptime-worker2-monitoring.md) | A second, **OneUptime-reporting** monitoring pattern for the 2.0 worker2 tier, ported from the 1.0 `App_SystemMonitor_Compass` monitors. | worker2/Worker/Monitor/Compass.php, worker2/Worker/Client/Compass.php, worker2/composer.json, _underscore/Cloud.php, worker2/Worker/Monitor/Operations.php, worker2/Worker/Monitor/Aig.php, worker2/Worker/Monitor/Prudential.php, worker2/Worker/Monitor/Nycdoe.php, worker2/Config/production.ini, worker2/Config/beta.ini, worker2/Config/sandbox-dev.ini |
|
|
37
38
|
| [Platform Cache Cleanup (_Worker_Platform_Cache — Clean + Truncate)](features/platform-cache-cleanup.md) | `_Worker_Platform_Cache` owns maintenance of the shared **Cache** cluster that backs api2's [multi-client data retrieval](../../api2/features/cross-client-data- | worker2/Worker/Platform/Cache.php, worker2/Controller/Index.php, worker2/_.php, dbchanges2/Core/2026-07-27a - PlatformCacheCleanCron.sql |
|
|
38
39
|
| [Service Request → Sales Order → Purchase Order generation (Sync/ServiceRequest)](features/service-request-sales-order-generation.md) | `_Worker_Sync_ServiceRequest` turns a **Service Request into a Sales Order, and then into one Purchase Order per vendor**, for **any** tenant. | worker2/Worker/Sync/ServiceRequest.php, _underscore/Model/Elite/ServiceRequest.php, dbchanges2/Core/2026-08-06a - Service request and sales order payload interceptors.sql |
|
|
39
40
|
| [Startech Webhook Handler (worker2)](features/startech-webhook-handler.md) | Receives inbound webhook events from Startech (Easeedesk) and creates or updates the corresponding ticket in TOGA 2.0. | worker2/Worker/Startech.php |
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Elastic Beanstalk health monitor → OneUptime (ElasticBeanstalkHealth)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: worker2
|
|
5
|
+
project: Worker
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-17
|
|
10
|
+
owners: [jcardinal]
|
|
11
|
+
files:
|
|
12
|
+
- worker2/Worker/Infrastructure/CloudWatch.php
|
|
13
|
+
related:
|
|
14
|
+
- ./cross-account-aws-access.md
|
|
15
|
+
- ./oneuptime-worker2-monitoring.md
|
|
16
|
+
- ./monitoring-framework.md
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Summary
|
|
20
|
+
|
|
21
|
+
`_Worker_Infrastructure_CloudWatch::ElasticBeanstalkHealth()` is a worker2 cron that reads
|
|
22
|
+
each Elastic Beanstalk (EB) environment's **enhanced-health** status and reports it to a
|
|
23
|
+
OneUptime **Incoming Request** monitor, which pages the team. It is a **"dumb reporter,
|
|
24
|
+
smart monitor"** heartbeat (the same Pattern-B contract as
|
|
25
|
+
[OneUptime push-metric monitors](./oneuptime-worker2-monitoring.md)): the worker decides
|
|
26
|
+
pass/fail and POSTs decided **string tokens** (`alarm=HIGH/OK`, `probe=DEGRADED/OK`) that
|
|
27
|
+
OneUptime string-matches — OneUptime cannot compare numbers on a pushed body.
|
|
28
|
+
|
|
29
|
+
The load-bearing design decision this doc records is the **paging (alarm) criteria**: page
|
|
30
|
+
on EB `Degraded`/`Severe`, but **suppress the common "an occasional HTTP 500 tripped
|
|
31
|
+
Degraded" false alarm** unless 5xx errors actually dominate the request mix.
|
|
32
|
+
|
|
33
|
+
**Critical behavior:** the method is **non-fatal and never throws** — it always returns a
|
|
34
|
+
string. worker2 has **no DLQ and a 3600s SQS visibility timeout**, so any uncaught 500
|
|
35
|
+
becomes a poison-message storm; an outer `catch(\Throwable)` is the backstop and the push
|
|
36
|
+
itself runs non-fatal.
|
|
37
|
+
|
|
38
|
+
## Key files / entry points
|
|
39
|
+
|
|
40
|
+
- `worker2/Worker/Infrastructure/CloudWatch.php` — `_Worker_Infrastructure_CloudWatch`,
|
|
41
|
+
action `ElasticBeanstalkHealth`, dispatched via
|
|
42
|
+
`_Worker::runTask('Infrastructure/CloudWatch/ElasticBeanstalkHealth', {awsAccountId,
|
|
43
|
+
environments, oneuptimeUrl})`.
|
|
44
|
+
- AWS access is obtained through `_Component_Aws_Workloads::assumeCredentials()` (STS-assume
|
|
45
|
+
a read-only role per account, one assume reused across regions) — see
|
|
46
|
+
[Cross-account AWS access](./cross-account-aws-access.md), which also documents the
|
|
47
|
+
`environments` region→env-names map parameter shape.
|
|
48
|
+
- `oneuptimeUrl` arrives as a **cron parameter and is a push credential** — never log it and
|
|
49
|
+
never record its value in a doc (see gotchas).
|
|
50
|
+
|
|
51
|
+
## Alarm / paging criteria (the decision logic)
|
|
52
|
+
|
|
53
|
+
Per environment, `alarm=HIGH` (page) when the EB `HealthStatus` is `Degraded` **or**
|
|
54
|
+
`Severe`. `Suspended` never pages.
|
|
55
|
+
|
|
56
|
+
- **`Severe` always pages.**
|
|
57
|
+
- **`Degraded` for a non-5xx reason** (latency, instances down, …) **always pages.**
|
|
58
|
+
- **`Degraded` attributed to HTTP 5xx errors pages only when 5xx errors dominate** — i.e.
|
|
59
|
+
the 5xx share of requests is at/above `HTTP_5XX_ALARM_RATIO` (default 0.80). An occasional
|
|
60
|
+
500 that trips Degraded is noise and must **not** page; a flood is a real problem and
|
|
61
|
+
**must** page.
|
|
62
|
+
- **Tiny-sample guard:** below `HTTP_5XX_MIN_REQUEST_COUNT` (default 20) requests in the
|
|
63
|
+
window, do **not** trust the ratio — page rather than let a 2-of-3 blip read as "80%
|
|
64
|
+
failing."
|
|
65
|
+
|
|
66
|
+
### Fail-safe: a blind read pages, never reads healthy
|
|
67
|
+
|
|
68
|
+
If the health read (`describeEnvironmentHealth`) throws `AwsException` for an environment,
|
|
69
|
+
the monitor sets **`alarm=HIGH`** for that environment (a blind read must never masquerade
|
|
70
|
+
as healthy) **and** sets **`probe=DEGRADED`** (coverage gap, distinct from a measured-bad
|
|
71
|
+
signal — same alarm-vs-probe split as the multi-client monitors in
|
|
72
|
+
[OneUptime push-metric monitors](./oneuptime-worker2-monitoring.md)).
|
|
73
|
+
|
|
74
|
+
### Configurable constants (top of the class)
|
|
75
|
+
|
|
76
|
+
| Constant | Default | Meaning |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `HEALTH_ALARM_STATUSES` | `['Degraded','Severe']` | HealthStatus values that page |
|
|
79
|
+
| `HTTP_5XX_ALARM_RATIO` | `0.80` | 5xx share (0.0–1.0) at/above which a 5xx-driven `Degraded` pages |
|
|
80
|
+
| `HTTP_5XX_MIN_REQUEST_COUNT` | `20` | Below this many requests in the window, page rather than trust the ratio |
|
|
81
|
+
| `HTTP_5XX_CAUSE_MARKERS` | `['5xx','http 5']` | Case-insensitive substrings identifying a 5xx-attributed EB `Cause` |
|
|
82
|
+
|
|
83
|
+
### Implementation shape
|
|
84
|
+
|
|
85
|
+
- `shouldPageForHealth(healthStatus, causes, applicationMetrics): [bool, ?float]` — returns
|
|
86
|
+
the page decision and the observed 5xx ratio.
|
|
87
|
+
- `causesAttributeTo5xx(causes): bool` — substring-matches `HTTP_5XX_CAUSE_MARKERS` against
|
|
88
|
+
the EB `Causes` strings (case-insensitive).
|
|
89
|
+
- The ratio is computed as `StatusCodes.Status5xx / RequestCount` from `ApplicationMetrics`
|
|
90
|
+
(raw counts — see below), **not** by parsing the percentage out of the `Causes` text.
|
|
91
|
+
- `describeEnvironmentHealth` is called with
|
|
92
|
+
`AttributeNames = ['HealthStatus','Status','Color','Causes','ApplicationMetrics']`.
|
|
93
|
+
- Per-environment report + OneUptime payload now include the per-env `alarm` token and the
|
|
94
|
+
observed `fivexxRatio`.
|
|
95
|
+
|
|
96
|
+
## How EB enhanced-health is read (durable AWS reference)
|
|
97
|
+
|
|
98
|
+
Facts verified against current AWS docs; they inform why the logic above is shaped as it is.
|
|
99
|
+
|
|
100
|
+
- **HealthStatus severity ladder:** `Ok → Info → Warning → Degraded → Severe` (plus the grey
|
|
101
|
+
states `Pending`/`Unknown`/`Suspended`/`NoData`). `Degraded` is the "high failure" tier
|
|
102
|
+
and is **routinely tripped by benign transients** (Auto Scaling scale-up, a mid-deploy
|
|
103
|
+
dip), which is exactly why `Degraded` alone is noisy. `Severe` = "very high failure /
|
|
104
|
+
environment effectively not serving."
|
|
105
|
+
- **`ApplicationMetrics` returns RAW COUNTS, not percentages** — despite the API-reference
|
|
106
|
+
prose saying "percentage"/"per second". Fields: `Duration` (Integer seconds, usually 10),
|
|
107
|
+
`RequestCount` (Integer, **total** requests over the window),
|
|
108
|
+
`StatusCodes.{Status2xx,Status3xx,Status4xx,Status5xx}` (Integer counts). AWS's own
|
|
109
|
+
example: 2xx 3391 + 5xx 843 = RequestCount 4234. With no traffic, `RequestCount=0` and
|
|
110
|
+
`StatusCodes` may be **absent** → treat as "no data," not "zero failures." The 5xx-ratio
|
|
111
|
+
denominator is `RequestCount` (the authoritative total).
|
|
112
|
+
- **Why an env is Degraded comes from `Causes`:** EB `Causes` strings literally contain e.g.
|
|
113
|
+
`"19.9 % of the requests are failing with HTTP 5xx."` A substring check reliably
|
|
114
|
+
**classifies** 5xx-driven vs. not (fail-safe: a wording change → treated as a normal
|
|
115
|
+
`Degraded` → pages). The **ratio itself must come from `ApplicationMetrics`**, never by
|
|
116
|
+
parsing the number out of `Causes`.
|
|
117
|
+
- **A failed application DEPLOYMENT is NOT reliably reflected in HealthStatus** — it can read
|
|
118
|
+
`Warning`/`Degraded`, or fail before any red request-failure signal. The authoritative
|
|
119
|
+
structured deploy signal is per-instance `describeInstancesHealth` →
|
|
120
|
+
`Deployment.Status ∈ {'In Progress','Deployed','Failed'}`. (This detector was evaluated and
|
|
121
|
+
removed this iteration — see Design history.)
|
|
122
|
+
- **IAM:** `describeEnvironmentHealth` / `describeInstancesHealth` / `describeEvents` are all
|
|
123
|
+
covered by the managed `AWSElasticBeanstalkReadOnly` policy and require enhanced health
|
|
124
|
+
enabled. No per-call charge.
|
|
125
|
+
|
|
126
|
+
## OneUptime monitor config (external, not code)
|
|
127
|
+
|
|
128
|
+
Paging depends on the OneUptime Incoming-Request monitor's **string-match** criteria on the
|
|
129
|
+
POSTed body — `Contains "alarm":"HIGH"` (and, if desired, `Contains "probe":"DEGRADED"`).
|
|
130
|
+
This is external OneUptime configuration, not worker2 code.
|
|
131
|
+
|
|
132
|
+
## Design history — rejected direction (this session)
|
|
133
|
+
|
|
134
|
+
An earlier iteration set `HEALTH_ALARM_STATUSES = ['Severe']` (dropping `Degraded` entirely)
|
|
135
|
+
and **added a separate deployment-failure detector** (`describeInstancesHealth` →
|
|
136
|
+
`Deployment.Status = 'Failed'`) to still catch deploy failures. That was **reverted** after a
|
|
137
|
+
scope change: the team decided they **do** want to page on `Degraded` (to catch a flood of
|
|
138
|
+
500s and non-500 degradations), with only the occasional-500 case suppressed via the 80%
|
|
139
|
+
ratio. The deployment-failure detector was **removed** — deploy failures that surface as
|
|
140
|
+
`Degraded` are now covered by the `Degraded` alarm. **Residual gap accepted for this
|
|
141
|
+
iteration:** a deploy that fails fast *without ever degrading health* is not caught.
|
|
142
|
+
|
|
143
|
+
## Known gaps / follow-ups (not done)
|
|
144
|
+
|
|
145
|
+
- **Per-region client construction is not individually guarded.** Each
|
|
146
|
+
`new ElasticBeanstalkClient` is not in its own try/catch, so a bad region/creds aborts the
|
|
147
|
+
**whole run** via the outer backstop instead of paging just that region's envs as blind.
|
|
148
|
+
Candidate follow-up now that blind reads page.
|
|
149
|
+
- **No first-party test harness exists in worker2** (all tests are vendor/).
|
|
150
|
+
`shouldPageForHealth()` and `causesAttributeTo5xx()` are pure and ideal to unit-test
|
|
151
|
+
(ratio at exactly 0.80; count 19 vs 20; `Severe` over a 5xx cause; empty causes; null
|
|
152
|
+
metrics) — deferred pending a harness.
|
|
153
|
+
|
|
154
|
+
## Gotchas / known issues
|
|
155
|
+
|
|
156
|
+
- **Keep the method non-fatal — never let it throw.** worker2 has no DLQ and a 3600s SQS
|
|
157
|
+
visibility timeout, so any uncaught 500 becomes a poison-message storm. The push runs
|
|
158
|
+
non-fatal and an outer `catch(\Throwable)` is the backstop.
|
|
159
|
+
- **A blind health read must page, not read healthy** — an `AwsException` on
|
|
160
|
+
`describeEnvironmentHealth` sets `alarm=HIGH` + `probe=DEGRADED` for that env.
|
|
161
|
+
- **`ApplicationMetrics` is raw counts, not percentages** — divide `Status5xx` by
|
|
162
|
+
`RequestCount`; `RequestCount=0`/absent `StatusCodes` means "no data," not "zero failures."
|
|
163
|
+
- **Classify 5xx-attribution from `Causes` text, but take the ratio from `ApplicationMetrics`
|
|
164
|
+
— never parse the percentage out of `Causes`.**
|
|
165
|
+
- **`oneuptimeUrl` is a push credential** — it arrives as a cron parameter; never log it or
|
|
166
|
+
record its value in a doc.
|
|
167
|
+
|
|
168
|
+
## Change history
|
|
169
|
+
- 2026-08-17 — Created. Documented the `ElasticBeanstalkHealth` alarm/paging criteria (page
|
|
170
|
+
on `Degraded`/`Severe`; suppress a 5xx-driven `Degraded` unless the 5xx share ≥
|
|
171
|
+
`HTTP_5XX_ALARM_RATIO` 0.80 with an `HTTP_5XX_MIN_REQUEST_COUNT` 20 tiny-sample guard;
|
|
172
|
+
`Severe` and non-5xx `Degraded` always page), the blind-read fail-safe (`alarm=HIGH` +
|
|
173
|
+
`probe=DEGRADED`), the four configurable constants, and the `shouldPageForHealth` /
|
|
174
|
+
`causesAttributeTo5xx` helper shape. Captured durable EB enhanced-health facts (severity
|
|
175
|
+
ladder; `ApplicationMetrics` returns raw counts not percentages; `Causes` classifies but
|
|
176
|
+
`ApplicationMetrics` sets the ratio; failed deploys aren't reliably in HealthStatus —
|
|
177
|
+
`describeInstancesHealth.Deployment.Status` is authoritative; `AWSElasticBeanstalkReadOnly`
|
|
178
|
+
covers the reads). Recorded the reverted `['Severe']`-only + deployment-failure-detector
|
|
179
|
+
direction and the accepted residual gap (a deploy that fails without degrading health).
|
|
180
|
+
(jcardinal)
|
|
181
|
+
</content>
|
|
182
|
+
</invoke>
|
|
@@ -6,14 +6,20 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-
|
|
10
|
-
owners: ["jcardinal"]
|
|
9
|
+
updated: 2026-08-17
|
|
10
|
+
owners: ["jcardinal", "mhammontree"]
|
|
11
11
|
files:
|
|
12
12
|
- worker2/Worker/Monitor/Compass.php
|
|
13
13
|
- worker2/Worker/Client/Compass.php
|
|
14
14
|
- worker2/composer.json
|
|
15
15
|
- _underscore/Cloud.php
|
|
16
16
|
- worker2/Worker/Monitor/Operations.php
|
|
17
|
+
- worker2/Worker/Monitor/Aig.php
|
|
18
|
+
- worker2/Worker/Monitor/Prudential.php
|
|
19
|
+
- worker2/Worker/Monitor/Nycdoe.php
|
|
20
|
+
- worker2/Config/production.ini
|
|
21
|
+
- worker2/Config/beta.ini
|
|
22
|
+
- worker2/Config/sandbox-dev.ini
|
|
17
23
|
related:
|
|
18
24
|
- ./oneuptime-incident-clickup-sync.md
|
|
19
25
|
- ./monitoring-framework.md
|
|
@@ -136,6 +142,69 @@ POSTed JSON body is addressed via the `requestBody` prefix — e.g.
|
|
|
136
142
|
The 10-min-Degraded / 15-min-Offline heartbeat thresholds pair with a **5-minute** cron
|
|
137
143
|
cadence. An initial 3/5-min setting false-alarmed on a single missed ping.
|
|
138
144
|
|
|
145
|
+
### Two kinds of monitor — liveness probes and log-scrapers are complements, not duplicates
|
|
146
|
+
|
|
147
|
+
A monitor that **scrapes log rows** for arrived-and-failed calls (`Monitor/Aig/EntitlementApiFailures`,
|
|
148
|
+
the five 1.0 `App_SystemMonitor_ServiceNow*` classes) is **structurally blind to a fully dead
|
|
149
|
+
endpoint**: a refused connection logs nothing, produces zero failure rows, and reads as healthy.
|
|
150
|
+
Pair every failure-rate monitor on an integration endpoint with a **liveness probe** that actually
|
|
151
|
+
touches it. Rules for the probe:
|
|
152
|
+
|
|
153
|
+
- Use an **unauthenticated GET** so the probe can never create or mutate a record.
|
|
154
|
+
- **Any structured HTTP response below 500 is HEALTHY** — it proves DNS, TLS, the load balancer,
|
|
155
|
+
routing, and the auth layer are all alive. A `401` from an unauthenticated call to a protected
|
|
156
|
+
route is a *passing* result, not a failure. Only ≥500 / connect failure / timeout means dead.
|
|
157
|
+
(Verified 2026-08-17: `api-writer.togahub.com/v2/health` → 200; unauthenticated `/v2/entitlements`
|
|
158
|
+
→ 401; both `alarm:"OK"`.)
|
|
159
|
+
- api2 short-circuits its health routes before any DB or Sentry work
|
|
160
|
+
(`api2/Controller/Index.php` `HEALTH_CHECK_ROUTES = ['/health','/v2/health']` → 200), so probing
|
|
161
|
+
them is cheap and does not depend on a client DB being reachable.
|
|
162
|
+
- **Token validity is out of scope for a worker2 probe** when the OAuth client lives in 1.0
|
|
163
|
+
(e.g. NYCDOE ServiceNow's `App_Api_NYCDOEV2` in `library`). Re-implementing it in worker2 would
|
|
164
|
+
duplicate credentials into a second repo and race the shared access token. Accept and record the
|
|
165
|
+
coverage gap rather than forking the client.
|
|
166
|
+
|
|
167
|
+
### Tunable thresholds live in `Core.CronJobs.parameters`, everything else stays a local
|
|
168
|
+
|
|
169
|
+
The alarm threshold is the **one** setting that goes in the DB, as
|
|
170
|
+
`parameters = '{"alertThreshold":N}'`, so it can be retuned without a deploy. worker2 spreads
|
|
171
|
+
`parameters` as **named PHP arguments**, so the JSON key must match the method's parameter name
|
|
172
|
+
**exactly** or the call fails. Every other monitor setting (URLs, cutoffs, window sizes) stays an
|
|
173
|
+
`ALL_CAPS` in-method local.
|
|
174
|
+
|
|
175
|
+
**Echo `alertThreshold` in the pushed body next to the measured count.** A historical alarm is
|
|
176
|
+
otherwise unreadable once the threshold has been retuned.
|
|
177
|
+
|
|
178
|
+
### Backlog monitors must exclude known-permanently-stranded rows
|
|
179
|
+
|
|
180
|
+
A backlog count that includes rows which will *never* drain pins the monitor HIGH from its first
|
|
181
|
+
run, and a monitor that is always red trains people to ignore it. Define a `BACKLOG_CUTOFF_DATE`
|
|
182
|
+
local at the date the monitor was written and count only rows on/after it. Report stranded/unmapped
|
|
183
|
+
row counts as **diagnostic fields that deliberately do not drive the alarm**.
|
|
184
|
+
|
|
185
|
+
### Monitors are safe to deploy inert
|
|
186
|
+
|
|
187
|
+
Ship with the `Core.CronJobs` row `isActive = 0`. Each method must guard on an empty push URL, log
|
|
188
|
+
`no OneUptime push URL configured`, and still record its measurement in `WorkerJobs` — so the code
|
|
189
|
+
can deploy and be hand-run before the monitor exists in OneUptime.
|
|
190
|
+
|
|
191
|
+
### Calibrate thresholds against the tier that runs the business logic
|
|
192
|
+
|
|
193
|
+
Several monitors live in worker2 but watch a pipeline whose crons run in the **1.0 worker** tier
|
|
194
|
+
against a 2.0 client DB (worker2 only READs it) — Compass and Prudential both work this way.
|
|
195
|
+
Thresholds must be derived from the **1.0 cron cadences and per-run throughput**, not from
|
|
196
|
+
worker2's own `*/5` schedule.
|
|
197
|
+
|
|
198
|
+
### End-to-end test procedure (no deploy required)
|
|
199
|
+
|
|
200
|
+
Testing **recovery** is the step people skip and the most valuable one:
|
|
201
|
+
|
|
202
|
+
1. `UPDATE Core.CronJobs SET parameters = '{"alertThreshold":-1}'` for the action.
|
|
203
|
+
2. Hand-run the action → confirm `alarm:"HIGH"`, the monitor flips **Offline**, an incident opens,
|
|
204
|
+
and the notification arrives.
|
|
205
|
+
3. Restore the real threshold and hand-run again → confirm the OK-gated criterion returns the
|
|
206
|
+
monitor to **Online** and resolves the incident.
|
|
207
|
+
|
|
139
208
|
## Provisioning a monitor (runbook)
|
|
140
209
|
|
|
141
210
|
1. Write the monitor method on `_Worker_Monitor_Compass` (or a new `_Worker_Monitor_<X>`),
|
|
@@ -144,9 +213,14 @@ cadence. An initial 3/5-min setting false-alarmed on a single missed ping.
|
|
|
144
213
|
**push credential**; never log it and never record its value in a doc.
|
|
145
214
|
3. Provision the OneUptime monitor by importing the monitor's OneUptime resource-export
|
|
146
215
|
JSON (authored under a local staging dir, e.g. `d:\STAGE` — these are import artifacts,
|
|
147
|
-
not repo files) and wiring the Contains criteria
|
|
148
|
-
|
|
149
|
-
|
|
216
|
+
not repo files) and wiring **only the body-`Contains` criteria** at this point.
|
|
217
|
+
The **push URL does not exist until the monitor is saved** — OneUptime generates it, it cannot
|
|
218
|
+
be pre-derived, so the monitor must exist before the worker code can be finished.
|
|
219
|
+
4. Add the `Core.CronJobs` row: `action = 'Monitor/<Class>/<Method>'`, schedule
|
|
220
|
+
`*/5 * * * *`, `maxExecutionTime` 120s, `parameters` NULL (or
|
|
221
|
+
`{"alertThreshold":N}`), `isActive = 0`. Then deploy worker2.
|
|
222
|
+
5. Flip `isActive = 1` and **confirm a push has landed**. Only then add the
|
|
223
|
+
**absence criteria** (not-received 10/15 min) — see the activation-ordering trap below.
|
|
150
224
|
|
|
151
225
|
### CronJob scheduling for these monitors
|
|
152
226
|
|
|
@@ -200,8 +274,15 @@ check for another client.
|
|
|
200
274
|
- OneUptime Incoming Request bodies are matched **as strings only** (Contains/NotContains) —
|
|
201
275
|
no numeric comparison, no JSON key targeting. Always emit a decided token, never a raw
|
|
202
276
|
number, for push monitors.
|
|
203
|
-
-
|
|
204
|
-
|
|
277
|
+
- **ACTIVATION-ORDERING TRAP.** Creating a monitor with the **absence** criteria already wired
|
|
278
|
+
while its cron is still `isActive = 0` makes it go **Offline and open an incident within 15
|
|
279
|
+
minutes** with nothing pushing. Wire body-match criteria at creation; add absence criteria only
|
|
280
|
+
after `isActive = 1` and a confirmed push — or mute the monitor until then.
|
|
281
|
+
- The OneUptime push URL is a credential — a holder can spoof a healthy heartbeat and thereby
|
|
282
|
+
silence a real outage. Keep it as an in-file `$ONEUPTIME_URL` local in the method (the
|
|
283
|
+
established team pattern — 11 pre-existing instances across `Monitor/Compass.php`,
|
|
284
|
+
`Monitor/Aig.php`, `Monitor/Operations.php`); never log it and never write its value into a doc.
|
|
285
|
+
Moving these to `Config/production.ini` is a recognized future improvement, not yet done.
|
|
205
286
|
- **`App_Client_Compass` (1.0) is unavailable in worker2.** Referencing it throws a
|
|
206
287
|
class-not-found `Error`, which `catch (Exception)` does NOT catch — the whole monitor
|
|
207
288
|
dies uncaught. Use `_Worker_Client_Compass::` constants only.
|
|
@@ -212,6 +293,19 @@ check for another client.
|
|
|
212
293
|
monitors must pass the region (see [Cloud S3 helpers](../../_underscore/features/cloud-s3-helpers.md)).
|
|
213
294
|
|
|
214
295
|
## Change history
|
|
296
|
+
- 2026-08-17 — TRUE-80587: added five monitors and generalized this doc beyond Compass —
|
|
297
|
+
`Monitor/Prudential/{SalesOrderGenerationBacklog,DellPurchaseOrderTransmissionBacklog,
|
|
298
|
+
OrderShippedUpdateBacklog}`, `Monitor/Aig/EntitlementApiHealth`,
|
|
299
|
+
`Monitor/Nycdoe/ServiceNowEndpointHealth` (cron rows in
|
|
300
|
+
`dbchanges2/Core/2026-08-07a - Prudential AIG ServiceNow OneUptime monitor crons.sql`).
|
|
301
|
+
New durable sections: **liveness probes vs. log-scrapers are complements** (a scraper cannot see
|
|
302
|
+
a dead endpoint; <500 including 401 is healthy), the **`alertThreshold` DB parameter** convention
|
|
303
|
+
(named-argument spread; echo it in the body), **excluding permanently-stranded rows** via a
|
|
304
|
+
`BACKLOG_CUTOFF_DATE`, **deploy-inert** (`isActive = 0` + empty-URL guard), calibrating against
|
|
305
|
+
the **1.0** tier's cadences, the no-deploy **end-to-end + recovery test procedure**, and the
|
|
306
|
+
**activation-ordering trap** (absence criteria before first push = false incident). See
|
|
307
|
+
[Prudential OneUptime order-pipeline monitors](../../../clients/prudential/features/oneuptime-order-pipeline-monitors.md).
|
|
308
|
+
(mhammontree)
|
|
215
309
|
- 2026-08-10 — Noted that worker2 gained its **first OneUptime API *reader*** (this doc covers
|
|
216
310
|
the push-only half; OneUptime was previously push-only, "dumb reporter, smart monitor"). The
|
|
217
311
|
reader polls open incidents and files ClickUp tasks — see
|
|
@@ -5,7 +5,7 @@ project: _Underscore
|
|
|
5
5
|
client: shared
|
|
6
6
|
type: standard
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-08-
|
|
8
|
+
updated: 2026-08-17
|
|
9
9
|
owners: [jcardinal, mhammontree, dfranks]
|
|
10
10
|
files: []
|
|
11
11
|
related:
|
|
@@ -269,6 +269,22 @@ WHERE
|
|
|
269
269
|
|
|
270
270
|
* If necessary, add comments to clarify complex sections of SQL code. Comments should be concise and informative.
|
|
271
271
|
* Prefer to use the `#` character to begin a comment rather than `--`.
|
|
272
|
+
* **Do not write a prose preamble on a migration file.** Comment each statement with a
|
|
273
|
+
short description of what it does and why. A multi-paragraph narrative over mechanical
|
|
274
|
+
`INSERT`s is not documentation — it rots, it repeats the ticket, and it buries the SQL.
|
|
275
|
+
Rollout/runbook steps belong on the ClickUp ticket; a reusable pattern belongs in the
|
|
276
|
+
knowledge base; the migration file gets one line per statement.
|
|
277
|
+
* **This is not a licence to strip PHP DocBlocks.** DocBlocks on classes and methods remain
|
|
278
|
+
required (see DocBlocks below) and are a different artifact. A docblock that records *why*
|
|
279
|
+
a query is written a certain way — e.g. "`Customers` is `LEFT` joined on purpose so the
|
|
280
|
+
monitor can see rows the transmission crons cannot" — is load-bearing: it prevents a future
|
|
281
|
+
"cleanup" to `INNER JOIN` that would silently blind the monitor. Keep those.
|
|
282
|
+
* Do not comment a migration with a dependency warning about an earlier file **in the same
|
|
283
|
+
folder**. The dbchanges2 executor applies each folder's files in **alphabetical order**, so an
|
|
284
|
+
earlier `YYYY-MM-DD` file in that folder is guaranteed already applied. A **cross-folder**
|
|
285
|
+
dependency (e.g. a `Client_<Name>/` file relying on a `Core/` change) is a different matter —
|
|
286
|
+
those are separate executor passes against separate clusters, so noting the ordering there is
|
|
287
|
+
legitimate and should be kept.
|
|
272
288
|
|
|
273
289
|
```sql
|
|
274
290
|
# Bad
|
|
@@ -832,5 +848,11 @@ See: 2.0/apps/worker2/features/cross-account-aws-access.md
|
|
|
832
848
|
|
|
833
849
|
## Change history
|
|
834
850
|
|
|
851
|
+
- 2026-08-17 — SQL Comments: banned prose preambles on migration files (one short description per
|
|
852
|
+
statement; runbooks go on the ticket, patterns in the knowledge base), while explicitly protecting
|
|
853
|
+
PHP DocBlocks that record *why* a query is shaped a certain way. Also scoped the "no
|
|
854
|
+
earlier-file dependency warning" rule to **within one folder** — `Core/` and `Client_<Name>/` are
|
|
855
|
+
separate executor passes against separate clusters, so a cross-folder ordering note is legitimate
|
|
856
|
+
and must be kept. (mhammontree)
|
|
835
857
|
- 2026-08-10 — Added "AWS access (worker2)" section: new worker2 AWS code must use `_Component_Aws_Workloads` (instance-role → per-account `WorkloadsRuntime` STS assume-role); legacy static key grandfathered for existing paths only. (jcardinal)
|
|
836
858
|
- 2026-08-01 — Recorded the Logs-cluster singular table-naming exception to the otherwise-plural table convention. (jcardinal)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -19,7 +19,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
19
19
|
## 2.0 framework
|
|
20
20
|
|
|
21
21
|
- **_underscore** (_Underscore) _(framework core)_ — 58 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
|
|
22
|
-
- **worker2** (Worker) —
|
|
22
|
+
- **worker2** (Worker) — 50 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
|
|
23
23
|
- **api2** (API) — 24 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
|
|
24
24
|
- **dbchanges2** (Database Changes) _(framework core)_ — 8 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
25
25
|
- **toga2-supply** (TOGa Supply) — 6 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
5
|
| [AIG Contract Reconciliation & Dealer Programs (STS_001 / SA_001)](features/contract-reconciliation.md) | 2.0 | How to reconcile an **AIG contract sales sheet** against the `Client_Aig` tenant, and the durable finding that the **Staples Advantage.com (`SA_001`) program do | _underscore/Model/Client/Entitlement.php, _underscore/Model/Aig/Entitlement.php, _underscore/Model/Client/Contact.php, _underscore/Model/Aig/Contact.php |
|
|
6
|
-
| [AIG Entitlement Intake & SaleItem Code Resolution](features/entitlement-intake.md) | 2.0 | The `_Model_Aig_Entitlement::prePost` interceptor below is the code path for AIG protection-plan entitlements arriving as `api2` V2 JSON POSTs — and that path * | _underscore/Model/Aig/Entitlement.php, _underscore/Model/Aig/Unit.php, api2/Component/Api/V2/V2.php, api2/Config/sandbox-dev.ini, dbchanges2/Client_Aig/2026-06-18a - TRUE-79534 AIG SaleItem codes.sql, dbchanges2/Client_Aig/2026-08-17a - TRUE-80562 AIG API identifier overrides.sql |
|
|
6
|
+
| [AIG Entitlement Intake & SaleItem Code Resolution](features/entitlement-intake.md) | 2.0 | The `_Model_Aig_Entitlement::prePost` interceptor below is the code path for AIG protection-plan entitlements arriving as `api2` V2 JSON POSTs — and that path * | _underscore/Model/Aig/Entitlement.php, _underscore/Model/Aig/Unit.php, api2/Component/Api/V2/V2.php, api2/Config/sandbox-dev.ini, dbchanges2/Client_Aig/2026-06-18a - TRUE-79534 AIG SaleItem codes.sql, dbchanges2/Client_Aig/2026-08-17a - TRUE-80562 AIG API identifier overrides.sql, worker2/Worker/Monitor/Aig.php, api2/Controller/Index.php |
|
|
7
7
|
| [AIG (Staples Protection Plan)](profile.md) | 2.0 | AIG is the warranty underwriter behind the **Staples Protection Plan** retail program. | |
|
|
@@ -14,7 +14,10 @@ files:
|
|
|
14
14
|
- api2/Config/sandbox-dev.ini
|
|
15
15
|
- dbchanges2/Client_Aig/2026-06-18a - TRUE-79534 AIG SaleItem codes.sql
|
|
16
16
|
- dbchanges2/Client_Aig/2026-08-17a - TRUE-80562 AIG API identifier overrides.sql
|
|
17
|
+
- worker2/Worker/Monitor/Aig.php
|
|
18
|
+
- api2/Controller/Index.php
|
|
17
19
|
related:
|
|
20
|
+
- 2.0/apps/worker2/features/oneuptime-worker2-monitoring.md
|
|
18
21
|
- clients/aig/features/contract-reconciliation.md
|
|
19
22
|
- 1.0/apps/library/features/toga2-api-client-and-bridge.md
|
|
20
23
|
- 2.0/apps/api2/features/request-logging.md
|
|
@@ -379,6 +382,23 @@ When AIG sends a new "Active SaleItemID" spreadsheet (columns `SaleItemID`, `Des
|
|
|
379
382
|
local pass is not evidence.** See the gotcha and
|
|
380
383
|
[local vs prod MySQL config parity](../../../2.0/apps/dbchanges2/workflows/local-vs-prod-mysql-config-parity.md).
|
|
381
384
|
|
|
385
|
+
## Monitoring the intake endpoint — the failure-scraper cannot see a dead endpoint
|
|
386
|
+
|
|
387
|
+
`Monitor/Aig/EntitlementApiFailures` (worker2 → OneUptime) counts **arrived-and-failed** intake
|
|
388
|
+
calls from the log tables. It is structurally blind to a **fully dead** endpoint: a refused
|
|
389
|
+
connection logs nothing, yields zero failure rows, and reads as healthy. TRUE-80587 therefore added
|
|
390
|
+
`Monitor/Aig/EntitlementApiHealth`, a **liveness probe** alongside it — an **unauthenticated GET**
|
|
391
|
+
(so it can never create a record) where **any structured HTTP response below 500 is a PASS**.
|
|
392
|
+
|
|
393
|
+
Verified 2026-08-17: `api-writer.togahub.com/v2/health` → **200**; unauthenticated
|
|
394
|
+
`/v2/entitlements` → **401**. The 401 is a *healthy* answer — it proves DNS, TLS, the load balancer,
|
|
395
|
+
routing, and the auth layer are all alive. `api2/Controller/Index.php`
|
|
396
|
+
`HEALTH_CHECK_ROUTES = ['/health','/v2/health']` short-circuits to 200 before any DB or Sentry work,
|
|
397
|
+
so the probe does not depend on `Client_Aig` being reachable.
|
|
398
|
+
|
|
399
|
+
See the shared pattern:
|
|
400
|
+
[OneUptime push-metric monitors for 2.0 workers](../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md).
|
|
401
|
+
|
|
382
402
|
## Client variations
|
|
383
403
|
|
|
384
404
|
This is AIG-specific behavior (the `_Model_Aig_Entitlement` override); other clients do not run
|
|
@@ -485,6 +505,10 @@ this interceptor or use this dual-purpose Items pattern.
|
|
|
485
505
|
This is a general dbchanges2 temp-table-staging rule, not AIG-specific.
|
|
486
506
|
|
|
487
507
|
## Change history
|
|
508
|
+
- 2026-08-17 — TRUE-80587: added `Monitor/Aig/EntitlementApiHealth`, an unauthenticated-GET liveness
|
|
509
|
+
probe on the intake endpoint, because the existing `EntitlementApiFailures` log-scraper cannot see
|
|
510
|
+
a fully dead endpoint. Documented that <500 (including the unauthenticated **401**) is a PASS.
|
|
511
|
+
(mhammontree)
|
|
488
512
|
|
|
489
513
|
- 2026-08-17 (later pass) — **Correction + final verification, supersedes two points in the entry
|
|
490
514
|
below.** (1) The nested-`Units` "cross-tenant field list" open question is **WITHDRAWN** — the six
|
|
@@ -6,11 +6,12 @@ apps:
|
|
|
6
6
|
- api2
|
|
7
7
|
- dbchanges2
|
|
8
8
|
- library
|
|
9
|
+
- worker2
|
|
9
10
|
project: API
|
|
10
11
|
client: aig
|
|
11
12
|
type: profile
|
|
12
13
|
status: active
|
|
13
|
-
updated: 2026-
|
|
14
|
+
updated: 2026-08-17
|
|
14
15
|
owners: ["mhammontree"]
|
|
15
16
|
files: []
|
|
16
17
|
related:
|
|
@@ -36,6 +37,9 @@ go out under the Staples Protection Plan brand and link to `staplesprotection.to
|
|
|
36
37
|
NetSuite item/SO/invoice traits).
|
|
37
38
|
- **`dbchanges2`** — `Client_Aig/` schema + reference-data migrations (e.g. the SaleItem code
|
|
38
39
|
catalog in `Client_Aig.Items`).
|
|
40
|
+
- **`worker2`** — OneUptime monitors: `Monitor/Aig/EntitlementApiFailures` (log-scraper) plus
|
|
41
|
+
`Monitor/Aig/EntitlementApiHealth` (liveness probe of the intake endpoint). See
|
|
42
|
+
features/entitlement-intake.md and the shared worker2 OneUptime monitoring doc.
|
|
39
43
|
- **`library` (1.0)** — the `App_Api_Toga2` bridge syncs 2.0 AIG contacts/entitlements down into the
|
|
40
44
|
legacy 1.0 `TOGA_AIG` DB (`Customers`/`ServiceRequests`), run by a worker cron every ~10 min. Note
|
|
41
45
|
the two AIG databases: **`TOGA_AIG`** = V1 legacy sync target; **`Client_Aig`** = V2 prod tenant. See
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
5
|
| [NYCDOE Ticket Hold-Status Sync (ServiceNow ⇄ TOGaDesk)](features/hold-status-sync.md) | 1.0 | DOE ticket **hold** status must round-trip between ServiceNow (SNOW) and TOGaDesk and **stay held** — holds are SLA-bearing in both systems. | worker/crons/sync/nycdoe/send_ticket_updates.php, worker/crons/sync/nycdoe/process_tickets.php, worker/crons/sync/nycdoe/send_request_item_updates.php, library/app/model/togadesk/repairorder.php, library/app/api/nycdoev2.php, togadesk/desk/includes/classes/class.repair.php |
|
|
6
|
-
| [NYCDOE ServiceNow / ASN Integration](features/servicenow-integration.md) | 1.0 | The NYCDOE/ServiceNow integration mirrors DOE's ServiceNow tickets (Incidents + RITMs) into local tables, turns vendor shipment notices into NetSuite Sales Orde | worker/crons/sync/nycdoe/import_asn.php, worker/crons/sync/nycdoe/import_inc.php, worker/crons/sync/nycdoe/legacy_import_asn.php, worker/crons/sync/nycdoe/legacy_process_asn_queue.php, worker/crons/sync/nycdoe/process_tickets.php, worker/crons/sync/nycdoe/1_send_asn_to_netsuite.php, worker/crons/sync/nycdoe/2_send_serials_to_netsuite.php, worker/crons/sync/nycdoe/3_create_installation_ticket.php, worker/crons/sync/nycdoe/test_multi_po_receipt_resolution.php, worker/crons/sync/nycdoe/send_ticket_updates.php, worker/crons/sync/nycdoe/send_request_item_updates.php, worker/crons/sync/nycdoe/send_nycdoe_proof_of_delivery.php, worker/crons/sync/nycdoe/sync_nycdoe_locations.php, worker/crons/sync/nycdoe/receive_edi_purchase_orders.php, worker/crons/sync/nycdoe/send_edi_open_invoices.php, worker/crons/notifications/nycdoe/, worker/schedules/cron.worker.sync.json, worker/schedules/cron.worker.notification.json, library/app/api/nycdoe.php, library/app/api/nycdoev2.php, library/app/nycdoe.php, library/app/asnprocessor/manufacturer.php, library/app/asnprocessor/apple.php, library/app/asnprocessor/lenovo.php, library/app/asnprocessor/lexmark.php, library/app/asnprocessor/acer.php, library/app/edi.php, library/app/netsuite.php, dbchanges/Core/SK/, dbchanges/TOGaDeskSupport/SK/ |
|
|
6
|
+
| [NYCDOE ServiceNow / ASN Integration](features/servicenow-integration.md) | 1.0 | The NYCDOE/ServiceNow integration mirrors DOE's ServiceNow tickets (Incidents + RITMs) into local tables, turns vendor shipment notices into NetSuite Sales Orde | worker/crons/sync/nycdoe/import_asn.php, worker/crons/sync/nycdoe/import_inc.php, worker/crons/sync/nycdoe/legacy_import_asn.php, worker/crons/sync/nycdoe/legacy_process_asn_queue.php, worker/crons/sync/nycdoe/process_tickets.php, worker/crons/sync/nycdoe/1_send_asn_to_netsuite.php, worker/crons/sync/nycdoe/2_send_serials_to_netsuite.php, worker/crons/sync/nycdoe/3_create_installation_ticket.php, worker/crons/sync/nycdoe/test_multi_po_receipt_resolution.php, worker/crons/sync/nycdoe/send_ticket_updates.php, worker/crons/sync/nycdoe/send_request_item_updates.php, worker/crons/sync/nycdoe/send_nycdoe_proof_of_delivery.php, worker/crons/sync/nycdoe/sync_nycdoe_locations.php, worker/crons/sync/nycdoe/receive_edi_purchase_orders.php, worker/crons/sync/nycdoe/send_edi_open_invoices.php, worker/crons/notifications/nycdoe/, worker/schedules/cron.worker.sync.json, worker/schedules/cron.worker.notification.json, library/app/api/nycdoe.php, library/app/api/nycdoev2.php, library/app/nycdoe.php, library/app/asnprocessor/manufacturer.php, library/app/asnprocessor/apple.php, library/app/asnprocessor/lenovo.php, library/app/asnprocessor/lexmark.php, library/app/asnprocessor/acer.php, library/app/edi.php, library/app/netsuite.php, dbchanges/Core/SK/, dbchanges/TOGaDeskSupport/SK/, worker2/Worker/Monitor/Nycdoe.php |
|
|
7
7
|
| [New York City Department of Education](profile.md) | 1.0 | NYC DOE (New York City Department of Education) is a TOGA client whose entire integration runs in the **1.0 worker tier** (~30 cron scripts under `worker/crons/ | |
|
|
@@ -6,7 +6,7 @@ project: Worker
|
|
|
6
6
|
client: nycdoe
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-08-
|
|
9
|
+
updated: 2026-08-17
|
|
10
10
|
owners: [mhammontree, sking]
|
|
11
11
|
files:
|
|
12
12
|
- worker/crons/sync/nycdoe/import_asn.php
|
|
@@ -39,8 +39,10 @@ files:
|
|
|
39
39
|
- library/app/netsuite.php
|
|
40
40
|
- dbchanges/Core/SK/
|
|
41
41
|
- dbchanges/TOGaDeskSupport/SK/
|
|
42
|
+
- worker2/Worker/Monitor/Nycdoe.php
|
|
42
43
|
related:
|
|
43
44
|
- ../profile.md
|
|
45
|
+
- ../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md
|
|
44
46
|
- hold-status-sync.md
|
|
45
47
|
- ../../../1.0/apps/worker/architecture.md
|
|
46
48
|
- ../../../1.0/apps/dbchanges/workflows/authoring-and-shipping-sql-files.md
|
|
@@ -551,6 +553,28 @@ use the toga DB MCP + `Logs.API` instead of running prod code locally.
|
|
|
551
553
|
`__get` throws "No field or quick query defined for key …". Read that column via **raw SQL**,
|
|
552
554
|
not the model.
|
|
553
555
|
|
|
556
|
+
## Monitoring the ServiceNow endpoint (worker2 liveness probe — TRUE-80587)
|
|
557
|
+
|
|
558
|
+
The five 1.0 `App_SystemMonitor_ServiceNow*` monitors scrape logs for **arrived-and-failed** calls,
|
|
559
|
+
so they are **structurally blind to a fully dead endpoint**: a refused connection logs nothing,
|
|
560
|
+
produces zero failure rows, and reads as healthy. `Monitor/Nycdoe/ServiceNowEndpointHealth`
|
|
561
|
+
(`worker2/Worker/Monitor/Nycdoe.php`, OneUptime push) is the complement — a **liveness probe** that
|
|
562
|
+
actually touches the endpoint.
|
|
563
|
+
|
|
564
|
+
- **Unauthenticated GET**, so it can never create a record.
|
|
565
|
+
- **Any structured HTTP response below 500 is a PASS** — it proves DNS, TLS, the load balancer,
|
|
566
|
+
routing, and the auth layer are alive. A `401` is a *healthy* answer, not a failure.
|
|
567
|
+
- **Accepted coverage gap: token validity is NOT monitored.** The OAuth client
|
|
568
|
+
`App_Api_NYCDOEV2` lives in the 1.0 `library` repo, which worker2 cannot reach. Re-implementing
|
|
569
|
+
it in worker2 would duplicate DOE's credentials into a second repo and race the shared access
|
|
570
|
+
token. An expired/revoked token will surface via the 1.0 failure monitors, not this probe — do
|
|
571
|
+
not "fix" this by forking the client.
|
|
572
|
+
|
|
573
|
+
This probe is the client's **only 2.0 footprint**. DOE is **1.0 by default** — `worker2` appears in
|
|
574
|
+
the client's `apps:` scope solely so this monitor loads, and its presence is **not** the start of a
|
|
575
|
+
2.0 migration (there is no `Client_Nycdoe` 2.0 tenant). All business logic stays in the 1.0 tier. See
|
|
576
|
+
[OneUptime push-metric monitors for 2.0 workers](../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md).
|
|
577
|
+
|
|
554
578
|
## Operating rules when changing this integration
|
|
555
579
|
|
|
556
580
|
1. **Trace the full pipeline downstream before fixing** — the constraint that makes an edit
|
|
@@ -563,6 +587,10 @@ use the toga DB MCP + `Logs.API` instead of running prod code locally.
|
|
|
563
587
|
of the consumer query; `php -l` every touched file.
|
|
564
588
|
|
|
565
589
|
## Change history
|
|
590
|
+
- 2026-08-17 — TRUE-80587: added `Monitor/Nycdoe/ServiceNowEndpointHealth` (worker2 → OneUptime), an
|
|
591
|
+
unauthenticated-GET liveness probe complementing the log-scraping 1.0 `App_SystemMonitor_ServiceNow*`
|
|
592
|
+
monitors, which cannot see a dead endpoint. Token validity is a deliberately accepted coverage gap
|
|
593
|
+
(`App_Api_NYCDOEV2` is 1.0-only). First 2.0 code for this client. (mhammontree)
|
|
566
594
|
- 2026-08-14 — Tied the DOE **missing-asset-tag** class to the existing "Lenovo Off-Layout ASN File"
|
|
567
595
|
bug: the +1 shift puts the serial in `assetTag` and means the real asset-tag column (`$cols[24]`)
|
|
568
596
|
is **never read**, so no unit from an off-layout file can get a tag (still **open** — needs the
|
|
@@ -6,11 +6,12 @@ apps:
|
|
|
6
6
|
- library
|
|
7
7
|
- togadesk
|
|
8
8
|
- dbchanges
|
|
9
|
+
- worker2
|
|
9
10
|
project: Worker
|
|
10
11
|
client: nycdoe
|
|
11
12
|
type: profile
|
|
12
13
|
status: active
|
|
13
|
-
updated: 2026-
|
|
14
|
+
updated: 2026-08-17
|
|
14
15
|
owners: [mhammontree, sking]
|
|
15
16
|
files: []
|
|
16
17
|
related:
|
|
@@ -27,8 +28,13 @@ proof-of-delivery back to ServiceNow. A parallel EDI relationship (850 POs in, i
|
|
|
27
28
|
runs over DOE's SFTP.
|
|
28
29
|
|
|
29
30
|
## Platforms & data
|
|
30
|
-
- **1.0 worker tier
|
|
31
|
+
- **1.0 worker tier** — all business logic. Local mirror tables live in `db_common`
|
|
31
32
|
(`NYCDOETickets`, `NYCDOELocations`, `AdvanceShippingNotice*`).
|
|
33
|
+
- **`worker2` (2.0) — monitoring only.** DOE's *only* 2.0 code is the OneUptime liveness probe
|
|
34
|
+
`Monitor/Nycdoe/ServiceNowEndpointHealth` (`worker2/Worker/Monitor/Nycdoe.php`, TRUE-80587).
|
|
35
|
+
This client remains **1.0 by default** — `worker2` is in `apps:` solely so that monitor loads.
|
|
36
|
+
It is **not** the start of a 2.0 migration and there is no `Client_Nycdoe` 2.0 tenant; do not
|
|
37
|
+
read it as a platform move.
|
|
32
38
|
- **TOGa Desk:** DOE is client id **16** (`db_togadesk`) — repair orders, managed service
|
|
33
39
|
orders, and the "#received / #ordered" Receiving Summary UI.
|
|
34
40
|
- **NetSuite:** Sales Orders, PO reconciliation, item receipts, Item Fulfillments, invoices
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
| [Prudential: Dell ASN units PRE/POST interceptor (legacy key + flat tracking)](features/dell-asn-units-interceptor.md) | 2.0 | After the tracking-number bridge migration, the ASN unit route was renamed (`advance-shipping-notice-units` → `advance-shipping-notice-item-units`), so the inhe | _underscore/Model/Prudential/AdvanceShippingNotice.php, dbchanges2/Client_Prudential/2026-06-10 - AsnUnitsInterceptor.sql |
|
|
6
6
|
| [Prudential: Dell LCH IOP transmissions (LCHRequestV2)](features/dell-lch-iop-transmissions.md) | 1.0 | Outbound order transmissions from the 1.0 worker tier to Dell's Lifecycle Hub (LCH) ITSM integration. | library/app/api/delllch.php, library/app/apitransaction.php, worker/crons/toga2/prudential/transmissions_to_dell_usa.php, worker/crons/toga2/prudential/transmissions_to_dell_ireland.php, worker/crons/toga2/prudential/transmissions_to_dell_india.php, worker/crons/toga2/prudential/generate_sales_and_purchase_orders_from_service_requests.php |
|
|
7
7
|
| [Prudential: Device information import + unit→contact linking (import_device_information.php)](features/device-information-import-and-contact-linking.md) | 1.0 | Prudential's **device-sync** cron (`worker/crons/toga2/prudential/import_device_information.php`) pulls device/asset records (from ServiceNow / the Dell CMDB fe | worker/crons/toga2/prudential/import_device_information.php, worker/crons/toga2/prudential/backfill_unit_contacts.php, dbchanges2/Client_Prudential/2026-07-07 - Contact Dedup Merge.sql |
|
|
8
|
+
| [Prudential: OneUptime order-pipeline backlog monitors (Monitor/Prudential/*)](features/oneuptime-order-pipeline-monitors.md) | 2.0 | Three worker2 OneUptime push monitors (TRUE-80587) that watch the Prudential/Dell order pipeline for **stalls**, which were previously invisible — a stuck pipel | worker2/Worker/Monitor/Prudential.php, worker2/Config/production.ini, dbchanges2/Core/2026-08-07a - Prudential AIG ServiceNow OneUptime monitor crons.sql, dbchanges2/Client_Prudential/2026-04-08 - Insert Customers.sql |
|
|
8
9
|
| [Prudential: Service Request Regional Address Validation](features/service-request-address-validation.md) | 2.0 | The `prePost` interceptor on `_Model_Prudential_ServiceRequest` validates `deliverToAddress` fields differently depending on which Prudential regional customer | _underscore/Model/Prudential/ServiceRequest.php, _underscore/Test/Prudential/ServiceRequestTest.php |
|
|
9
10
|
| [Prudential: Service Request rejection alert email](features/service-request-rejection-alert-email.md) | 2.0 | When a Prudential ServiceNow→TOGa service-request submission (`POST /v2/service-requests`) is **rejected by validation**, TOGa now sends a real-time internal al | worker2/Worker/Client/Prudential/reports/ReqRejectionEmail.php, _underscore/Model/Prudential/ServiceRequest.php |
|
|
10
11
|
| [Prudential Order Shipped Email — transmit_ordershipped_updates_prudential.php](features/transmit-ordershipped-email.md) | 1.0 | Cron script that transmits "Order Shipped" updates to ServiceNow (RITM) and sends a shipped notification email to the end user. | worker/crons/toga2/prudential/transmit_ordershipped_updates_prudential.php, worker/crons/toga2/prudential/transmit_closecomplete_updates_prudential.php, worker/crons/toga2/prudential/transmit_rejected_cancelled_updates_prudential.php, worker/crons/toga2/prudential/generate_sales_and_purchase_orders_from_service_requests.php, worker/crons/toga2/prudential_beta/generate_sales_and_purchase_orders_from_service_requests.php, worker/crons/notifications/reports/prudential_exception_report.php |
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Prudential: OneUptime order-pipeline backlog monitors (Monitor/Prudential/*)"
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: worker2
|
|
5
|
+
project: Worker
|
|
6
|
+
client: prudential
|
|
7
|
+
type: client-feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-08-17
|
|
10
|
+
owners: ["mhammontree"]
|
|
11
|
+
files:
|
|
12
|
+
- worker2/Worker/Monitor/Prudential.php
|
|
13
|
+
- worker2/Config/production.ini
|
|
14
|
+
- dbchanges2/Core/2026-08-07a - Prudential AIG ServiceNow OneUptime monitor crons.sql
|
|
15
|
+
- dbchanges2/Client_Prudential/2026-04-08 - Insert Customers.sql
|
|
16
|
+
related:
|
|
17
|
+
- ../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md
|
|
18
|
+
- ../profile.md
|
|
19
|
+
- ./transmit-ordershipped-email.md
|
|
20
|
+
- ./dell-lch-iop-transmissions.md
|
|
21
|
+
- ../../../2.0/apps/worker2/features/service-request-sales-order-generation.md
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Summary
|
|
25
|
+
|
|
26
|
+
Three worker2 OneUptime push monitors (TRUE-80587) that watch the Prudential/Dell order pipeline
|
|
27
|
+
for **stalls**, which were previously invisible — a stuck pipeline produced no error, no email,
|
|
28
|
+
and no alert. They implement the shared pattern in
|
|
29
|
+
[OneUptime push-metric monitors for 2.0 workers](../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md);
|
|
30
|
+
read that first for the payload contract, criteria set, and provisioning runbook.
|
|
31
|
+
|
|
32
|
+
- `Monitor/Prudential/SalesOrderGenerationBacklog` — Service Requests not yet turned into Sales Orders.
|
|
33
|
+
- `Monitor/Prudential/DellPurchaseOrderTransmissionBacklog` — POs not yet transmitted to Dell.
|
|
34
|
+
- `Monitor/Prudential/OrderShippedUpdateBacklog` — order-shipped updates not yet transmitted.
|
|
35
|
+
|
|
36
|
+
## Key files / entry points
|
|
37
|
+
|
|
38
|
+
- `worker2/Worker/Monitor/Prudential.php` — `_Worker_Monitor_Prudential`; one `public static`
|
|
39
|
+
action method per monitor, each self-contained (in-method `ALL_CAPS` locals + `$push` closure).
|
|
40
|
+
- `dbchanges2/Core/2026-08-07a - Prudential AIG ServiceNow OneUptime monitor crons.sql` — the
|
|
41
|
+
`Core.CronJobs` rows (shipped `isActive = 0`, `parameters = '{"alertThreshold":N}'`).
|
|
42
|
+
|
|
43
|
+
## How it works
|
|
44
|
+
|
|
45
|
+
### The monitors read a 2.0 DB but watch 1.0 crons
|
|
46
|
+
|
|
47
|
+
Prudential's order-pipeline **business logic runs in the 1.0 worker tier** against the 2.0
|
|
48
|
+
`Client_Prudential` database. The monitors live in worker2 and only **READ** that database — the
|
|
49
|
+
same split as the Compass monitors. Thresholds are therefore calibrated against the **1.0 cron
|
|
50
|
+
cadences**, not worker2's own `*/5` schedule:
|
|
51
|
+
|
|
52
|
+
| 1.0 cron | Cadence | Throughput |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `generate_sales_and_purchase_orders` | every 3 min | 1 request per run (≈20/hour) |
|
|
55
|
+
| `transmissions_to_dell_{usa,ireland,india}` | every 5 min | one region each |
|
|
56
|
+
| `transmit_ordershipped_updates_prudential` | every 2 min | — |
|
|
57
|
+
|
|
58
|
+
### `BACKLOG_CUTOFF_DATE` — excluding permanently-stranded rows
|
|
59
|
+
|
|
60
|
+
`BACKLOG_CUTOFF_DATE = 2026-08-07`. Rows before it are excluded because they will **never** drain:
|
|
61
|
+
|
|
62
|
+
- ~38 Service Requests orphaned by the **2026-07-17 Dell regional-split cutover**.
|
|
63
|
+
- Two-phase order-shipped stranding — `transmit_ordershipped_updates_prudential` stamps the
|
|
64
|
+
transmitted column in Phase 1, so a Phase-2 crash strands that PO's email forever (see the
|
|
65
|
+
[profile gotchas](../profile.md) and [transmit-ordershipped-email](./transmit-ordershipped-email.md)).
|
|
66
|
+
|
|
67
|
+
Counting them would pin the monitor HIGH on its very first run, which trains people to ignore it.
|
|
68
|
+
|
|
69
|
+
### Diagnostic fields that deliberately do NOT drive the alarm
|
|
70
|
+
|
|
71
|
+
`DellPurchaseOrderTransmissionBacklog` also reports:
|
|
72
|
+
|
|
73
|
+
- `strandedCount` — `ServiceRequests.customerId IS NULL`.
|
|
74
|
+
- `unmappedCustomerCount` — customer is not one of the three regional customer uuids.
|
|
75
|
+
|
|
76
|
+
Both are informational only. The three regional transmission crons **INNER JOIN `Customers` and
|
|
77
|
+
filter to a single region uuid each**, so these rows are invisible to *every* transmitter — they
|
|
78
|
+
are a data-integrity problem, not a transmission backlog, and alarming on them would misroute the
|
|
79
|
+
response.
|
|
80
|
+
|
|
81
|
+
**The monitor `LEFT JOIN`s `Customers` on purpose** so it can see rows the crons cannot. Changing
|
|
82
|
+
it to an `INNER JOIN` would silently blind the monitor — the DocBlock on the method says so, and
|
|
83
|
+
that docblock is load-bearing; do not "tidy" it away.
|
|
84
|
+
|
|
85
|
+
## Reference data (verified 2026-08-17)
|
|
86
|
+
|
|
87
|
+
- The USA / Ireland / India regional customer uuids are seeded in
|
|
88
|
+
`dbchanges2/Client_Prudential/2026-04-08 - Insert Customers.sql` — **not** `2024-01-01.sql`, which
|
|
89
|
+
an in-code comment incorrectly claims.
|
|
90
|
+
- `Client_Prudential.Vendors.id = 1` is Dell.
|
|
91
|
+
|
|
92
|
+
## Gotchas / known issues
|
|
93
|
+
|
|
94
|
+
- Thresholds are DB-tunable (`Core.CronJobs.parameters` → `{"alertThreshold":N}`) — retune there,
|
|
95
|
+
never by editing PHP. The JSON key must match the method's parameter name exactly.
|
|
96
|
+
- The crons ship `isActive = 0`; the monitors do nothing until activated, and each guards on an
|
|
97
|
+
empty push URL. Do not add OneUptime absence criteria until a push has landed.
|
|
98
|
+
|
|
99
|
+
## Change history
|
|
100
|
+
- 2026-08-17 — TRUE-80587: built the three backlog monitors; set `BACKLOG_CUTOFF_DATE` to exclude
|
|
101
|
+
the ~38 Dell regional-split orphans and the two-phase order-shipped strandings; made
|
|
102
|
+
`strandedCount` / `unmappedCustomerCount` non-alarming diagnostics behind a deliberate
|
|
103
|
+
`LEFT JOIN Customers`; calibrated thresholds against the 1.0 cron cadences; corrected the
|
|
104
|
+
regional-customer-uuid seed-file reference to `2026-04-08 - Insert Customers.sql`. (mhammontree)
|
|
105
|
+
|
|
106
|
+
## Related docs
|
|
107
|
+
- [OneUptime push-metric monitors for 2.0 workers](../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md) — the shared pattern, payload contract, and runbook.
|
|
108
|
+
- [Prudential Financial profile](../profile.md)
|
|
@@ -15,9 +15,10 @@ client: prudential
|
|
|
15
15
|
type: profile
|
|
16
16
|
status: active
|
|
17
17
|
updated: 2026-08-17
|
|
18
|
-
owners: ["jcardinal", "rgirish", "bala"]
|
|
18
|
+
owners: ["jcardinal", "rgirish", "bala", "mhammontree"]
|
|
19
19
|
files: []
|
|
20
20
|
related:
|
|
21
|
+
- features/oneuptime-order-pipeline-monitors.md
|
|
21
22
|
- features/dell-asn-units-interceptor.md
|
|
22
23
|
- features/service-request-address-validation.md
|
|
23
24
|
- features/service-request-rejection-alert-email.md
|
|
@@ -81,7 +82,14 @@ order-status transmissions.
|
|
|
81
82
|
(E_ALL→ErrorException), so `!== false` guards do not work — use the `safeFetchPdf()` pattern. See
|
|
82
83
|
the exception report and the transmit-ordershipped-email feature doc.
|
|
83
84
|
|
|
85
|
+
## Monitoring
|
|
86
|
+
- `Monitor/Prudential/{SalesOrderGenerationBacklog,DellPurchaseOrderTransmissionBacklog,OrderShippedUpdateBacklog}`
|
|
87
|
+
(worker2 → OneUptime) watch the order pipeline for stalls. Thresholds are DB-tunable and the
|
|
88
|
+
monitors deliberately ignore pre-2026-08-07 permanently-stranded rows. See
|
|
89
|
+
features/oneuptime-order-pipeline-monitors.md.
|
|
90
|
+
|
|
84
91
|
## Related docs
|
|
92
|
+
- OneUptime order-pipeline backlog monitors (worker2).
|
|
85
93
|
- Dell ASN units interceptor.
|
|
86
94
|
- Dell LCH IOP transmissions (LCHRequestV2, outbound 1.0).
|
|
87
95
|
- 2.0 _underscore: Tracking-Number Bridge Migration.
|
package/package.json
CHANGED