toga-ai 1.0.451 → 1.0.453
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/2.0/apps/api2/INDEX.md +1 -0
- package/knowledge/2.0/apps/api2/features/request-logging.md +60 -0
- package/knowledge/INDEX.md +1 -1
- package/knowledge/clients/aig/INDEX.md +2 -1
- package/knowledge/clients/aig/features/contract-reconciliation.md +85 -0
- package/knowledge/clients/aig/features/entitlement-intake.md +40 -3
- package/knowledge/sessions/2026-07-28-true-80179-aig-reconciliation-mhammontree.md +71 -0
- package/package.json +1 -1
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
| [Nested FK object embedding is gated by the CHILD record's own ACL](features/nested-fk-acl-embedding.md) | When the V2 JSON engine serializes a foreign-key field into a **nested object** (in `getFullModelData()`, ~V2.php L6016-6060), it re-checks the **child** record | api2/Component/Api/V2/V2.php, dbchanges2/Client_Compass/2026-07-23b - PurchaseOrdersRecordReadAcl.sql |
|
|
11
11
|
| [Nested-relationship writes & child matching (link vs. create)](features/nested-relationship-writes.md) | When a 2.0 API write payload (`POST`/`PUT`) contains a **nested related object** (e.g. | api2/Component/Api/V2/V2.php |
|
|
12
12
|
| [Record Scripts (computed/aggregate /v2 endpoints — the authoring contract)](features/record-scripts.md) | In api2 you almost never write a controller. | api2/Component/Api/V2/V2.php, _underscore/Model/Team/Sprint.php, _underscore/Query.php |
|
|
13
|
+
| [V2 Request Logging & Where Requests Land (client vs core log DB)](features/request-logging.md) | The V2 engine logs **every inbound request** — success *and* failure, with response code and payload — and routes each log entry to one of two places depending | api2/Component/Api/V2/V2.php, _underscore/Model/Client/Logs/Api.php, _underscore/Model/Core/Logs/Api.php |
|
|
13
14
|
| [POST + JSON-body args for scripted APIs](features/scripted-api-post-body-args.md) | The V2 engine can run a Record Script (scripted API) for a **POST** request, and a scripted API can receive its arguments from the **JSON request body** instead | api2/Component/Api/V2/V2.php |
|
|
14
15
|
| [TOGa IQ Sprint Dashboard API (Record Scripts)](features/sprint-dashboard-api.md) | The internal **TOGa IQ sprint dashboard** is served in production by **six api2 Record Scripts** on `_Model_Team_Sprint` (`_underscore/Model/Team/Sprint.php`), | _underscore/Model/Team/Sprint.php, api2/Component/Api/V2/V2.php, dbchanges2/Core/2026-07-24a - SprintDashboardRecordScripts.sql, dbchanges2/Client_True/2026-07-24b - SprintDashboardScriptAcl.sql |
|
|
15
16
|
| [Surface action-state via the surface=<slug> request option (M2M-safe)](features/surface-meta-option.md) | An opt-in V2 engine request option, `surface=<slug>`, that attaches per-record UI action state (`isVisible`/`isEnabled`) to a GET response **under `meta.surface | api2/Component/Api/V2/V2.php, _underscore/Model/Core/Surface.php |
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: V2 Request Logging & Where Requests Land (client vs core log DB)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
repo: api2
|
|
5
|
+
project: API
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-07-28
|
|
10
|
+
owners: ["mhammontree"]
|
|
11
|
+
files:
|
|
12
|
+
- api2/Component/Api/V2/V2.php
|
|
13
|
+
- _underscore/Model/Client/Logs/Api.php
|
|
14
|
+
- _underscore/Model/Core/Logs/Api.php
|
|
15
|
+
related:
|
|
16
|
+
- ../architecture.md
|
|
17
|
+
- ../../../../clients/aig/features/entitlement-intake.md
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Summary
|
|
21
|
+
|
|
22
|
+
The V2 engine logs **every inbound request** — success *and* failure, with response code and
|
|
23
|
+
payload — and routes each log entry to one of two places depending on **how far the request got
|
|
24
|
+
before it failed**. If you audit a client's API traffic by looking only at `Logs_<Client>`, you
|
|
25
|
+
will miss pre-scope failures and file-based logs. This doc says where requests actually land.
|
|
26
|
+
|
|
27
|
+
## How it works
|
|
28
|
+
|
|
29
|
+
In `api2/Component/Api/V2/V2.php` (~L2168) every request is logged and routed:
|
|
30
|
+
|
|
31
|
+
- **Request resolves to a client** → written to the **CLIENT log DB** via
|
|
32
|
+
`_Model_Client_Logs_Api` → table `Logs_<Client>.Api` (e.g. `Logs_Aig.Api`).
|
|
33
|
+
- **Request fails *before* client scoping** (bad/expired auth, unknown client — e.g. auth
|
|
34
|
+
errors `EN-1` / `EN-4`) → written to the **CORE log DB** via `_Model_Core_Logs_Api` → table
|
|
35
|
+
`Logs_2.Api` (for the 2.0 Core). Pre-scope failures therefore land in **Core** logs, **not**
|
|
36
|
+
the client log.
|
|
37
|
+
- There is also a **config-gated branch** (~L2166): when `_Config::api('log_filepath')` is set,
|
|
38
|
+
the log entry is written to a **file** on the host instead of the DB.
|
|
39
|
+
|
|
40
|
+
## Blind spots when auditing a client's API traffic
|
|
41
|
+
|
|
42
|
+
Looking only at `Logs_<Client>.Api` misses three sources:
|
|
43
|
+
|
|
44
|
+
1. **Pre-scope failures** — auth/unknown-client failures are in the **Core** log DB (`Logs_2.Api`),
|
|
45
|
+
because scoping never resolved to the client.
|
|
46
|
+
2. **File-based logs** — if `log_filepath` is configured, entries are on the host filesystem,
|
|
47
|
+
not in any log DB.
|
|
48
|
+
3. **Non-API loads** — anything that reaches the data via a worker, a `dbchanges2` migration, or
|
|
49
|
+
a direct DB write **never touches api2**, so it produces **no** api2 log entry at all.
|
|
50
|
+
|
|
51
|
+
This is exactly what made the AIG audit (TRUE-80179) non-obvious: the only `POST /v2/entitlements`
|
|
52
|
+
attempts anywhere were 7 dev/QA tests in the **Core** log (`Logs_2`), while the client's real
|
|
53
|
+
`Client_Aig` entitlements came from a bulk load that never went through api2 — see
|
|
54
|
+
[AIG entitlement intake → Intake reality](../../../../clients/aig/features/entitlement-intake.md).
|
|
55
|
+
|
|
56
|
+
## Change history
|
|
57
|
+
|
|
58
|
+
- 2026-07-28 — Documented from the TRUE-80179 AIG log audit: V2 logs every request and routes it
|
|
59
|
+
to `Logs_<Client>` (post-scope) or `Logs_2` Core (pre-scope failure), with a config-gated
|
|
60
|
+
file-log branch. Captured the three audit blind spots. (mhammontree)
|
package/knowledge/INDEX.md
CHANGED
|
@@ -19,7 +19,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
|
|
|
19
19
|
|
|
20
20
|
- **_underscore** (_Underscore) _(framework core)_ — 39 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
|
|
21
21
|
- **worker2** (Worker) — 31 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
|
|
22
|
-
- **api2** (API) —
|
|
22
|
+
- **api2** (API) — 18 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
|
|
23
23
|
- **dbchanges2** (Database Changes) _(framework core)_ — 3 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
|
|
24
24
|
- **toga2-supply** (TOGa Supply) — 3 doc(s) → [2.0/apps/toga2-supply/INDEX.md](2.0/apps/toga2-supply/INDEX.md)
|
|
25
25
|
- **saml** (SAML SSO Gateway) — 3 doc(s) → [2.0/apps/saml/INDEX.md](2.0/apps/saml/INDEX.md)
|
|
@@ -2,5 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
|
-
| [AIG
|
|
5
|
+
| [AIG Contract Reconciliation & Dealer Programs (STS_001 / SA_001)](features/contract-reconciliation.md) | 2.0 | How to reconcile an **AIG contract sales sheet** against the `Client_Aig` tenant, and the durable finding that the **Staples Advantage.com (`SA_001`) program is | _underscore/Model/Client/Entitlement.php, _underscore/Model/Aig/Entitlement.php, _underscore/Model/Client/Contact.php, _underscore/Model/Aig/Contact.php |
|
|
6
|
+
| [AIG Entitlement Intake & SaleItem Code Resolution](features/entitlement-intake.md) | 2.0 | The `_Model_Aig_Entitlement::prePost` interceptor below is the code path defined for AIG protection-plan entitlements arriving as `api2` V2 JSON POSTs. | _underscore/Model/Aig/Entitlement.php, dbchanges2/Client_Aig/2026-06-18a - TRUE-79534 AIG SaleItem codes.sql |
|
|
6
7
|
| [AIG (Staples Protection Plan)](profile.md) | 2.0 | AIG is the warranty underwriter behind the **Staples Protection Plan** retail program. | |
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: AIG Contract Reconciliation & Dealer Programs (STS_001 / SA_001)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
project: API
|
|
5
|
+
client: aig
|
|
6
|
+
type: client-feature
|
|
7
|
+
status: active
|
|
8
|
+
updated: 2026-07-28
|
|
9
|
+
owners: ["mhammontree"]
|
|
10
|
+
files:
|
|
11
|
+
- _underscore/Model/Client/Entitlement.php
|
|
12
|
+
- _underscore/Model/Aig/Entitlement.php
|
|
13
|
+
- _underscore/Model/Client/Contact.php
|
|
14
|
+
- _underscore/Model/Aig/Contact.php
|
|
15
|
+
related:
|
|
16
|
+
- clients/aig/features/entitlement-intake.md
|
|
17
|
+
- ../../../2.0/apps/api2/features/request-logging.md
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Summary
|
|
21
|
+
|
|
22
|
+
How to reconcile an **AIG contract sales sheet** against the `Client_Aig` tenant, and the
|
|
23
|
+
durable finding that the **Staples Advantage.com (`SA_001`) program is entirely absent from
|
|
24
|
+
`Client_Aig`** (TRUE-80179). AIG runs **two dealer programs under the one `Client_Aig`
|
|
25
|
+
tenant**, distinguished by `DealerId` in AIG's own data:
|
|
26
|
+
|
|
27
|
+
| DealerId | Program |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `STS_001` | **Staples Technology Solutions** |
|
|
30
|
+
| `SA_001` | **Staples Advantage.com** |
|
|
31
|
+
|
|
32
|
+
Only `STS_001` contracts are present in `Client_Aig`; `SA_001` was never ingested.
|
|
33
|
+
|
|
34
|
+
## Match keys (sales sheet → `Client_Aig`)
|
|
35
|
+
|
|
36
|
+
Empirically validated against 448 clean matches (consistent base-plan + coverage dates):
|
|
37
|
+
|
|
38
|
+
| AIG sales-sheet column | `Client_Aig` field | Notes |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| **AIG Contract Number** (13-digit, `1000…` family, e.g. `1000046237903`) | `Entitlements.number` | the primary contract identity |
|
|
41
|
+
| **Client Contract Number** (e.g. `7679463206-2`) | `Entitlements.receiptNumber` | also embedded in `vendorEntitlementNumber` as `<dealerPrefix>_<clientContract>` |
|
|
42
|
+
|
|
43
|
+
## Active / lifecycle semantics
|
|
44
|
+
|
|
45
|
+
- **Sales-sheet "Active"** = the **Cancel Date is blank** (there is no explicit active flag on
|
|
46
|
+
the AIG sheet).
|
|
47
|
+
- **Contact active flag** = `Contacts.isActive`.
|
|
48
|
+
- **Entitlement lifecycle** is `entitlementStageId`. In `Client_Aig` this is **currently all
|
|
49
|
+
NULL**, so entitlement stage is **not** a reliable active signal for this tenant — use
|
|
50
|
+
contract cancel-date / `Contacts.isActive` instead.
|
|
51
|
+
|
|
52
|
+
## The SA_001 gap (TRUE-80179)
|
|
53
|
+
|
|
54
|
+
Reconciling a weekly AIG sales sheet (**1,149 contracts** across `STS_001` + `SA_001`) against
|
|
55
|
+
`Client_Aig` (**430 entitlements**):
|
|
56
|
+
|
|
57
|
+
- **448 matched**, **0 DB-only**, **701 missing**.
|
|
58
|
+
- The 701 missing = **156 active `STS_001`** + **545 `SA_001`** (506 of them active).
|
|
59
|
+
- The entire `SA_001` feed is **absent from `Client_Aig`** — confirmed absent from **all** local
|
|
60
|
+
tenant DBs, not just this one.
|
|
61
|
+
|
|
62
|
+
**Real support failure that surfaced it:** a customer (client contract `7679463206-2`, AIG
|
|
63
|
+
contract `1000046237903`, an **active 2YR Printer** plan) called in and could not be found,
|
|
64
|
+
because their `SA_001` contract was never ingested.
|
|
65
|
+
|
|
66
|
+
**Open scope question (unresolved this session):** is `SA_001` (Staples Advantage.com)
|
|
67
|
+
*supposed* to route into `Client_Aig` at all, or is it a separate program with its own
|
|
68
|
+
destination? This needs an answer from AIG / the team before back-filling — do not assume the
|
|
69
|
+
gap is simply a missed load.
|
|
70
|
+
|
|
71
|
+
## How to load a missing program / sheet
|
|
72
|
+
|
|
73
|
+
If `SA_001` (or any new sheet) is confirmed in-scope for `Client_Aig`, it is loaded the same way
|
|
74
|
+
the SaleItem catalog is — a `dbchanges2/Client_Aig/` migration with a session-scoped temp table
|
|
75
|
+
+ anti-join (see [entitlement-intake.md → Uploading new codes](entitlement-intake.md#uploading-new-codes-the-recurring-task)),
|
|
76
|
+
**not** via the API. See that doc's *Intake reality* for why no live API feed exists.
|
|
77
|
+
|
|
78
|
+
## Change history
|
|
79
|
+
|
|
80
|
+
- 2026-07-28 — TRUE-80179: reconciled a 1,149-contract AIG sheet vs `Client_Aig` (448 matched,
|
|
81
|
+
701 missing). Documented the `STS_001`/`SA_001` dealer-program split, the empirically-validated
|
|
82
|
+
match keys (AIG Contract Number → `number`, Client Contract Number → `receiptNumber`), the
|
|
83
|
+
active/`entitlementStageId`-NULL semantics, and the finding that the whole `SA_001` program is
|
|
84
|
+
missing from `Client_Aig` (drove a real "customer not found" support call). Scope of `SA_001`
|
|
85
|
+
left open for AIG/team. (mhammontree)
|
|
@@ -5,12 +5,14 @@ project: API
|
|
|
5
5
|
client: aig
|
|
6
6
|
type: client-feature
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-07-
|
|
8
|
+
updated: 2026-07-28
|
|
9
9
|
owners: ["mhammontree"]
|
|
10
10
|
files:
|
|
11
11
|
- _underscore/Model/Aig/Entitlement.php
|
|
12
12
|
- dbchanges2/Client_Aig/2026-06-18a - TRUE-79534 AIG SaleItem codes.sql
|
|
13
13
|
related:
|
|
14
|
+
- clients/aig/features/contract-reconciliation.md
|
|
15
|
+
- 2.0/apps/api2/features/request-logging.md
|
|
14
16
|
- 2.0/apps/api2/features/nested-relationship-writes.md
|
|
15
17
|
- 2.0/apps/api2/architecture.md
|
|
16
18
|
- 2.0/apps/dbchanges2/architecture.md
|
|
@@ -19,13 +21,42 @@ related:
|
|
|
19
21
|
|
|
20
22
|
## Summary
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
The `_Model_Aig_Entitlement::prePost` interceptor below is the code path defined for AIG
|
|
25
|
+
protection-plan entitlements arriving as `api2` V2 JSON POSTs. **In reality no live API feed
|
|
26
|
+
runs — contracts are loaded into `Client_Aig` as a periodic bulk load, the same way the
|
|
27
|
+
SaleItem catalog is (see [Intake reality](#intake-reality-how-contracts-actually-arrive),
|
|
28
|
+
TRUE-80179).** On a V2 POST, before the entitlement is written, the interceptor resolves the
|
|
29
|
+
**sold warranty SKU**
|
|
24
30
|
(`saleItem.partNumber`) against `Client_Aig.Items` to set the `Entitlement.saleItemId` foreign
|
|
25
31
|
key and to attach fulfillment types/methods. If that part number has no matching `Items` row,
|
|
26
32
|
the FK can't resolve and intake fails with **"Missing AIG item ID."** Keeping
|
|
27
33
|
`Client_Aig.Items` populated with AIG's current sale-item catalog is what keeps intake working.
|
|
28
34
|
|
|
35
|
+
## Intake reality (how contracts actually arrive)
|
|
36
|
+
|
|
37
|
+
The API-intake path described in *How it works* is **real code but is not the live feed.** An
|
|
38
|
+
audit of `Logs_Aig.Api` over 2025-09-02 → 2026-07-28 (TRUE-80179) found:
|
|
39
|
+
|
|
40
|
+
- **Zero entitlement-creation calls** — no `POST /v2/entitlements`, no PUT upserts, no cXML.
|
|
41
|
+
`/v2/entitlements` sees **GETs only** (46,627 reads). `STS_001` / `SA_001` / "Staples
|
|
42
|
+
Advantage" appear in **zero inbound payloads**.
|
|
43
|
+
- The existing **430** `Client_Aig` entitlements were all created in a **single Sept-2025 bulk
|
|
44
|
+
load** (all `dtCreated` 2025-09, purchase dates Mar–Aug 2025) — an out-of-band
|
|
45
|
+
migration/script, **not** an API feed. **No AIG entitlement-creating worker exists in
|
|
46
|
+
worker2.**
|
|
47
|
+
- The only `POST /v2/entitlements` calls **anywhere** are **7 developer/QA test attempts** in the
|
|
48
|
+
2.0 **Core** log (`Logs_2`, not the client log), 2026-04-10 & 04-13 from `127.0.0.1` with dummy
|
|
49
|
+
data ("XYZ Vendor / Jane Doe"), **all failed** (401 missing/expired token; 500 "Subscription
|
|
50
|
+
not found/not valid"). Pre-scope auth failures land in Core logs — see
|
|
51
|
+
[V2 request logging](../../../2.0/apps/api2/features/request-logging.md).
|
|
52
|
+
|
|
53
|
+
**Practical takeaway:** AIG intake is a **periodic bulk load**, not the live API push this doc
|
|
54
|
+
originally implied. A new AIG sales sheet is loaded like the SaleItem catalog — a
|
|
55
|
+
`dbchanges2/Client_Aig/` migration (staged temp table + anti-join), **not** the API. Do **not**
|
|
56
|
+
chase a nonexistent "intake bug" or wait on an API feed that does not run. For reconciling a
|
|
57
|
+
sales sheet against the tenant (and the `SA_001` program gap), see
|
|
58
|
+
[AIG contract reconciliation](contract-reconciliation.md).
|
|
59
|
+
|
|
29
60
|
## Key files / entry points
|
|
30
61
|
|
|
31
62
|
- **`_underscore/Model/Aig/Entitlement.php`** — `prePost(&$api, &$payload)` is the PRE-POST
|
|
@@ -153,6 +184,12 @@ this interceptor or use this dual-purpose Items pattern.
|
|
|
153
184
|
|
|
154
185
|
## Change history
|
|
155
186
|
|
|
187
|
+
- 2026-07-28 — TRUE-80179: corrected the intake premise. A `Logs_Aig.Api` audit (Sept 2025 →
|
|
188
|
+
Jul 2026) found **zero** entitlement-creation API calls — all 430 `Client_Aig` entitlements
|
|
189
|
+
came from a single Sept-2025 bulk load, and the only `POST /v2/entitlements` calls anywhere are
|
|
190
|
+
7 failed dev/QA tests in the Core `Logs_2`. Intake is a periodic bulk load, not a live API
|
|
191
|
+
feed. Added *Intake reality* + the API-vs-bulk gotcha, and linked the new
|
|
192
|
+
contract-reconciliation and V2 request-logging docs. (mhammontree)
|
|
156
193
|
- 2026-07-09 — TRUE-79534 SaleItem load reworked: the 2,200-code `INSERT ... SELECT FROM
|
|
157
194
|
(<2,199 `UNION ALL` links>)` derived table failed at parse time with ERROR 1436 (Thread
|
|
158
195
|
stack overrun). Rebuilt as a `TEMPORARY` staging table filled by a flat multi-row `VALUES`
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: session
|
|
3
|
+
slug: true-80179-aig-reconciliation
|
|
4
|
+
title: AIG Staples sales-sheet ↔ Client_Aig reconciliation
|
|
5
|
+
author: mhammontree
|
|
6
|
+
repos: [_underscore, api2]
|
|
7
|
+
framework: "2.0"
|
|
8
|
+
client: aig
|
|
9
|
+
status: active
|
|
10
|
+
created: 2026-07-28
|
|
11
|
+
updated: 2026-07-28
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# Session: true-80179-aig-reconciliation
|
|
15
|
+
**Date:** 2026-07-28
|
|
16
|
+
**Project/Repo:** api2 / _underscore (2.0), client AIG (Staples Protection Plan)
|
|
17
|
+
**Task:** TRUE-80179 — verify an AIG weekly sales .xlsx against `Client_Aig` entitlements, quantify gaps, and determine how (and whether) the missing contracts get ingested.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What WORKED
|
|
22
|
+
<!-- Include specific file paths and evidence -->
|
|
23
|
+
- **Reconciliation method (validated):** key spreadsheet **AIG Contract # → `Entitlements.number`** (proven by 448 clean matches with consistent base-plan + coverage dates), **Client Contract # → `Entitlements.receiptNumber`** (also embedded in `vendorEntitlementNumber` as `<dealerPrefix>_<clientContract>`). "Active" on the sheet = **Cancel Date blank**.
|
|
24
|
+
- **Dependency-free xlsx parsing** via PowerShell `System.IO.Compression` (scratchpad `inspect-xlsx.ps1`, `recon.ps1`, `recon2.ps1`) — parsed all 1,149 detail rows, converted Excel serial dates (epoch 1899-12-30). No Excel/module needed.
|
|
25
|
+
- **Read-only local MySQL** via `C:/xampp_8x/mysql/bin/mysql.exe -u root` (root/no password).
|
|
26
|
+
- **Reconciliation result:** sheet has TWO dealer programs — STS_001 (Staples Technology Solutions, 604 rows) + SA_001 (Staples Advantage.com, 545 rows). vs `Client_Aig` 430 entitlements: **448 matched, 0 DB-only, 701 missing** (156 active STS_001 + 545 SA_001 [506 active]). Matched data consistent: 0 base-plan / 0 coverage-end / 0 purchase-date mismatches; only 5 benign coverage-start diffs (DB start = purchase date, sheet = +12 days).
|
|
27
|
+
- **Intake root-cause via `Logs_Aig.Api`** (user imported it locally; window 2025-09-02 → 2026-07-28): **ZERO entitlement-creation calls** (no POST/PUT `/v2/entitlements`, no cXML). `/v2/entitlements` = 46,627 GET reads only. The 430 existing entitlements ALL have `dtCreated` in 2025-09 → a single out-of-band **bulk load**, not an API feed. No AIG entitlement-creating worker in `worker2`.
|
|
28
|
+
- **Logging mechanism verified in code** (`api2/Component/Api/V2/V2.php` ~L2168): every request logged (success + failure); routes to `Logs_<Client>` once client resolves, else 2.0 Core log `Logs_2`. Checked `Logs_2`: the only entitlement POSTs anywhere are **7 localhost dev/QA tests** (2026-04-10 & 04-13, 127.0.0.1, "XYZ Vendor/Jane Doe" dummy data), all failed (401 EN-1/EN-4, 500 "Subscription not found/not valid").
|
|
29
|
+
- **Caller confirmed:** contract `7679463206-2` (AIG# `1000046237903`, SA_001, active 2YR Printer plan) is on the sheet but absent from ALL local tenant DBs — why support couldn't find her.
|
|
30
|
+
- **Deliverables:** `c:/WWW/TRUE-80179_AIG_reconciliation.md` + 2 CSVs. `/capture` published 3 KB docs (see file state).
|
|
31
|
+
|
|
32
|
+
## What did NOT work — DO NOT RETRY THESE
|
|
33
|
+
<!-- Exact failure reasons — do not vague-ify -->
|
|
34
|
+
- **DO NOT sample only the top of the sheet.** My first probe used 5 AIG numbers from the sheet's first rows (all `1000046…`, all SA_001) and every one was above the DB's max `number` → I wrongly concluded "the sets don't overlap at all / the program is absent entirely." The full 1,149-row run corrected this to **448 matches**. The sheet is multi-program; the head is all SA_001. Always run the full diff before concluding.
|
|
35
|
+
- **DO NOT run multiple payload `LIKE` scans in one batch against `Logs_Aig`.** 4 `requestPayload/responsePayload LIKE '%…%'` queries over 564K MEDIUMTEXT rows → **2-minute timeout (exit 143)**. Scope by indexed cols (`route`/`method`/`dtStamp`) first, or narrow the date range; run heavy scans one at a time.
|
|
36
|
+
- The first local import did **not** include `Logs_Aig` (only `Client_*` DBs) — had to have the user import it from prod before the API-log investigation was possible.
|
|
37
|
+
- The `Logs` DB (not `Logs_2`) is the **legacy 1.0** API log — uppercase `API` table, no `route`/`hostname` columns → `ERROR 1054 Unknown column`. Not usable for 2.0 api2 analysis; use `Logs_2` for 2.0 Core.
|
|
38
|
+
|
|
39
|
+
## Not tried yet (candidates for next session)
|
|
40
|
+
- **Resolve the SA_001 scope question with AIG/team:** does Staples Advantage.com (`SA_001`) route into `Client_Aig` at all, or is it a separate program? (Gates any back-fill of the 545.)
|
|
41
|
+
- **Find how the Sept-2025 bulk load of the 430 was performed** — no `worker2` job exists; look for a one-off load script / migration, or check worker/CloudWatch logs around 2025-09-02. This is the mechanism to reuse for the 701.
|
|
42
|
+
- **Check file-based API logging** (`_Config::api('log_filepath')`) on the prod host — a blind spot the DBs can't see.
|
|
43
|
+
- **Investigate the 156 missing active STS_001** specifically: are their sale-item codes in `Client_Aig.Items`? Any intake failures? (These are the "same program that's already in the DB" gap.)
|
|
44
|
+
- **Draft the `dbchanges2/Client_Aig/` load migration** for the 701 (staged temp table + anti-join, generated UUIDs, keyed on `number`) — only after the scope answer and after verifying SA sale-item codes exist in `Client_Aig.Items`.
|
|
45
|
+
- **Pull an SA_001-only CSV** for support to reference in the interim.
|
|
46
|
+
|
|
47
|
+
## Current file state
|
|
48
|
+
| File | Status | Notes |
|
|
49
|
+
|------|--------|-------|
|
|
50
|
+
| c:/WWW/TRUE-80179_AIG_reconciliation.md | Created | Full deliverable: reconciliation + caller + intake investigation + logging mechanism + 2 blind spots |
|
|
51
|
+
| c:/WWW/TRUE-80179_missing_from_db.csv | Created | The 701 contracts on the sheet but not in Client_Aig (actionable list) |
|
|
52
|
+
| c:/WWW/TRUE-80179_sheet_contracts.csv | Created | All 1,149 parsed contract rows, dates normalized |
|
|
53
|
+
| scratchpad/inspect-xlsx.ps1, recon.ps1, recon2.ps1 | Created (temp) | Read-only analysis scripts; session-temp scratchpad |
|
|
54
|
+
| knowledge/clients/aig/features/contract-reconciliation.md | Created (pushed) | STS_001/SA_001 split, match keys, 701 gap, unresolved SA_001 scope question |
|
|
55
|
+
| knowledge/2.0/apps/api2/features/request-logging.md | Created (pushed) | V2 logs every request → Logs_<Client> post-scope vs Logs_2 Core pre-scope; audit blind spots |
|
|
56
|
+
| knowledge/clients/aig/features/entitlement-intake.md | Updated (pushed) | Corrected false "arrives via API POST" premise → Intake reality section |
|
|
57
|
+
|
|
58
|
+
## Decisions made
|
|
59
|
+
- **Match key = AIG Contract # ↔ `Entitlements.number`** (not `vendorEntitlementNumber`). Rationale: 448 empirical matches with aligned base-plan/coverage dates. Rejected: keying on `vendorEntitlementNumber`/`receiptNumber` (those hold `<dealer>_<clientContract>`, a different value).
|
|
60
|
+
- **Reconcile in-memory (read-only), no scratch DB tables.** Rationale: pure verification, avoid mutating the local DB. Rejected: staging table inside `Client_Aig`.
|
|
61
|
+
- **Deliverable kept as a local file, not a published Artifact.** Rationale: contains AIG client business data.
|
|
62
|
+
- **api2 request-logging documented as a `feature` doc, not an architecture edit** (session-capture's call). Rationale: discrete mechanism with code anchors, matches existing api2 feature-doc pattern. Could be moved onto `api2/architecture.md` if a senior prefers.
|
|
63
|
+
|
|
64
|
+
## Blockers
|
|
65
|
+
- **SA_001 scope question is unresolved** — needs an answer from AIG/the team (does Staples Advantage.com belong in `Client_Aig`?). This gates any load/back-fill of the 545 SA_001 (and shapes whether the 701 is one problem or two).
|
|
66
|
+
|
|
67
|
+
## Exact next step
|
|
68
|
+
> Get the AIG/team answer on whether `SA_001` (Staples Advantage.com) is supposed to route into `Client_Aig`. In parallel, determine how the Sept-2025 bulk load of the existing 430 was done (search for a load script/migration; check worker/CloudWatch logs ~2025-09-02) — that's the mechanism to reuse for loading the 701. Reference `c:/WWW/TRUE-80179_AIG_reconciliation.md` and `TRUE-80179_missing_from_db.csv`.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
_Saved by /session-save on 2026-07-28_
|
package/package.json
CHANGED