toga-ai 1.0.545 → 1.0.546

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.
@@ -30,6 +30,7 @@
30
30
  | [Background Email-Template Worker (_Worker_Notification_EmailTemplate)](features/notification-email-template.md) | `_Worker_Notification_EmailTemplate::Send(...)` dispatches a **stored, client-defined `EmailTemplates` row off-thread** as a background WorkerJob. | worker2/Worker/Notification/EmailTemplate.php, worker2/Worker/Client/True.php, _underscore/Model/Client/EmailTemplate.php |
31
31
  | [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 |
32
32
  | [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 |
33
+ | [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 |
33
34
  | [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 |
34
35
  | [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 |
35
36
  | [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,121 @@
1
+ ---
2
+ title: OneUptime Incident → ClickUp Task Sync (Monitor/Oneuptime/SyncIncidents)
3
+ framework: "2.0"
4
+ repo: worker2
5
+ project: Worker
6
+ client: shared
7
+ type: feature
8
+ status: active
9
+ updated: 2026-08-10
10
+ owners: ["jcardinal"]
11
+ files:
12
+ - worker2/Component/Api/Oneuptime/Oneuptime.php
13
+ - worker2/Worker/Monitor/Oneuptime.php
14
+ - worker2/Config/production.ini
15
+ - dbchanges2/Team/2026-08-10a - OneUptime Incident ClickUp Tasks.sql
16
+ - dbchanges2/Core/2026-08-10b - OneUptime Incident Sync CronJob.sql
17
+ related:
18
+ - ./oneuptime-worker2-monitoring.md
19
+ - ./error-escalation-cron.md
20
+ - ./creating-worker-actions.md
21
+ - ./team-sprint-management.md
22
+ ---
23
+
24
+ ## Summary
25
+
26
+ An internal/shared TOGA ops feature: worker2 polls the OneUptime API every 15 minutes for
27
+ **currently-open** incidents and ensures a ClickUp task exists for each, so operational
28
+ incidents become actionable tickets automatically without duplicates. This is the **first
29
+ *reader* of the OneUptime API** in worker2 — until now OneUptime was **push-only** (workers
30
+ POST metrics/heartbeats to Incoming-Request monitors; see
31
+ [OneUptime push-metric monitors](./oneuptime-worker2-monitoring.md)). The model was "dumb
32
+ reporter, smart monitor"; this feature adds the reader half.
33
+
34
+ ## Key files / entry points
35
+
36
+ - `worker2/Component/Api/Oneuptime/Oneuptime.php` — `_Component_Api_Oneuptime`, the OneUptime
37
+ API read client, modeled on `_Component_Api_Togaiq`. Reads a new `[oneuptime]` config group
38
+ (endpoint, api_key, project_id) via `_Config`; `isConfigured()` guard; `send()` wraps
39
+ `_ApiRequest` with `APIKey` + `ProjectID` headers; `getActiveIncidents()` returns normalized
40
+ open incidents (filters out resolved **in PHP**).
41
+ - `worker2/Worker/Monitor/Oneuptime.php` — `_Worker_Monitor_Oneuptime::SyncIncidents(): string`,
42
+ the cron action. Returns a structured summary string on every path
43
+ (`incidentsPolled` / `created` / `skipped` / `failed`).
44
+
45
+ ## How it works
46
+
47
+ Canonical worker2 scheduled-3rd-party-API-job shape (see
48
+ [Creating Worker Actions](./creating-worker-actions.md)): a `Core.CronJobs` row (cron expr,
49
+ Central tz) → CronScheduler Lambda enqueues → `Controller/Index::worker()` dispatches the
50
+ `action` `Monitor/Oneuptime/SyncIncidents` to `_Worker_Monitor_Oneuptime::SyncIncidents`.
51
+ HTTP goes through `_ApiRequest`; secrets come from `_Config::oneuptime()` reading
52
+ `Config/<env>.ini`; ClickUp uses `_Component_Api_Clickup::send()`.
53
+
54
+ ### Open-only
55
+
56
+ Only currently-open incidents are synced. The list route returns all incidents and resolved
57
+ ones are filtered out in PHP inside `getActiveIncidents()`.
58
+
59
+ ### Claim-first (unique-key) dedup
60
+
61
+ For each open incident, INSERT a ledger row into `OneUptimeIncidentTasks` keyed on the
62
+ OneUptime incident id **before** calling ClickUp. A unique-key violation means a task already
63
+ exists → skip. On success, create the ClickUp task via
64
+ `_Component_Api_Clickup::send('POST','/list/{listId}/task', …)` and attach the returned id to
65
+ the ledger row; on failure, **delete the claim and re-throw**. This is the established
66
+ worker2 way to prevent duplicate ClickUp tasks under overlapping cron runs — pattern copied
67
+ from `_Worker_Infrastructure_Errors::createClickupTask`. `INSERT … WHERE NOT EXISTS` is
68
+ **insufficient** under REPEATABLE READ; the UNIQUE key is the concurrency arbiter.
69
+
70
+ ### Target list = current sprint list
71
+
72
+ The ClickUp task lands in the **current sprint** list, resolved by `GET /folder/{id}` and
73
+ matching the list whose `start_date`/`due_date` window contains now (mirrors
74
+ `_Worker_Team_Sprint::SprintLock` — see [Team Sprint Management](./team-sprint-management.md)
75
+ and the sprint-promotion note in [Error Escalation Cron](./error-escalation-cron.md)). Folder
76
+ id is read from `[clickup] sprint_folder_id` with a constant fallback (`90020432579`).
77
+
78
+ ## Data model
79
+
80
+ `OneUptimeIncidentTasks` (CREATE on the **Team** cluster — chosen over Logs;
81
+ `dbchanges2/Team/2026-08-10a`): `id`, `uuid char(36)`, `dtCreated`,
82
+ `oneuptimeIncidentId varchar(64)`, `clickupIdentifier varchar(64) NULL`. The **UNIQUE KEY on
83
+ `oneuptimeIncidentId`** is the dedup contract, same rationale as `IssueClickupTasks`.
84
+
85
+ ## Provisioning / deploy
86
+
87
+ - `dbchanges2/Core/2026-08-10b` inserts the `Core.CronJobs` row: action
88
+ `Monitor/Oneuptime/SyncIncidents`, schedule `*/15 * * * *`, `maxExecutionTime` 120, seeded
89
+ **`isActive = 0`**. Flip to 1 only after (a) the ledger table exists, (b) the `[oneuptime]`
90
+ config group is populated, and (c) the incident-list route is confirmed.
91
+ - `[oneuptime]` config group (endpoint, api_key, project_id) added to
92
+ `worker2/Config/production.ini` with placeholders — **values are filled by the developer,
93
+ not committed**. Credentials live only in the ini files.
94
+
95
+ ## Configuration / credentials
96
+
97
+ - `[oneuptime]` — `endpoint`, `api_key`, `project_id`. The hosted OneUptime SaaS base is
98
+ `https://oneuptime.com` (confirmed from `worker/.ebextensions/045_oneuptime_agent.config`);
99
+ the REST API path is appended to that base.
100
+ - `[clickup]` — `sprint_folder_id` (fallback constant `90020432579`) plus the ClickUp token.
101
+ ClickUp/OneUptime token **values** live in `worker2/Config/<env>.ini` — location only,
102
+ never the value.
103
+
104
+ ## Gotchas / known issues
105
+
106
+ - **Incident-list route/fields are PLACEHOLDER** (`/api/incident/get-list`) pending
107
+ confirmation against the live OneUptime instance. Do not enable the cron (`isActive = 1`)
108
+ until the route and returned fields are verified.
109
+ - **OneUptime cannot filter open-only server-side here** — resolution filtering happens in
110
+ PHP, so the returned field set must actually carry the resolved/open state.
111
+ - Ship the worker2 code deploy and both dbchanges2 migrations **together**; the cron row is
112
+ inert until the action is deployed and the ledger table exists.
113
+
114
+ ## Change history
115
+ - 2026-08-10 — Built: first OneUptime API *reader* (`_Component_Api_Oneuptime`) + the
116
+ `Monitor/Oneuptime/SyncIncidents` cron that claim-first-dedups an open incident into a
117
+ ClickUp task in the current sprint list; new `OneUptimeIncidentTasks` ledger (Team cluster,
118
+ UNIQUE on incident id) and a seeded-inactive `*/15 * * * *` cron row. Incident-list route
119
+ left PLACEHOLDER pending confirmation. (jcardinal)
120
+ </content>
121
+ </invoke>
@@ -15,6 +15,7 @@ files:
15
15
  - _underscore/Cloud.php
16
16
  - worker2/Worker/Monitor/Operations.php
17
17
  related:
18
+ - ./oneuptime-incident-clickup-sync.md
18
19
  - ./monitoring-framework.md
19
20
  - ./all-client-email-queue-monitor.md
20
21
  - ../../_underscore/features/cloud-s3-helpers.md
@@ -211,6 +212,10 @@ check for another client.
211
212
  monitors must pass the region (see [Cloud S3 helpers](../../_underscore/features/cloud-s3-helpers.md)).
212
213
 
213
214
  ## Change history
215
+ - 2026-08-10 — Noted that worker2 gained its **first OneUptime API *reader*** (this doc covers
216
+ the push-only half; OneUptime was previously push-only, "dumb reporter, smart monitor"). The
217
+ reader polls open incidents and files ClickUp tasks — see
218
+ [OneUptime Incident → ClickUp Task Sync](./oneuptime-incident-clickup-sync.md). (jcardinal)
214
219
  - 2026-08-10 — Documented OneUptime incident/alert `{{requestBody.*}}` templating (missing
215
220
  paths → empty string; `Not Recieved In Minutes` heartbeat spelling), discovered while
216
221
  wiring the second all-client `_Worker_Monitor_Operations` monitor —
@@ -18,8 +18,8 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
18
18
 
19
19
  ## 2.0 framework
20
20
 
21
- - **_underscore** (_Underscore) _(framework core)_ — 48 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
22
- - **worker2** (Worker) — 43 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
21
+ - **_underscore** (_Underscore) _(framework core)_ — 49 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
22
+ - **worker2** (Worker) — 44 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
23
23
  - **api2** (API) — 22 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) — 5 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.545",
3
+ "version": "1.0.546",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",