@datarails-ai/dr-cli 1.6.105 → 1.6.107
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/dist/cli.js +1001 -361
- package/dist/scopes-map.json +21 -1
- package/dist/skills/dr-cli/SKILL.md +8 -3
- package/dist/skills/dr-cli/reference/datamappers.md +23 -12
- package/dist/skills/dr-cli/reference/integrations.md +33 -1
- package/dist/skills/dr-cli/reference/metrics.md +73 -3
- package/dist/skills/dr-cli/reference/templates.md +3 -2
- package/dist/skills/fx-conversion-matrix/SKILL.md +10 -16
- package/dist/skills/validate-workato-migration/SKILL.md +5 -2
- package/package.json +2 -2
package/dist/scopes-map.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"cliVersion": "1.6.
|
|
3
|
+
"cliVersion": "1.6.107",
|
|
4
4
|
"_contract": "Resolve a command path through `aliases` (canonical prefix + alias segment -> canonical path) before any lookup. A path listed in `pendingCommands`, or whose first segment is a key of `pending`, is UNDECIDED, not unrestricted: fail closed or skip it, and never read a path's absence from `commands` as 'no requirement'. An entry carrying `denied` is UNAVAILABLE to any AGENT-SCOPED credential — one whose `scopes` claim carries at least one `resource:action` entry; a claim that is absent, empty, capability-only or wholly unparseable is UNRESTRICTED, and this mark does not apply to it — whatever else that entry says: it is not a ceiling and it is not always-available, its `denied.reason` says why and `denied.until` names the ticket that lifts it, and the absence of `requires` on it must NEVER be read as 'no requirement'. Only an entry in `commands` with an empty `requires` means always-available.",
|
|
5
5
|
"commands": {
|
|
6
6
|
"login": {
|
|
@@ -739,6 +739,26 @@
|
|
|
739
739
|
}
|
|
740
740
|
]
|
|
741
741
|
},
|
|
742
|
+
"functions data": {
|
|
743
|
+
"requires": [
|
|
744
|
+
{
|
|
745
|
+
"resource": "tables",
|
|
746
|
+
"action": "read"
|
|
747
|
+
}
|
|
748
|
+
]
|
|
749
|
+
},
|
|
750
|
+
"functions drilldown": {
|
|
751
|
+
"requires": [
|
|
752
|
+
{
|
|
753
|
+
"resource": "tables",
|
|
754
|
+
"action": "read"
|
|
755
|
+
},
|
|
756
|
+
{
|
|
757
|
+
"resource": "dashboards",
|
|
758
|
+
"action": "read"
|
|
759
|
+
}
|
|
760
|
+
]
|
|
761
|
+
},
|
|
742
762
|
"functions delete": {
|
|
743
763
|
"requires": [
|
|
744
764
|
{
|
|
@@ -239,7 +239,11 @@ area's gotchas.
|
|
|
239
239
|
- `metrics suggestions list|refresh` + `metrics dimensions suggestions list|refresh` — AI suggestion agents (list shows suggestions + `last_run` status; `refresh` triggers a run, `--wait [--timeout <s>]` polls to completion). Gated per-org by Unleash flags; a successful `metrics migrate` auto-triggers both agents, so a 409 from `refresh` right after usually means it's already running — check `list`.
|
|
240
240
|
- `metrics suggestions profile` — read-only: profiles every table and returns, per table, the `reporting_axis` (WHICH date column a BASE metric should bucket by, with `chosen_by` naming the rule), `row_grain.reads_as` (`movements` -> time_aggregation SUM, `balances` -> EOP), candidate `measures`, `categoricals`, and the metrics already defined there. Use this BEFORE proposing any metric: `date_field` cannot be read off the payload (no field marks the reporting column) and guessing it produces a silently wrong number that passes validation. `reporting_axis: null` and `reads_as: "unknown"` are real answers - do not substitute a guess. All measure statistics are SAMPLED from storage-ordered windows and named `sampled_*`; there is deliberately no sum/avg. Needs no Unleash flag. ~30s and ~230 requests on a 43-table org.
|
|
241
241
|
- `metrics dimensions suggestions profile` — read-only: profiles every table/field and returns scored candidate dimension groups (value-overlap grouping, existing-dimension dedupe, machine-readable rejection reasons) in ONE call. Use this instead of looping `templates distinct` per field when reasoning about what dimensions an org should have. Needs no Unleash flag. `--json` for the payload, `--out <file>` when only `summary`/`groups` matter, `--suppression <file>` when you already hold the existing-dimension and dismissed lists. Also emits `near_misses` — pairs just under the merge threshold, for you to judge rather than silently dropped.
|
|
242
|
-
- `functions list|get|create|update|delete|set-filters` — a function's **definition
|
|
242
|
+
- `functions list|get|create|update|delete|set-filters` — a function's **definition**.
|
|
243
|
+
- `functions data <id> --filter "F=V1,V2" --date "Reporting Date=2025-01-31" [--agg YTD]` — the
|
|
244
|
+
function's **live value**, computed by the same endpoint the Excel add-in uses for
|
|
245
|
+
`DR.GET`/`DR.YTD`; `functions drilldown <id> … [--out rows.csv]` — the rows behind it.
|
|
246
|
+
`create`/`update --date-field <Date field>` is required for YTD/QTD/MTD to work.
|
|
243
247
|
- _`set-filters <id> --file <json> [--confirm]` is the **only** way to author a
|
|
244
248
|
function's row-level filters (create/update don't touch them). FULL REPLACE —
|
|
245
249
|
an empty array clears all; dimension `values` are a plain list, date filters
|
|
@@ -552,8 +556,9 @@ returns the source rows behind the number.
|
|
|
552
556
|
counts — and a token; re-run with `--confirm-token` to fire it) → poll `scans
|
|
553
557
|
status` again. This is a **full historical** rescan (every calc field × every
|
|
554
558
|
version). To only pick up a datamapper change on the live template, prefer
|
|
555
|
-
`datamappers update <id> --rescan latest` (latest version of
|
|
556
|
-
documents only) — far cheaper and lower-blast.
|
|
559
|
+
`datamappers update <id> --payload-file <p> --rescan latest` (latest version of
|
|
560
|
+
the mapper's bound documents only) — far cheaper and lower-blast. It publishes a
|
|
561
|
+
new mapper version, so the mapper gets a **new id**, which dr prints.
|
|
557
562
|
|
|
558
563
|
**Build a `create` body from plain-English intent** (calc models, datamappers,
|
|
559
564
|
metrics): you resolve names → integer IDs yourself against the tenant
|
|
@@ -67,12 +67,23 @@ value-inference behavior. `NAME` is the target **table field** name (the
|
|
|
67
67
|
## Update / preview / bind / delete
|
|
68
68
|
|
|
69
69
|
- `datamappers update`, `datamappers delete` (two-step confirm).
|
|
70
|
-
- `datamappers update --
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
- `datamappers update <id> --payload-file <p>` publishes the payload as a **new
|
|
71
|
+
version** of the mapper, the same request the UI's "Publish and scan" sends
|
|
72
|
+
(`POST /api/templates/<tid>/mappers` with `datamapper_id` = the old id). The
|
|
73
|
+
server adds any new columns to the table, binds the new version to the old
|
|
74
|
+
one's documents, unbinds the old one, and rescans (`--rescan latest` by
|
|
75
|
+
default). The payload needs `config` and `sheet_name`; dr fills in `name`,
|
|
76
|
+
`ordinal`, the bound documents and the source version from the old mapper,
|
|
77
|
+
and any of those keys in the payload wins.
|
|
78
|
+
- **The mapper gets a new id.** dr prints it (`note: mapper <old> was published
|
|
79
|
+
as new version <new>`). Use the new id for the next update, and keep an
|
|
80
|
+
old→new log if anything outside the table refers to the mapper id.
|
|
81
|
+
`update` refuses an old id that is bound to no documents, and points at
|
|
82
|
+
`datamappers list --table <tid>` for the current one.
|
|
83
|
+
- A mapper made by an org import or template push has no source version on
|
|
84
|
+
record, and `update` stops with an error. Add `"document_version_id"` to the
|
|
85
|
+
payload: an ACTIVE version of one of its documents, with a `sheet_name` that
|
|
86
|
+
exists in it.
|
|
76
87
|
- `datamappers preview --payload-file <p>` — renders mapper output for sample
|
|
77
88
|
input ("what would this extract?") before saving.
|
|
78
89
|
- `datamappers bind <mapper_id> --doc <id> [--rescan latest|all]` — change which
|
|
@@ -82,15 +93,15 @@ value-inference behavior. `NAME` is the target **table field** name (the
|
|
|
82
93
|
|
|
83
94
|
`datamappers update <id> --payload-file <p> [--field NAME:TYPE ...]`. Repeatable;
|
|
84
95
|
`TYPE` is `Text|Float|Date|Integer`. Each `--field` becomes a `fields_to_change`
|
|
85
|
-
entry
|
|
96
|
+
entry in the body, telling the server to set that column's type **explicitly**
|
|
86
97
|
instead of inferring it — this is exactly what the web UI's "Publish and scan"
|
|
87
|
-
does (same `
|
|
88
|
-
is `fields_to_change`).
|
|
98
|
+
does (same `POST api/templates/<tid>/mappers` endpoint; the only payload
|
|
99
|
+
difference is `fields_to_change`).
|
|
89
100
|
|
|
90
101
|
**When you need it:** adding a calc column that multiplies/divides by a
|
|
91
102
|
**LUT-injected column**. LUT columns land as **Text**; the server infers Text for
|
|
92
103
|
them, so a formula like `[Posting Amount] * [Sign]` fails to materialise and the
|
|
93
|
-
|
|
104
|
+
publish returns a bare `HTTP 500` (`ETLError: … incorrect formula syntax`) — even
|
|
94
105
|
though the formula is valid. Fixing the LUT column's type up-front lets it
|
|
95
106
|
materialise:
|
|
96
107
|
|
|
@@ -120,12 +131,12 @@ valid formula the ETL compiler can't resolve (unknown/wrong-cased function,
|
|
|
120
131
|
unresolvable `[field]` reference, a string-constant that happens to be quoted)
|
|
121
132
|
still returns a bare 500.
|
|
122
133
|
|
|
123
|
-
After `create`, the CLI polls the template's `fields[]` for up to 30s for every
|
|
134
|
+
After `create` and `update`, the CLI polls the template's `fields[]` for up to 30s for every
|
|
124
135
|
declared calc field to materialise, and warns (pointing at `mapper-recipes get`
|
|
125
136
|
for working formulas) if any are missing — this catches the EOMONTH failure
|
|
126
137
|
mode. Skipped when `--no-rescan` is set.
|
|
127
138
|
|
|
128
|
-
On a
|
|
139
|
+
On a create or update 500, the CLI writes a `dr-cli-error-<timestamp>.md` to the cwd capturing
|
|
129
140
|
URL + status + request/response bodies; the path is named in the stderr error.
|
|
130
141
|
|
|
131
142
|
Formula syntax:
|
|
@@ -12,7 +12,7 @@ Write:
|
|
|
12
12
|
|
|
13
13
|
- `integrations add` (payload-file), `integrations sync`,
|
|
14
14
|
`integrations test-connection`, `integrations update`,
|
|
15
|
-
`integrations delete` (two-step confirm).
|
|
15
|
+
`integrations delete` (two-step confirm, Tier A, see below).
|
|
16
16
|
- `integrations revoke <id>` (two-step confirm; Tier A on prod) — Disconnect a
|
|
17
17
|
`DatarailsConnector` OAuth data source: `POST /api/v2/data_integrations/<id>/revoke`.
|
|
18
18
|
The grant is cleared locally first (`oauth_tokens`/`oauth_pending` dropped,
|
|
@@ -23,6 +23,38 @@ Write:
|
|
|
23
23
|
`revoked` may leave the grant live at the vendor. Legacy vendors are refused.
|
|
24
24
|
- `integrations share users` / `integrations share groups`.
|
|
25
25
|
|
|
26
|
+
### Deleting a data source (`integrations delete <id>`)
|
|
27
|
+
|
|
28
|
+
`DELETE /api/v3/data_integrations/<id>/`. It cannot be undone and **cascades to queries and
|
|
29
|
+
documents**. Typical use: removing a validation or staging datasource that holds live customer
|
|
30
|
+
credentials once its bindings are gone.
|
|
31
|
+
|
|
32
|
+
1. **Plan:** run it without a token, as the identity that owns the data source (on a staging org,
|
|
33
|
+
the impersonated staging user, never the operator):
|
|
34
|
+
`dr integrations delete <id> --server <S> --account <user>`. It prints `name`, `type`, `status`,
|
|
35
|
+
`org` (name + id) and `shared` (user/group counts), plus the exact confirm command with a token
|
|
36
|
+
that expires in **10 minutes** and is bound to this id and verb. Check the org id and the name
|
|
37
|
+
before going on: the plan does **not** list the queries and documents the cascade will remove.
|
|
38
|
+
Make sure nothing you want to keep still points at this data source.
|
|
39
|
+
2. **Relay and get a "yes"**: name, org and why it is being deleted.
|
|
40
|
+
3. **Confirm:** re-run the printed command with `--confirm-token <tok>`. On a prod tenant (`US`,
|
|
41
|
+
`US2`, `UK`, `CA`, `EU`, `STUDIO`, `DEMO`) this is **Tier A**: the binary shows a fresh word in a
|
|
42
|
+
desktop dialog (or a TTY prompt) and a human must type it. With no interactive channel it exits
|
|
43
|
+
non-zero; hand the printed line to the user rather than retrying. Success prints
|
|
44
|
+
`Deleted integration <id> — "<name>".`
|
|
45
|
+
4. **Verify:** `dr integrations get <id> --server <S> --account <user>` returns `HTTP 404`.
|
|
46
|
+
|
|
47
|
+
Notes:
|
|
48
|
+
|
|
49
|
+
- `dr connectors` `Connector` rows that reference the data source (`--secret-ref`) are **not**
|
|
50
|
+
deleted, and dr-cli has no connector delete. Delete the `dr connectors` bindings first
|
|
51
|
+
(`dr connectors query delete`), then record the orphaned connector id.
|
|
52
|
+
- A `403` (`delete refused: …`) means the identity can't delete it: switch to the owner's account,
|
|
53
|
+
not to the operator.
|
|
54
|
+
- Deleting a validation data source on the Workato-migration staging orgs left the staging fileboxes
|
|
55
|
+
in place (their data-query rows pointed at the data source). Check one with `dr filebox get` after
|
|
56
|
+
the delete if you need them as evidence.
|
|
57
|
+
|
|
26
58
|
## IT-admin file-sync (`integrations it`)
|
|
27
59
|
|
|
28
60
|
File-sync connectors only — OneDrive / SharePoint / Egnyte. Output redacts
|
|
@@ -478,11 +478,10 @@ dr metrics dimensions suggestions profile -s DEV --account support@acme.com --js
|
|
|
478
478
|
51-table org. Read `summary.empty_unverified` as "at least this many
|
|
479
479
|
fields' emptiness is unproven", not as an exact census.
|
|
480
480
|
|
|
481
|
-
## Functions (DR.GET definitions)
|
|
481
|
+
## Functions (DR.GET definitions and values)
|
|
482
482
|
|
|
483
483
|
- `functions list`, `functions get <id>` — `get` returns the **definition**,
|
|
484
|
-
|
|
485
|
-
`DR.GET(...)` through the add-in and are not exposed by this CLI.
|
|
484
|
+
not the value (for the value see `functions data` below).
|
|
486
485
|
- The core row is `id / name / agg / template / value_field`; below it `get`
|
|
487
486
|
prints a **FILTERS** section (one row per persisted filter: `field`, `name`,
|
|
488
487
|
`type`, `excluded`, `values`) and the **default agg date field** when set.
|
|
@@ -492,6 +491,18 @@ dr metrics dimensions suggestions profile -s DEV --account support@acme.com --js
|
|
|
492
491
|
blob (owned by the add-in), shown verbatim as compact JSON — read it there
|
|
493
492
|
rather than asking the customer to re-check the UI.
|
|
494
493
|
- `functions create`, `functions update`, `functions delete` (two-step confirm).
|
|
494
|
+
- `--date-field <id|name>` (create and update) sets the function's **default
|
|
495
|
+
aggregation date field** (must be a Date field of the template) and sends the
|
|
496
|
+
platform's default per-period roll-up config (every period by month, `sum`,
|
|
497
|
+
end-of-period — what UI-created functions carry; a function needing MTD by
|
|
498
|
+
day must be adjusted in the UI). **Without it `DR.YTD`/`QTD`/`MTD`/…
|
|
499
|
+
do not work for the function anywhere** — `functions data --agg YTD` answers
|
|
500
|
+
HTTP 400 `{"DateAgg":[…]}` and the xlsx auto-calculate engine fails outright.
|
|
501
|
+
`create` without it prints a one-line warning on stderr. A later
|
|
502
|
+
`update`/`set-filters` full PUT keeps the date field (verified) — so
|
|
503
|
+
`update --template <id>` on a function that has one is **refused unless
|
|
504
|
+
`--date-field` is passed too** (the old field belongs to the old table, and
|
|
505
|
+
the server checks only its type).
|
|
495
506
|
- `functions set-filters <id> --file <json> [--confirm]` — **the only way to
|
|
496
507
|
author a function's filters** (`create`/`update` don't touch them). **FULL
|
|
497
508
|
REPLACE**: the server deletes every existing filter and recreates from the
|
|
@@ -505,6 +516,65 @@ dr metrics dimensions suggestions profile -s DEV --account support@acme.com --js
|
|
|
505
516
|
`--confirm`; internally a read-modify-write PUT that preserves the core fields
|
|
506
517
|
and calculated-value links.
|
|
507
518
|
|
|
519
|
+
### Live values: `functions data`
|
|
520
|
+
|
|
521
|
+
`functions data <id> [--filter "NAME=V1,V2"]… [--date "NAME=DATE[,DATE]"]… [--agg DEFAULT|YTD|YTG|QTD|QTG|MTD|MTG] [--json]`
|
|
522
|
+
evaluates the function through `PUT /api/functions/<id>/data/v2` — the endpoint
|
|
523
|
+
the Excel add-in calls for `DR.GET` (`--agg DEFAULT`) and `DR.YTD`/… — so the
|
|
524
|
+
number is the one Excel shows, with the function's own filters always applied
|
|
525
|
+
(a `--filter` can only narrow them, never override).
|
|
526
|
+
|
|
527
|
+
- Fields are named (or given by id) and resolved on the function's template;
|
|
528
|
+
the add-in's canonical field name goes on the wire. An unknown field fails
|
|
529
|
+
client-side with the list of valid fields.
|
|
530
|
+
- **Dates.** The endpoint wants **Excel serial numbers** (2025-01-31 = 45688);
|
|
531
|
+
epoch seconds and ISO strings are not rejected server-side, they silently
|
|
532
|
+
return nothing. The CLI converts: on a Date field (via `--date` or `--filter`)
|
|
533
|
+
pass `YYYY-MM-DD`, `M/D/YYYY`, an ISO datetime, a serial, or epoch seconds.
|
|
534
|
+
A bare month (`2025-06`) is **refused** — tables store a specific day
|
|
535
|
+
(usually month-END), so a month's 1st would match nothing (DEFAULT) or stop a
|
|
536
|
+
month short (YTD). Pass the stored day, e.g. `2025-06-30`.
|
|
537
|
+
- Several values on one field return **one row per value combination**; the
|
|
538
|
+
table shows each field's key (serials rendered back as dates) and `VALUE`
|
|
539
|
+
(rounded to 4 decimals for display; `--json` is the server body verbatim).
|
|
540
|
+
- No row at all prints `(no data: nothing matches these filters)` — a real
|
|
541
|
+
answer (unknown value, or the function's own filter excludes it), not an error.
|
|
542
|
+
- Errors: a per-query `error.msg` (e.g. "Field X is not related to function")
|
|
543
|
+
and any non-2xx exit non-zero; an HTTP 400 such as
|
|
544
|
+
`{"DateAgg":["Function N has no default aggregation date field"]}` is shown
|
|
545
|
+
verbatim with the `--date-field` fix. Under `--json` the body is printed first.
|
|
546
|
+
|
|
547
|
+
### Rows behind a value: `functions drilldown`
|
|
548
|
+
|
|
549
|
+
`functions drilldown <id> [--filter …]… [--exclude …]… [--date …]… [--agg …] [--columns a,b] [--limit 20] [--out rows.csv] [--csv] [--json]`
|
|
550
|
+
calls `PUT /api/functions/<id>/drilldown/v4` with the same filters (as the
|
|
551
|
+
add-in's filter objects, field id + type resolved from the template).
|
|
552
|
+
|
|
553
|
+
- Prints `N rows × M columns`, the function's own aggregate over those rows
|
|
554
|
+
(`SUM(Amount) over these rows: …` — equals `functions data` with the same
|
|
555
|
+
filters), then the first `--limit` rows (0 = all) of the filtered fields and
|
|
556
|
+
the value field, or of `--columns`. Date columns arrive as epoch seconds and
|
|
557
|
+
are shown as dates.
|
|
558
|
+
- Above the server's inline cap (≈ tens of thousands of rows) the answer is
|
|
559
|
+
`too_large_data`. Without `--out` that is an error naming the size; narrow
|
|
560
|
+
with more `--filter`s or add `--out`. With `--out <file.csv>` the CLI takes
|
|
561
|
+
the add-in's **CSV export** path automatically (`export_to_csv` → cache-key
|
|
562
|
+
poll → report download, ~15 s for 25k rows × 215 columns, 20 MB); `--csv`
|
|
563
|
+
forces it. An inline answer with `--out` is written as CSV too (schema
|
|
564
|
+
columns, dates as `YYYY-MM-DD`). `--out` raises the command budget to 300 s
|
|
565
|
+
(`--timeout <s>` overrides).
|
|
566
|
+
- `--json` prints the inline body verbatim (rows plus a trailing
|
|
567
|
+
`{fields, empty_fields}` schema object); with `--out`, a JSON summary
|
|
568
|
+
(`source`, `rows`, `columns`, `aggregate`, `report_id`).
|
|
569
|
+
- **Credential scopes:** a scoped credential (API key) needs `tables:read`
|
|
570
|
+
**and `dashboards:read`** for `drilldown`. The CSV export path polls
|
|
571
|
+
`/api/cache/cache_keys_status` and downloads `/api/dashboards/report/<n>`,
|
|
572
|
+
both of which the server scopes to `dashboards`; without it the export fails
|
|
573
|
+
at the first status poll (error 40301) after the server has started the task.
|
|
574
|
+
The CLI declares `dashboards:read` for every drill-down, inline included,
|
|
575
|
+
because scopes are per command, not per flag. `functions data` needs
|
|
576
|
+
`tables:read` only.
|
|
577
|
+
|
|
508
578
|
## Customer-facing docs (KB)
|
|
509
579
|
|
|
510
580
|
Help Center → the **"Semantic Layer"** category. Find current articles with `dr kb search "metric KPI"` (or
|
|
@@ -149,8 +149,9 @@ except on `update`, which resolves the range's own table automatically.
|
|
|
149
149
|
the blast radius (document + version counts) and get a token, then re-run with
|
|
150
150
|
`--confirm-token` — token-only, no word gate even on prod (a rescan re-derives
|
|
151
151
|
data, it doesn't delete it). To pick up a datamapper change on the live template
|
|
152
|
-
**without** touching history, use `datamappers update <id> --
|
|
153
|
-
instead (re-extracts the latest version of the mapper's bound
|
|
152
|
+
**without** touching history, use `datamappers update <id> --payload-file <p>
|
|
153
|
+
--rescan latest` instead (re-extracts the latest version of the mapper's bound
|
|
154
|
+
documents; it publishes a new mapper version, so the mapper gets a new id); a full rescan will re-run pre-existing
|
|
154
155
|
calc fields against old rows, so a latent divide-by-null there fails the whole
|
|
155
156
|
scan. Refuses `UsageStats` on every tenant (system data, not customer-owned).
|
|
156
157
|
- `dataflow get` — the dependency graph: inputs → mappers → LUTs → table →
|
|
@@ -431,27 +431,20 @@ this path that advice does not hold.) The generator omits it.
|
|
|
431
431
|
`document_version_id` is required and is **not** in `dr datamappers get` output —
|
|
432
432
|
read it from the upload response or `dr filebox versions <filebox_id>`.
|
|
433
433
|
|
|
434
|
-
### Changing a mapper that already exists: remap
|
|
434
|
+
### Changing a mapper that already exists: remap
|
|
435
435
|
|
|
436
436
|
Widening an existing feed mapper, or adding reporting-amount columns to a business
|
|
437
|
-
table's mappers, means editing mappers that already exist. `dr datamappers update
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
fails with a bare HTTP 500. The server log shows `AttributeError: 'NoneType' object has
|
|
442
|
-
no attribute 'get_document_data'`. No request body fixes it, because the endpoint never
|
|
443
|
-
reads a version from the body.
|
|
437
|
+
table's mappers, means editing mappers that already exist. `dr datamappers update
|
|
438
|
+
<id> --payload-file <p>` does this as a remap: it publishes the edited config as a new
|
|
439
|
+
version of the mapper, the way the UI's "Publish and scan" does, and fills in `name`,
|
|
440
|
+
`ordinal`, the bound documents and the source version from the old mapper.
|
|
444
441
|
|
|
445
|
-
|
|
446
|
-
|
|
442
|
+
A mapper created by an org import or template push has no source version on record,
|
|
443
|
+
and `update` stops with an error saying so. Put a version in the payload:
|
|
447
444
|
|
|
448
445
|
```json
|
|
449
446
|
{
|
|
450
|
-
"name": "<existing name>",
|
|
451
|
-
"datamapper_id": <existing mapper id>,
|
|
452
|
-
"ordinal": <existing ordinal>,
|
|
453
447
|
"document_version_id": <an ACTIVE version of one of its documents>,
|
|
454
|
-
"selected_document_ids": [<its mapped_documents_ids>],
|
|
455
448
|
"sheet_name": "<a sheet that exists in THAT version>",
|
|
456
449
|
"config": { ... the edited config ... }
|
|
457
450
|
}
|
|
@@ -459,7 +452,8 @@ mapper's id replaces it in place and records a real source version:
|
|
|
459
452
|
|
|
460
453
|
- **The mapper gets a new id.** The old id stays behind bound to no documents, and
|
|
461
454
|
lookups, which live on the table, are unaffected. Keep an old→new id log for rollback.
|
|
462
|
-
- **`ordinal` must be the existing one.**
|
|
455
|
+
- **`ordinal` must be the existing one.** `update` sends it for you; a lower one in the
|
|
456
|
+
payload is refused as a duplicate mapper.
|
|
463
457
|
- **`sheet_name` must exist in the version you pass**, and a mapper's
|
|
464
458
|
`preview_sheet_name` is often stale. Check with `dr filebox sheets <version_id>`; when
|
|
465
459
|
the preview sheet is gone and the version has one sheet, use that one.
|
|
@@ -754,7 +748,7 @@ the package layout reaches every producer.
|
|
|
754
748
|
| `#NAME?` on the label cell | `TEXT()` wrapped around `DR.MONTH()` | Step 4 |
|
|
755
749
|
| Self-rate is not exactly 1 | ratio not anchored to the target row | Step 4 |
|
|
756
750
|
| Custom code rejected by the Tables dialog | never registered as an org currency | Step 1 |
|
|
757
|
-
| `datamappers update
|
|
751
|
+
| `datamappers update`: mapper has no source document version | mapper made by an org import | `document_version_id` in the payload, Step 6 |
|
|
758
752
|
| Remap 500s: `Cannot read sheet with name …` | chosen version is in `ERROR` status | use the newest ACTIVE version, Step 6 |
|
|
759
753
|
| New lookup columns empty on every target row | lookup built while the FX table was still scanning | rebuild the lookup, Step 7 |
|
|
760
754
|
| Opening balances have no currency amounts | calc-model rows skip the mappers | **Step 7c** |
|
|
@@ -152,8 +152,11 @@ goes merge → new vN → §3 → `dr connectors query repoint` → re-sync. Cut
|
|
|
152
152
|
|
|
153
153
|
The staging datasource holds **live customer credentials**, so remove it right away:
|
|
154
154
|
1. `dr connectors query list` → `dr connectors query delete <queryId>` for each binding.
|
|
155
|
-
2. `dr integrations delete <ds
|
|
156
|
-
|
|
155
|
+
2. `dr integrations delete <ds> $STG` prints a plan and a confirm token. Re-run it with
|
|
156
|
+
`--confirm-token <tok>`. Prod is Tier A, so a human types the word shown in the desktop dialog; with
|
|
157
|
+
no interactive channel, hand the line to the user. Verify with `dr integrations get <ds> $STG` → 404.
|
|
158
|
+
dr-cli has no connector delete, so the orphaned `Connector` row points at a deleted datasource.
|
|
159
|
+
Record its id. (dr-cli skill, `reference/integrations.md`, "Deleting a data source".)
|
|
157
160
|
3. Keep the staging fileboxes as evidence until cut-over + ticket close, then delete the `<Customer>` tree.
|
|
158
161
|
4. Delete the local `wk/` and `st/` downloads: they are customer data. Keep only `report.md`.
|
|
159
162
|
5. Record the report, what was deleted and what was kept in the migration ticket.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datarails-ai/dr-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.107",
|
|
4
4
|
"description": "Datarails CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@datarails-ai/dr-appspace-cli": "0.11.
|
|
20
|
+
"@datarails-ai/dr-appspace-cli": "0.11.3",
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
22
22
|
"@napi-rs/keyring": "^1.3.0",
|
|
23
23
|
"commander": "^12.1.0",
|