toga-ai 1.0.776 → 1.0.777

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.
@@ -5,7 +5,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
5
5
  ## 1.0 framework
6
6
 
7
7
  - **library** (Library) _(framework core)_ — 24 doc(s) → [1.0/apps/library/INDEX.md](1.0/apps/library/INDEX.md)
8
- - **worker** (Worker) — 33 doc(s) → [1.0/apps/worker/INDEX.md](1.0/apps/worker/INDEX.md)
8
+ - **worker** (Worker) — 34 doc(s) → [1.0/apps/worker/INDEX.md](1.0/apps/worker/INDEX.md)
9
9
  - **dbchanges** (Database Changes) _(framework core)_ — 1 doc(s) → [1.0/apps/dbchanges/INDEX.md](1.0/apps/dbchanges/INDEX.md)
10
10
  - **worker1.5** (Worker 1.5) — 0 doc(s) → [1.0/apps/worker1.5/INDEX.md](1.0/apps/worker1.5/INDEX.md)
11
11
  - **togadesk** (TOGa Desk) — 13 doc(s) → [1.0/apps/togadesk/INDEX.md](1.0/apps/togadesk/INDEX.md)
@@ -2,6 +2,7 @@
2
2
 
3
3
  | Doc | Framework | Summary | Files |
4
4
  |-----|-----------|---------|-------|
5
+ | [NYCDOE EDI 850 Receive & 997 Acknowledgement](features/edi-850-receive-and-997-ack.md) | 1.0 | DOE sends purchase orders as **EDI 850** files over their SFTP; TOGA turns each one into a NetSuite Sales Order and sends back an **EDI 997** functional acknowl | worker/crons/sync/nycdoe/receive_edi_purchase_orders.php, worker/schedules/cron.worker.sync.json, library/app/edi.php |
5
6
  | [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
7
  | [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
8
  | [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/ | |
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: NYCDOE EDI 850 Receive & 997 Acknowledgement
3
+ framework: "1.0"
4
+ repo: worker
5
+ project: Worker
6
+ client: nycdoe
7
+ type: client-feature
8
+ status: active
9
+ updated: 2026-09-04
10
+ owners: [mhammontree]
11
+ files:
12
+ - worker/crons/sync/nycdoe/receive_edi_purchase_orders.php
13
+ - worker/schedules/cron.worker.sync.json
14
+ - library/app/edi.php
15
+ related:
16
+ - servicenow-integration.md
17
+ - ../profile.md
18
+ - ../../../1.0/apps/worker/architecture.md
19
+ - ../../../1.0/apps/library/architecture.md
20
+ ---
21
+
22
+ ## Summary
23
+
24
+ DOE sends purchase orders as **EDI 850** files over their SFTP; TOGA turns each one into a
25
+ NetSuite Sales Order and sends back an **EDI 997** functional acknowledgement. There is
26
+ **no separate 997 cron** — the 997 is built and uploaded inline at the end of the 850
27
+ receiver, so anything that aborts the receiver also means DOE never gets an ack.
28
+
29
+ This doc owns the 850-in / 997-out surface. The broader DOE ticket + ASN pipeline lives in
30
+ [servicenow-integration.md](servicenow-integration.md).
31
+
32
+ ## How it works
33
+
34
+ 1. **Cron:** `worker/crons/sync/nycdoe/receive_edi_purchase_orders.php`, schedule
35
+ `30 9,15 * * *` (9:30 AM and 3:30 PM) in `worker/schedules/cron.worker.sync.json`.
36
+ 2. Pulls every file from `/outbound` on DOE's SFTP `transfer.schools.nyc` (SSH key file
37
+ `library/ssl/doe/doedimedu.pem`; username and key live in the
38
+ [DOE profile](../profile.md) / on disk — never in this doc).
39
+ 3. `App_Edi::translatePurchaseOrder850()` parses each file. Only files whose
40
+ `senderId == 'NYCDOE'` are processed.
41
+ 4. Creates the NetSuite Sales Order (DOE customer internal id **21797**) and attaches the
42
+ raw 850 file.
43
+ 5. **Then** builds the 997 via
44
+ `App_Edi::generateAcknowledgements997FromPurchaseOrders850()` (`library/app/edi.php`,
45
+ ~line 348) and `put`s it to `/inbound` as `997_<original 850 filename>`
46
+ (cron ~lines 338-350).
47
+ 6. Logs **both** the 850 and the 997 to `App_Model_FileLog` (`db_logs`, table
48
+ `Logs.FileLog`, `legacy` environment) under job `EDI_NYCDOE_PO`, then deletes the 850
49
+ from DOE's SFTP.
50
+
51
+ ### 997 segment structure
52
+
53
+ `ISA` / `GS(FA)`, then per PO: `ST(997)`, `AK1(PO, groupStartIdentifier)`,
54
+ `AK2(850, transactionSetIdentifier)`, `AK5(A)`, `AK9(A,1,1,1)`, `SE(6)`; then `GE` / `IEA`.
55
+ Transaction set control number starts at **1001** and increments per PO. Default
56
+ separators: `~` element, `\n` segment.
57
+
58
+ Field mapping (verified against 850 FileLog id 880810):
59
+
60
+ | 997 segment | Source in the 850 |
61
+ |---|---|
62
+ | `AK1~PO~2` | the 850's `GS~PO~NYCDOE~2127360111~…~2~X~004010` |
63
+ | `AK2~850~004204317` | the 850's `ST~850~004204317` |
64
+ | (PO number, elsewhere) | `BEG~00~KN~WR270037765` |
65
+
66
+ ## Gotchas
67
+
68
+ - **The cron header comment is STALE.** It says "INTENDED TO BE RUN EVERY HOUR". It runs
69
+ twice a day. `worker/schedules/cron.worker.sync.json` is the source of truth.
70
+ - **The 997 generator is an "always accept" stub — still OPEN.**
71
+ `library/app/edi.php` ~lines 393-412 hardcode `AK5 = 'A'` and `AK9 = 'A','1','1','1'`, so
72
+ every 997 reports "accepted, 1 transaction set" no matter what the 850 contained. It can
73
+ never report a reject or a real transaction count. Out of scope for TRUE-81757; needs its
74
+ own ticket if DOE ever audits the acks beyond `AK2`.
75
+ - **An exception in the NetSuite loop skips the 997 entirely** and leaves the 850 on SFTP,
76
+ so the file re-processes next run and DOE gets no ack at all. That fail-loud abort is
77
+ correct for 1.0 sync/cron code, but it is a distinct cause from a *malformed* 997 —
78
+ check which one you have before touching the generator.
79
+ - **`generateAcknowledgements997FromPurchaseOrders850()` has exactly one production
80
+ caller** (this DOE cron). The other two callers are dev scratch scripts under
81
+ `test/@jeff/edi/` and `test/@pinal/netSuites/`, so a change to it is DOE-only in effect.
82
+ - **`sync/prudential/receive_edi_purchase_orders.php` does NOT use this 997 function.** Do
83
+ not assume the two EDI receivers share the ack path.
84
+ - **EDI PO104 leading-zero suppression** — DOE's IBM translator sends `.94` not `0.94`;
85
+ exposure is in `App_Edi::translatePurchaseOrder850()`, not the cron. See
86
+ [servicenow-integration.md](servicenow-integration.md).
87
+
88
+ ## Debugging a DOE 997 complaint
89
+
90
+ 1. Query `Logs.FileLog` on the `legacy` environment for job `EDI_NYCDOE_PO`.
91
+ 2. Match the pair: the 997 row's `fileName` is `997_` + the 850's `fileName` (e.g. id
92
+ `880810` = the 850, `880811` = its 997).
93
+ 3. `fileData` is a BLOB — read it with `CONVERT(fileData USING latin1)` to see the EDI text.
94
+ 4. The 850 is deleted from DOE's SFTP after a successful run, but the **raw file data is
95
+ retained in `Logs.FileLog`**, so a 997 can be regenerated from the stored 850 without
96
+ asking DOE to resend.
97
+
98
+ ## Change history
99
+ - 2026-09-04 — **Fixed (TRUE-81757): `AK2` sent the wrong transaction set id.**
100
+ `App_Edi::generateAcknowledgements997FromPurchaseOrders850()` (`library/app/edi.php`
101
+ line 400) hardcoded `'855'`; changed to `'850'` — the 997 acknowledges an inbound **850**
102
+ Purchase Order, so `AK201` must be `850`. Not an isolated event: the line has read `'855'`
103
+ since the function was first written (commit `3136e813`), and every 997 in `Logs.FileLog`
104
+ back to at least 2026-03-20 shows `AK2~855` (ids 880811, 868639, 814727, 810405) — DOE's
105
+ translator silently accepted it for months and complained only once. **Business decision
106
+ (Eric): fix going forward only** — no back-fix and no resend of historical 997s.
107
+ Also documented the full 850-in/997-out flow, the always-accept `AK5`/`AK9` stub (still
108
+ open), and the `Logs.FileLog` debugging path. (mhammontree)
@@ -6,7 +6,7 @@ project: Worker
6
6
  client: nycdoe
7
7
  type: client-feature
8
8
  status: active
9
- updated: 2026-08-18
9
+ updated: 2026-09-04
10
10
  owners: [mhammontree, sking]
11
11
  files:
12
12
  - worker/crons/sync/nycdoe/import_asn.php
@@ -42,6 +42,7 @@ files:
42
42
  - worker2/Worker/Monitor/Nycdoe.php
43
43
  related:
44
44
  - ../profile.md
45
+ - edi-850-receive-and-997-ack.md
45
46
  - ../../../2.0/apps/worker2/features/oneuptime-worker2-monitoring.md
46
47
  - hold-status-sync.md
47
48
  - ../../../1.0/apps/worker/architecture.md
@@ -90,7 +91,7 @@ ticket state / ETA / proof-of-delivery back to ServiceNow. A parallel EDI surfac
90
91
  | Proof of delivery → ServiceNow | `send_nycdoe_proof_of_delivery.php` | every 5 min |
91
92
  | Locations sync | `sync_nycdoe_locations.php` | daily 3:00 AM |
92
93
  | Site-id monitor | `email_notification_siteid.php` | daily 7:01 AM |
93
- | EDI 850 POs in → NetSuite SO + 997 ack | `receive_edi_purchase_orders.php` (`senderId == 'NYCDOE'` only) | 9:30 AM & 3:30 PM |
94
+ | EDI 850 POs in → NetSuite SO + 997 ack | `receive_edi_purchase_orders.php` (`senderId == 'NYCDOE'` only) — see [edi-850-receive-and-997-ack.md](edi-850-receive-and-997-ack.md) | 9:30 AM & 3:30 PM |
94
95
  | EDI invoices out (NetSuite saved search 2108) | `send_edi_open_invoices.php` | every 2 h at :13 |
95
96
  | Installation schedule reports | `notifications/nycdoe/send_installation_schedules_doe.php` (3 business days ahead, weekends skipped, **holidays NOT skipped**), daily + current-week variants, weekly part-orders | 5–8 AM daily/Mondays |
96
97
 
@@ -647,6 +648,7 @@ the client's `apps:` scope solely so this monitor loads, and its presence is **n
647
648
  of the consumer query; `php -l` every touched file.
648
649
 
649
650
  ## Change history
651
+ - 2026-09-04 — Split the EDI 850-in / 997-ack surface into its own doc, [edi-850-receive-and-997-ack.md](edi-850-receive-and-997-ack.md) (TRUE-81757 `AK2~855`→`850` fix, always-accept `AK5`/`AK9` stub, `Logs.FileLog` debugging). This doc keeps the ticket/ASN pipeline. (mhammontree)
650
652
  - 2026-08-18 — Repaired stranded ASN `26644` / customer PO `WR260175404-RPL` (**data-only, no code
651
653
  in `worker` or `dbchanges`**): item `54552` (`DOE-62C5GAR1US`, unit `604254`, serial `VKVY4802`)
652
654
  had been `pending` with a NULL `togadeskRepairOrderId` since 2026-07-02. Repointed
@@ -757,6 +759,7 @@ the client's `apps:` scope solely so this monitor loads, and its presence is **n
757
759
  ## Related docs
758
760
 
759
761
  - [NYC DOE client profile](../profile.md)
762
+ - [NYCDOE EDI 850 Receive & 997 Acknowledgement](edi-850-receive-and-997-ack.md) — 850-in/997-out
760
763
  - [Worker (1.0) architecture](../../../1.0/apps/worker/architecture.md) — cron dispatch,
761
764
  role election, schedule files
762
765
  - Local deep-dive (full WR260236464 case study with record IDs):
@@ -11,11 +11,12 @@ project: Worker
11
11
  client: nycdoe
12
12
  type: profile
13
13
  status: active
14
- updated: 2026-08-17
14
+ updated: 2026-09-04
15
15
  owners: [mhammontree, sking]
16
16
  files: []
17
17
  related:
18
18
  - features/servicenow-integration.md
19
+ - features/edi-850-receive-and-997-ack.md
19
20
  ---
20
21
 
21
22
  ## Summary
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.776",
3
+ "version": "1.0.777",
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",