toga-ai 1.0.943 → 1.0.944

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,7 +17,7 @@
17
17
  | [Prudential: Send Shipments for the Day report (daily cron)](features/send-shipments-for-the-day.md) | Daily 9:00 PM Prudential/Dell cron emailing an Excel of every device shipped today (tracking, serial, XID, FedEx status, vendor); open for the ASN join chain an |
18
18
  | [Staples 856 ASN Outbound (NetSuite fulfillments → SFTP, tracked in StaplesAdvanceShipNotices)](features/staples-asn-856-outbound.md) | Hourly cron sending Staples 856 ASNs for shipped NetSuite item fulfillments, one row per fulfillment in `Common.StaplesAdvanceShipNotices`; open for the queue/r |
19
19
  | [Staples cXML Order Import (SFTP → NetSuite)](features/staples-cxml-order-import.md) | Hourly cron importing Staples cXML POs from SFTP into NetSuite Sales Orders (writes 855 ack back); open for the per-file flow, saved-search-8412 Location resolu |
20
- | [UMA Student Roster Sync (SFTP → TOGaDeskSupport customers) + Ivanti Ticket Sync](features/uma-student-sync.md) | Daily SFTP full-roster file loads UMA students into TOGaDeskSupport.customers (clientId 10); open for the file format, insert/deactivate rules, how the Ivanti t |
20
+ | [UMA Student Roster Sync (SFTP → TOGaDeskSupport customers) + Ivanti Ticket Sync](features/uma-student-sync.md) | Daily SFTP full-roster file loads UMA students into TOGaDeskSupport.customers (clientId 10); plus the once-a-day Ivanti ticket sync (escalations reach UMA only |
21
21
  | [Walmart Daily Sales Report (send_toga_walmart_report.php)](features/walmart-daily-sales-report.md) | The two Walmart sales workbooks (summary + details) built from `TOGA_Walmart` (in-store) and `TOGA_WalmartEComm` (.COM); open for the pseudo-store 1472 channel |
22
22
  | [Diagnosing frozen 1.0 worker cron check-ins (Sentry "missed" flood)](workflows/diagnosing-frozen-cron-checkins.md) | Ordered path to diagnose frozen 1.0 worker cron timestamps + a Sentry `worker1` "missed" flood; open when check-ins stall and you suspect a wedged lock. |
23
23
  | [isFulfillable Multi-Client Backfill (all togasupply clients)](workflows/isfulfillable-multi-client-backfill.md) | One-time backfill catching up `Items.isFulfillable` on existing items across all 17 togasupply clients; open when running/re-running it or deciding whether rema |
@@ -6,7 +6,7 @@ project: Worker
6
6
  client: uma
7
7
  type: client-feature
8
8
  status: active
9
- updated: 2026-09-28
9
+ updated: 2026-10-05
10
10
  owners: ["mhammontree"]
11
11
  files:
12
12
  - worker/crons/togadesk/sync_uma_customers.php
@@ -17,7 +17,7 @@ related:
17
17
  - 1.0/apps/worker/architecture.md
18
18
  ---
19
19
 
20
- Daily SFTP full-roster file loads UMA students into TOGaDeskSupport.customers (clientId 10); open for the file format, insert/deactivate rules, how the Ivanti ticket sync depends on it, health-check queries, and the PII/hardcoded-credential traps.
20
+ Daily SFTP full-roster file loads UMA students into TOGaDeskSupport.customers (clientId 10); plus the once-a-day Ivanti ticket sync (escalations reach UMA only when it runs); open for the file format, insert/deactivate rules, escalation timing, health-check queries, and the PII/hardcoded-credential traps.
21
21
 
22
22
  ## Summary
23
23
 
@@ -35,7 +35,15 @@ UMA students reach our system through a **daily SFTP file**, not an API. `togade
35
35
  - existing → **untouched** (name/email/phone are never updated);
36
36
  - existing but absent from the file → `isActive = 0`. The file is the **full roster**.
37
37
 
38
- **Ticket sync (`sync_uma_tickets.php`):** uses `App_Api_UMA` (`library/app/api/uma.php`, extends `App_Api_Ivanti`, endpoint `umaservicecenter.saasit.com`) to pull new student incidents and push TOGaDesk tickets. A ticket is created only when the incident email matches a student's `emailPersonal`/`emailWork`.
38
+ **Ticket sync (`sync_uma_tickets.php`):** uses `App_Api_UMA` (`library/app/api/uma.php`, extends `App_Api_Ivanti`, endpoint `umaservicecenter.saasit.com`). Each run, in order:
39
+ 1. Pull new Ivanti incidents → TOGaDesk tickets. Created only when the incident email matches a student's `emailPersonal`/`emailWork`.
40
+ 2. Close TOGaDesk tickets whose incident is resolved in Ivanti.
41
+ 3. **Escalate ("send new tickets back to uma"):** clientId 10 tickets with `referenceId IS NULL AND dtSynced IS NULL` → `App_Api_UMA::postNewIncident()`; Ivanti RecId stored in `tickets.referenceId`.
42
+ 4. Push Closed TOGaDesk tickets back to Ivanti as Resolved.
43
+
44
+ Nothing is sent at escalation time — an escalated ticket waits for the next run.
45
+
46
+ **Ticket sync schedule** (`schedules/cron.worker.togadesk.json`, server time = Central): **once per day** — Mon–Thu `0 15 * * 1-4`, Fri `30 11 * * 5`, Sat `0 17 * * 6`, Mon `0 1 * * 1`. No Sunday run (~32 h gap Sat 17:00 → Mon 01:00). Runs take ~2 min. Fix if asked: restore an hourly (or tighter) range.
39
47
 
40
48
  ## Health check (read-only prod, env `legacy`)
41
49
 
@@ -43,6 +51,7 @@ UMA students reach our system through a **daily SFTP file**, not an API. `togade
43
51
  - **Runs:** `Common.CronJobExecutions` (~120M rows, **no index** on `job`/`dtCheckIn`). Bound by id range (~750k rows/day, e.g. `id > MAX(id) - N`) and match `job = '/var/www/html/crons/togadesk/sync_uma_customers.php'`.
44
52
  - `dtCheckOut` set = finished cleanly; a thrown error leaves it NULL.
45
53
  - ~12-13 s = file processed; ~2 s = SFTP root was empty.
54
+ - **Ticket sync runs:** same table, `job = '/var/www/html/crons/togadesk/sync_uma_tickets.php'`. Escalation send time = run time; check Ivanti created timestamps, not `dtSynced`.
46
55
  - **Normal pattern:** one file/day. Occasional misses or a late file arriving with the next day's — harmless, since only the newest (full roster) is parsed.
47
56
 
48
57
  ## Gotchas
@@ -54,6 +63,9 @@ UMA students reach our system through a **daily SFTP file**, not an API. `togade
54
63
  - **PII.** Files hold DOB and SSN last 4. When investigating, pull only dates/file names from FileLog, never `fileData`.
55
64
  - **Hardcoded credentials — treat as leaked, rotate.** SFTP login is hardcoded in `sync_uma_customers.php`; the Ivanti API key is hardcoded in `library/app/api/uma.php`. Do not copy them anywhere.
56
65
  - Does not call `App_Database::closeConnections()`.
66
+ - **Escalations batch once a day.** Cron entry names still say windows like "9:00–21:00" — misleading; the cron expressions are single hours. Cause: `d53e1ab35` (TRUE-61196, 2025-03-10, UTC→CST) replaced hourly ranges (`0 3-15 * * 2-5`, `0 0-15 * * 6`, `0 0-17 * * 0`, `0 1-15 * * 1`) with single hours; later TZ shifts `9732b7b50` (TRUE-74692) and `9f16ad1de` (TRUE-77365) kept single hours.
67
+ - **`tickets.dtSynced` is not the send time.** On push the code sets it to the ticket's created timestamp; some rows show the run time instead.
57
68
 
58
69
  ## Change history
59
70
  - 2026-09-28 — Documented (TRUE-82352 investigation). Open incident: no UMA file since 2026-09-20; runs 9-21..9-27 clean with empty SFTP; togadesk worker instance changed that day but SFTP login still works from the new box — likely UMA stopped uploading, awaiting UMA confirmation. No wrong deactivations; new students and their tickets missing since 9-20. (mhammontree)
71
+ - 2026-10-05 — TRUE-82504 escalation-batch investigation: escalations reach UMA's Ivanti once a day (prod: tickets created 9/29 20:17 → 9/30 08:21 all sent 9/30 15:01–15:02 CT; repeated 10/1). Findings delivered, no fix requested. (mhammontree)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.943",
3
+ "version": "1.0.944",
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",