Skip to content

docs: document embed user pre-provisioning and the split AI billing tabs - #11711

Open
keydunov wants to merge 2 commits into
masterfrom
claude/gallant-ramanujan-sqdmwh
Open

docs: document embed user pre-provisioning and the split AI billing tabs#11711
keydunov wants to merge 2 commits into
masterfrom
claude/gallant-ramanujan-sqdmwh

Conversation

@keydunov

@keydunov keydunov commented Sep 1, 2026

Copy link
Copy Markdown
Member

Check List

  • Docs have been added / updated if required
  • Tests have been run in packages where changes have been made if available
  • Linter has been run for changed code
  • Tests for the changes have been added if not covered yet

Description of Changes Made

Documentation gaps found while cross-checking recent cubedevinc/cubejs-enterprise changes against the docs. All are surgical edits to existing pages — no new pages, no docs.json changes.

  • reference/embed-apis/generate-session.mdx: documents the two new admin endpoints for provisioning an embed user ahead of their first session — POST /api/v1/embed-tenants/{embedTenantName}/user and .../users (bulk).
  • admin/account-billing/ai-tokens.mdx: the single "AI Tokens Usage" tab was split into two tabs, AI Usage and AI Requests; updated the doc to match.
  • admin/deployment/index.mdx: documents the account-wide and per-user default deployment pin (which deployment people land on) and its precedence order.
  • docs/integrations/dbt.mdx: documents the Validation level / Validation schema dbt-push settings, the per-warehouse support caveat, and authoring/validating dbt models conversationally from Analytics Chat.
  • embedding/iframe/creator-mode.mdx: documents the workbook header actions menu (Rename, Duplicate, View all, New workbook, Delete) now available in embedded Creator Mode, and its permission gates.
  • docs/explore-analyze/workbooks/calculated-fields.mdx: distinguishes the structured bins/groups editor from the new SQL-only fallback editor used for CASE expressions, computed calculations, and saved workbook fields.

- reference/embed-apis: document POST .../user and .../users for
  provisioning embed users ahead of their first session (CUB-4148)
- admin/account-billing/ai-tokens: the AI Tokens Usage tab was split into
  AI Usage and AI Requests (CUB-3881); update the tab names accordingly
@mintlify

mintlify Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
cubed3 🟢 Ready View Preview Sep 1, 2026, 12:26 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@claude

claude Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished @keydunov's task in 1m 31s —— View job


Review: docs-only, no blockers — 0 high, 2 medium, 2 low

Docs-only change, both edits land in the right place and match the surrounding style. Main issue: the new section points at a tenantGroups field that isn't documented anywhere on the page, and restates content the generated API reference already carries. 3 inline comments posted.

Full review

Todos

  • Gather context (diff, both files, docs-mintlify/CLAUDE.md)
  • Classify request — code review, no implementation
  • Cross-check claims against docs-mintlify/api-reference/api.yaml
  • Check existing review threads for duplicates (none exist)
  • Post inline comments and summary

What's good

  • Both edits are surgical edits to existing pages, no new pages, no docs.json change — matches the "prefer editing over creating" guidance in docs-mintlify/CLAUDE.md.
  • The new section is placed after the creator-mode bootstrap material and before the admin API section, which is the right narrative slot.
  • Group-field tri-state semantics (replaced when supplied / untouched when omitted / cleared with []) match ProvisionEmbedUserInput in api.yaml:8849-8870 exactly, and match how the existing groups table on the same page describes it.
  • The 100-entry bulk bound and the succeeded/failed partial-success shape both check out against api.yaml:8882-8909.
  • Correctly notes userAttributes/securityContext are not accepted — consistent with the schema, which omits them.

Findings

# Severity File Issue
1 Medium generate-session.mdx:282 tenantGroups is described as one of "the same fields as generate-session above", but it's not in the Request Body table on this page. Dangling reference.
2 Medium generate-session.mdx:271-284 Duplicates provisionEmbedUser / provisionEmbedUsers in api-reference/api.yaml with no cross-link; also drops two load-bearing details (tenant created on demand; tenantGroups must be created first via POST .../groups).
3 Low ai-tokens.mdx:81 "spend" collides with the money sense used at line 55 ("on-demand spending limit"); the subject here is token consumption.
4 Low generate-session.mdx:280 "is partially successful" reads as a property of the call rather than a capability — "supports partial success" is clearer.

Pre-existing, not introduced here

### Response (line 299) is an H3 nested under ## Embed-tenant admin API, so the generate-session response is structurally a subsection of the admin API. This predates the PR, but the new section pushes it one more heading away from the endpoint it documents. Worth promoting to ## and moving it up next to the Request Body table in a follow-up.

Not verifiable here

The AI Usage / AI Requests tab split, and the "per user or per role", "chart or table", "live tail" specifics, come from cubedevinc/cubejs-enterprise and can't be checked against this repo. Taking those on the author's word.

Checks not run

No tests or lint — the diff touches only .mdx content, and this repo has no docs test suite. A yarn dev render check in docs-mintlify/ would confirm the MDX parses, but nothing in the diff uses components or syntax that could break it.

· branch [`claude/gallant-ramanujan-sqdmwh`](https://github.com/cube-js/cube/tree/claude/gallant-ramanujan-sqdmwh)


The singular endpoint provisions one user; the plural endpoint provisions up to 100 in a single request and is partially successful — it returns `succeeded` and `failed` arrays instead of failing the whole batch for one bad entry, with each failure keyed by `externalId`.

Each user takes the same fields as `generate-session` above — `externalId`, `email`, `userProfile`, `groups`, `tenantGroups` — except `userAttributes` and `securityContext`, which every session re-applies and so are not accepted here. Provisioning is idempotent: an existing `externalId` is updated rather than rejected, `email` and `userProfile` are overwritten only when supplied, and each group field is replaced when supplied, left untouched when omitted, and cleared with `[]`. Omit `email` and Cube derives a placeholder address instead, which makes the user harder to recognize in a list.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tenantGroups is presented as one of "the same fields as generate-session above", but it doesn't appear anywhere above on this page — the Request Body table (lines 35–49) documents groups but not tenantGroups. A reader following the "above" pointer to find out what it means comes up empty.

It does exist in the API (api.yaml:8859, and GenerateSession accepts it per api-reference/changelog.mdx:199) — so the fix is to add the missing row to the Request Body table rather than to drop it here:

| tenantGroups | string[] | No | Per-embed-tenant groups for sharing and organizing content within a single embed tenant (creator mode), namespaced separately from the account-wide groups. |

Same page also omits tenantGroupDefinitions and embedTenantProfile from that table for the same reason.

Comment on lines +271 to +284
## Provisioning users ahead of their first session

An embed user is normally created only when they generate their first session — so you cannot add them to a group or share a workbook or dashboard with them until they have opened the embed at least once. To make a user addressable immediately, provision them directly:

```text
POST /api/v1/embed-tenants/{embedTenantName}/user
POST /api/v1/embed-tenants/{embedTenantName}/users
```

The singular endpoint provisions one user; the plural endpoint provisions up to 100 in a single request and is partially successful — it returns `succeeded` and `failed` arrays instead of failing the whole batch for one bad entry, with each failure keyed by `externalId`.

Each user takes the same fields as `generate-session` above — `externalId`, `email`, `userProfile`, `groups`, `tenantGroups` — except `userAttributes` and `securityContext`, which every session re-applies and so are not accepted here. Provisioning is idempotent: an existing `externalId` is updated rather than rejected, `email` and `userProfile` are overwritten only when supplied, and each group field is replaced when supplied, left untouched when omitted, and cleared with `[]`. Omit `email` and Cube derives a placeholder address instead, which makes the user harder to recognize in a list.

These endpoints use the same `Api-Key` authentication as Generate Session and require admin access.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both endpoints are already documented in the generated API reference — provisionEmbedUser (api-reference/api.yaml:3048) and provisionEmbedUsers (:3147), including the 1–100 batch bound, the succeeded/failed shape, and per-field idempotency semantics. This section restates all of it in prose with no link between the two, so they'll drift.

Worth adding a link to the reference (e.g. /api-reference/embed-tenants/provisionembeduser) and trimming the per-field rules here to the pointer plus the one thing the reference doesn't convey — why you'd provision ahead of a session. That's also closer to the docs-mintlify guidance to say it once.

Two details the prose drops that are load-bearing:

  • The embed tenant is created on demand, so {embedTenantName} need not exist yet (api.yaml:3092).
  • tenantGroups entries must be created first via POST /embed-tenants/{embedTenantName}/groups (api.yaml:8867) — otherwise the call fails, and the admin-API section right below this one only documents GET/DELETE for groups.

- Total token usage over time
- Remaining allocation from per-seat grants and token packages
- Breakdown by usage dimension
- **AI Usage** shows spend per user or per role over a billing period, as a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"spend" is ambiguous on this page — it's used a few lines up (line 55) for actual money, in "monthly on-demand spending limit". Here it means token consumption, which is what the sentence above it says ("monitor token consumption"). Suggest keeping the vocabulary consistent:

Suggested change
- **AI Usage** shows spend per user or per role over a billing period, as a
- **AI Usage** shows token consumption per user or per role over a billing
period, as a chart or table, including remaining allocation from per-seat
grants and token packages

…rkbook menu, and calculated-field SQL editor

- admin/deployment: document the account-wide and per-user default
  deployment pin (CUB-4183-ish landing-deployment feature)
- docs/integrations/dbt: document the Validation level / Validation schema
  push settings and authoring dbt models from Analytics Chat
- embedding/iframe/creator-mode: document the workbook header actions menu
  (Rename, Duplicate, View all, New workbook, Delete) in embedded Creator Mode
- docs/explore-analyze/workbooks/calculated-fields: distinguish the
  structured bins/groups editor from the SQL-only fallback editor
@claude

claude Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished @keydunov's task in 1m 59s —— View job


Review of 1e995ae: docs-only, no blockers — 0 high, 3 medium, 3 low

New commit adds four more sections (default deployment, dbt validation levels + Analytics Chat authoring, workbook header controls, calculated-field editor). All land in sensible slots. The one thing worth fixing before merge: the dbt validation-level row leaves two earlier statements on the same page claiming the push is only dbt parse-validated. 4 inline comments posted; the 3 threads from the previous commit still apply.

Full review

Todos

  • Gather context (diff of 52aa2a0..HEAD, four newly-touched files + surrounding sections)
  • Classify request — code review, no implementation
  • Check existing review threads (3 open, all still applicable — none resolved)
  • Verify internal links and cross-page vocabulary
  • Post inline comments and summary

What's good

  • All six edits remain surgical additions to existing pages — no new pages, no docs.json change, matching docs-mintlify/CLAUDE.md.
  • /docs/explore-analyze/analytics-chat resolves (docs/explore-analyze/analytics-chat.mdx); every other internal link in the new text points at an existing anchor.
  • The dbt validation table rows are genuinely useful — the "you own this schema, Cube never creates or drops it, only the temporary relation is cleaned up" detail is exactly the kind of thing a data engineer needs before enabling Build.
  • Warehouse-support <Note> is consistent with the Limitations list further down the page.
  • ### Default deployment sits correctly as an H3 under ## List of deployments, next to the deployments-list screenshot it refers to.
  • MDX components used (<Note>, <Steps>/<Step>, tables) are all in the approved set and nest validly.

Findings

# Severity File Issue
1 Medium dbt.mdx:615 New Parse/Compile/Build setting contradicts two earlier statements (:576 intro and the Push step at ~:666) that still describe validation as dbt parse only.
2 Medium calculated-fields.mdx:150-153 "that same structured editor, letting you change its name and SQL expression" — the bins/groups panel edits boundaries and group membership, not a raw SQL expression; wording looks carried over from the generic editor. Also restates the split already made at :144.
3 Medium deployment/index.mdx:28-37 Precedence prose is hard to follow: bullets run account-wide → per-user but resolution runs the reverse, so "the next one in this order" points backwards; "so it only applies until…" has three candidate antecedents.
4 Low creator-mode.mdx:29-31 Manage / Edit workbook permissions are named but defined nowhere else in docs-mintlify; no link to how an embed user acquires them.
5 Low creator-mode.mdx:29-31 Dashboard section above ends with a "hide header controls" pointer; the workbook section is silent on whether the same is possible.
6 Low dbt.mdx:616 "Required when validation level is Build" vs. the fallback note — unclear whether the schema is still required when the warehouse silently falls back to Parse.

Still open from the previous commit

All three threads on 52aa2a0 remain unresolved and still apply to the current diff — nothing in 1e995ae touched generate-session.mdx or ai-tokens.mdx:

  • generate-session.mdx:282 — dangling tenantGroups reference (not in the Request Body table).
  • generate-session.mdx:284 — duplicates provisionEmbedUser/provisionEmbedUsers from api-reference/api.yaml with no cross-link; drops the on-demand tenant creation and group-must-exist-first details.
  • ai-tokens.mdx:81 — "spend" collides with the money sense used at :55.

Not verifiable here

The Analytics Chat dbt-authoring loop (live sandbox, confirm-before-commit), the workbook actions menu and its permission gating, the default-deployment pinning UI, and the calculated-field editor split all come from cubedevinc/cubejs-enterprise and can't be checked against this repo. Taking those on the author's word; the findings above are internal-consistency issues, not disputes about behavior.

Checks not run

No tests or lint — the diff is .mdx content only and this repo has no docs test suite. A yarn dev render check in docs-mintlify/ would confirm the MDX parses, but the new <Note> and table syntax are structurally identical to what already renders on these pages.

· branch [`claude/gallant-ramanujan-sqdmwh`](https://github.com/cube-js/cube/tree/claude/gallant-ramanujan-sqdmwh)

| --- | --- |
| **Models path** | Directory in the dbt project where generated model files are written. Defaults to `models/marts/cube/`. |
| **Delivery mode** | **Open a pull request** (default) pushes to a `cube/dbt-push/*` branch and opens a PR/MR. **Commit directly to a branch** commits straight to a branch you name — validation still runs. |
| **Validation level** | How thoroughly a model is checked before it's committed: **Parse** only confirms the project still parses; **Compile** also compiles the generated SQL; **Build** additionally runs the model (and its tests) against your warehouse, in the **validation schema** below, so a broken model is caught before the PR opens. |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding configurable validation levels leaves two earlier statements on this page describing only the Parse case as if it were the whole story:

  • Line 576 (section intro): "validated by a real dbt parse in Cube's sandbox before the PR is opened".
  • The Push step (line ~666): "runs dbt deps + dbt parse. If parse fails, the push stops with dbt's own output and no pull request is opened."

A reader who sets Build and then reads the Push step is told their model is only parsed. Both should generalize to "the configured validation level" and point back to this row — otherwise the page contradicts itself on what actually gains the PR its green status.

Fix this →

Comment on lines +150 to +153
Select a calculated field in the sidebar to open its editor. A field created by
the **bins** or **groups** panel reopens that same structured editor, letting you
change its **name** and **SQL expression**. Any other calculated field — a `CASE`
expression, a calculation like **% of total**, or a field saved to the workbook —

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two problems in the structured-editor half of this sentence:

  1. "that same structured editor, letting you change its name and SQL expression" — "that same" points at the bins/groups panel described immediately above (line 144, "Edit bins… or Edit groups…"), but that panel edits boundaries, ranges, label style, group membership — not a raw SQL expression. The old text's "name and SQL expression" reads like it was carried over from the generic editor and reattached to the wrong one. If the structured editor really does expose a SQL box alongside the bins controls, worth saying so explicitly, since line 144 has just told the reader that panel is the structured alternative to hand-written SQL.

  2. This paragraph now overlaps the one at line 144–146, which already says only panel-generated fields offer Edit bins…/Edit groups…. Consider folding the two together rather than restating the same split from the other direction.

Comment on lines +28 to +37
list and chooses **Set as default** (or **Remove as default**). The pinned
deployment is marked with a home icon and becomes the landing deployment for
anyone who hasn't chosen one of their own.
- **Per user** — anyone can pin their own default from their account
**Preferences**, which takes precedence over the account-wide pin. The
deployment you most recently switched to also counts as a personal choice and
outranks the account pin, so it only applies until you actively switch to
something else.

Draft deployments are never candidates for either pin, and a pin you no longer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The precedence story is hard to follow as written:

  • The bullets run Account-widePer user, but resolution runs the other way (per-user pin, then most-recent, then account pin). The closing "skipped in favor of the next one in this order" then points back at a list that reads in the opposite direction of the order it means.
  • "The deployment you most recently switched to also counts as a personal choice and outranks the account pin, so it only applies until you actively switch to something else" — "it" has three candidate antecedents (the personal pin, the most-recent deployment, the account pin). Given "outranks the account pin", the intended subject seems to be the account pin, but the nearest noun is the wrong one.

An explicit ranked list would carry this better than prose, e.g.:

Cube picks the landing deployment in this order, skipping drafts and any deployment you no longer have access to:

  1. Your own default, pinned in account Preferences
  2. The deployment you most recently switched to
  3. The account-wide default, pinned by an admin from the menu in the deployments list (marked with a home icon)

Fix this →

Comment on lines +29 to +31
**Duplicate**, **View all**, **New workbook**, and **Delete**. Rename and Delete
require the embed user's **Manage** permission on the workbook; Duplicate
requires **Manage** or **Edit**. Double-clicking the workbook name also renames

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manage and Edit are introduced here as named workbook permissions, but nothing else in docs-mintlify defines them — grep -rn "Manage" docs/explore-analyze/workbooks/ embedding/iframe/ matches only these two lines. An embed integrator reading this has no way to find out how an embed user acquires Manage vs Edit on a workbook. Worth linking to wherever workbook sharing/permissions are described (or to the group-based sharing model, since the section right below is about embed-tenant groups).

Also, the Dashboard header controls section directly above ends with a pointer to Show or hide header controls. This new section is silent on whether the workbook actions menu can be hidden the same way — a reader will reasonably assume it can. Worth saying either way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants