toga-ai 1.0.372 → 1.0.374
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.
|
@@ -33,19 +33,35 @@ reviewer.
|
|
|
33
33
|
|
|
34
34
|
## Design
|
|
35
35
|
|
|
36
|
-
A single
|
|
36
|
+
A single **source-generic, single-anchor** mapping table in the integration schema
|
|
37
|
+
(`Client_True` / `DB_TRUE`, **not** Forecast). A source system + its record id anchor the entity; a
|
|
38
|
+
target system + its id are the mapping. NetSuite is a `sourceSystem` *value* (`'netsuite'`), never a
|
|
39
|
+
privileged column, and there is deliberately **no** cross-system correlation key (`entityUuid`):
|
|
40
|
+
every integration asks the same single-anchor question — "for this source record, what's its
|
|
41
|
+
ClickUp/Salesforce/… id?" — which needs no id-to-id web.
|
|
37
42
|
|
|
38
|
-
- **Columns
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
- **Columns:** `id`, `entityType` (e.g. `opportunity`), `sourceSystem` (e.g. `netsuite`),
|
|
44
|
+
`sourceId` (the source record id), `targetSystem` (e.g. `clickup`), `targetExternalId` (the value;
|
|
45
|
+
`NULL` = claimed/in-flight), `dtCreated`/`dtUpdated`. No synthetic row `uuid` — `uq_claim` is the
|
|
46
|
+
natural key.
|
|
47
|
+
- **Uniqueness:** `UNIQUE (entityType, sourceSystem, sourceId, targetSystem)` = the atomic claim
|
|
48
|
+
(one mapping per source record per target system); `UNIQUE (targetSystem, entityType,
|
|
49
|
+
targetExternalId)` = no two source records share one target id (NULLs exempt, so many in-flight
|
|
50
|
+
rows coexist).
|
|
51
|
+
- **Atomic claim = one `INSERT IGNORE` + `getAffectedRows()`** — no sentinel value, no correlation
|
|
52
|
+
step: the row's presence is the claim, `targetExternalId IS NULL` marks in-flight. Raw `_Query` is
|
|
53
|
+
required because the ORM `save()` cannot express a conditional/affected-rows write — see
|
|
54
|
+
[model-save-vs-query-atomic-update](../features/model-save-vs-query-atomic-update.md). Winner
|
|
55
|
+
writes `targetExternalId` back via the model; failure path deletes the in-flight row
|
|
56
|
+
(`… AND targetExternalId IS NULL`). Because the table stands alone, the claim has **no ordering
|
|
57
|
+
dependency** on the Forecast import (unlike a column claim, which needs the opportunity row
|
|
58
|
+
upserted first).
|
|
59
|
+
- **Scales without schema change:** a new integration adds rows with a new `targetSystem` value; a
|
|
60
|
+
new source adds a new `sourceSystem` value. Keyed on the source record id in the integration
|
|
61
|
+
schema, the mapping is independent of the Forecast DB by construction.
|
|
62
|
+
|
|
63
|
+
The `entityUuid`/cross-system-correlation variant is deliberately avoided — it only pays off if the
|
|
64
|
+
*source* system (NetSuite) itself stopped being the identity anchor, which is not a concern here.
|
|
49
65
|
|
|
50
66
|
## Rebuttal to the clickupTaskId-column mandate
|
|
51
67
|
|
|
@@ -75,3 +91,7 @@ holds, the mandated column approach is what ships.
|
|
|
75
91
|
|
|
76
92
|
- 2026-07-17 — Proposed as a rebuttal to the reviewer-mandated clickupTaskId-column approach
|
|
77
93
|
(TRUE-80044). (dfranks)
|
|
94
|
+
- 2026-07-17 — Refined to a source-generic, single-anchor design: `(sourceSystem, sourceId,
|
|
95
|
+
targetSystem)` key with a single `INSERT IGNORE` claim; dropped the `entityUuid` correlation/two-
|
|
96
|
+
step as over-engineered for the stated concerns (future integrations + Forecast-sync decoupling),
|
|
97
|
+
both of which the single-anchor key already satisfies. (dfranks)
|
package/package.json
CHANGED