toga-ai 1.0.306 → 1.0.307
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/1.0/apps/library/features/startech-pcmaticb2b-sync.md +4 -3
- package/knowledge/clients/pcmaticb2b/INDEX.md +1 -0
- package/knowledge/clients/pcmaticb2b/features/startech-entitlement-provisioning.md +118 -0
- package/knowledge/clients/pcmaticb2b/features/startech-ticket-sync.md +31 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ project: Library
|
|
|
6
6
|
client: pcmaticb2b
|
|
7
7
|
type: client-feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-07-
|
|
9
|
+
updated: 2026-07-09
|
|
10
10
|
owners: [snaredla]
|
|
11
11
|
files:
|
|
12
12
|
- library/app/api/toga2.php
|
|
@@ -75,11 +75,12 @@ Ruled out while debugging "nothing syncs to V1" (0/77 contacts + 0/37 entitlemen
|
|
|
75
75
|
|
|
76
76
|
Imports Startech (Easeedesk V3) config into TOGA 2.0 — users, groups, devices, categories, ticket types.
|
|
77
77
|
|
|
78
|
-
- **Groups**
|
|
79
|
-
- **Categories** — `App_Api_StarTechTicket::getCategories($companyId, $ticketTypeIds)` forwards a `ticket_type` filter alongside `company`.
|
|
78
|
+
- **Groups** come from `dynamic_field_options->data->groups` (keys `ID`/`group_name`) — verified 2026-07-09 returning **16 groups** for company 24412. The earlier claim that this returns empty and groups must come from `/groups_dispatching` was **wrong**: the empty result was caused by **incorrect credentials** in `startechticket.php` (`agilant.api`), not the endpoint. Fixed by using the `pcmaticb2b@startechteam.ro` account. `/groups_dispatching` returned 0 and is not used.
|
|
79
|
+
- **Categories** — `App_Api_StarTechTicket::getCategories($companyId, $ticketTypeIds)` forwards a `ticket_type` filter alongside `company`. **Verified 2026-07-09**: `company=24412&ticket_type=50,54` returns 15 categories (the scoped set); the `ticket_type` param works as intended.
|
|
80
80
|
- Any single upsert failing aborts the run (all `send()` calls throw on API error); the block order is users → groups → devices → categories → ticket types.
|
|
81
81
|
|
|
82
82
|
## Change history
|
|
83
83
|
|
|
84
84
|
- 2026-06-23: Initial doc — ticket type maps (both directions), NULL sync behavior, TOGADESK_PCS type added
|
|
85
85
|
- 2026-07-06: Added syncWithToga V1 leg (cross-ref gating, cron-abort ordering, debugging findings) and supporting-records import notes (groups via groups_dispatching, getCategories ticket-type filter)
|
|
86
|
+
- 2026-07-09: Corrected the groups note — groups come from `dynamic_field_options->data->groups` (16 groups); the empty result was a credentials bug (`agilant.api`), not the endpoint. Confirmed `getCategories` `ticket_type` filter works (`50,54` → 15 categories).
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
|
+
| [PC Matic B2B — Startech Entitlement Provisioning (customer + SKU)](features/startech-entitlement-provisioning.md) | 2.0 | When a PC Matic B2B entitlement is created in TOGA 2.0 (`POST /entitlements`), the client registers the customer on StarTech's OptimumDesk platform and assigns | _underscore/Trait/Startech/Entitlement.php, _underscore/Model/Pcmaticb2b/Entitlement.php, _underscore/Config.php, api2/Config/production.ini, api2/Config/beta.ini, api2/Config/sandbox-client.ini, test/@srija/Startech Testing/PC Matic B2B/test_e2e_pcmaticb2b.sh |
|
|
5
6
|
| [PC Matic B2B — Startech Ticket Sync](features/startech-ticket-sync.md) | 1.0 | Bidirectional ticket sync between TOGaDesk 1.0 (client 177), TOGA 2.0 (client 21), and Startech (Easeedesk). | worker/crons/toga2/startech/sync_togadesk_startech_pcmaticb2b.php, worker/crons/toga2/startech/common_import_supporting_records.php, library/app/api/toga2.php, library/app/api/startechticket.php, togadesk/desk/includes/controllers/quickactions.php, togadesk/desk/template/pages/tickets/manage.php, togadesk/desk/includes/functions.php, worker2/Worker/Startech.php, _underscore/Trait/Startech/Ticket.php, dbchanges2/Client_Pcmaticb2b/2026-06-22-pcmaticb2b-enhancements.sql |
|
|
6
7
|
| [PC Matic B2B Client Profile](profile.md) | 1.0 | PC Matic B2B is a client using TOGaDesk 1.0 for ticket management, with TOGA 2.0 as the data layer and Startech (Easeedesk) as an external ticketing system for | worker/crons/toga2/startech/sync_togadesk_startech_pcmaticb2b.php, togadesk/desk/includes/functions.php |
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: PC Matic B2B — Startech Entitlement Provisioning (customer + SKU)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
project: TOGa
|
|
5
|
+
client: pcmaticb2b
|
|
6
|
+
type: client-feature
|
|
7
|
+
status: active
|
|
8
|
+
updated: 2026-07-09
|
|
9
|
+
owners: [snaredla]
|
|
10
|
+
files:
|
|
11
|
+
- _underscore/Trait/Startech/Entitlement.php
|
|
12
|
+
- _underscore/Model/Pcmaticb2b/Entitlement.php
|
|
13
|
+
- _underscore/Config.php
|
|
14
|
+
- api2/Config/production.ini
|
|
15
|
+
- api2/Config/beta.ini
|
|
16
|
+
- api2/Config/sandbox-client.ini
|
|
17
|
+
- test/@srija/Startech Testing/PC Matic B2B/test_e2e_pcmaticb2b.sh
|
|
18
|
+
related:
|
|
19
|
+
- clients/pcmaticb2b/features/startech-ticket-sync.md
|
|
20
|
+
- clients/pcmaticb2b/profile.md
|
|
21
|
+
- 1.0/apps/library/features/startech-pcmaticb2b-sync.md
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Summary
|
|
25
|
+
|
|
26
|
+
When a PC Matic B2B entitlement is created in TOGA 2.0 (`POST /entitlements`), the client
|
|
27
|
+
registers the customer on StarTech's OptimumDesk platform and assigns the entitlement SKU.
|
|
28
|
+
This is the "provisioning" leg — distinct from the ticket sync. It is **one-way, POST-only**:
|
|
29
|
+
it fires on entitlement create, not on update.
|
|
30
|
+
|
|
31
|
+
## Key files / entry points
|
|
32
|
+
|
|
33
|
+
- `_Model_Pcmaticb2b_Entitlement::postPost` (`_underscore/Model/Pcmaticb2b/Entitlement.php`)
|
|
34
|
+
activates the subscription (`isActive = true`) then calls the trait via
|
|
35
|
+
`use _Trait_Startech_Entitlement { postPost as traitEntitlementPostPost; }`.
|
|
36
|
+
- `_Trait_Startech_Entitlement::postPost` (`_underscore/Trait/Startech/Entitlement.php`)
|
|
37
|
+
does the two OptimumDesk calls.
|
|
38
|
+
|
|
39
|
+
## How it works
|
|
40
|
+
|
|
41
|
+
1. `POST /customer` — body `{ firstName, lastName, emailAddress }` →
|
|
42
|
+
`{"status":"OK","customerId":"<id>"}`. If already present, the response message contains
|
|
43
|
+
`Already Registered` + `customerId=<id>` (regex-extracted).
|
|
44
|
+
2. `POST /sku` — body is a **JSON array** of assignment objects:
|
|
45
|
+
`[{ "customerID": "<id>", "sku": "140102", "purchaseDate": "YYYY-MM-DD", "quantity": "1" }]`
|
|
46
|
+
→ `{"status":"OK","service_id":<id>,"sku":140102}`.
|
|
47
|
+
- `customerID` is **capital-D** (lowercase `customerId` fails customer resolution).
|
|
48
|
+
- `sku` `140102` = `_Model_Pcmaticb2b_Entitlement::STARTECH_ENTITLEMENT_SKU`.
|
|
49
|
+
|
|
50
|
+
## Endpoint & credentials
|
|
51
|
+
|
|
52
|
+
- Unified endpoint `https://scuses.optimumdesk.com`, **HTTP Basic auth**, account
|
|
53
|
+
`pcmaticb2b@startechteam.ro`.
|
|
54
|
+
- Credentials come from config section **`[startechPcmaticb2b]`**, read via
|
|
55
|
+
`_Config::startechPcmaticb2b('opDeskEndpoint' | 'opDeskUsername' | 'opDeskPassword')`.
|
|
56
|
+
`_Config` has **no explicit method** — `__callStatic` maps the method name directly to the
|
|
57
|
+
ini section name, so the section name and the call must match exactly.
|
|
58
|
+
- The section exists in `production.ini`, `beta.ini`, and `sandbox-client.ini`
|
|
59
|
+
(key order: endpoint, username, password). It was previously named `[asiIntegration]`
|
|
60
|
+
(account `asi.integration`) — renamed because that account's catalog lacked SKU 140102.
|
|
61
|
+
|
|
62
|
+
## Data model
|
|
63
|
+
|
|
64
|
+
- `_Model_Pcmaticb2b_Entitlement` adds `c_togaServiceRequestId` (INTEGER). The trait does
|
|
65
|
+
**not** write it — it is set later by the `syncWithToga` V1 write-back leg.
|
|
66
|
+
- `prePost` rejects a cancelled subscription (`dateCancelled !== null` → "Subscription not valid").
|
|
67
|
+
|
|
68
|
+
## Client variations
|
|
69
|
+
|
|
70
|
+
Provisioning is pcmaticb2b-only; the trait is applied solely to `_Model_Pcmaticb2b_Entitlement`.
|
|
71
|
+
|
|
72
|
+
## Verifying it worked
|
|
73
|
+
|
|
74
|
+
There is **no GET-SKU / list-services endpoint** on the provisioning API — probing
|
|
75
|
+
`/sku?customerID=`, `/customer/{id}/services`, `/skus/{id}` all return the OptimumDesk
|
|
76
|
+
"machine-to-machine" 404 page. Only `GET /customer/{id}` works, and it does **not** list SKUs.
|
|
77
|
+
|
|
78
|
+
The authoritative check is the **outbound API log**:
|
|
79
|
+
```sql
|
|
80
|
+
SELECT direction, method, route, responseCode, responsePayload
|
|
81
|
+
FROM Logs_Pcmaticb2b.Api
|
|
82
|
+
WHERE direction = 'OUT' AND route IN ('/customer', '/sku')
|
|
83
|
+
ORDER BY id DESC LIMIT 4;
|
|
84
|
+
```
|
|
85
|
+
Look for `OUT POST /sku` → `service_id` + `sku:140102`, `responseCode 200`. The framework
|
|
86
|
+
logs the trait's outbound calls here with `direction='OUT'`.
|
|
87
|
+
|
|
88
|
+
## End-to-end verification (2026-07-09, post-deploy)
|
|
89
|
+
|
|
90
|
+
Confirmed live against production `api.togahub.com`:
|
|
91
|
+
- `POST /entitlements` → 201; subscription flipped `isActive=1`.
|
|
92
|
+
- Trait fired → OUT log showed `POST /customer` OK (`customerId 1864974`) and
|
|
93
|
+
`POST /sku` OK (`service_id 623917`, `sku 140102`).
|
|
94
|
+
|
|
95
|
+
Runnable harness: `test/@srija/Startech Testing/PC Matic B2B/test_e2e_pcmaticb2b.sh` (bash +
|
|
96
|
+
curl + python). Covers entitlement flow, provisioning direct, ticketing, and import read-side
|
|
97
|
+
with PASS/FAIL assertions. TOGA2 curl auth = `POST /auth/api {client,api,secret}` →
|
|
98
|
+
`data.tokens.access`, then `Authorization: Bearer`.
|
|
99
|
+
|
|
100
|
+
## Gotchas / known issues
|
|
101
|
+
|
|
102
|
+
- **Silent failure.** On any error the trait `error_log`s and returns — no exception. If creds
|
|
103
|
+
or endpoint are wrong, provisioning fails invisibly. Check `error_log` / the OUT log.
|
|
104
|
+
- **`/sku` must be an array**, and `customerID` must be capital-D.
|
|
105
|
+
- **One-way, POST-only.** No `postPut` — an entitlement created/updated through any non-POST
|
|
106
|
+
path (or the `syncWithToga` PUT write-back) does not (re)register the SKU.
|
|
107
|
+
- **Config drift across envs.** All three env inis must carry `[startechPcmaticb2b]`; a missing
|
|
108
|
+
section means `_Config::startechPcmaticb2b()` returns falsy and the trait bails.
|
|
109
|
+
|
|
110
|
+
## Related docs
|
|
111
|
+
|
|
112
|
+
- Ticket sync: `clients/pcmaticb2b/features/startech-ticket-sync.md`
|
|
113
|
+
- Library sync engine + import: `1.0/apps/library/features/startech-pcmaticb2b-sync.md`
|
|
114
|
+
|
|
115
|
+
## Change history
|
|
116
|
+
|
|
117
|
+
- 2026-07-09: Initial doc — entitlement→OptimumDesk customer+SKU provisioning, unified
|
|
118
|
+
endpoint, `[startechPcmaticb2b]` config rename, no-GET-SKU / OUT-log verification, E2E test.
|
|
@@ -5,7 +5,7 @@ project: TOGa
|
|
|
5
5
|
client: pcmaticb2b
|
|
6
6
|
type: client-feature
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-07-
|
|
8
|
+
updated: 2026-07-09
|
|
9
9
|
owners: [snaredla]
|
|
10
10
|
files:
|
|
11
11
|
- worker/crons/toga2/startech/sync_togadesk_startech_pcmaticb2b.php
|
|
@@ -22,6 +22,7 @@ related:
|
|
|
22
22
|
- clients/pcmaticb2b/profile.md
|
|
23
23
|
- 2.0/apps/worker2/features/startech-webhook-handler.md
|
|
24
24
|
- 1.0/apps/library/features/startech-pcmaticb2b-sync.md
|
|
25
|
+
- clients/pcmaticb2b/features/startech-entitlement-provisioning.md
|
|
25
26
|
---
|
|
26
27
|
|
|
27
28
|
## Summary
|
|
@@ -72,6 +73,8 @@ Column: `TINYINT(1) UNSIGNED NULL DEFAULT NULL`
|
|
|
72
73
|
|
|
73
74
|
The `ticketType` on Startech-originated tickets is resolved dynamically via `c_startechTicketTypeId` on `TicketTypes` — not hardcoded.
|
|
74
75
|
|
|
76
|
+
**Verified 2026-07-09 (company 24412):** `getTicketTypes(24412)` returns exactly two active types — **50 = Support Request**, **54 = Phone Call Support**. The import cron uses `STARTECH_TICKET_TYPE_IDS='50,54'` and maps them to TOGaDesk departments `50→336` (Support Request), `54→337` (Phone Call/PCS). The older `SUPPORT REQUEST=6 / API=201` values above are stale for this company — treat 50/54 as authoritative.
|
|
77
|
+
|
|
75
78
|
## Sync Direction 1: Startech to TOGA 2.0 (Webhook)
|
|
76
79
|
|
|
77
80
|
`worker2/Worker/Startech.php` — `_Worker_Startech::Webhook()`
|
|
@@ -162,7 +165,34 @@ const TOGADESK_TICKET_TYPE__TOGADESK_PCS = 'TOGaDesk-PCS';
|
|
|
162
165
|
- **Staff-email collision.** `App_Api_Toga2::syncToga2ContactIntoTogadesk1People` matches `people` by email OR referenceId and **updates in place**. If the email already exists as a staff/admin account (clientid ≠ 177), it links `referenceId` onto that staff row and never creates a client-177 `type='user'` customer. Use a fresh, non-staff email for customer test tickets.
|
|
163
166
|
- **The escalate button applies desk changes unconditionally.** The handler sets dept→337, `escalateToStartech=1`, Ticket Type→"Phone Call Support", and adds history **regardless of 2.0 linkage**. The `c_escalateToStartech=1` PUT (which triggers Startech) fires **only when `referenceId` is already set**; unlinked tickets are left for the sync cron to link — the button does not create the 2.0 ticket on-demand.
|
|
164
167
|
|
|
168
|
+
## Sync Risks (2026-07-09, from full-path trace)
|
|
169
|
+
|
|
170
|
+
These are latent issues in the current loop-guard design — flagged for a follow-up fix,
|
|
171
|
+
not yet resolved:
|
|
172
|
+
|
|
173
|
+
1. **`c_escalateToStartech` is never reset after escalation.** Once an analyst escalates,
|
|
174
|
+
the 2.0 record keeps `=1` permanently. Every subsequent togadesk→2.0 sync PUT (every 2 min
|
|
175
|
+
on any ticket/note change) delivers `$outData` with `escalate=1` + `c_startechTicketId` set,
|
|
176
|
+
so `postPut` passes the `!== 1` guard and re-pushes a `change_ticket_status`/category update
|
|
177
|
+
to StarTech each cycle. Not an infinite loop, but repeated echo updates.
|
|
178
|
+
2. **Webhook flips `1→0`, silencing later analyst-side updates.** Once StarTech's webhook writes
|
|
179
|
+
`c_escalateToStartech=0` on an escalated ticket, later Togadesk edits (synced up without
|
|
180
|
+
setting escalate) leave the stored value at 0, so `postPut`'s `!==1` guard blocks them —
|
|
181
|
+
legitimate analyst changes to an escalated ticket may stop propagating to StarTech.
|
|
182
|
+
3. **Interceptor firing is DB-gated.** `postPost`/`postPut` only run if an active
|
|
183
|
+
`ApiPayloadInterceptor` row exists for `_Model_Pcmaticb2b_Ticket` POST/PUT
|
|
184
|
+
(`api2/Component/Api/V2/V2.php`). Correct trait code is insufficient — verify the rows in
|
|
185
|
+
the live client DB or escalation silently never fires.
|
|
186
|
+
|
|
187
|
+
## Verification
|
|
188
|
+
|
|
189
|
+
- **Entitlement provisioning** (customer + SKU) — see
|
|
190
|
+
`clients/pcmaticb2b/features/startech-entitlement-provisioning.md`. Confirm via
|
|
191
|
+
`Logs_Pcmaticb2b.Api` `direction='OUT'` rows for `/customer` + `/sku`.
|
|
192
|
+
- **Runnable E2E harness:** `test/@srija/Startech Testing/PC Matic B2B/test_e2e_pcmaticb2b.sh`.
|
|
193
|
+
|
|
165
194
|
## Change history
|
|
166
195
|
|
|
167
196
|
- 2026-06-23: Initial doc — full bidirectional sync, c_escalateToStartech semantics, ticket type maps, escalate button, DB migration, constants, gotchas
|
|
168
197
|
- 2026-07-06: Added sync prerequisites/gotchas (entitlement gate, staff-email collision) and clarified the escalate button's actual behavior (desk changes always; 2.0 PUT only when linked)
|
|
198
|
+
- 2026-07-09: Corrected Startech ticket-type IDs (50 Support Request, 54 Phone Call Support for company 24412); added Sync Risks (escalate flag never reset, webhook 1→0 silencing, interceptor DB-gating) and Verification (OUT-log + E2E test); cross-linked entitlement provisioning.
|
package/package.json
CHANGED