toga-ai 1.0.859 → 1.0.860
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.
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
| [ClickUp Rich-Text Custom Fields via Quill Delta (API)](features/clickup-richtext-api.md) | How to write formatted text into a ClickUp text/long-text custom field via the undocumented `value_richtext` Quill Delta key; open when a richtext ClickUp field |
|
|
18
18
|
| [ClickUp Subtask Activity → Parent Opportunity/Epic Comments](features/clickup-subtask-activity.md) | Mirrors subtask status/comment activity up to its top-level Opportunity/Epic as one comment; open for the subtask fan-out, its dedup ledger, or structural ances |
|
|
19
19
|
| [ClickUp Task Description Fluffer (Talos KB Investigation)](features/clickup-task-fluffer-talos.md) | Async worker that "fluffs" a new ClickUp task by running its name+description through the Talos `dev-core` KB agent and writing the report back; open for the fl |
|
|
20
|
+
| [ClickUp Webhook Health Monitor → OneUptime (Monitor/Clickup/CheckWebhook)](features/clickup-webhook-health-monitor.md) | worker2 cron that checks the team's ClickUp webhook subscriptions and pages via a OneUptime Incoming-Request monitor; open when tuning the ClickUp webhook alarm |
|
|
20
21
|
| [ClickUp Work Type Automation (Committed / Conditional / Stretch)](features/clickup-work-type-automation.md) | Auto-maintains each ClickUp task's Work Type (Committed/Conditional/Stretch) from its dependencies, status, and due date; open when work-type promotion/demotion |
|
|
21
22
|
| [worker2 — Committed Secrets & Config Exposure (debt register)](features/committed-secrets-and-config-debt.md) | Standing list of credentials committed to the worker2 repo (locations only); open before adding a credential to worker2 or assuming a config value is private. |
|
|
22
23
|
| [Compass VIP Support Importer (worker2)](features/compass-vip-support-importer.md) | worker2 action that ingests Compass's quarterly VIP spreadsheet and sets each VIP's support tech (`Users.c_supportedByUserId` in `Client_Compass`); open when wo |
|
|
@@ -6,13 +6,14 @@ project: Worker
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
10
|
-
owners: [ajean]
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: [ajean, jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- worker2/Worker/Clickup/Health.php
|
|
13
13
|
- worker2/Database/ClickupHealthWatchdog.sql
|
|
14
14
|
related:
|
|
15
15
|
- ./clickup-project-routing.md
|
|
16
|
+
- ./clickup-webhook-health-monitor.md
|
|
16
17
|
- ../architecture.md
|
|
17
18
|
---
|
|
18
19
|
|
|
@@ -41,6 +42,10 @@ Data model:
|
|
|
41
42
|
- **Inbound query must match `Clickup/Webhook` exactly.** `LIKE 'Clickup/%'` also matches the watchdog's own `Clickup/Health/Check` rows and the timer never expires.
|
|
42
43
|
- **Email identifier is `'True'`** (internal/team `clientIdentifier`, via `_Worker_Notification_Email::Send`).
|
|
43
44
|
- **Business window enforced in code too** (Mon–Fri 09:00–17:00 Central), not just the cron — a manual off-hours run is a safe no-op.
|
|
45
|
+
- **⚠ Latent blind spot: the webhook-health probe only sees webhooks the query token created.** `GET /team/{id}/webhook` returns **only** webhooks created by the calling identity. `Check()` queries as the worker2 service account (`_Config::clickup('token')`, `pk_87469444`), so a webhook owned by a **different** ClickUp identity is invisible — the probe sees zero webhooks and always reports healthy, and can never catch a real failure. Proven 2026-09-21 on team `8577082` (the live webhook was owned by an OAuth app, user `12633140`). Fix is to keep the monitored webhook **created under the same service token** — see [ClickUp Webhook Health Monitor](./clickup-webhook-health-monitor.md) for the full gotcha and the recreation done on 2026-09-21. (Not yet fixed in code here.)
|
|
46
|
+
|
|
47
|
+
## Change history
|
|
48
|
+
- 2026-09-21 — Recorded the token-ownership blind spot in the webhook-health probe (queries as the service account, so a webhook created under another identity reads as "no webhooks / healthy"). Sibling OneUptime monitor added — see [ClickUp Webhook Health Monitor](./clickup-webhook-health-monitor.md). (jcardinal)
|
|
44
49
|
|
|
45
50
|
## Related
|
|
46
51
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ClickUp Webhook Health Monitor → OneUptime (Monitor/Clickup/CheckWebhook)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: worker2
|
|
5
|
+
project: Worker
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-09-21
|
|
10
|
+
owners: [jcardinal]
|
|
11
|
+
files:
|
|
12
|
+
- worker2/Worker/Monitor/Clickup.php
|
|
13
|
+
related:
|
|
14
|
+
- ./oneuptime-worker2-monitoring.md
|
|
15
|
+
- ./clickup-connectivity-watchdog.md
|
|
16
|
+
- ./clickup-project-routing.md
|
|
17
|
+
- ../workflows/clickup-credential-rotation.md
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
worker2 cron that checks the team's ClickUp webhook subscriptions and pages via a OneUptime Incoming-Request monitor; open when tuning the ClickUp webhook alarm or the token it queries under.
|
|
21
|
+
|
|
22
|
+
## Summary
|
|
23
|
+
|
|
24
|
+
`_Worker_Monitor_Clickup::CheckWebhook()` (action `Monitor/Clickup/CheckWebhook`, cron `*/10 * * * *` Central) is a **"dumb reporter, smart monitor"** heartbeat on the [OneUptime push-metric pattern](./oneuptime-worker2-monitoring.md). No DB. Modeled on `_Worker_Monitor_Operations`.
|
|
25
|
+
|
|
26
|
+
Catches the **silent webhook outage** EB health checks cannot see: if ClickUp suspends or fails our inbound webhook (`https://webhook.togahub.com/clickup`), inbound tasks stop arriving and nothing else notices.
|
|
27
|
+
|
|
28
|
+
Distinct from and **stricter than** the sibling email watchdog [`_Worker_Clickup_Health`](./clickup-connectivity-watchdog.md): this alarms on any `togahub.com` webhook not `health.status = "active"`; the watchdog only emails on `status = "failing"` in business hours.
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
- Reads subscriptions: `_Component_Api_Clickup::send('GET','/team')` → for each team `_Component_Api_Clickup::send('GET','/team/{id}/webhook')`.
|
|
33
|
+
- POSTs a metric body via `_ApiRequest` to a OneUptime incoming-request heartbeat URL: `alarm` (`OK`/`DEGRADED`), `probe` (`OK`/`DEGRADED`), plus `webhookCount`, `activeCount`, `failures`.
|
|
34
|
+
- **Alarm rule:** `DEGRADED` when any webhook whose endpoint contains `togahub.com` is not `health.status = "active"`.
|
|
35
|
+
- **Push URL is an in-file `$ONEUPTIME_URL` local, not `[oneuptime]` config** — the established team convention for every `Worker/Monitor/*` file (Operations, Staples, Compass, Aig, Prudential, Nycdoe, Fleet). A cso review suggested reading it from config; the developer rejected that on purpose — the heartbeat URL is treated as low-sensitivity and stays inline, matching the siblings. See the credential note in [OneUptime push-metric monitors](./oneuptime-worker2-monitoring.md). Ships blank with a soft-fail guard until the real URL is pasted in.
|
|
36
|
+
- Cron row: `dbchanges2/Core/2026-09-21c - Insert ClickUp Webhook Health Monitor CronJob.sql`. OneUptime import artifact `clickup-webhook-health.json` lives in a local staging dir, not the repo (import artifacts are not version-controlled — see the pattern doc's provisioning runbook).
|
|
37
|
+
|
|
38
|
+
## Gotchas
|
|
39
|
+
|
|
40
|
+
- **`GET /team/{id}/webhook` only returns webhooks CREATED BY the calling token.** A webhook owned by a different ClickUp identity is **invisible** even on the same team. Proven 2026-09-21: the worker2 service token (`_Config::clickup('token')`, `pk_87469444` "Development Team") saw **zero** webhooks on team `8577082`, while the webhook actually feeding worker2 was owned by a different identity (an OAuth app, user `12633140`) and visible only to that token. So the monitor (and `_Worker_Clickup_Health`) can only see a webhook if it was created under the **same token they query with** — recreate any monitored webhook under the service account.
|
|
41
|
+
- **`pk_` personal tokens go RAW in the `Authorization` header (no `Bearer`); OAuth access tokens use `Bearer`.** `_Component_Api_Clickup::send()` sends the token raw, so it works with a `pk_` token and would need the `Bearer` prefix for an OAuth token.
|
|
42
|
+
- Keep the metric POST non-fatal — a monitoring outage must never break the worker job.
|
|
43
|
+
|
|
44
|
+
## Change history
|
|
45
|
+
- 2026-09-21 — Created `_Worker_Monitor_Clickup::CheckWebhook` (OneUptime, `*/10`, stricter than the email watchdog). Recreated the inbound webhook under the service account (`pk_87469444`, new id `bd6168ab-…`, deleting the old OAuth-owned one) so both this monitor and `_Worker_Clickup_Health` can see it — the two were previously blind to it (token-ownership gotcha above). (jcardinal)
|
|
46
|
+
|
|
47
|
+
## Related
|
|
48
|
+
|
|
49
|
+
- [OneUptime push-metric monitors for 2.0 workers](./oneuptime-worker2-monitoring.md) — the reporter pattern, payload contract, and monitor-import JSON shape.
|
|
50
|
+
- [ClickUp Connectivity Watchdog](./clickup-connectivity-watchdog.md) — the sibling email-alert webhook-health cron (`_Worker_Clickup_Health`).
|
|
51
|
+
- [ClickUp Project & Opportunity Multi-List Routing](./clickup-project-routing.md) — the integration this protects.
|
|
52
|
+
- [Rotating the ClickUp API credential](../workflows/clickup-credential-rotation.md) — the service-account token this queries under.
|
package/knowledge/INDEX.md
CHANGED
|
@@ -20,7 +20,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
20
20
|
## 2.0 framework
|
|
21
21
|
|
|
22
22
|
- **_underscore** (_Underscore) _(framework core)_ — 88 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
|
|
23
|
-
- **worker2** (Worker) —
|
|
23
|
+
- **worker2** (Worker) — 74 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
|
|
24
24
|
- **api2** (API) — 26 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
|
|
25
25
|
- **dbchanges2** (Database Changes) _(framework core)_ — 19 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
26
26
|
- **toga2-supply** (TOGa Supply) — 9 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
|
package/package.json
CHANGED