@datarails-ai/dr-cli 0.0.1-locked → 1.6.71
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/README.md +608 -0
- package/dist/chunk-DWMCBGQH.js +242 -0
- package/dist/cli.js +64468 -0
- package/dist/kb-6UWI7Q32.js +21 -0
- package/dist/scopes-map.json +4412 -0
- package/dist/skills/connector-sandbox/SKILL.md +95 -0
- package/dist/skills/datarails-connect-workato/SKILL.md +140 -0
- package/dist/skills/datarails-connectors-onboard-connector/SKILL.md +813 -0
- package/dist/skills/dr-cli/SKILL.md +659 -0
- package/dist/skills/dr-cli/reference/admin.md +796 -0
- package/dist/skills/dr-cli/reference/budget-builder.md +151 -0
- package/dist/skills/dr-cli/reference/calc-vals.md +73 -0
- package/dist/skills/dr-cli/reference/calcmodels.md +76 -0
- package/dist/skills/dr-cli/reference/cash.md +61 -0
- package/dist/skills/dr-cli/reference/dashboards-widgets.md +85 -0
- package/dist/skills/dr-cli/reference/datamappers.md +150 -0
- package/dist/skills/dr-cli/reference/desk.md +472 -0
- package/dist/skills/dr-cli/reference/filebox-documents.md +373 -0
- package/dist/skills/dr-cli/reference/forecast.md +51 -0
- package/dist/skills/dr-cli/reference/integrations.md +57 -0
- package/dist/skills/dr-cli/reference/lookups.md +168 -0
- package/dist/skills/dr-cli/reference/metrics.md +512 -0
- package/dist/skills/dr-cli/reference/multi-product.md +180 -0
- package/dist/skills/dr-cli/reference/reconciliation-mec.md +76 -0
- package/dist/skills/dr-cli/reference/rh-config.md +84 -0
- package/dist/skills/dr-cli/reference/safety.md +143 -0
- package/dist/skills/dr-cli/reference/spend-control.md +206 -0
- package/dist/skills/dr-cli/reference/templates.md +163 -0
- package/dist/skills/dr-cli/reference/workflows.md +137 -0
- package/dist/skills/dr-error-enrichment/SKILL.md +80 -0
- package/dist/skills/dr-error-enrichment/reference/core.md +257 -0
- package/dist/skills/dr-error-enrichment/reference/groundcover.md +84 -0
- package/dist/skills/dr-error-enrichment/reference/jira-bugs.md +219 -0
- package/dist/skills/dr-error-enrichment/reference/safety-backup.md +122 -0
- package/dist/skills/dr-error-enrichment-author/SKILL.md +219 -0
- package/dist/skills/dr-error-enrichment-improve/SKILL.md +218 -0
- package/dist/skills/dr-error-enrichment-maintain/SKILL.md +237 -0
- package/dist/skills/dr-error-enrichment-reconcile/SKILL.md +167 -0
- package/dist/skills/dr-filebox-api-setup/SKILL.md +170 -0
- package/dist/skills/dr-switch-user/SKILL.md +395 -0
- package/dist/skills/dr-validate/SKILL.md +392 -0
- package/dist/skills/dr-validate/report-template.html +950 -0
- package/dist/skills/fx-conversion-matrix/SKILL.md +763 -0
- package/dist/skills/fx-conversion-matrix/scripts/_args.mjs +52 -0
- package/dist/skills/fx-conversion-matrix/scripts/_xlsx.mjs +241 -0
- package/dist/skills/fx-conversion-matrix/scripts/build-matrix.mjs +366 -0
- package/dist/skills/fx-conversion-matrix/scripts/gen-mappers.mjs +171 -0
- package/dist/skills/fx-conversion-matrix/scripts/rates-to-xlsx.mjs +172 -0
- package/dist/skills/fx-onboard/SKILL.md +325 -0
- package/dist/skills/mec-table-validation/SKILL.md +383 -0
- package/dist/skills/plugins.json +24 -0
- package/dist/skills/validate-workato-migration/SKILL.md +167 -0
- package/dist/skills/validate-workato-migration/reference/gotchas.md +16 -0
- package/dist/skills/validate-workato-migration/reference/staging-orgs.md +26 -0
- package/dist/skills/validate-workato-migration/scripts/compare_files.py +255 -0
- package/dist/zendeskKb-JPSHVOPH.js +243 -0
- package/package.json +56 -9
- package/scripts/postinstall.mjs +91 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dr-cli
|
|
3
|
+
description: Use when customer success or engineering needs to inspect OR change a customer's Datarails setup from the command line, or create/update/delete Datarails resources (templates, dashboards, widgets, functions, calculated values, dynamic ranges, datamappers, LUTs, fileboxes, integrations, users). Triggers - "create a chart/KPI/pie/table on this dashboard", "bulk-create users", "defer the invite emails", "change a user's login email", "turn email notifications on/off for a user", "re-enable emails for everyone in this org", "create N viewers with specific data permissions", "bulk-grant table/dashboard/filebox permissions from a CSV", "create many permission groups from a CSV", "upload this file", "compare Datarails values", "how many X does this customer have", "am I logged in", "who am I on this tenant", "is this the right customer?", "trigger a rescan", "look up a metric/KPI". Install/update/login → /dr-cli:install; a misbehaving CLI → /dr-cli:doctor; FX → /dr-cli:fx-conversion-matrix then /dr-cli:fx-onboard.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dr-cli — Datarails CLI
|
|
7
|
+
|
|
8
|
+
`dr` is a Node.js CLI for working with a customer's Datarails environment
|
|
9
|
+
(templates, dashboards, widgets, functions, calculated values, ranges,
|
|
10
|
+
datamappers, LUTs, fileboxes, integrations, metrics, reconciliation/MEC,
|
|
11
|
+
forecast, cash, spend, workflows, users, orgs) from any terminal on macOS or
|
|
12
|
+
Windows. Reads and writes are both supported.
|
|
13
|
+
|
|
14
|
+
This SKILL.md is the **router**: safety rules, auth, the full command map, the
|
|
15
|
+
core workflows, and the foot-guns that bite. Per-area detail lives in
|
|
16
|
+
`reference/*.md` — read the named file when you operate that area. Exact flags
|
|
17
|
+
for any command come from `dr <command> --help` (the binary is authoritative).
|
|
18
|
+
|
|
19
|
+
## Safety rules (enforce these)
|
|
20
|
+
|
|
21
|
+
1. **Prod writes need explicit in-chat confirmation.** ANY mutating command —
|
|
22
|
+
`create` / `update` / `delete` **and every other write path** (e.g.
|
|
23
|
+
`register-identity`, `bulk-create`, `bulk-set-email`, `bulk-permissions`,
|
|
24
|
+
`set-email`, `set-email-notifications`, `bulk-set-email-notifications`,
|
|
25
|
+
`set-password`, `set-field-type`) — on `US`, `US2`, `UK`, `CA`,
|
|
26
|
+
`EU`, `DEMO` (DEMO is a customer-facing prod tenant, not a sandbox) must be
|
|
27
|
+
confirmed by the user before you run them. `register-identity --confirm` in
|
|
28
|
+
particular sends real invite emails to customers, so it counts as a prod
|
|
29
|
+
write. Demonstrate on `DEV` / `DEV-1` / `TEST` / `TEST-1`..`TEST-7` first when
|
|
30
|
+
you can. Reads never need confirmation.
|
|
31
|
+
2. **Every `delete` is a two-step confirm.** Running `… delete <id>` without a
|
|
32
|
+
token fetches the target, prints its name + key attributes, and emits a
|
|
33
|
+
short-lived token bound to `(resource, id, verb)`. Re-run with
|
|
34
|
+
`--confirm-token <tok>` to actually delete. `templates set-field-type` is
|
|
35
|
+
gated the same way (it can break widgets/ranges). Relay the target details to
|
|
36
|
+
the user first. See [reference/safety.md](reference/safety.md) for the
|
|
37
|
+
interactive prod gate and how the token works.
|
|
38
|
+
3. **Prod destructives end in a desktop dialog, not a chat word.** After the
|
|
39
|
+
user's in-chat "yes, do it", re-invoke with the token — the binary pops a
|
|
40
|
+
dialog (or TTY prompt) where the *user* types a fresh challenge word; in a
|
|
41
|
+
headless shell it refuses non-zero. Don't add your own word ritual in chat.
|
|
42
|
+
Non-prod (`DEV`/`DEV-1`/`TEST`/`TEST-1`..`TEST-7`) is token-only, a plain
|
|
43
|
+
"yes" suffices; `DEMO` counts as prod. Details in
|
|
44
|
+
[reference/safety.md](reference/safety.md).
|
|
45
|
+
4. **Credentials are sensitive.** Sessions live in the OS keychain, or in a
|
|
46
|
+
credential file where one is in use — never extract or echo JWTs or session
|
|
47
|
+
IDs into chat.
|
|
48
|
+
5. **Don't invent commands.** If it isn't in the command map below, it doesn't
|
|
49
|
+
exist — escalate or ask. Never guess a flag; run `dr <command> --help`.
|
|
50
|
+
6. **`UsageStats` is off-limits.** Never rescan/mutate it; `rescan table`
|
|
51
|
+
refuses it by name on every tenant.
|
|
52
|
+
|
|
53
|
+
## Auth
|
|
54
|
+
|
|
55
|
+
Sessions live in the **OS keychain** (Windows Credential Manager / macOS
|
|
56
|
+
Keychain), keyed by `(server, email)` — or in a **credential file** where one is
|
|
57
|
+
in use (see below). With the keychain, multiple servers and multiple identities
|
|
58
|
+
per server can be logged in at once.
|
|
59
|
+
|
|
60
|
+
- `dr login --server US` — browser OAuth; session to the keychain, or to the
|
|
61
|
+
credential file when one is in use (see below).
|
|
62
|
+
- `dr login --api-key --server US` — save a user-bound **API key** instead of a
|
|
63
|
+
browser session. The key is read from a hidden prompt, or from stdin when
|
|
64
|
+
piped (`printf '%s\n' "$KEY" | dr login --api-key -s us`; piped, `-s` is
|
|
65
|
+
required unless a credential file already names the server; don't run the
|
|
66
|
+
piped form under shell tracing or command logging). Never pass the key as an
|
|
67
|
+
argument or paste it into chat. `dr` exchanges it for a JWT itself, so no
|
|
68
|
+
re-login is ever needed while the key is live. Keys come from an operator
|
|
69
|
+
today (no self-service command yet). `login-as` cannot run from an API-key
|
|
70
|
+
identity.
|
|
71
|
+
- `dr login-as <email> --server US` — impersonate a user, **JWT only, no
|
|
72
|
+
browser**. Needs an operator `login` first; stores a switchable identity you
|
|
73
|
+
then target with `--account <email>`. `--as <operator-email>` picks the
|
|
74
|
+
operator if several are stored; `--user-id <n>` skips the email lookup.
|
|
75
|
+
Refreshes/auto-remints silently — no re-prompt until the operator expires.
|
|
76
|
+
- `dr whoami --server US` — confirm who/where you are. Offline (decodes the local
|
|
77
|
+
JWT, no network). **Always sanity-check after login or a server switch.**
|
|
78
|
+
Shows `Impersonated by:` for a `login-as` identity, and a `Scope:` row for
|
|
79
|
+
every identity (see below).
|
|
80
|
+
- `dr logout --server US` / `dr logout --all`.
|
|
81
|
+
|
|
82
|
+
A **credential file wins over the keychain**: `dr` looks at
|
|
83
|
+
`DR_CREDENTIALS_FILE`, or `~/.dr/session.json` when that variable is unset, and
|
|
84
|
+
if the file is there every command reads its credentials from it — even on a
|
|
85
|
+
host whose keychain works — and writes it only when they change (`login`,
|
|
86
|
+
`logout`, a JWT refresh). Only when that one path is absent does `dr` use the
|
|
87
|
+
keychain. That is what makes `dr` usable where no keychain exists (CI, headless
|
|
88
|
+
hosts, containers). `dr whoami`'s `Auth:` line names the file in use. The file holds one
|
|
89
|
+
identity: `login` re-authenticates it and `logout` removes the file, but
|
|
90
|
+
`login-as` is refused (nowhere to put a second identity). If those credentials
|
|
91
|
+
are a bare token pair provisioned by something other than `dr login`, they
|
|
92
|
+
carry no session cookie and `login` / `logout` refuse over them: whatever
|
|
93
|
+
provisioned them owns renewing them. A file holding an `apiKey` is the CLI's
|
|
94
|
+
own to renew: `logout` deletes it and `login --api-key` replaces the key, while
|
|
95
|
+
a plain `login` is refused over it even when the file also holds a cookie,
|
|
96
|
+
because the key is what later commands authenticate as. `dr` warns on stderr,
|
|
97
|
+
once per identity, when a provisioner-supplied `apiKeyExpiresAt` is within
|
|
98
|
+
14 days — from any command that authenticates and from `whoami`, which is where
|
|
99
|
+
an operator goes to inspect a credential; `login`, `logout` and `login-as` do
|
|
100
|
+
not show it. Nothing derives that date: the
|
|
101
|
+
exchange response does not carry it and `login --api-key` does not set it, so
|
|
102
|
+
update it in the file alongside the key, or the warning keeps naming the old
|
|
103
|
+
one.
|
|
104
|
+
|
|
105
|
+
`--server <KEY>` is **required on every command that hits an API**. Valid keys:
|
|
106
|
+
`US`, `US2`, `UK`, `CA`, `EU`, `DEV`, `DEV-1`, `TEST`, `TEST-1`, `TEST-2`, `TEST-3`, `TEST-4`, `TEST-5`, `TEST-6`, `TEST-7`, `DEMO` (case-insensitive).
|
|
107
|
+
|
|
108
|
+
You can also pass a full **`https://<host>.datarails.com` URL** instead of a
|
|
109
|
+
key to reach an ad-hoc / PR-preview environment, e.g.
|
|
110
|
+
`dr login --server https://<preview-host>.datarails.com`. Only `https`
|
|
111
|
+
and `*.datarails.com` hosts are accepted; the session is keyed by the hostname.
|
|
112
|
+
`dr logout --all` only revokes the built-in registry servers — log out of a URL
|
|
113
|
+
environment explicitly with `dr logout --server <url>`.
|
|
114
|
+
|
|
115
|
+
**Multi-identity:** when more than one account is stored for a server, pass
|
|
116
|
+
`--account <email>`. With one identity stored, `--account` can be omitted; a
|
|
117
|
+
missing `--account` against a multi-identity server errors with the available
|
|
118
|
+
emails.
|
|
119
|
+
|
|
120
|
+
### Credential scope
|
|
121
|
+
|
|
122
|
+
An identity may carry a **scope** — a ceiling chosen by whoever approved the
|
|
123
|
+
credential (an agent's definition, an API key, a device-flow login), and it is a
|
|
124
|
+
ceiling on top of the user's own permissions, never a grant beyond them.
|
|
125
|
+
Commands outside it are hidden from `--help`, and invoking one anyway — or
|
|
126
|
+
hitting a server with it — exits **3** naming the `resource:action` that is
|
|
127
|
+
missing. **`dr whoami` prints the ceiling**: `Scope: Read only` (or `Read and
|
|
128
|
+
write` / `Full access`) for a preset, otherwise a `custom (N resources)` tree of
|
|
129
|
+
products, resources and the actions allowed on each, and
|
|
130
|
+
`Scope: unrestricted (no ceiling on this credential)` for a token that carries
|
|
131
|
+
no claim at all. Under `login-as` it reads `(inherited from operator)` — the
|
|
132
|
+
ceiling is the operator's. `dr whoami --json` adds `scopes` carrying the claim
|
|
133
|
+
exactly as the token holds it — an array, or a space-separated string, or `null`
|
|
134
|
+
when the token has no such claim. It is **not** normalised, so an entry `dr`
|
|
135
|
+
could not parse is still visible there; read the `Scope:` row for the ceiling
|
|
136
|
+
that is actually in force.
|
|
137
|
+
|
|
138
|
+
**Do not try to work around a scope** — no direct API calls, no switching
|
|
139
|
+
identity to dodge it. Report what you cannot do and the `resource:action` it
|
|
140
|
+
needs, so whoever minted the credential can widen it.
|
|
141
|
+
|
|
142
|
+
**`dr --help` can list less than the full tree, for two different reasons.**
|
|
143
|
+
The ROOT listing is context-dependent, and **a short listing never means "the
|
|
144
|
+
command does not exist."** Two mechanisms shorten it and they do not behave the
|
|
145
|
+
same:
|
|
146
|
+
|
|
147
|
+
1. **No identity resolved** — no `--server` and no credential file, or a
|
|
148
|
+
`--server` whose stored identities `--account` did not narrow to one. Only
|
|
149
|
+
the few commands that run without an identity are listed (`login` among
|
|
150
|
+
them) and a line says why. Everything else is still registered, still runs,
|
|
151
|
+
and **still prints its own `--help`**; only the root listing changes. Re-run
|
|
152
|
+
as `dr --help --server <key>` — adding `--account <email>` when that server
|
|
153
|
+
holds more than one identity — to see the real tree.
|
|
154
|
+
2. **A scope-restricted credential** — an identity DID resolve, and its token's
|
|
155
|
+
scope claim does not cover every command. The families it may not use are
|
|
156
|
+
hidden, and targeted help does **not** stay available: `dr <family> --help`
|
|
157
|
+
for a hidden one exits **3** with its own message naming the missing
|
|
158
|
+
`resource:action`. That is a credential limit, not a missing feature —
|
|
159
|
+
`dr whoami` shows the scope the identity carries.
|
|
160
|
+
|
|
161
|
+
Never tell a user `dr` cannot do something on the strength of a bare
|
|
162
|
+
`dr --help`.
|
|
163
|
+
|
|
164
|
+
**A server can refuse on scope too, and that also exits 3.** The hidden-command
|
|
165
|
+
rules above are this CLI's own map talking; the servers enforce the ceiling
|
|
166
|
+
themselves and answer `403` with a code:
|
|
167
|
+
|
|
168
|
+
- **`40301` — the credential's scope does not cover this call.** The message
|
|
169
|
+
reads `POST /api/…: this identity's credential scope does not allow it
|
|
170
|
+
(needs dashboards:write); run 'dr whoami' to see the scopes this
|
|
171
|
+
identity carries`. The scope is named from the local command map, so it is
|
|
172
|
+
absent for a command the map does not classify — the refusal is the same either way. **Do not retry, and do not
|
|
173
|
+
re-`login`**: a fresh token carries the same ceiling. Report the missing
|
|
174
|
+
`resource:action` to whoever minted the credential.
|
|
175
|
+
- **`40302` — the endpoint has no scope declared on the server yet.** The
|
|
176
|
+
message says `this endpoint is not yet scope-declared on the server; report
|
|
177
|
+
to #dr-cli`. Nothing about the credential is wrong; the CLI reached a route
|
|
178
|
+
the server's scope table does not know. Retrying cannot help — report it.
|
|
179
|
+
|
|
180
|
+
Neither goes through the JWT refresh ladder (a ceiling is not an expiry), so
|
|
181
|
+
neither can present as `session expired`. Any other `403` is an ordinary
|
|
182
|
+
permission / tenant / feature-flag refusal, still exits **1**, and is worth a
|
|
183
|
+
second look at `--server`, the org context, and the request body.
|
|
184
|
+
|
|
185
|
+
**JWT refresh is automatic** — the CLI refreshes before each request and on
|
|
186
|
+
401/403, except on the two scope codes above, which no refresh can lift. Only
|
|
187
|
+
re-`login` when you see `session expired` as the *final* error after an
|
|
188
|
+
auto-refresh attempt. Do not re-login proactively on an expiry countdown.
|
|
189
|
+
|
|
190
|
+
**Connectors over VPN (TLS):** `dr connectors …` reaches the control-plane over
|
|
191
|
+
the corporate VPN. A TLS/certificate error there (`self signed certificate in
|
|
192
|
+
chain`, `unable to verify the first certificate`) means the VPN is inspecting
|
|
193
|
+
TLS — trust its gateway root CA via `NODE_EXTRA_CA_CERTS=<gateway-ca.pem>`,
|
|
194
|
+
which keeps verification on. Never set `NODE_TLS_REJECT_UNAUTHORIZED=0` (it also
|
|
195
|
+
exposes the monolith connection carrying the JWT). The CLI appends this fix to
|
|
196
|
+
the error inline; full steps in `dr connectors --help`.
|
|
197
|
+
|
|
198
|
+
## Command map (don't improvise)
|
|
199
|
+
|
|
200
|
+
Every entry is a real subcommand. If it's not here, it doesn't exist. Names only
|
|
201
|
+
— run `dr <command> --help` for flags. `→` points to the reference file with that
|
|
202
|
+
area's gotchas.
|
|
203
|
+
|
|
204
|
+
**Session:** `login`, `whoami`, `logout`, `update` (self-upgrade the CLI).
|
|
205
|
+
|
|
206
|
+
**Templates / tables / ranges** → [reference/templates.md](reference/templates.md)
|
|
207
|
+
- `templates list|get|create|sample|distinct|aggregate|set-alias|set-field-alias|set-field-type`
|
|
208
|
+
- `set-alias` / `set-field-alias` set what the Datarails UI calls a table's or
|
|
209
|
+
field's **system name** — same value, different word. Read them with
|
|
210
|
+
`templates get <id> --json`.
|
|
211
|
+
- `data-models list|get`
|
|
212
|
+
- `dynamic-ranges list|get|create|update|delete|data`
|
|
213
|
+
- `scans status`, `rescan table`, `dataflow get`
|
|
214
|
+
|
|
215
|
+
**Datamappers** → [reference/datamappers.md](reference/datamappers.md)
|
|
216
|
+
- `datamappers list|get|update|delete|custom-functions|preview|bind|processed-versions|connected-fileboxes`
|
|
217
|
+
- `datamappers create flat|dimension|multiple|from-file`
|
|
218
|
+
- `mapper-recipes list|get|save`
|
|
219
|
+
|
|
220
|
+
**Calc models** → [reference/calcmodels.md](reference/calcmodels.md)
|
|
221
|
+
- `calcmodels list|get|create|update|set-flow|recalculate|delete` (alias `calc-models`)
|
|
222
|
+
|
|
223
|
+
**Calculated values (per-table)** → [reference/calc-vals.md](reference/calc-vals.md)
|
|
224
|
+
- `calc-vals list|get|create|update|delete` (alias `calcvals`) — `--table <id>` required on every subcommand
|
|
225
|
+
|
|
226
|
+
**Metrics (KPIs) & functions** → [reference/metrics.md](reference/metrics.md)
|
|
227
|
+
- `metrics list|get|data|drilldown`
|
|
228
|
+
- `metrics create base|calc`, `metrics update|delete`
|
|
229
|
+
- `metrics re-aggregate` — rebuild pre-aggregated metric values (targeted ids, or `--all` org-wide); add `--wait [--timeout <s>]` on targeted ids to block until done (exits non-zero on failure/timeout)
|
|
230
|
+
- `metrics migrate` — org-wide metrics+dimensions migration (V1→V2 backfill; `--dry-run` first)
|
|
231
|
+
- `metrics categories list|get|create|update|delete`
|
|
232
|
+
- `metrics dimensions list|get|create|update|delete|preview`
|
|
233
|
+
- `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`.
|
|
234
|
+
- `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.
|
|
235
|
+
- `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.
|
|
236
|
+
- `functions list|get|create|update|delete|set-filters` — a function's **definition** only.
|
|
237
|
+
- _`set-filters <id> --file <json> [--confirm]` is the **only** way to author a
|
|
238
|
+
function's row-level filters (create/update don't touch them). FULL REPLACE —
|
|
239
|
+
an empty array clears all; dimension `values` are a plain list, date filters
|
|
240
|
+
carry the add-in's opaque From/To blob. Dry-run unless `--confirm`._
|
|
241
|
+
To write a function's `DR.GET` into a raw `.xlsx`, that's `documents
|
|
242
|
+
add-functions` (see the Fileboxes/documents group), not a `functions`
|
|
243
|
+
subcommand.
|
|
244
|
+
|
|
245
|
+
**Dashboards, widgets, storyboards, reports, extables** → [reference/dashboards-widgets.md](reference/dashboards-widgets.md)
|
|
246
|
+
- `dashboards list|get|create|delete|prepare|set-date-picker`
|
|
247
|
+
- `dashboards push <id> --to <orgs> [--override]` — copy a dashboard into other
|
|
248
|
+
organizations (two-step confirm). Destinations must come from
|
|
249
|
+
`organizations push-targets`.
|
|
250
|
+
- `widgets list|get|data|create|update|delete|chart|kpi|pie|table|gauge|waterfall|published-item|text` (alias `widget`)
|
|
251
|
+
— `widgets data` applies the dashboard's saved filter bar + date picker by
|
|
252
|
+
default so results match the product UI; `--no-dashboard-context` computes
|
|
253
|
+
from the widget's own settings only.
|
|
254
|
+
- `storyboards list|get|slides|prepare|delete`
|
|
255
|
+
- `reports list|get|clone|delete`
|
|
256
|
+
- `extables list|get|clone|delete`
|
|
257
|
+
|
|
258
|
+
**Budget Builder (Budget management templates)** → [reference/budget-builder.md](reference/budget-builder.md)
|
|
259
|
+
- `budget-builder build|validate-row|add-row|save` — preview/build a budget
|
|
260
|
+
template definition, manage custom rows, persist to Budget management.
|
|
261
|
+
**Run the pre-flight questionnaire in the reference before building** —
|
|
262
|
+
scaffold-inherited values (actuals ending, fill mode, budget year) are the
|
|
263
|
+
#1 source of silently-wrong templates.
|
|
264
|
+
- `documents split create|list|status|undo` — split a saved budget file into
|
|
265
|
+
per-department child files (create/undo are two-step confirms).
|
|
266
|
+
|
|
267
|
+
**Fileboxes & documents** → [reference/filebox-documents.md](reference/filebox-documents.md)
|
|
268
|
+
- `filebox list|get|versions|tags|sheets|preview|create|upload|upload-version|update|download` (alias `fileboxes`)
|
|
269
|
+
- `filebox archive|archive-version|restore-version|set-version-include|set-version-date-tag|set-version-workflow|set-version-file-status|set-version-cycle`
|
|
270
|
+
- _archived versions (opt-in; defaults unchanged): `versions --archived|--all` to discover them; `archive-version`/`restore-version` also take `--doc` + `--version-number <n>` or `--latest-archived`/`--latest-active`_
|
|
271
|
+
- _include in database: `versions --included` lists the versions whose `include_file` flag is on (intent, not delivered rows); `set-version-include <vid> --include on|off` writes the flag (two-step confirm both ways — off deletes the version's table rows, on queues an ETL scan). `--doc <id> --all-except-latest` is the bulk cleanup; it never targets the latest, and warns in the plan if the latest is itself excluded_
|
|
272
|
+
- `filebox share|shares|set-option|set-tag-config|set-parent|lock|unlock|lock-date-tag|unlock-date-tag|locked-date-tags`
|
|
273
|
+
- `filebox get-auto-calc-settings|set-auto-calc-frequency|set-sync-frequency`
|
|
274
|
+
- `filebox push <id> --to <orgs> [--override]` — copy a filebox's latest version
|
|
275
|
+
and its dependent objects into other organizations (two-step confirm).
|
|
276
|
+
Destinations must come from `organizations push-targets`.
|
|
277
|
+
- `filebox data-query get|set|set-sync-interval|clear|sync` (alias `dq`)
|
|
278
|
+
- `filebox validation-rules options|set`
|
|
279
|
+
- `documents support-api set`, `documents calculate|sheets|debug-zip`
|
|
280
|
+
- `documents auto-calculate|add-functions|add-extables|add-dynamic-ranges` —
|
|
281
|
+
push a raw `.xlsx` through the server with **no filebox**: `auto-calculate`
|
|
282
|
+
recomputes it; `add-functions` injects Datarails functions' `DR.GET` formulas
|
|
283
|
+
into it by function id; `add-extables` registers ExTables into it by extable
|
|
284
|
+
id; `add-dynamic-ranges` registers Dynamic Ranges into it by range id. These
|
|
285
|
+
"add X to an Excel file" commands live under `documents`, **not** under
|
|
286
|
+
`functions`/`extables`/`dynamic-ranges`.
|
|
287
|
+
|
|
288
|
+
**Lookups (LUTs)** → [reference/lookups.md](reference/lookups.md)
|
|
289
|
+
- `lut list|list-by-doc|unmapped|data|create|create-table-lookup|update|update-table-lookup|delete|reorder|save-mappings|export` (alias `lookups`)
|
|
290
|
+
- Filebox vs table: **filebox lookups** use `create`/`update` (payload file; source is an uploaded file, keys in leading columns, **surfaces unmapped items** via `lut unmapped`). **table lookups** use `create-table-lookup`/`update-table-lookup` (flags — `--source-table`/`--keys`/`--fields`; source is another table, keys anywhere, **no unmapped-item surfacing**). Full decision guide in the reference.
|
|
291
|
+
|
|
292
|
+
**Integrations & company data sources** → [reference/integrations.md](reference/integrations.md)
|
|
293
|
+
- `integrations list|get|types|status|query-status|errors|sync|test-connection|add|update|delete|revoke`
|
|
294
|
+
- _`revoke <id>` is the OAuth **Disconnect** for a `DatarailsConnector` data source: it clears the
|
|
295
|
+
grant (`authorised=false`, `oauth` + `oauth_secrets` kept) and then revokes it at the vendor,
|
|
296
|
+
best-effort, when `oauth.revoke_url` is set. Two-step confirm (Tier A on prod); the output
|
|
297
|
+
names the vendor outcome (`revoked`, `rejected`, `not_supported`, ...). The customer must
|
|
298
|
+
reconnect before the next sync._
|
|
299
|
+
- `integrations share users|groups`
|
|
300
|
+
- `integrations it list|get|add|update|delete|resync` (IT-admin file-sync; redacts secrets by default)
|
|
301
|
+
- `entities list|qbd-availability|netsuite-connections|rename|rename-group|delete|mark-completed` (alias `companies`)
|
|
302
|
+
- `entities create qbo|xero|qbd|netsuite` (connected accounting systems)
|
|
303
|
+
- `error-enrichments list|stats|get|create|update|delete|test-regex|export|import` — the
|
|
304
|
+
regex→readable-message rules shown when a sync fails. `get`/`update`/`delete` take
|
|
305
|
+
one **or more** ids (`update` applies the same patch to each); `create` and
|
|
306
|
+
`update` also accept an **array** `--payload-file` (rule objects for `create`,
|
|
307
|
+
`{id, ...fields}` patches for `update`) for batch writes. Rules are **per server**;
|
|
308
|
+
`list`/`stats` take `--all-servers`, writes take one `--server`. `import` is
|
|
309
|
+
wipe-and-replace and zeroes hits/feedback counters — it is not the reconcile
|
|
310
|
+
tool: fleet changes are batch `create`/`update`, and `import` runs only when the
|
|
311
|
+
user names it and confirms the analytics loss and id reassignment. Start at the
|
|
312
|
+
**`dr-error-enrichment` skill** (router + shared reference on matching, safety,
|
|
313
|
+
and groundcover), then go straight to the task skill: **`dr-error-enrichment-author`**
|
|
314
|
+
to write/edit/delete rules, **`dr-error-enrichment-reconcile`** to diff and align
|
|
315
|
+
rules across servers, **`dr-error-enrichment-maintain`** to approve high-hit drafts
|
|
316
|
+
and fix thumbs-down rules, **`dr-error-enrichment-improve`** to mine groundcover
|
|
317
|
+
for unmatched errors and propose new rules.
|
|
318
|
+
|
|
319
|
+
**Reconciliation & MEC close-dates** → [reference/reconciliation-mec.md](reference/reconciliation-mec.md)
|
|
320
|
+
- `reconciliation accounts list|entities|entity-currencies|info|progress|settings|update-settings|set-assignee|clear-assignee|set-due-date|sign` (alias `recon`)
|
|
321
|
+
- `reconciliation processes dates|accounts`
|
|
322
|
+
- `reconciliation evidences list|get|process|supporting|file|create`
|
|
323
|
+
- `reconciliation filebox list|get|progress|create|delete|unlinked`
|
|
324
|
+
- `reconciliation audit status`
|
|
325
|
+
- `mec close-dates get|set`
|
|
326
|
+
|
|
327
|
+
**Workflows v2 (close & non-MEC) + collection processes** → [reference/workflows.md](reference/workflows.md)
|
|
328
|
+
- `workflow` and `mec workflow` share the same surface: `list|get|create|update|activate|deactivate|archive|restore|delete|clone|periods`, plus sub-groups `process`, `step`, `task`, `member`, `group` (`mec workflow` also has `accounts`)
|
|
329
|
+
- `collection-processes list|get|create|set-tag-config|add-fileboxes|add-folders|calculate` (alias `collection-process`)
|
|
330
|
+
|
|
331
|
+
**Forecast (Planning)** → [reference/forecast.md](reference/forecast.md)
|
|
332
|
+
- `forecast cycles list|get|documents|lock|unlock|set-default|roll-forward`
|
|
333
|
+
- `forecast scenarios list|get|versions|lock|unlock|set-default|delete|clone|clone-from-budget|bulk-edit|create`
|
|
334
|
+
|
|
335
|
+
**Cash** (own module) → [reference/cash.md](reference/cash.md)
|
|
336
|
+
- `cash currencies list|prefs|set-prefs`, `cash transactions`, `cash rescan-rules`, `cash set-default-currency`
|
|
337
|
+
- `cash rules list|get|create|update|delete|delete-all|reorder|import-csv|export-csv|ai-trigger`
|
|
338
|
+
- `cash tags list`, `cash hidden-rules upsert|delete`
|
|
339
|
+
|
|
340
|
+
**Spend Control** (own module) → [reference/spend-control.md](reference/spend-control.md)
|
|
341
|
+
- `spend-control billing-frequencies list`, `spend-control contracts list|get|extract-from-files|bulk-create|update|archive|restore|delete`, `spend-control files upload|list|get|delete`
|
|
342
|
+
- Attaching a document whose field values you already know? `spend-control files upload` returns file_ids with NO AI extraction cost; `extract-from-files` is for when you need the fields parsed.
|
|
343
|
+
- Need a contract UUID for `get`/`update`/`archive`/`delete`? `spend-control contracts list --all` is the only source.
|
|
344
|
+
|
|
345
|
+
**Multi-product (product-content catalog & per-org assignment)** → [reference/multi-product.md](reference/multi-product.md)
|
|
346
|
+
- `multi-product product-content list`
|
|
347
|
+
- `multi-product org-products list|set` — `set` has replace semantics; two-step confirm gated
|
|
348
|
+
|
|
349
|
+
**Legacy RH_CONFIG inspection (read-only)** → [reference/rh-config.md](reference/rh-config.md)
|
|
350
|
+
- `rh_config config|tables|download <bucket-id>` — inspect / download the bucket's config workbook (the Excel with the `RH_Config` sheet that the legacy parser reads).
|
|
351
|
+
- _`rh_config download` is broken (its endpoint rejects the JWT and it saves the login HTML page). Download instead with `filebox download <document> --doc-version <id>`, using `id` + `document` from `rh_config config <bucket-id> --json`._
|
|
352
|
+
- `rh_config doc-templates <doc-id> [--legacy-only]` / `rh_config version-templates <ver-id> [--v2] [--legacy-only]` — list TableTemplates with the `is_rh_config` flag surfaced.
|
|
353
|
+
|
|
354
|
+
**IT / admin / misc** → [reference/admin.md](reference/admin.md)
|
|
355
|
+
- `users list|get|can-login-as|me|set-password|set-email|set-email-notifications|bulk-create|bulk-set-email|bulk-set-email-notifications|register-identity|permissions|bulk-permissions`
|
|
356
|
+
- _`set-email <user_id> <new_email>` changes one user's **login email** via
|
|
357
|
+
`PUT /api/it/users/<id>` (the IT admin edit dialog's endpoint; preserves
|
|
358
|
+
`excel_online_email` and triggers the server's SSO email sync). **Dry-run by
|
|
359
|
+
default** — it GETs the user and prints `current -> new`; add `--confirm` to
|
|
360
|
+
apply. A target already in use errors (`email already in use`)._
|
|
361
|
+
- _`bulk-set-email --file <csv>` renames many users' login emails in one go
|
|
362
|
+
(CSV header `source,target`, one row per user). Same safety model as
|
|
363
|
+
`bulk-create`: resolves + validates EVERYTHING first — an unknown source,
|
|
364
|
+
sources spanning **more than one organization**, a target that collides with
|
|
365
|
+
an existing user, or a swap/chain all abort **before any write**. Dry-run
|
|
366
|
+
unless `--confirm`; on execute each row is isolated (a failure is recorded,
|
|
367
|
+
the batch continues, a non-empty failure set exits non-zero). Template:
|
|
368
|
+
`docs/examples/users-bulk-set-email.csv`._
|
|
369
|
+
- _`set-email-notifications <user_id> --enable|--disable` is the admin form's
|
|
370
|
+
**"Enable notifications"** toggle (`disable_emails`), written through the same
|
|
371
|
+
`PUT /api/it/users/<id>`. Exactly one of `--enable`/`--disable` required.
|
|
372
|
+
**Dry-run unless `--confirm`.** Refuses sync-service and support accounts
|
|
373
|
+
(provisioned notifications-off; the bulk verb skips them for the same
|
|
374
|
+
reason). Only `disable_emails` changes — the body
|
|
375
|
+
echoes the current `email` and `excel_online_email` verbatim so the server's
|
|
376
|
+
SSO email-sync never fires. **Blocked users:** the write lands, but reads
|
|
377
|
+
stay `off` until the user is unblocked (the server reports
|
|
378
|
+
`disable_emails OR is_blocked`) — the command says so; don't retry. To find
|
|
379
|
+
affected users, `users list` has an `EMAIL_NOTIF` column and
|
|
380
|
+
`--email-notifications on|off`._
|
|
381
|
+
- _`bulk-set-email-notifications --organization <id> --enable|--disable`
|
|
382
|
+
applies that toggle to a whole org (per-user writes — there is no org-level
|
|
383
|
+
notification setting). **Always skips** sync-service users, support users,
|
|
384
|
+
and users whose state the server didn't report; `--only-changed` also skips
|
|
385
|
+
users already in the target state, making re-runs cheap — but **never**
|
|
386
|
+
skips a blocked user, whose read state (`_disable_emails OR is_blocked`)
|
|
387
|
+
says nothing about the stored column. Aborts before any
|
|
388
|
+
write if the org matches no users. Dry-run unless `--confirm`; per-user
|
|
389
|
+
isolation on execute, failed ids named, non-zero exit._
|
|
390
|
+
- _`bulk-create --file <csv>` invites many users in one go, each scoped to
|
|
391
|
+
permission groups (the UI's "Invite Users → Set Permissions" flow, automated).
|
|
392
|
+
**Dry-run by default — add `--confirm` to actually create** (it sends real
|
|
393
|
+
invite emails). CSV header:
|
|
394
|
+
`email,first_name,last_name,role,permission_groups,department,job_role`
|
|
395
|
+
plus an **optional 8th column `register_identity`** (blank/absent ⇒ `true`;
|
|
396
|
+
set `false` to create that user WITHOUT identity-provider registration /
|
|
397
|
+
invite email — deferred setup). Blank `role` = VIEWER; `permission_groups`
|
|
398
|
+
are `;`-separated group **names**. Target org auto-resolves from the tenant's
|
|
399
|
+
permission groups, or pass `--organization <id>`. Existing emails aren't
|
|
400
|
+
recreated but ARE re-scoped (their listed groups get assigned), so re-runs
|
|
401
|
+
are idempotent and repair a prior partial failure. **`--no-register-identity`**
|
|
402
|
+
forces the deferred behavior for the whole batch; send the invites later with
|
|
403
|
+
`register-identity`._
|
|
404
|
+
- _`register-identity --file <csv>` sends the deferred invites for a
|
|
405
|
+
`bulk-create --no-register-identity` batch: feed it the SAME CSV (only `email` is
|
|
406
|
+
read), it resolves each email to its user and calls
|
|
407
|
+
`PUT /api/it/users/<id>/register_identity` to register + invite. Dry-run
|
|
408
|
+
unless `--confirm`; honest per-row status `registered`/`already_exists`/
|
|
409
|
+
`failed` (only `failed` exits non-zero, so re-runs are idempotent —
|
|
410
|
+
already-registered users report `already_exists`)._
|
|
411
|
+
- _`permissions <get|set-role|grant-table|revoke-table|grant-element|revoke-element|set-filters|remove-group>`
|
|
412
|
+
is the Permission Manager, one user at a time: data-table roles, element roles
|
|
413
|
+
(filebox/lookup/model/report/dashboard/storyboard/datasource), org role, and
|
|
414
|
+
row-level data-access filters. Requires the `use_new_table_perms` flag.
|
|
415
|
+
**Dry-run unless `--confirm`.**_
|
|
416
|
+
- _`bulk-permissions --file <csv>` applies many of those grants at once. Header:
|
|
417
|
+
`email,resource,type,ids,role,filter_values,filter_excluded` — one row per
|
|
418
|
+
grant, `resource` ∈ `table|element|role|filter`. Resolves everything first
|
|
419
|
+
and fails loud before any write (unknown email or table/element role aborts
|
|
420
|
+
the run); `filter` rows for a user aggregate into one full-replace. **Dry-run
|
|
421
|
+
unless `--confirm`.** Template: `docs/examples/users-bulk-permissions.csv`._
|
|
422
|
+
- `organizations list|get|add|contacts|permission-groups|push-targets|create-group|update-group|delete-group|bulk-groups` (alias `orgs`), `support-manager list`
|
|
423
|
+
- _`push-targets` lists the organizations this account may push a dashboard or filebox into — always run it before `dashboards push` / `filebox push`_
|
|
424
|
+
- _`create-group|update-group|delete-group` manage permission groups on the IT
|
|
425
|
+
app; `bulk-groups --file <csv>` provisions and augments many groups + their
|
|
426
|
+
membership from one CSV (header `group_name,role,members`). Dry-run unless
|
|
427
|
+
`--confirm`; `delete-group` uses the two-step confirm-token flow._
|
|
428
|
+
- `organizations export create|delete`, `organizations import run|delete-orgs` — full-org
|
|
429
|
+
migration between servers (export → email → import → email → export delete).
|
|
430
|
+
- _Both POSTs return immediately; **completion is email-only — there is no status
|
|
431
|
+
API to poll**. `import run` is permanent by default (`--temporary` opts into a
|
|
432
|
+
GC'd throwaway) and skips unknown model types by default (`--no-skip-models` to
|
|
433
|
+
fail instead). `import delete-orgs` **permanently deletes the whole organization**
|
|
434
|
+
(word-gated on prod). Renamed copies get RANDOMIZED user passwords (per-org
|
|
435
|
+
secret, recorded nowhere — use impersonation); real migrations pass
|
|
436
|
+
`--keep-user-passwords`. Full runbook: [reference/admin.md](reference/admin.md)._
|
|
437
|
+
- `devices list|get|logs|request-logs|received-logs|download-logs|commands|command-delete`
|
|
438
|
+
- `features list`, `features groups list|get`, `features orgs list|add|remove`
|
|
439
|
+
- `semantictables list|get|data|distinct` (alias `semtables`), `fx rates`
|
|
440
|
+
- `fx set-posting|set-reporting` (Monetary field FX roles; `--all-tables` sweeps the org), `fx default-currency` (org-wide default, Super Admin), `fx add-currency` (org custom currency, e.g. BUSD), `fx convert-functions|convert-widgets` (bulk currency-aware sweeps, `--off` to roll back)
|
|
441
|
+
- `kb search|get|categories|sections|articles-in-section|recent|attachments|article-images`
|
|
442
|
+
- `mcp register|unregister|list|serve`, `skill list|print|install|init-project`
|
|
443
|
+
|
|
444
|
+
**Desk** → [reference/desk.md](reference/desk.md)
|
|
445
|
+
- `desk teams list` — the org's Desk teams with their support emails; the only way
|
|
446
|
+
to get a `team_id` (no email-to-team lookup exists anywhere in the platform)
|
|
447
|
+
- `desk smtp set <team>` — store + verify a customer app password; `<team>` is an
|
|
448
|
+
id, a support email, or a team name (resolved against `teams list`)
|
|
449
|
+
- `desk smtp rotate <team>` — replace a stored app password in place when `set`
|
|
450
|
+
reports an existing ACTIVE connection; the row is never deactivated, so the
|
|
451
|
+
team keeps sending authenticated throughout
|
|
452
|
+
- `desk smtp get|test <team>` — inspect a stored connection (does it actually
|
|
453
|
+
route?) and re-test the credential without re-submitting it
|
|
454
|
+
- `desk support-email set <team> <email>` — register the team's
|
|
455
|
+
inbound address; do this BEFORE the customer creates their auto-forward rule
|
|
456
|
+
- `desk sendgrid register <domain>|status|verify` — SendGrid domain authentication
|
|
457
|
+
- `desk ticket create <team> --title … --requester-email … [--attach <path> …]` — open a
|
|
458
|
+
ticket; `<team>` resolves like `smtp set`'s. **Desk emails a confirmation to the
|
|
459
|
+
requester**, so it is confirm-gated and keeps the interactive word gate on production
|
|
460
|
+
- `desk clone --source-org <id> --target-org <id> [--dry-run]` — copy a reference
|
|
461
|
+
org's Desk (missing users with the e-mail domain swapped, missing teams + members,
|
|
462
|
+
config, tickets with history) into the token's org; match-or-create, safe to re-run.
|
|
463
|
+
Does NOT copy the org's `desk*` feature flags — `features orgs add` them first
|
|
464
|
+
- _Every `desk` verb is **org-scoped from the token** and takes no `org_id`: the
|
|
465
|
+
org is whatever `--server` + `--account` resolve to. Every one EXCEPT
|
|
466
|
+
`ticket create` is admin-only. `ticket create` instead needs Desk access — a
|
|
467
|
+
membership in some Desk team, or platform admin. Either way an integrations
|
|
468
|
+
engineer's own identity in a customer org is refused, so the working identity is
|
|
469
|
+
`dr login-as <customer-admin>` then `--account <that-email>`._
|
|
470
|
+
- _`--attach` is **create-then-upload**, not one call: the confirmation email goes out
|
|
471
|
+
before the files exist, a failed upload exits non-zero naming which files landed, and
|
|
472
|
+
the fix is to attach from the UI — re-running opens a SECOND ticket and re-emails the
|
|
473
|
+
requester. Extensions and the 25 MB cap are checked locally, before the create, and
|
|
474
|
+
`--json` becomes `{ticket, attachments}` (bare ticket when `--attach` is unused), so
|
|
475
|
+
read `.ticket.ticket_number` not `.ticket_number` when attaching._
|
|
476
|
+
- _The description is ALSO posted as the requester's first inbound message by default
|
|
477
|
+
(`--no-thread` opts out), because the UI's conversation pane renders the `messages`
|
|
478
|
+
table and not the `description` column - without it a CLI-created ticket looks empty.
|
|
479
|
+
Sends no email (`direction: inbound`). It does NOT clear the "requester not linked to
|
|
480
|
+
any record" banner - matching only runs in desk-ai's inbound handler; use
|
|
481
|
+
`--contact-id`._
|
|
482
|
+
- _`ticket create` may come back with a different team, status, priority or assignee
|
|
483
|
+
than you sent: an assignee forces `to_do`, an omitted `--due-date` is back-filled
|
|
484
|
+
from the computed SLA, and a routing rule can move the ticket to another team or
|
|
485
|
+
set the priority/assignee **for a flag you did not pass** (passing one suppresses
|
|
486
|
+
the matching rule). The command says so in its output — it is the server, not a
|
|
487
|
+
dropped flag._
|
|
488
|
+
- _`smtp set` reads the password from `--password-file` or `--password-stdin`
|
|
489
|
+
**only** — it is never a command-line argument. A `200` with `verified: false`
|
|
490
|
+
is the normal "customer gave us the wrong credential" outcome, not an error._
|
|
491
|
+
|
|
492
|
+
## Core workflows
|
|
493
|
+
|
|
494
|
+
Add `--json` to any `list`/`get`/`data` when you'll parse the output; the default
|
|
495
|
+
table form is for humans. On Windows, pipe large `--json` to a file first
|
|
496
|
+
(`dr … --json > out.json`) — direct piping into `ConvertFrom-Json` can truncate.
|
|
497
|
+
**Read that file as UTF-8** — dr JSON carries non-ASCII and HTML-escaped entities
|
|
498
|
+
(`&`, `'`, smart quotes); Python's default `cp1252` on Windows raises
|
|
499
|
+
`UnicodeDecodeError` mid-parse (`open(path, encoding="utf-8")`). And note some
|
|
500
|
+
`list` endpoints are **paginated** — `--json` returns a `{count,next,previous,results}`
|
|
501
|
+
envelope with only the first page, not the whole set (e.g. `features list`); pull
|
|
502
|
+
the rest with `--page`/`--page-size` rather than assuming one call is complete.
|
|
503
|
+
|
|
504
|
+
**KB-first when the user speaks product, not CLI.** If the request is a symptom
|
|
505
|
+
or how-to in product terms ("reconciliation isn't pairing", "how do I explain X
|
|
506
|
+
to the customer"), search the Help Center *before* acting: `dr kb search
|
|
507
|
+
"<query>"` (global content — no `--server`) or the `dr-zendesk-kb` MCP. It
|
|
508
|
+
returns the current article as markdown + URL — ground and cite your answer, then
|
|
509
|
+
map to the right `dr` command. Don't rely on memorized KB content; each reference
|
|
510
|
+
file also names the relevant KB folder for its area.
|
|
511
|
+
|
|
512
|
+
**Explore a tenant.** `dr whoami --server US` (confirm tenant) → `templates list`
|
|
513
|
+
→ `dashboards list` → `functions list` → `metrics list`. Pick an ID and drill:
|
|
514
|
+
`templates get <id>` shows field names + IDs you'll need downstream.
|
|
515
|
+
|
|
516
|
+
**Peek at table data.** `templates sample <template_id> --rows 10 --server US`
|
|
517
|
+
(latest version, newest rows). `--fields "A,B"` projects columns; `--offset N`
|
|
518
|
+
pages; `--filter "Region=EU"` / `--filter-range "Period=2026-01..2026-12"`
|
|
519
|
+
narrow rows (dates as calendar dates or epoch seconds — see
|
|
520
|
+
reference/templates.md).
|
|
521
|
+
|
|
522
|
+
**Pull a function definition.** `functions get <id> --server US` returns the
|
|
523
|
+
*definition* — template, field, aggregator, and a **FILTERS** section (each
|
|
524
|
+
persisted filter's field/name/type/excluded/values), plus the default agg date
|
|
525
|
+
field; `--json` adds `filters` + `default_agg_*`. It is **not** the live value
|
|
526
|
+
(that's computed in Excel via `DR.GET`). A date filter's From/To lives inside
|
|
527
|
+
that filter's `values` — read it there instead of asking the customer.
|
|
528
|
+
|
|
529
|
+
**Pull raw rows from a dynamic range.** Ranges nest under a table:
|
|
530
|
+
`dynamic-ranges list --table <template_id>` → `dynamic-ranges data <range_id>
|
|
531
|
+
--table <template_id> --json`.
|
|
532
|
+
|
|
533
|
+
**Pull a KPI value.** `metrics list` → `metrics data --id <id> --scenario Actuals
|
|
534
|
+
--from 2026-03-01 --to 2026-03-31 --server US`. `metrics drilldown --id <id> …`
|
|
535
|
+
returns the source rows behind the number.
|
|
536
|
+
|
|
537
|
+
**Trigger a rescan.** `scans status <template_id>` → `rescan table <template_id>`
|
|
538
|
+
(two-step confirm: the first run prints the blast radius — document + version
|
|
539
|
+
counts — and a token; re-run with `--confirm-token` to fire it) → poll `scans
|
|
540
|
+
status` again. This is a **full historical** rescan (every calc field × every
|
|
541
|
+
version). To only pick up a datamapper change on the live template, prefer
|
|
542
|
+
`datamappers update <id> --rescan latest` (latest version only; mirrors "Publish
|
|
543
|
+
and scan") — far cheaper and lower-blast.
|
|
544
|
+
|
|
545
|
+
**Build a `create` body from plain-English intent** (calc models, datamappers,
|
|
546
|
+
metrics): you resolve names → integer IDs yourself against the tenant
|
|
547
|
+
(`templates list`, `templates get <id>`, `whoami`), construct the body, write it
|
|
548
|
+
to a tmpfile, then `… create --file <tmpfile>`. The operator never captures
|
|
549
|
+
network traffic or hand-edits JSON. Full recipes in the relevant reference file.
|
|
550
|
+
|
|
551
|
+
## Foot-guns
|
|
552
|
+
|
|
553
|
+
- **"System name" is spelled `alias` here.** The Datarails UI, Help Center, and
|
|
554
|
+
most operators say **system name** for a table's or field's stable machine
|
|
555
|
+
identifier — the thing `DR.GET(value,"{department}")` resolves in `{braces}`,
|
|
556
|
+
and the thing template-library import maps on. dr-cli and the monolith API
|
|
557
|
+
both call it `alias`. If an operator asks for a system name, reach for
|
|
558
|
+
`templates set-alias` / `templates set-field-alias`, and read current values
|
|
559
|
+
with `templates get <id> --json` (the text table does not show them). Do not
|
|
560
|
+
report it as unsupported. Note the word is overloaded: command aliases
|
|
561
|
+
(`orgs` → `organizations`), `entities rename --alias` (a *display* name), and
|
|
562
|
+
filebox alias-matching are **not** system names. See reference/templates.md.
|
|
563
|
+
- **Metric value-field aggregators** are `SUM`, `COUNT`, `CUMULATIVE_SUM`,
|
|
564
|
+
`CUMULATIVE_COUNT` only — `AVG`/`MIN`/`MAX` are rejected. See reference/metrics.md.
|
|
565
|
+
- **CALC metric formulas:** each referenced metric name in `[brackets]`;
|
|
566
|
+
constants-only is rejected; reserved tokens `DAYS_IN_PERIOD` /
|
|
567
|
+
`PERIODS_IN_YEAR` are bare (not bracketed); time modifiers are
|
|
568
|
+
`[M].SHIFT(...)` / `[M].AS_OF(...)` — SHIFT unit `consumption_period`
|
|
569
|
+
follows the query grain; `PERIODS_IN_YEAR` metrics reject day-grain
|
|
570
|
+
queries. See reference/metrics.md.
|
|
571
|
+
- **`metrics data --agg`** is `DEFAULT|MTD|QTD|YTD|MTG|QTG|YTG`. The `*TG` "to
|
|
572
|
+
go" values accumulate **forward** from the current bucket (inclusive) to the
|
|
573
|
+
period end — the mirror of `*TD`. See reference/metrics.md.
|
|
574
|
+
- **Calc-model types** are `BEGINNING_BALANCE_Y_TO_M`, `BEGINNING_BALANCE_ONE_TO_M`
|
|
575
|
+
(`ONE_TO_M`, not `ONETIME_TO_M`), `CUMULATIVE_TO_M`. Self-loop models use
|
|
576
|
+
`DAILY`, not `AUTO`. See reference/calcmodels.md.
|
|
577
|
+
- **Calculated values are per-table** — `calc-vals` needs `--table <id>` on every
|
|
578
|
+
subcommand (incl. `get`/`delete`), and is distinct from calc models, functions,
|
|
579
|
+
and metrics. Flag-mode `update` leaves the value's FE "From" source untouched;
|
|
580
|
+
use `--file` to change it. See reference/calc-vals.md.
|
|
581
|
+
- **`templates set-field-type`** accepts `Text|Float|Date|Integer` and is
|
|
582
|
+
confirm-token gated.
|
|
583
|
+
- **Adding a calc column that references a LUT-injected column** (e.g.
|
|
584
|
+
`Amount = [Posting Amount] * [Sign]` where `[Sign]` comes from a lookup and
|
|
585
|
+
lands as **Text**): a plain `datamappers update … --rescan all` 500s
|
|
586
|
+
(`ETLError: … incorrect formula syntax`) because the server *infers* the LUT
|
|
587
|
+
column as Text and `Text * number` won't materialise. The UI "Publish and
|
|
588
|
+
scan" avoids this by sending `fields_to_change`. Replicate it from the CLI
|
|
589
|
+
with `datamappers update <id> --payload-file <p> --field <LUT_col>:Integer
|
|
590
|
+
--rescan all` (repeatable). Caveat: the server **rejects the type change with
|
|
591
|
+
HTTP 400** when the template has more than one mapper. See
|
|
592
|
+
reference/datamappers.md.
|
|
593
|
+
- **`datamappers create` needs the type up-front** — pick `flat`/`dimension`/
|
|
594
|
+
`multiple`/`from-file`. Use `--doc-version` (not `--version`, which collides
|
|
595
|
+
with the global `dr --version`).
|
|
596
|
+
- **Duplicating a mapper onto another table** — `datamappers get <mapper>
|
|
597
|
+
--table <src> --json` emits the source `template_id`; feed the (reshaped) body
|
|
598
|
+
to `datamappers create from-file <target>` and every `map_to` field type is
|
|
599
|
+
auto-resolved from the source template — no manual `--field` per field. It
|
|
600
|
+
**fails loudly** if any `map_to` target can't be resolved on the source rather
|
|
601
|
+
than mis-inferring it (DR-51801). Override with `--field NAME:TYPE`. See
|
|
602
|
+
reference/datamappers.md.
|
|
603
|
+
- **`--table` is required** on `dynamic-ranges list|data` and `lut list` — get the
|
|
604
|
+
template ID from `templates list` first.
|
|
605
|
+
- **`functions get`** returns the definition, never the live value.
|
|
606
|
+
- **Chart type** accepts either a composite literal (`column-stacked-percent`) or
|
|
607
|
+
flags (`--type column --stacked --percent`) — pick one.
|
|
608
|
+
- **`filebox data-query sync`** — scope to a period with `--date YYYY-MM-DD`
|
|
609
|
+
(e.g. `--date 2026-07-01`), not raw `--tag` JSON. The CLI truncates the
|
|
610
|
+
date to whatever granularity the filebox's own DATE tag actually uses —
|
|
611
|
+
no need to know if it's yearly/quarterly/monthly/daily/weekly. `--tag` is
|
|
612
|
+
an unvalidated escape hatch that forwards straight to the server; a
|
|
613
|
+
malformed value 500s with no error body. See reference/filebox-documents.md.
|
|
614
|
+
- **"User has no table permissions" is almost always a misread.** To see which
|
|
615
|
+
tables a user can access, use `dr users permissions get <id>` — never the raw
|
|
616
|
+
`GET /api/it/users/<id>` object's `permissions` field. That field is Django
|
|
617
|
+
**global capability flags** (`user.user_permissions`), empty for essentially
|
|
618
|
+
every VIEWER, and says nothing about data access; real table access lives in the
|
|
619
|
+
`user_to_check_role_id` sweep that `get` runs. See reference/admin.md.
|
|
620
|
+
|
|
621
|
+
## Reference files
|
|
622
|
+
|
|
623
|
+
Read the matching file before operating that area; it carries the valid enums,
|
|
624
|
+
required-flag traps, and create-body recipes that `--help` doesn't spell out.
|
|
625
|
+
Each also names the relevant Help Center (KB) folder for customer-facing docs.
|
|
626
|
+
|
|
627
|
+
- [reference/safety.md](reference/safety.md) — confirm-token flow, interactive prod gate, escalation
|
|
628
|
+
- [reference/templates.md](reference/templates.md) — templates, fields/aliases, data-models, dynamic ranges, scans
|
|
629
|
+
- [reference/datamappers.md](reference/datamappers.md) — datamappers, calc-field formulas, recipes
|
|
630
|
+
- [reference/calcmodels.md](reference/calcmodels.md) — calc-model types, flow, create bodies
|
|
631
|
+
- [reference/calc-vals.md](reference/calc-vals.md) — per-table Calculated Values (formula refs, field/format semantics)
|
|
632
|
+
- [reference/metrics.md](reference/metrics.md) — metrics, categories, dimensions, functions
|
|
633
|
+
- [reference/dashboards-widgets.md](reference/dashboards-widgets.md) — dashboards, widgets, storyboards, reports, extables
|
|
634
|
+
- [reference/filebox-documents.md](reference/filebox-documents.md) — fileboxes, documents
|
|
635
|
+
- [reference/lookups.md](reference/lookups.md) — lookups (LUTs): filebox-sourced + table-sourced
|
|
636
|
+
- [reference/integrations.md](reference/integrations.md) — customer + IT-admin integrations, company data sources (entities)
|
|
637
|
+
- [reference/reconciliation-mec.md](reference/reconciliation-mec.md) — reconciliation, MEC close-dates
|
|
638
|
+
- [reference/workflows.md](reference/workflows.md) — workflow / mec workflow engine, collection processes
|
|
639
|
+
- [reference/forecast.md](reference/forecast.md) — forecast cycles & scenarios (Planning)
|
|
640
|
+
- [reference/cash.md](reference/cash.md) — Cash module
|
|
641
|
+
- [reference/spend-control.md](reference/spend-control.md) — Spend Control module
|
|
642
|
+
- [reference/multi-product.md](reference/multi-product.md) — product-content catalog + per-org assignment (replace-semantics PUT)
|
|
643
|
+
- [reference/desk.md](reference/desk.md) — Desk: outbound-email onboarding (SMTP app password + SendGrid domain auth) and ticket creation
|
|
644
|
+
- [reference/rh-config.md](reference/rh-config.md) — legacy RH_CONFIG inspection (read-only)
|
|
645
|
+
- [reference/admin.md](reference/admin.md) — users, orgs, devices, feature flags, semantic tables, fx, kb, mcp, skill
|
|
646
|
+
|
|
647
|
+
Everything else is discoverable: `dr --help` (families) → `dr <family> --help`
|
|
648
|
+
(subcommands) → `dr <family> <sub> --help` (flags). The binary is the source of
|
|
649
|
+
truth; `docs/reference.html` is a generated dump of all of it.
|
|
650
|
+
|
|
651
|
+
One catch on the first step: `dr --help` enumerates every family only when an
|
|
652
|
+
identity resolves AND that identity's credential scope covers them (see Auth).
|
|
653
|
+
A scope-restricted credential lists fewer families, and for a hidden one
|
|
654
|
+
`dr <family> --help` is refused with exit 3 naming the missing
|
|
655
|
+
`resource:action` — check `dr whoami` before concluding anything. Otherwise the short
|
|
656
|
+
listing is a missing identity: run it as `dr --help --server <key>`, plus
|
|
657
|
+
`--account <email>` where that server holds several identities, and the
|
|
658
|
+
per-family and per-command `--help` render in full either way. A short root
|
|
659
|
+
listing is never a missing command.
|